Browse Source

Fix failing tests

pull/3001/head
Jeremy Koritzinsky 7 years ago
parent
commit
ccfcbadc2f
  1. 2
      src/Markup/Avalonia.Markup.Xaml/XamlIl/AvaloniaXamlIlRuntimeCompiler.cs
  2. 16
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs
  3. 85
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs
  4. 2
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs

2
src/Markup/Avalonia.Markup.Xaml/XamlIl/AvaloniaXamlIlRuntimeCompiler.cs

@ -117,7 +117,7 @@ namespace Avalonia.Markup.Xaml.XamlIl
var tb = _sreBuilder.DefineType("Builder_" + Guid.NewGuid().ToString("N") + "_" + uri); var tb = _sreBuilder.DefineType("Builder_" + Guid.NewGuid().ToString("N") + "_" + uri);
var clrPropertyBuilder = tb.DefineNestedType("ClrProperties_" + Guid.NewGuid().ToString("N")); var clrPropertyBuilder = tb.DefineNestedType("ClrProperties_" + Guid.NewGuid().ToString("N"));
var indexerClosureType = tb.DefineNestedType("IndexerClosure_" + Guid.NewGuid().ToString("N")); var indexerClosureType = _sreBuilder.DefineType("IndexerClosure_" + Guid.NewGuid().ToString("N"));
var compiler = new AvaloniaXamlIlCompiler(new AvaloniaXamlIlCompilerConfiguration(_sreTypeSystem, asm, var compiler = new AvaloniaXamlIlCompiler(new AvaloniaXamlIlCompilerConfiguration(_sreTypeSystem, asm,
_sreMappings, _sreXmlns, AvaloniaXamlIlLanguage.CustomValueConverter, _sreMappings, _sreXmlns, AvaloniaXamlIlLanguage.CustomValueConverter,

16
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs

@ -30,13 +30,19 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
{ {
if (directive.Namespace == XamlNamespaces.Xaml2006 if (directive.Namespace == XamlNamespaces.Xaml2006
&& directive.Name == "DataContextType" && directive.Name == "DataContextType"
&& directive.Values.Count == 1 && directive.Values.Count == 1)
&& directive.Values[0] is XamlIlAstTextNode text)
{ {
on.Children.Remove(child); on.Children.RemoveAt(i);
i--; i--;
directiveDataContextTypeNode = new AvaloniaXamlIlDataContextTypeMetadataNode(on, if (directive.Values[0] is XamlIlAstTextNode text)
XamlIlTypeReferenceResolver.ResolveType(context, text.Text, isMarkupExtension: false, text, strict: true).Type); {
directiveDataContextTypeNode = new AvaloniaXamlIlDataContextTypeMetadataNode(on,
XamlIlTypeReferenceResolver.ResolveType(context, text.Text, isMarkupExtension: false, text, strict: true).Type);
}
else
{
throw new XamlIlParseException("x:DataContextType should be set to a type name.", directive.Values[0]);
}
} }
} }
else if (child is XamlIlAstXamlPropertyValueNode pv else if (child is XamlIlAstXamlPropertyValueNode pv

85
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs

@ -11,11 +11,12 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
{ {
class XamlIlPropertyInfoAccessorFactoryEmitter class XamlIlPropertyInfoAccessorFactoryEmitter
{ {
private bool _indexerClosureTypeInitialized = false; private const string IndexerClosureFactoryMethodName = "CreateAccessor";
private readonly IXamlIlTypeBuilder _indexerClosureType; private readonly IXamlIlTypeBuilder _indexerClosureTypeBuilder;
private IXamlIlType _indexerClosureType;
public XamlIlPropertyInfoAccessorFactoryEmitter(IXamlIlTypeBuilder indexerClosureType) public XamlIlPropertyInfoAccessorFactoryEmitter(IXamlIlTypeBuilder indexerClosureType)
{ {
_indexerClosureType = indexerClosureType; _indexerClosureTypeBuilder = indexerClosureType;
} }
public IXamlIlType EmitLoadInpcPropertyAccessorFactory(XamlIlEmitContext context, IXamlIlEmitter codeGen) public IXamlIlType EmitLoadInpcPropertyAccessorFactory(XamlIlEmitContext context, IXamlIlEmitter codeGen)
@ -32,60 +33,70 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
return EmitCreateAccessorFactoryDelegate(context, codeGen); return EmitCreateAccessorFactoryDelegate(context, codeGen);
} }
private void EmitLoadPropertyAccessorFactory(XamlIlEmitContext context, IXamlIlEmitter codeGen, IXamlIlType type, string accessorFactoryName) private void EmitLoadPropertyAccessorFactory(XamlIlEmitContext context, IXamlIlEmitter codeGen, IXamlIlType type, string accessorFactoryName, bool isStatic = true)
{ {
var types = context.GetAvaloniaTypes(); var types = context.GetAvaloniaTypes();
var weakReferenceType = context.Configuration.TypeSystem.GetType("System.WeakReference"); var weakReferenceType = context.Configuration.TypeSystem.GetType("System.WeakReference");
FindMethodMethodSignature accessorFactorySignature = new FindMethodMethodSignature(accessorFactoryName, types.IPropertyAccessor, weakReferenceType, types.IPropertyInfo) FindMethodMethodSignature accessorFactorySignature = new FindMethodMethodSignature(accessorFactoryName, types.IPropertyAccessor, weakReferenceType, types.IPropertyInfo)
{ {
IsStatic = true IsStatic = isStatic
}; };
codeGen.Ldftn(type.GetMethod(accessorFactorySignature)); codeGen.Ldftn(type.GetMethod(accessorFactorySignature));
} }
public IXamlIlType EmitLoadIndexerAccessorFactory(XamlIlEmitContext context, IXamlIlEmitter codeGen, IXamlIlAstValueNode value) public IXamlIlType EmitLoadIndexerAccessorFactory(XamlIlEmitContext context, IXamlIlEmitter codeGen, IXamlIlAstValueNode value)
{ {
const string indexerClosureFactoryMethodName = "CreateAccessor";
var types = context.GetAvaloniaTypes();
var intType = context.Configuration.TypeSystem.GetType("System.Int32"); var intType = context.Configuration.TypeSystem.GetType("System.Int32");
var weakReferenceType = context.Configuration.TypeSystem.GetType("System.WeakReference"); if (_indexerClosureType is null)
if (!_indexerClosureTypeInitialized)
{ {
var indexAccessorFactoryMethod = context.GetAvaloniaTypes().PropertyInfoAccessorFactory.GetMethod( _indexerClosureType = InitializeClosureType(context);
new FindMethodMethodSignature(
"CreateIndexerPropertyAccessor",
types.IPropertyAccessor,
weakReferenceType,
types.IPropertyInfo,
intType)
{
IsStatic = true
});
var indexField = _indexerClosureType.DefineField(intType, "_index", false, false);
var ctor = _indexerClosureType.DefineConstructor(false, intType);
ctor.Generator
.Ldarg_0()
.Stfld(indexField);
_indexerClosureType.DefineMethod(
types.IPropertyAccessor,
new[] { weakReferenceType, types.IPropertyInfo },
indexerClosureFactoryMethodName,
isPublic: false,
isStatic: false,
isInterfaceImpl: false)
.Generator
.Ldarg_0()
.Ldarg(1)
.Ldfld(indexField)
.EmitCall(indexAccessorFactoryMethod);
} }
context.Emit(value, codeGen, intType); context.Emit(value, codeGen, intType);
codeGen.Newobj(_indexerClosureType.FindConstructor(new List<IXamlIlType> { intType })); codeGen.Newobj(_indexerClosureType.FindConstructor(new List<IXamlIlType> { intType }));
EmitLoadPropertyAccessorFactory(context, codeGen, _indexerClosureType, indexerClosureFactoryMethodName); EmitLoadPropertyAccessorFactory(context, codeGen, _indexerClosureType, IndexerClosureFactoryMethodName, isStatic: false);
return EmitCreateAccessorFactoryDelegate(context, codeGen); return EmitCreateAccessorFactoryDelegate(context, codeGen);
} }
private IXamlIlType InitializeClosureType(XamlIlEmitContext context)
{
var types = context.GetAvaloniaTypes();
var intType = context.Configuration.TypeSystem.GetType("System.Int32");
var weakReferenceType = context.Configuration.TypeSystem.GetType("System.WeakReference");
var indexAccessorFactoryMethod = context.GetAvaloniaTypes().PropertyInfoAccessorFactory.GetMethod(
new FindMethodMethodSignature(
"CreateIndexerPropertyAccessor",
types.IPropertyAccessor,
weakReferenceType,
types.IPropertyInfo,
intType)
{
IsStatic = true
});
var indexField = _indexerClosureTypeBuilder.DefineField(intType, "_index", false, false);
var ctor = _indexerClosureTypeBuilder.DefineConstructor(false, intType);
ctor.Generator
.Ldarg_0()
.Ldarg(1)
.Stfld(indexField)
.Ret();
_indexerClosureTypeBuilder.DefineMethod(
types.IPropertyAccessor,
new[] { weakReferenceType, types.IPropertyInfo },
IndexerClosureFactoryMethodName,
isPublic: true,
isStatic: false,
isInterfaceImpl: false)
.Generator
.Ldarg(1)
.Ldarg(2)
.LdThisFld(indexField)
.EmitCall(indexAccessorFactoryMethod)
.Ret();
return _indexerClosureTypeBuilder.CreateType();
}
private IXamlIlType EmitCreateAccessorFactoryDelegate(XamlIlEmitContext context, IXamlIlEmitter codeGen) private IXamlIlType EmitCreateAccessorFactoryDelegate(XamlIlEmitContext context, IXamlIlEmitter codeGen)
{ {
var types = context.GetAvaloniaTypes(); var types = context.GetAvaloniaTypes();

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

@ -302,7 +302,7 @@ namespace Avalonia.Markup.Xaml.UnitTests
<UserControl <UserControl
xmlns='https://github.com/avaloniaui' xmlns='https://github.com/avaloniaui'
xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests;assembly=Avalonia.Markup.Xaml.UnitTests' xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests;assembly=Avalonia.Markup.Xaml.UnitTests'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' x:DataContextType='{x:Type local:XamlIlBugTestsDataContext}' />"); xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' x:DataContextType='local:XamlIlBugTestsDataContext' />");
} }
} }

Loading…
Cancel
Save