Browse Source

Convert IAvaloniaXamlIlParentStackProvider to eager one if needed (#16028)

pull/16058/head
Julien Lebosquain 2 years ago
committed by GitHub
parent
commit
4aec7acdd4
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 17
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs
  2. 1
      src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
  3. 27
      src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlParentStackProviderWrapper.cs
  4. 8
      src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs

17
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs

@ -76,7 +76,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
ContextTypeBuilderCallback = definition =>
{
EmitNameScopeField(rv, typeSystem, definition);
EmitEagerParentStackProvider(rv, typeSystem, definition);
EmitEagerParentStackProvider(rv, typeSystem, definition, runtimeHelpers);
}
};
return (rv, emit);
@ -104,7 +104,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
private static void EmitEagerParentStackProvider(
XamlLanguageTypeMappings mappings,
IXamlTypeSystem typeSystem,
IXamlILContextDefinition<IXamlILEmitter> definition)
IXamlILContextDefinition<IXamlILEmitter> definition,
IXamlType runtimeHelpers)
{
var interfaceType = typeSystem.FindType("Avalonia.Markup.Xaml.XamlIl.Runtime.IAvaloniaXamlIlEagerParentStackProvider");
@ -122,14 +123,22 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
typeSystem.FindType("System.Object"),
typeSystem.FindType("System.Type")));
var asEagerParentStackProviderMethod = runtimeHelpers.GetMethod(new FindMethodMethodSignature(
"AsEagerParentStackProvider",
interfaceType,
mappings.ParentStackProvider)
{
IsStatic = true
});
// IAvaloniaXamlIlEagerParentStackProvider? ParentProvider
// => (IAvaloniaXamlIlEagerParentStackProvider)_serviceProvider.GetService(typeof(IAvaloniaXamlIlParentStackProvider))
// => XamlIlRuntimeHelpers.AsEagerParentStackProvider(_serviceProvider.GetService(typeof(IAvaloniaXamlIlParentStackProvider)));
var parentProviderGetter = ImplementInterfacePropertyGetter("ParentProvider");
parentProviderGetter.Generator
.LdThisFld(definition.ParentServiceProviderField)
.Ldtype(mappings.ParentStackProvider)
.EmitCall(serviceProviderGetServiceMethod)
.Castclass(interfaceType)
.EmitCall(asEagerParentStackProviderMethod)
.Ret();
IXamlMethodBuilder<IXamlILEmitter> ImplementInterfacePropertyGetter(string propertyName)

1
src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj

@ -52,6 +52,7 @@
<Compile Include="XamlIl\Runtime\IAvaloniaXamlIlControlTemplateProvider.cs" />
<Compile Include="XamlIl\Runtime\IAvaloniaXamlIlParentStackProvider.cs" />
<Compile Include="XamlIl\Runtime\IAvaloniaXamlIlXmlNamespaceInfoProviderV1.cs" />
<Compile Include="XamlIl\Runtime\XamlIlParentStackProviderWrapper.cs" />
<Compile Include="XamlIl\Runtime\XamlIlRuntimeHelpers.cs" />
<Compile Include="XamlLoadException.cs" />
<Compile Include="XamlTypes.cs" />

27
src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlParentStackProviderWrapper.cs

@ -0,0 +1,27 @@
using System.Collections.Generic;
using System.Linq;
namespace Avalonia.Markup.Xaml.XamlIl.Runtime;
/// <summary>
/// Wraps a <see cref="IAvaloniaXamlIlParentStackProvider"/> into a <see cref="IAvaloniaXamlIlEagerParentStackProvider"/>,
/// for backwards compatibility.
/// </summary>
internal sealed class XamlIlParentStackProviderWrapper : IAvaloniaXamlIlEagerParentStackProvider
{
private readonly IAvaloniaXamlIlParentStackProvider _provider;
private IReadOnlyList<object>? _directParentsStack;
public XamlIlParentStackProviderWrapper(IAvaloniaXamlIlParentStackProvider provider)
=> _provider = provider;
public IEnumerable<object> Parents
=> _provider.Parents;
public IReadOnlyList<object> DirectParentsStack
=> _directParentsStack ??= _provider.Parents.Reverse().ToArray();
public IAvaloniaXamlIlEagerParentStackProvider? ParentProvider
=> null;
}

8
src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs

@ -95,6 +95,14 @@ namespace Avalonia.Markup.Xaml.XamlIl.Runtime
return resourceNodes;
}
/// <summary>
/// Converts a <see cref="IAvaloniaXamlIlParentStackProvider"/> into a
/// <see cref="IAvaloniaXamlIlEagerParentStackProvider"/>.
/// </summary>
public static IAvaloniaXamlIlEagerParentStackProvider AsEagerParentStackProvider(
this IAvaloniaXamlIlParentStackProvider provider)
=> provider as IAvaloniaXamlIlEagerParentStackProvider ?? new XamlIlParentStackProviderWrapper(provider);
// Parent resource nodes are often the same (e.g. most values in a ResourceDictionary), cache the last ones.
private sealed class LastParentStack
{

Loading…
Cancel
Save