Browse Source

Merge branch 'master' into issue2613

pull/2645/head
FoggyFinder 7 years ago
committed by GitHub
parent
commit
648770741e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      src/Avalonia.Build.Tasks/Program.cs
  2. 7
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs
  3. 2
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
  4. 61
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs
  5. 42
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs

11
src/Avalonia.Build.Tasks/Program.cs

@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.IO;
using System.Linq;
using Microsoft.Build.Framework;
namespace Avalonia.Build.Tasks
@ -11,8 +12,14 @@ namespace Avalonia.Build.Tasks
{
if (args.Length != 3)
{
Console.Error.WriteLine("input references output");
return 1;
if (args.Length == 1)
args = new[] {"original.dll", "references", "out.dll"}
.Select(x => Path.Combine(args[0], x)).ToArray();
else
{
Console.Error.WriteLine("input references output");
return 1;
}
}
return new CompileAvaloniaXamlTask()

7
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs

@ -16,8 +16,10 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
if (!(node is XamlIlAstObjectNode on
&& on.Type.GetClrType().FullName == "Avalonia.Styling.Setter"))
return node;
var parent = context.ParentNodes().OfType<XamlIlAstObjectNode>()
.FirstOrDefault(x => x.Type.GetClrType().FullName == "Avalonia.Styling.Style");
.FirstOrDefault(p => p.Type.GetClrType().FullName == "Avalonia.Styling.Style");
if (parent == null)
throw new XamlIlParseException(
"Avalonia.Styling.Setter is only valid inside Avalonia.Styling.Style", node);
@ -53,8 +55,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
.OfType<XamlIlAstXamlPropertyValueNode>().FirstOrDefault(p => p.Property.GetClrProperty().Name == "Value");
if (valueProperty?.Values?.Count == 1 && valueProperty.Values[0] is XamlIlAstTextNode)
{
var propType = avaloniaPropertyNode.Property.Getter?.ReturnType
?? avaloniaPropertyNode.Property.Setters.First().Parameters[0];
var propType = avaloniaPropertyNode.AvaloniaPropertyType;
if (!XamlIlTransformHelpers.TryGetCorrectlyTypedValue(context, valueProperty.Values[0],
propType, out var converted))
throw new XamlIlParseException(

2
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs

@ -10,6 +10,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public IXamlIlType BindingPriority { get; }
public IXamlIlType AvaloniaObjectExtensions { get; }
public IXamlIlType AvaloniaProperty { get; }
public IXamlIlType AvaloniaPropertyT { get; }
public IXamlIlType IBinding { get; }
public IXamlIlMethod AvaloniaObjectBindMethod { get; }
public IXamlIlMethod AvaloniaObjectSetValueMethod { get; }
@ -26,6 +27,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
IAvaloniaObject = ctx.Configuration.TypeSystem.GetType("Avalonia.IAvaloniaObject");
AvaloniaObjectExtensions = ctx.Configuration.TypeSystem.GetType("Avalonia.AvaloniaObjectExtensions");
AvaloniaProperty = ctx.Configuration.TypeSystem.GetType("Avalonia.AvaloniaProperty");
AvaloniaPropertyT = ctx.Configuration.TypeSystem.GetType("Avalonia.AvaloniaProperty`1");
BindingPriority = ctx.Configuration.TypeSystem.GetType("Avalonia.Data.BindingPriority");
IBinding = ctx.Configuration.TypeSystem.GetType("Avalonia.Data.IBinding");
IDisposable = ctx.Configuration.TypeSystem.GetType("System.IDisposable");

61
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs

@ -44,7 +44,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
return true;
}
public static XamlIlAvaloniaPropertyNode CreateNode(XamlIlAstTransformationContext context,
public static IXamlIlAvaloniaPropertyNode CreateNode(XamlIlAstTransformationContext context,
string propertyName, IXamlIlAstTypeReference selectorTypeReference, IXamlIlLineInfo lineInfo)
{
XamlIlAstNamePropertyReference forgedReference;
@ -63,8 +63,14 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
xmlOwner += parsedPropertyName.owner;
var tref = XamlIlTypeReferenceResolver.ResolveType(context, xmlOwner, false, lineInfo, true);
forgedReference = new XamlIlAstNamePropertyReference(lineInfo,
tref, parsedPropertyName.name, tref);
var propertyFieldName = parsedPropertyName.name + "Property";
var found = tref.Type.GetAllFields()
.FirstOrDefault(f => f.IsStatic && f.IsPublic && f.Name == propertyFieldName);
if (found == null)
throw new XamlIlParseException(
$"Unable to find {propertyFieldName} field on type {tref.Type.GetFullName()}", lineInfo);
return new XamlIlAvaloniaPropertyFieldNode(context.GetAvaloniaTypes(), lineInfo, found);
}
var clrProperty =
@ -75,13 +81,20 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
clrProperty);
}
}
interface IXamlIlAvaloniaPropertyNode : IXamlIlAstValueNode
{
IXamlIlType AvaloniaPropertyType { get; }
}
class XamlIlAvaloniaPropertyNode : XamlIlAstNode, IXamlIlAstValueNode, IXamlIlAstEmitableNode
class XamlIlAvaloniaPropertyNode : XamlIlAstNode, IXamlIlAstValueNode, IXamlIlAstEmitableNode, IXamlIlAvaloniaPropertyNode
{
public XamlIlAvaloniaPropertyNode(IXamlIlLineInfo lineInfo, IXamlIlType type, XamlIlAstClrProperty property) : base(lineInfo)
{
Type = new XamlIlAstClrTypeReference(this, type, false);
Property = property;
AvaloniaPropertyType = Property.Getter?.ReturnType
?? Property.Setters.First().Parameters[0];
}
public XamlIlAstClrProperty Property { get; }
@ -93,6 +106,46 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
throw new XamlIlLoadException(Property.Name + " is not an AvaloniaProperty", this);
return XamlIlNodeEmitResult.Type(0, Type.GetClrType());
}
public IXamlIlType AvaloniaPropertyType { get; }
}
class XamlIlAvaloniaPropertyFieldNode : XamlIlAstNode, IXamlIlAstValueNode, IXamlIlAstEmitableNode, IXamlIlAvaloniaPropertyNode
{
private readonly IXamlIlField _field;
public XamlIlAvaloniaPropertyFieldNode(AvaloniaXamlIlWellKnownTypes types,
IXamlIlLineInfo lineInfo, IXamlIlField field) : base(lineInfo)
{
_field = field;
var avaloniaPropertyType = field.FieldType;
while (avaloniaPropertyType != null)
{
if (avaloniaPropertyType.GenericTypeDefinition?.Equals(types.AvaloniaPropertyT) == true)
{
AvaloniaPropertyType = avaloniaPropertyType.GenericArguments[0];
return;
}
avaloniaPropertyType = avaloniaPropertyType.BaseType;
}
throw new XamlIlParseException(
$"{field.Name}'s type {field.FieldType} doesn't inherit from AvaloniaProperty<T>, make sure to use typed properties",
lineInfo);
}
public IXamlIlAstTypeReference Type => new XamlIlAstClrTypeReference(this, _field.FieldType, false);
public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
{
codeGen.Ldsfld(_field);
return XamlIlNodeEmitResult.Type(0, _field.FieldType);
}
public IXamlIlType AvaloniaPropertyType { get; }
}
interface IXamlIlAvaloniaProperty

42
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs

@ -207,6 +207,33 @@ namespace Avalonia.Markup.Xaml.UnitTests
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'/>", typeof(XamlIlTests).Assembly);
Assert.Equal(Design.GetDataContext(loaded), SomeStaticProperty);
}
[Fact]
public void Attached_Properties_From_Static_Types_Should_Work_In_Style_Setters_Bug_2561()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var parsed = (Window)AvaloniaXamlLoader.Parse(@"
<Window
xmlns='https://github.com/avaloniaui'
xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests;assembly=Avalonia.Markup.Xaml.UnitTests'
>
<Window.Styles>
<Style Selector='TextBox'>
<Setter Property='local:XamlIlBugTestsStaticClassWithAttachedProperty.TestInt' Value='100'/>
</Style>
</Window.Styles>
<TextBox/>
</Window>
");
var tb = ((TextBox)parsed.Content);
parsed.Show();
tb.ApplyTemplate();
Assert.Equal(100, XamlIlBugTestsStaticClassWithAttachedProperty.GetTestInt(tb));
}
}
}
public class XamlIlBugTestsEventHandlerCodeBehind : Window
@ -272,4 +299,19 @@ namespace Avalonia.Markup.Xaml.UnitTests
{
}
public static class XamlIlBugTestsStaticClassWithAttachedProperty
{
public static readonly AvaloniaProperty<int> TestIntProperty = AvaloniaProperty
.RegisterAttached<Control, int>("TestInt", typeof(XamlIlBugTestsStaticClassWithAttachedProperty));
public static void SetTestInt(Control control, int value)
{
control.SetValue(TestIntProperty, value);
}
public static int GetTestInt(Control control)
{
return (int)control.GetValue(TestIntProperty);
}
}
}

Loading…
Cancel
Save