Skip to content

Commit 242a467

Browse files
fix: Address review
1 parent a56325d commit 242a467

File tree

10 files changed

+52
-503
lines changed

10 files changed

+52
-503
lines changed

src/Avalonia.Base/Controls/INotSharedDeferredContent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
/// <summary>
44
/// Represents a not shared deferred content.
55
/// </summary>
6-
public interface INotSharedDeferredContent: IDeferredContent
6+
internal interface INotSharedDeferredContent: IDeferredContent
77
{
88
}

src/Avalonia.Base/Controls/ResourceDictionary.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ public void AddDeferred(object key, Func<IServiceProvider?, object?> factory)
147147
public void AddDeferred(object key, IDeferredContent deferredContent)
148148
=> Add(key, deferredContent);
149149

150-
public void AddNotShared(object key, INotSharedDeferredContent notSharedDeferredContent)
151-
=> Add(key, notSharedDeferredContent);
150+
public void AddNotSharedDeferred(object key, IDeferredContent deferredContent)
151+
=> Add(key, new NotSharedDeferredItem(deferredContent));
152152

153153
public void Clear()
154154
{
@@ -383,10 +383,10 @@ private sealed class DeferredItem : IDeferredContent
383383
public object? Build(IServiceProvider? serviceProvider) => _factory(serviceProvider);
384384
}
385385

386-
private sealed class NotSharedDeferredItem(Func<IServiceProvider?, object?> factory) : INotSharedDeferredContent
386+
private sealed class NotSharedDeferredItem(IDeferredContent deferredContent) : INotSharedDeferredContent
387387
{
388-
private readonly Func<IServiceProvider?, object?> _factory = factory;
389-
public object? Build(IServiceProvider? serviceProvider) => _factory(serviceProvider);
388+
private readonly IDeferredContent _deferredContent = deferredContent ;
389+
public object? Build(IServiceProvider? serviceProvider) => _deferredContent.Build(serviceProvider);
390390
}
391391
}
392392
}

src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AstNodes/XamlNotSharedDeferredContentNode.cs

Lines changed: 0 additions & 219 deletions
This file was deleted.

src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,6 @@ void InsertBeforeMany(Type[] types, params IXamlAstTransformer[] t)
8888

8989
InsertBefore<AvaloniaXamlIlTransformInstanceAttachedProperties>(new AvaloniaXamlIlTransformRoutedEvent());
9090

91-
InsertAfter<AvaloniaXamlIlDeferredResourceTransformer>(new XSharedTransformer());
92-
9391
Transformers.Add(new AvaloniaXamlIlControlTemplatePriorityTransformer());
9492
Transformers.Add(new AvaloniaXamlIlMetadataRemover());
9593
Transformers.Add(new AvaloniaXamlIlEnsureResourceDictionaryCapacityTransformer());

src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDeferredResourceTransformer.cs

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Visitors;
5+
using XamlX;
56
using XamlX.Ast;
67
using XamlX.Emit;
78
using XamlX.IL;
@@ -22,23 +23,61 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod
2223
if (pa.Property.DeclaringType == types.ResourceDictionary && pa.Property.Name == "Content"
2324
&& ShouldBeDeferred(pa.Values[1]))
2425
{
26+
IXamlMethod addMethod = TryGetSharedValue(pa.Values[1], out var isShared) && !isShared
27+
? types.ResourceDictionaryNotSharedDeferedAdd
28+
: types.ResourceDictionaryDeferredAdd;
29+
2530
pa.Values[1] = new XamlDeferredContentNode(pa.Values[1], types.XamlIlTypes.Object, context.Configuration);
2631
pa.PossibleSetters = new List<IXamlPropertySetter>
2732
{
28-
new XamlDirectCallPropertySetter(types.ResourceDictionaryDeferredAdd),
33+
new XamlDirectCallPropertySetter(addMethod),
2934
};
3035
}
3136
else if (pa.Property.Name == "Resources" && pa.Property.Getter?.ReturnType.Equals(types.IResourceDictionary) == true
3237
&& ShouldBeDeferred(pa.Values[1]))
3338
{
39+
IXamlMethod addMethod = TryGetSharedValue(pa.Values[1], out var isShared) && !isShared
40+
? types.ResourceDictionaryNotSharedDeferedAdd
41+
: types.ResourceDictionaryDeferredAdd;
42+
3443
pa.Values[1] = new XamlDeferredContentNode(pa.Values[1], types.XamlIlTypes.Object, context.Configuration);
3544
pa.PossibleSetters = new List<IXamlPropertySetter>
3645
{
37-
new AdderSetter(pa.Property.Getter, types.ResourceDictionaryDeferredAdd),
46+
new AdderSetter(pa.Property.Getter, addMethod),
3847
};
3948
}
4049

4150
return node;
51+
52+
bool TryGetSharedValue(IXamlAstValueNode valueNode, out bool value)
53+
{
54+
value = default;
55+
if (valueNode is XamlAstConstructableObjectNode co)
56+
{
57+
// Try find x:Share directive
58+
if (co.Children.Find(d => d is XamlAstXmlDirective { Namespace: XamlNamespaces.Xaml2006, Name: "Shared" }) is XamlAstXmlDirective sharedDirective)
59+
{
60+
if (sharedDirective.Values.Count == 1 && sharedDirective.Values[0] is XamlAstTextNode text)
61+
{
62+
if (bool.TryParse(text.Text, out var parseValue))
63+
{
64+
// If the parser succeeds, remove the x:Share directive
65+
co.Children.Remove(sharedDirective);
66+
return true;
67+
}
68+
else
69+
{
70+
context.ReportTransformError("Invalid argument type for x:Shared directive.", node);
71+
}
72+
}
73+
else
74+
{
75+
context.ReportTransformError("Invalid number of arguments for x:Shared directive.", node);
76+
}
77+
}
78+
}
79+
return false;
80+
}
4281
}
4382

4483
private static bool ShouldBeDeferred(IXamlAstValueNode node)
@@ -58,14 +97,6 @@ private static bool ShouldBeDeferred(IXamlAstValueNode node)
5897
return false;
5998
}
6099

61-
var sharedVisitor = new NotSharedVisitor();
62-
_ = sharedVisitor.Visit(node);
63-
// Ingnore if Element is marked with x:Shared="false"
64-
if (sharedVisitor.Count > 0)
65-
{
66-
return false;
67-
}
68-
69100
// Do not defer resources, if it has any x:Name registration, as it cannot be delayed.
70101
// This visitor will count x:Name registrations, ignoring nested NestedScopeMetadataNode scopes.
71102
// We set target scope level to 0, assuming that this resource node is a scope of itself.
@@ -79,7 +110,7 @@ private static bool ShouldBeDeferred(IXamlAstValueNode node)
79110

80111
return true;
81112
}
82-
113+
83114
class AdderSetter : IXamlILOptimizedEmitablePropertySetter, IEquatable<AdderSetter>
84115
{
85116
private readonly IXamlMethod _getter;

src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ sealed class AvaloniaXamlIlWellKnownTypes
118118
public IXamlType IResourceDictionary { get; }
119119
public IXamlType ResourceDictionary { get; }
120120
public IXamlMethod ResourceDictionaryDeferredAdd { get; }
121-
public IXamlMethod ResourceDictionaryNotSharedAdd { get; }
121+
public IXamlMethod ResourceDictionaryNotSharedDeferedAdd { get; }
122122
public IXamlMethod ResourceDictionaryEnsureCapacity { get; }
123123
public IXamlMethod ResourceDictionaryGetCount { get; }
124124
public IXamlType IThemeVariantProvider { get; }
@@ -130,7 +130,6 @@ sealed class AvaloniaXamlIlWellKnownTypes
130130
public IXamlType IReadOnlyListOfT { get; }
131131
public IXamlType ControlTemplate { get; }
132132
public IXamlType EventHandlerT { get; }
133-
public IXamlMethod? NotSharedDeferredContentExecutorCustomization { get; set; }
134133

135134
sealed internal class InteractivityWellKnownTypes
136135
{
@@ -314,7 +313,7 @@ public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg)
314313
ResourceDictionary = cfg.TypeSystem.GetType("Avalonia.Controls.ResourceDictionary");
315314
ResourceDictionaryDeferredAdd = ResourceDictionary.GetMethod("AddDeferred", XamlIlTypes.Void, true, XamlIlTypes.Object,
316315
cfg.TypeSystem.GetType("Avalonia.Controls.IDeferredContent"));
317-
ResourceDictionaryNotSharedAdd = ResourceDictionary.GetMethod("AddNotShared", XamlIlTypes.Void, true, XamlIlTypes.Object,
316+
ResourceDictionaryNotSharedDeferedAdd = ResourceDictionary.GetMethod("AddNotSharedDeferred", XamlIlTypes.Void, true, XamlIlTypes.Object,
318317
cfg.TypeSystem.GetType("Avalonia.Controls.INotSharedDeferredContent"));
319318

320319
ResourceDictionaryEnsureCapacity = ResourceDictionary.GetMethod("EnsureCapacity", XamlIlTypes.Void, true, XamlIlTypes.Int32);
@@ -328,9 +327,6 @@ public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg)
328327
IReadOnlyListOfT = cfg.TypeSystem.GetType("System.Collections.Generic.IReadOnlyList`1");
329328
EventHandlerT = cfg.TypeSystem.GetType("System.EventHandler`1");
330329
Interactivity = new InteractivityWellKnownTypes(cfg);
331-
var runtimeHelpers = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.XamlIlRuntimeHelpers");
332-
NotSharedDeferredContentExecutorCustomization =
333-
runtimeHelpers.FindMethod(m => m.Name == "NotSharedDeferredTransformationFactoryV0");
334330
}
335331
}
336332

0 commit comments

Comments
 (0)