Remove PropertyPath. (#19133)
* Remove PropertyPath. It was added as part of #2734 with the intention of it being used for animation setters, but this was never implemented. There's no point carrying this old unused code around - if we want to implement this feature we can add it back in. * Update API suppressions.
This commit is contained in:
@@ -7,6 +7,48 @@
|
||||
<Left>baseline/netstandard2.0/Avalonia.Base.dll</Left>
|
||||
<Right>target/netstandard2.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Avalonia.Data.Core.CastTypePropertyPathElement</Target>
|
||||
<Left>baseline/netstandard2.0/Avalonia.Base.dll</Left>
|
||||
<Right>target/netstandard2.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Avalonia.Data.Core.ChildTraversalPropertyPathElement</Target>
|
||||
<Left>baseline/netstandard2.0/Avalonia.Base.dll</Left>
|
||||
<Right>target/netstandard2.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Avalonia.Data.Core.EnsureTypePropertyPathElement</Target>
|
||||
<Left>baseline/netstandard2.0/Avalonia.Base.dll</Left>
|
||||
<Right>target/netstandard2.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Avalonia.Data.Core.IPropertyPathElement</Target>
|
||||
<Left>baseline/netstandard2.0/Avalonia.Base.dll</Left>
|
||||
<Right>target/netstandard2.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Avalonia.Data.Core.PropertyPath</Target>
|
||||
<Left>baseline/netstandard2.0/Avalonia.Base.dll</Left>
|
||||
<Right>target/netstandard2.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Avalonia.Data.Core.PropertyPathBuilder</Target>
|
||||
<Left>baseline/netstandard2.0/Avalonia.Base.dll</Left>
|
||||
<Right>target/netstandard2.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Avalonia.Data.Core.PropertyPropertyPathElement</Target>
|
||||
<Left>baseline/netstandard2.0/Avalonia.Base.dll</Left>
|
||||
<Right>target/netstandard2.0/Avalonia.Base.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Avalonia.Utilities.CharacterReader</Target>
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Avalonia.Data.Core
|
||||
{
|
||||
public class PropertyPath
|
||||
{
|
||||
public IReadOnlyList<IPropertyPathElement> Elements { get; }
|
||||
|
||||
public PropertyPath(IEnumerable<IPropertyPathElement> elements)
|
||||
{
|
||||
Elements = elements.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyPathBuilder
|
||||
{
|
||||
readonly List<IPropertyPathElement> _elements = new List<IPropertyPathElement>();
|
||||
|
||||
public PropertyPathBuilder Property(IPropertyInfo property)
|
||||
{
|
||||
_elements.Add(new PropertyPropertyPathElement(property));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public PropertyPathBuilder ChildTraversal()
|
||||
{
|
||||
_elements.Add(new ChildTraversalPropertyPathElement());
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyPathBuilder EnsureType(Type type)
|
||||
{
|
||||
_elements.Add(new EnsureTypePropertyPathElement(type));
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyPathBuilder Cast(Type type)
|
||||
{
|
||||
_elements.Add(new CastTypePropertyPathElement(type));
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyPath Build()
|
||||
{
|
||||
return new PropertyPath(_elements);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IPropertyPathElement
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class PropertyPropertyPathElement : IPropertyPathElement
|
||||
{
|
||||
public IPropertyInfo Property { get; }
|
||||
|
||||
public PropertyPropertyPathElement(IPropertyInfo property)
|
||||
{
|
||||
Property = property;
|
||||
}
|
||||
}
|
||||
|
||||
public class ChildTraversalPropertyPathElement : IPropertyPathElement
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EnsureTypePropertyPathElement : IPropertyPathElement
|
||||
{
|
||||
public Type Type { get; }
|
||||
|
||||
public EnsureTypePropertyPathElement(Type type)
|
||||
{
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
|
||||
public class CastTypePropertyPathElement : IPropertyPathElement
|
||||
{
|
||||
public CastTypePropertyPathElement(Type type)
|
||||
{
|
||||
Type = type;
|
||||
}
|
||||
|
||||
public Type Type { get; }
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,6 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
|
||||
new AvaloniaXamlIlDuplicateSettersChecker(),
|
||||
new AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer(),
|
||||
new AvaloniaXamlIlBindingPathParser(),
|
||||
new AvaloniaXamlIlPropertyPathTransformer(),
|
||||
new AvaloniaXamlIlSetterTargetTypeMetadataTransformer(),
|
||||
new AvaloniaXamlIlSetterTransformer(),
|
||||
new AvaloniaXamlIlStyleValidatorTransformer(),
|
||||
|
||||
-262
@@ -1,262 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Avalonia.Markup.Parsers;
|
||||
using XamlX;
|
||||
using XamlX.Ast;
|
||||
using XamlX.Transform;
|
||||
using XamlX.Transform.Transformers;
|
||||
using XamlX.TypeSystem;
|
||||
using XamlX.Emit;
|
||||
using XamlX.IL;
|
||||
|
||||
namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
||||
{
|
||||
class XamlPropertyPathException : XamlTransformException
|
||||
{
|
||||
public XamlPropertyPathException(string message, IXamlLineInfo lineInfo, Exception? innerException = null)
|
||||
: base(message, lineInfo, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class AvaloniaXamlIlPropertyPathTransformer : IXamlAstTransformer
|
||||
{
|
||||
public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
|
||||
{
|
||||
if (node is XamlAstXamlPropertyValueNode pv
|
||||
&& pv.Values.Count == 1
|
||||
&& pv.Values[0] is XamlAstTextNode text
|
||||
&& pv.Property.GetClrProperty().Getter?.ReturnType
|
||||
.Equals(context.GetAvaloniaTypes().PropertyPath) == true
|
||||
)
|
||||
{
|
||||
var parentScope = context.ParentNodes().OfType<AvaloniaXamlIlTargetTypeMetadataNode>()
|
||||
.FirstOrDefault();
|
||||
if(parentScope == null)
|
||||
throw new XamlPropertyPathException("No target type scope found for property path", text);
|
||||
if (parentScope.ScopeType != AvaloniaXamlIlTargetTypeMetadataNode.ScopeTypes.Style)
|
||||
throw new XamlPropertyPathException("PropertyPath is currently only valid for styles", pv);
|
||||
|
||||
|
||||
IEnumerable<PropertyPathGrammar.ISyntax> parsed;
|
||||
try
|
||||
{
|
||||
parsed = PropertyPathGrammar.Parse(text.Text);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new XamlPropertyPathException("Unable to parse PropertyPath: " + e.Message, text, innerException: e);
|
||||
}
|
||||
|
||||
var elements = new List<IXamlIlPropertyPathElementNode>();
|
||||
var currentType = parentScope.TargetType.GetClrType();
|
||||
|
||||
|
||||
var expectProperty = true;
|
||||
var expectCast = true;
|
||||
var expectTraversal = false;
|
||||
var types = context.GetAvaloniaTypes();
|
||||
|
||||
IXamlType GetType(string? ns, string name)
|
||||
{
|
||||
return TypeReferenceResolver.ResolveType(context, $"{ns}:{name}", false,
|
||||
text, true).GetClrType();
|
||||
}
|
||||
|
||||
void HandleProperty(string name, string? typeNamespace, string? typeName)
|
||||
{
|
||||
if(!expectProperty || currentType == null)
|
||||
throw new XamlPropertyPathException("Unexpected property node", text);
|
||||
|
||||
var propertySearchType =
|
||||
typeName != null ? GetType(typeNamespace, typeName) : currentType;
|
||||
|
||||
IXamlIlPropertyPathElementNode? prop = null;
|
||||
var avaloniaPropertyFieldName = name + "Property";
|
||||
var avaloniaPropertyField = propertySearchType.GetAllFields().FirstOrDefault(f =>
|
||||
f.IsStatic && f.IsPublic && f.Name == avaloniaPropertyFieldName);
|
||||
if (avaloniaPropertyField != null)
|
||||
{
|
||||
prop = new XamlIlAvaloniaPropertyPropertyPathElementNode(avaloniaPropertyField,
|
||||
XamlIlAvaloniaPropertyHelper.GetAvaloniaPropertyType(avaloniaPropertyField, types, text));
|
||||
}
|
||||
else
|
||||
{
|
||||
var clrProperty = propertySearchType.GetAllProperties().FirstOrDefault(p => p.Name == name);
|
||||
if (clrProperty is not null)
|
||||
prop = new XamlIClrPropertyPathElementNode(clrProperty);
|
||||
}
|
||||
|
||||
if (prop == null)
|
||||
throw new XamlPropertyPathException(
|
||||
$"Unable to resolve property {name} on type {propertySearchType.GetFqn()}",
|
||||
text);
|
||||
|
||||
currentType = prop.Type;
|
||||
elements.Add(prop);
|
||||
expectProperty = false;
|
||||
expectTraversal = expectCast = true;
|
||||
}
|
||||
|
||||
foreach (var ge in parsed)
|
||||
{
|
||||
if (ge is PropertyPathGrammar.ChildTraversalSyntax)
|
||||
{
|
||||
if (!expectTraversal)
|
||||
throw new XamlPropertyPathException("Unexpected child traversal .", text);
|
||||
elements.Add(new XamlIlChildTraversalPropertyPathElementNode());
|
||||
expectTraversal = expectCast = false;
|
||||
expectProperty = true;
|
||||
}
|
||||
else if (ge is PropertyPathGrammar.EnsureTypeSyntax ets)
|
||||
{
|
||||
if(!expectCast)
|
||||
throw new XamlPropertyPathException("Unexpected cast node", text);
|
||||
currentType = GetType(ets.TypeNamespace, ets.TypeName);
|
||||
elements.Add(new XamlIlCastPropertyPathElementNode(currentType, true));
|
||||
expectProperty = false;
|
||||
expectCast = expectTraversal = true;
|
||||
}
|
||||
else if (ge is PropertyPathGrammar.CastTypeSyntax cts)
|
||||
{
|
||||
if(!expectCast)
|
||||
throw new XamlPropertyPathException("Unexpected cast node", text);
|
||||
//TODO: Check if cast can be done
|
||||
currentType = GetType(cts.TypeNamespace, cts.TypeName);
|
||||
elements.Add(new XamlIlCastPropertyPathElementNode(currentType, false));
|
||||
expectProperty = false;
|
||||
expectCast = expectTraversal = true;
|
||||
}
|
||||
else if (ge is PropertyPathGrammar.PropertySyntax ps)
|
||||
{
|
||||
HandleProperty(ps.Name, null, null);
|
||||
}
|
||||
else if (ge is PropertyPathGrammar.TypeQualifiedPropertySyntax tqps)
|
||||
{
|
||||
HandleProperty(tqps.Name, tqps.TypeNamespace, tqps.TypeName);
|
||||
}
|
||||
else
|
||||
throw new XamlPropertyPathException("Unexpected node " + ge, text);
|
||||
|
||||
}
|
||||
var propertyPathNode = new XamlIlPropertyPathNode(text, elements, types);
|
||||
if (propertyPathNode.Type == null)
|
||||
throw new XamlPropertyPathException("Unexpected end of the property path", text);
|
||||
pv.Values[0] = propertyPathNode;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
interface IXamlIlPropertyPathElementNode
|
||||
{
|
||||
void Emit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen);
|
||||
IXamlType? Type { get; }
|
||||
}
|
||||
|
||||
class XamlIlChildTraversalPropertyPathElementNode : IXamlIlPropertyPathElementNode
|
||||
{
|
||||
public void Emit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
||||
=> codeGen.EmitCall(
|
||||
context.GetAvaloniaTypes()
|
||||
.PropertyPathBuilder.GetMethod(m => m.Name == "ChildTraversal"));
|
||||
|
||||
public IXamlType? Type => null;
|
||||
}
|
||||
|
||||
class XamlIlAvaloniaPropertyPropertyPathElementNode : IXamlIlPropertyPathElementNode
|
||||
{
|
||||
private readonly IXamlField _field;
|
||||
|
||||
public XamlIlAvaloniaPropertyPropertyPathElementNode(IXamlField field, IXamlType propertyType)
|
||||
{
|
||||
_field = field;
|
||||
Type = propertyType;
|
||||
}
|
||||
|
||||
public void Emit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
||||
=> codeGen
|
||||
.Ldsfld(_field)
|
||||
.EmitCall(context.GetAvaloniaTypes()
|
||||
.PropertyPathBuilder.GetMethod(m => m.Name == "Property"));
|
||||
|
||||
public IXamlType Type { get; }
|
||||
}
|
||||
|
||||
class XamlIClrPropertyPathElementNode : IXamlIlPropertyPathElementNode
|
||||
{
|
||||
private readonly IXamlProperty _property;
|
||||
|
||||
public XamlIClrPropertyPathElementNode(IXamlProperty property)
|
||||
{
|
||||
_property = property;
|
||||
}
|
||||
|
||||
public void Emit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
||||
{
|
||||
context.Configuration.GetExtra<XamlIlClrPropertyInfoEmitter>()
|
||||
.Emit(context, codeGen, _property);
|
||||
|
||||
codeGen.EmitCall(context.GetAvaloniaTypes()
|
||||
.PropertyPathBuilder.GetMethod(m => m.Name == "Property"));
|
||||
}
|
||||
|
||||
public IXamlType Type => _property.PropertyType;
|
||||
}
|
||||
|
||||
class XamlIlCastPropertyPathElementNode : IXamlIlPropertyPathElementNode
|
||||
{
|
||||
private readonly IXamlType _type;
|
||||
private readonly bool _ensureType;
|
||||
|
||||
public XamlIlCastPropertyPathElementNode(IXamlType type, bool ensureType)
|
||||
{
|
||||
_type = type;
|
||||
_ensureType = ensureType;
|
||||
}
|
||||
|
||||
public void Emit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
||||
{
|
||||
codeGen
|
||||
.Ldtype(_type)
|
||||
.EmitCall(context.GetAvaloniaTypes()
|
||||
.PropertyPathBuilder.GetMethod(m => m.Name == (_ensureType ? "EnsureType" : "Cast")));
|
||||
}
|
||||
|
||||
public IXamlType Type => _type;
|
||||
}
|
||||
|
||||
class XamlIlPropertyPathNode : XamlAstNode, IXamlIlPropertyPathNode, IXamlAstEmitableNode<IXamlILEmitter, XamlILNodeEmitResult>
|
||||
{
|
||||
private readonly List<IXamlIlPropertyPathElementNode> _elements;
|
||||
private readonly AvaloniaXamlIlWellKnownTypes _types;
|
||||
|
||||
public XamlIlPropertyPathNode(IXamlLineInfo lineInfo,
|
||||
List<IXamlIlPropertyPathElementNode> elements,
|
||||
AvaloniaXamlIlWellKnownTypes types) : base(lineInfo)
|
||||
{
|
||||
_elements = elements;
|
||||
_types = types;
|
||||
Type = new XamlAstClrTypeReference(this, types.PropertyPath, false);
|
||||
}
|
||||
|
||||
public IXamlAstTypeReference Type { get; }
|
||||
public IXamlType? PropertyType => _elements.LastOrDefault()?.Type;
|
||||
public XamlILNodeEmitResult Emit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
||||
{
|
||||
codeGen
|
||||
.Newobj(_types.PropertyPathBuilder.GetConstructor());
|
||||
foreach(var e in _elements)
|
||||
e.Emit(context, codeGen);
|
||||
codeGen.EmitCall(_types.PropertyPathBuilder.GetMethod(m => m.Name == "Build"));
|
||||
return XamlILNodeEmitResult.Type(0, _types.PropertyPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface IXamlIlPropertyPathNode : IXamlAstValueNode
|
||||
{
|
||||
IXamlType? PropertyType { get; }
|
||||
}
|
||||
}
|
||||
-3
@@ -77,9 +77,6 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
||||
.FirstOrDefault(x => x.Property.GetClrProperty().Name == "PropertyPath");
|
||||
if (propertyPath == null)
|
||||
throw new XamlStyleTransformException("Setter without a property or property path is not valid", node);
|
||||
if (propertyPath.Values[0] is IXamlIlPropertyPathNode ppn
|
||||
&& ppn.PropertyType != null)
|
||||
propType = ppn.PropertyType;
|
||||
else
|
||||
throw new XamlStyleTransformException("Unable to get the property path property type", node);
|
||||
}
|
||||
|
||||
-4
@@ -49,8 +49,6 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
||||
public IXamlMethod INameScopeComplete { get; }
|
||||
public IXamlType IPropertyInfo { get; }
|
||||
public IXamlType ClrPropertyInfo { get; }
|
||||
public IXamlType PropertyPath { get; }
|
||||
public IXamlType PropertyPathBuilder { get; }
|
||||
public IXamlType IPropertyAccessor { get; }
|
||||
public IXamlType PropertyInfoAccessorFactory { get; }
|
||||
public IXamlType CompiledBindingPathBuilder { get; }
|
||||
@@ -240,8 +238,6 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
||||
false, AvaloniaProperty, XamlIlTypes.Object, BindingPriority);
|
||||
IPropertyInfo = cfg.TypeSystem.GetType("Avalonia.Data.Core.IPropertyInfo");
|
||||
ClrPropertyInfo = cfg.TypeSystem.GetType("Avalonia.Data.Core.ClrPropertyInfo");
|
||||
PropertyPath = cfg.TypeSystem.GetType("Avalonia.Data.Core.PropertyPath");
|
||||
PropertyPathBuilder = cfg.TypeSystem.GetType("Avalonia.Data.Core.PropertyPathBuilder");
|
||||
IPropertyAccessor = cfg.TypeSystem.GetType("Avalonia.Data.Core.Plugins.IPropertyAccessor");
|
||||
PropertyInfoAccessorFactory = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.PropertyInfoAccessorFactory");
|
||||
CompiledBindingPathBuilder = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.CompiledBindingPathBuilder");
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using XamlX;
|
||||
using XamlX.Ast;
|
||||
|
||||
namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
||||
{
|
||||
internal class XamlPropertyPathException : XamlTransformException
|
||||
{
|
||||
public XamlPropertyPathException(string message, IXamlLineInfo lineInfo, Exception? innerException = null)
|
||||
: base(message, lineInfo, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user