Skip to content

Commit 0fdb9ff

Browse files
[XC] add IRootObjectProvider (#28310)
* [XC] add IRootObjectProvider this was never meant to be public, but it was. and people are using it - fixes #16881 * ignore case
1 parent f709bc7 commit 0fdb9ff

File tree

12 files changed

+68
-15
lines changed

12 files changed

+68
-15
lines changed

src/Controls/src/Build.Tasks/NodeILExtensions.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,8 @@ public static IEnumerable<Instruction> PushServiceProvider(this INode node, ILCo
625625
//Add a SimpleValueTargetProvider and register it as IProvideValueTarget, IReferenceProvider and IProvideParentValues
626626
if (createAllServices
627627
|| requiredServices.Contains(module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IProvideParentValues")), TypeRefComparer.Default)
628-
|| requiredServices.Contains(module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IReferenceProvider")), TypeRefComparer.Default))
628+
|| requiredServices.Contains(module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IReferenceProvider")), TypeRefComparer.Default)
629+
|| requiredServices.Contains(module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IRootObjectProvider")), TypeRefComparer.Default))
629630
{
630631
alreadyContainsProvideValueTarget = true;
631632
var pushParentIl = node.PushParentObjectsArray(context).ToList();
@@ -644,9 +645,25 @@ public static IEnumerable<Instruction> PushServiceProvider(this INode node, ILCo
644645
foreach (var instruction in PushNamescopes(node, context, module))
645646
yield return instruction;
646647

647-
yield return Create(Ldc_I4_0); //don't ask
648+
//rootObject
649+
if (context.Root is VariableDefinition rootVariable)
650+
yield return Create(Ldloc, rootVariable);
651+
else if (context.Root is FieldReference rootField)
652+
{
653+
yield return Create(Ldarg_0);
654+
yield return Create(Ldfld, rootField);
655+
}
656+
else
657+
yield return Create(Ldnull);
658+
648659
yield return Create(Newobj, module.ImportCtorReference(context.Cache,
649-
("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "SimpleValueTargetProvider"), paramCount: 4));
660+
type: ("Microsoft.Maui.Controls.Xaml", "Microsoft.Maui.Controls.Xaml.Internals", "SimpleValueTargetProvider"),
661+
parameterTypes: [
662+
("mscorlib", "System", "Object[]"),
663+
("mscorlib", "System", "Object"),
664+
("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "INameScope[]"),
665+
("mscorlib", "System", "Object"),
666+
]));
650667

651668
//store the provider so we can register it again with a different key
652669
yield return Create(Dup);
@@ -660,6 +677,12 @@ public static IEnumerable<Instruction> PushServiceProvider(this INode node, ILCo
660677
yield return Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
661678
yield return Create(Ldloc, refProvider);
662679
yield return Create(Callvirt, addService);
680+
681+
yield return Create(Dup); //Keep the serviceProvider on the stack
682+
yield return Create(Ldtoken, module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Xaml", "IRootObjectProvider")));
683+
yield return Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
684+
yield return Create(Ldloc, refProvider);
685+
yield return Create(Callvirt, addService);
663686
}
664687
}
665688

src/Controls/src/Build.Tasks/XamlCache.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Microsoft.Maui.Controls.XamlC;
44
using Mono.Cecil;
55
using Mono.Cecil.Cil;
6+
using Mono.Cecil.Rocks;
67

78
namespace Microsoft.Maui.Controls.Build.Tasks;
89

@@ -38,8 +39,13 @@ public TypeDefinition Resolve(TypeReference typeReference) =>
3839
public FieldReference GetOrAddFieldReference((ModuleDefinition module, string fieldRefKey) key, Func<(ModuleDefinition module, string fieldRefKey), FieldReference> valueFactory) =>
3940
GetOrAdd(_fieldReferenceCache, key, valueFactory);
4041

41-
public TypeReference GetOrAddTypeReference(ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type) =>
42-
GetOrAdd(_typeReferenceCache, (module, type.ToString()), x => x.module.ImportReference(x.module.GetTypeDefinition(this, type)));
42+
public TypeReference GetOrAddTypeReference(ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type) => GetOrAdd(_typeReferenceCache, (module, type.ToString()), x =>
43+
{
44+
if (type.typeName.EndsWith("[]", StringComparison.InvariantCultureIgnoreCase))
45+
return x.module.GetTypeDefinition(this, (type.assemblyName, type.clrNamespace, type.typeName.Substring(0, type.typeName.Length-2))).MakeArrayType();
46+
else
47+
return x.module.ImportReference(x.module.GetTypeDefinition(this, type));
48+
});
4349

4450
public TypeReference GetOrAddTypeReference(ModuleDefinition module, string typeKey, Func<(ModuleDefinition module, string typeKey), TypeReference> valueFactory) =>
4551
GetOrAdd(_typeReferenceCache, (module, typeKey), valueFactory);

src/Controls/src/Xaml/PublicAPI/net-android/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ Microsoft.Maui.Controls.Embedding.EmbeddingExtensions
88
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider
99
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider.ValueTargetProvider(object! targetObject, object! targetProperty) -> void
1010
Microsoft.Maui.Controls.Xaml.ResourceDictionaryHelpers
11+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.RootObject.get -> object
12+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.SimpleValueTargetProvider(object[] objectAndParents, object targetProperty, Microsoft.Maui.Controls.Internals.INameScope[] scopes, object rootObject) -> void

src/Controls/src/Xaml/PublicAPI/net-ios/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ Microsoft.Maui.Controls.Embedding.EmbeddingExtensions
88
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider
99
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider.ValueTargetProvider(object! targetObject, object! targetProperty) -> void
1010
Microsoft.Maui.Controls.Xaml.ResourceDictionaryHelpers
11+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.RootObject.get -> object
12+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.SimpleValueTargetProvider(object[] objectAndParents, object targetProperty, Microsoft.Maui.Controls.Internals.INameScope[] scopes, object rootObject) -> void

src/Controls/src/Xaml/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ Microsoft.Maui.Controls.Embedding.EmbeddingExtensions
88
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider
99
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider.ValueTargetProvider(object! targetObject, object! targetProperty) -> void
1010
Microsoft.Maui.Controls.Xaml.ResourceDictionaryHelpers
11+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.RootObject.get -> object
12+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.SimpleValueTargetProvider(object[] objectAndParents, object targetProperty, Microsoft.Maui.Controls.Internals.INameScope[] scopes, object rootObject) -> void

src/Controls/src/Xaml/PublicAPI/net-tizen/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ Microsoft.Maui.Controls.Embedding.EmbeddingExtensions
88
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider
99
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider.ValueTargetProvider(object! targetObject, object! targetProperty) -> void
1010
Microsoft.Maui.Controls.Xaml.ResourceDictionaryHelpers
11+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.RootObject.get -> object
12+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.SimpleValueTargetProvider(object[] objectAndParents, object targetProperty, Microsoft.Maui.Controls.Internals.INameScope[] scopes, object rootObject) -> void

src/Controls/src/Xaml/PublicAPI/net-windows/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ Microsoft.Maui.Controls.Embedding.EmbeddingExtensions
88
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider
99
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider.ValueTargetProvider(object! targetObject, object! targetProperty) -> void
1010
Microsoft.Maui.Controls.Xaml.ResourceDictionaryHelpers
11+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.RootObject.get -> object
12+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.SimpleValueTargetProvider(object[] objectAndParents, object targetProperty, Microsoft.Maui.Controls.Internals.INameScope[] scopes, object rootObject) -> void

src/Controls/src/Xaml/PublicAPI/net/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#nullable enable
2+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.RootObject.get -> object
23
~Microsoft.Maui.Controls.Xaml.TemplateBindingExtension.TypedBinding.get -> Microsoft.Maui.Controls.Internals.TypedBindingBase
34
~Microsoft.Maui.Controls.Xaml.TemplateBindingExtension.TypedBinding.set -> void
45
~static Microsoft.Maui.Controls.Embedding.EmbeddingExtensions.UseMauiEmbeddedApp<TApp>(this Microsoft.Maui.Hosting.MauiAppBuilder builder, System.Func<System.IServiceProvider, TApp> implementationFactory) -> Microsoft.Maui.Hosting.MauiAppBuilder
@@ -8,3 +9,4 @@ Microsoft.Maui.Controls.Embedding.EmbeddingExtensions
89
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider
910
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider.ValueTargetProvider(object! targetObject, object! targetProperty) -> void
1011
Microsoft.Maui.Controls.Xaml.ResourceDictionaryHelpers
12+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.SimpleValueTargetProvider(object[] objectAndParents, object targetProperty, Microsoft.Maui.Controls.Internals.INameScope[] scopes, object rootObject) -> void

src/Controls/src/Xaml/PublicAPI/netstandard/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ Microsoft.Maui.Controls.Embedding.EmbeddingExtensions
88
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider
99
Microsoft.Maui.Controls.Xaml.Internals.ValueTargetProvider.ValueTargetProvider(object! targetObject, object! targetProperty) -> void
1010
Microsoft.Maui.Controls.Xaml.ResourceDictionaryHelpers
11+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.RootObject.get -> object
12+
~Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider.SimpleValueTargetProvider(object[] objectAndParents, object targetProperty, Microsoft.Maui.Controls.Internals.INameScope[] scopes, object rootObject) -> void

src/Controls/src/Xaml/XamlServiceProvider.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,11 @@ public ValueTargetProvider(object targetObject, object targetProperty)
135135
}
136136
#nullable restore
137137

138-
public class SimpleValueTargetProvider : IProvideParentValues, IProvideValueTarget, IReferenceProvider
138+
public class SimpleValueTargetProvider : IProvideParentValues, IProvideValueTarget, IReferenceProvider, IRootObjectProvider
139139
{
140140
readonly object[] objectAndParents;
141141
readonly object targetProperty;
142+
readonly object rootObject;
142143
readonly INameScope[] scopes;
143144

144145
[Obsolete("Use the other ctor")]
@@ -147,7 +148,13 @@ public SimpleValueTargetProvider(object[] objectAndParents, object targetPropert
147148
{
148149
}
149150

151+
[Obsolete("Use the other ctor")]
150152
public SimpleValueTargetProvider(object[] objectAndParents, object targetProperty, INameScope[] scopes, bool notused)
153+
: this(objectAndParents, targetProperty, scopes, null)
154+
{
155+
}
156+
157+
public SimpleValueTargetProvider(object[] objectAndParents, object targetProperty, INameScope[] scopes, object rootObject)
151158
{
152159
if (objectAndParents == null)
153160
throw new ArgumentNullException(nameof(objectAndParents));
@@ -157,8 +164,10 @@ public SimpleValueTargetProvider(object[] objectAndParents, object targetPropert
157164
this.objectAndParents = objectAndParents;
158165
this.targetProperty = targetProperty;
159166
this.scopes = scopes;
167+
this.rootObject = rootObject ?? objectAndParents[objectAndParents.Length - 1];
160168
}
161169

170+
public object RootObject => rootObject;
162171
IEnumerable<object> IProvideParentValues.ParentObjects => objectAndParents;
163172
object IProvideValueTarget.TargetObject => objectAndParents[0];
164173
object IProvideValueTarget.TargetProperty => targetProperty;

0 commit comments

Comments
 (0)