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 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,
_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
&& directive.Name == "DataContextType"
&& directive.Values.Count == 1
&& directive.Values[0] is XamlIlAstTextNode text)
&& directive.Values.Count == 1)
{
on.Children.Remove(child);
on.Children.RemoveAt(i);
i--;
directiveDataContextTypeNode = new AvaloniaXamlIlDataContextTypeMetadataNode(on,
XamlIlTypeReferenceResolver.ResolveType(context, text.Text, isMarkupExtension: false, text, strict: true).Type);
if (directive.Values[0] is XamlIlAstTextNode text)
{
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

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

@ -11,11 +11,12 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
{
class XamlIlPropertyInfoAccessorFactoryEmitter
{
private bool _indexerClosureTypeInitialized = false;
private readonly IXamlIlTypeBuilder _indexerClosureType;
private const string IndexerClosureFactoryMethodName = "CreateAccessor";
private readonly IXamlIlTypeBuilder _indexerClosureTypeBuilder;
private IXamlIlType _indexerClosureType;
public XamlIlPropertyInfoAccessorFactoryEmitter(IXamlIlTypeBuilder indexerClosureType)
{
_indexerClosureType = indexerClosureType;
_indexerClosureTypeBuilder = indexerClosureType;
}
public IXamlIlType EmitLoadInpcPropertyAccessorFactory(XamlIlEmitContext context, IXamlIlEmitter codeGen)
@ -32,60 +33,70 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
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 weakReferenceType = context.Configuration.TypeSystem.GetType("System.WeakReference");
FindMethodMethodSignature accessorFactorySignature = new FindMethodMethodSignature(accessorFactoryName, types.IPropertyAccessor, weakReferenceType, types.IPropertyInfo)
{
IsStatic = true
IsStatic = isStatic
};
codeGen.Ldftn(type.GetMethod(accessorFactorySignature));
}
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 weakReferenceType = context.Configuration.TypeSystem.GetType("System.WeakReference");
if (!_indexerClosureTypeInitialized)
if (_indexerClosureType is null)
{
var indexAccessorFactoryMethod = context.GetAvaloniaTypes().PropertyInfoAccessorFactory.GetMethod(
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);
_indexerClosureType = InitializeClosureType(context);
}
context.Emit(value, codeGen, 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);
}
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)
{
var types = context.GetAvaloniaTypes();

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

@ -302,7 +302,7 @@ namespace Avalonia.Markup.Xaml.UnitTests
<UserControl
xmlns='https://github.com/avaloniaui'
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