diff --git a/api/Avalonia.nupkg.xml b/api/Avalonia.nupkg.xml
index be134deadc..347e6b3b08 100644
--- a/api/Avalonia.nupkg.xml
+++ b/api/Avalonia.nupkg.xml
@@ -7,6 +7,48 @@
baseline/netstandard2.0/Avalonia.Base.dll
target/netstandard2.0/Avalonia.Base.dll
+
+ CP0001
+ T:Avalonia.Data.Core.CastTypePropertyPathElement
+ baseline/netstandard2.0/Avalonia.Base.dll
+ target/netstandard2.0/Avalonia.Base.dll
+
+
+ CP0001
+ T:Avalonia.Data.Core.ChildTraversalPropertyPathElement
+ baseline/netstandard2.0/Avalonia.Base.dll
+ target/netstandard2.0/Avalonia.Base.dll
+
+
+ CP0001
+ T:Avalonia.Data.Core.EnsureTypePropertyPathElement
+ baseline/netstandard2.0/Avalonia.Base.dll
+ target/netstandard2.0/Avalonia.Base.dll
+
+
+ CP0001
+ T:Avalonia.Data.Core.IPropertyPathElement
+ baseline/netstandard2.0/Avalonia.Base.dll
+ target/netstandard2.0/Avalonia.Base.dll
+
+
+ CP0001
+ T:Avalonia.Data.Core.PropertyPath
+ baseline/netstandard2.0/Avalonia.Base.dll
+ target/netstandard2.0/Avalonia.Base.dll
+
+
+ CP0001
+ T:Avalonia.Data.Core.PropertyPathBuilder
+ baseline/netstandard2.0/Avalonia.Base.dll
+ target/netstandard2.0/Avalonia.Base.dll
+
+
+ CP0001
+ T:Avalonia.Data.Core.PropertyPropertyPathElement
+ baseline/netstandard2.0/Avalonia.Base.dll
+ target/netstandard2.0/Avalonia.Base.dll
+
CP0001
T:Avalonia.Utilities.CharacterReader
diff --git a/src/Avalonia.Base/Data/Core/PropertyPath.cs b/src/Avalonia.Base/Data/Core/PropertyPath.cs
deleted file mode 100644
index f5b3f92353..0000000000
--- a/src/Avalonia.Base/Data/Core/PropertyPath.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Avalonia.Data.Core
-{
- public class PropertyPath
- {
- public IReadOnlyList Elements { get; }
-
- public PropertyPath(IEnumerable elements)
- {
- Elements = elements.ToArray();
- }
- }
-
- public class PropertyPathBuilder
- {
- readonly List _elements = new List();
-
- 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; }
- }
-}
diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs
index 4fec398c95..e0225a24f7 100644
--- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs
+++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs
@@ -60,7 +60,6 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
new AvaloniaXamlIlDuplicateSettersChecker(),
new AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer(),
new AvaloniaXamlIlBindingPathParser(),
- new AvaloniaXamlIlPropertyPathTransformer(),
new AvaloniaXamlIlSetterTargetTypeMetadataTransformer(),
new AvaloniaXamlIlSetterTransformer(),
new AvaloniaXamlIlStyleValidatorTransformer(),
diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlPropertyPathTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlPropertyPathTransformer.cs
deleted file mode 100644
index 27413b386a..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlPropertyPathTransformer.cs
+++ /dev/null
@@ -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()
- .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 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();
- 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 context, IXamlILEmitter codeGen);
- IXamlType? Type { get; }
- }
-
- class XamlIlChildTraversalPropertyPathElementNode : IXamlIlPropertyPathElementNode
- {
- public void Emit(XamlEmitContext 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 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 context, IXamlILEmitter codeGen)
- {
- context.Configuration.GetExtra()
- .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 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
- {
- private readonly List _elements;
- private readonly AvaloniaXamlIlWellKnownTypes _types;
-
- public XamlIlPropertyPathNode(IXamlLineInfo lineInfo,
- List 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 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; }
- }
-}
diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs
index 68a5321bf2..86812240df 100644
--- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs
+++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs
@@ -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);
}
diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
index 32c09b5cc7..cab4716aa3 100644
--- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
+++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
@@ -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");
diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/XamlPropertyPathException.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/XamlPropertyPathException.cs
new file mode 100644
index 0000000000..52e10aa4cc
--- /dev/null
+++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/XamlPropertyPathException.cs
@@ -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)
+ {
+ }
+ }
+}