-
Notifications
You must be signed in to change notification settings - Fork 1.9k
[XSG] better AppThemeBinding #32441
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[XSG] better AppThemeBinding #32441
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -560,10 +560,11 @@ internal static bool ProvideValueForAppThemeBindingExtension(ElementNode node, I | |||||||||||||
|
|
||||||||||||||
| // Get the target property type for type conversion | ||||||||||||||
| ITypeSymbol? propertyType = null; | ||||||||||||||
| IFieldSymbol? bpFieldSymbol = null; | ||||||||||||||
| if (node.TryGetPropertyName(node.Parent, out XmlName propertyName) && context.Variables.TryGetValue(node.Parent, out ILocalValue parentVar)) | ||||||||||||||
| { | ||||||||||||||
| var localName = propertyName.LocalName; | ||||||||||||||
| var bpFieldSymbol = parentVar.Type.GetBindableProperty(propertyName.NamespaceURI, ref localName, out bool attached, context, node as IXmlLineInfo); | ||||||||||||||
| bpFieldSymbol = parentVar.Type.GetBindableProperty(propertyName.NamespaceURI, ref localName, out bool attached, context, node as IXmlLineInfo); | ||||||||||||||
| var propertySymbol = parentVar.Type.GetAllProperties(localName, context).FirstOrDefault(); | ||||||||||||||
| var typeandconverter = bpFieldSymbol?.GetBPTypeAndConverter(context); | ||||||||||||||
| propertyType = typeandconverter?.type ?? propertySymbol?.Type; | ||||||||||||||
|
|
@@ -573,6 +574,32 @@ internal static bool ProvideValueForAppThemeBindingExtension(ElementNode node, I | |||||||||||||
| if (propertyType is null) | ||||||||||||||
| propertyType = context.Compilation.ObjectType; | ||||||||||||||
|
|
||||||||||||||
| // Helper to get value from node - handles both ValueNode (direct conversion) and ElementNode (via getNodeValue) | ||||||||||||||
| string? GetNodeValueString(INode? targetNode) | ||||||||||||||
| { | ||||||||||||||
| if (targetNode is null) | ||||||||||||||
| return null; | ||||||||||||||
|
|
||||||||||||||
| if (targetNode is ValueNode vn) | ||||||||||||||
| { | ||||||||||||||
| // For ValueNode, convert directly using the property type | ||||||||||||||
| if (bpFieldSymbol is not null) | ||||||||||||||
| return vn.ConvertTo(bpFieldSymbol, writer, context, context.Variables.TryGetValue(node.Parent, out var pv) ? pv : null); | ||||||||||||||
| else if (propertyType is not null) | ||||||||||||||
| return vn.ConvertTo(propertyType, writer, context, context.Variables.TryGetValue(node.Parent, out var pv) ? pv : null); | ||||||||||||||
| else | ||||||||||||||
| return NodeSGExtensions.ValueForLanguagePrimitive(vn.Value as string ?? string.Empty, context.Compilation.ObjectType, context, vn); | ||||||||||||||
| } | ||||||||||||||
| else if (targetNode is ElementNode) | ||||||||||||||
| { | ||||||||||||||
| // For ElementNode, use getNodeValue to get the variable reference | ||||||||||||||
| var local = getNodeValue(targetNode, propertyType); | ||||||||||||||
| return local.ValueAccessor; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| return null; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Extract Light, Dark, and Default values from the markup extension | ||||||||||||||
| string? lightValue = null; | ||||||||||||||
| string? darkValue = null; | ||||||||||||||
|
|
@@ -583,24 +610,21 @@ internal static bool ProvideValueForAppThemeBindingExtension(ElementNode node, I | |||||||||||||
| || node.Properties.TryGetValue(new XmlName(null, "Default"), out defaultNode) | ||||||||||||||
| || (node.CollectionItems.Count == 1 && (defaultNode = node.CollectionItems[0]) != null)) | ||||||||||||||
| { | ||||||||||||||
| var defaultLocal = getNodeValue(defaultNode, propertyType); | ||||||||||||||
| defaultValue = defaultLocal.ValueAccessor; | ||||||||||||||
| defaultValue = GetNodeValueString(defaultNode); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Check for Light property | ||||||||||||||
| if (node.Properties.TryGetValue(new XmlName("", "Light"), out INode? lightNode) | ||||||||||||||
| || node.Properties.TryGetValue(new XmlName(null, "Light"), out lightNode)) | ||||||||||||||
| { | ||||||||||||||
| var lightLocal = getNodeValue(lightNode, propertyType); | ||||||||||||||
| lightValue = lightLocal.ValueAccessor; | ||||||||||||||
| lightValue = GetNodeValueString(lightNode); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Check for Dark property | ||||||||||||||
| if (node.Properties.TryGetValue(new XmlName("", "Dark"), out INode? darkNode) | ||||||||||||||
| || node.Properties.TryGetValue(new XmlName(null, "Dark"), out darkNode)) | ||||||||||||||
| { | ||||||||||||||
| var darkLocal = getNodeValue(darkNode, propertyType); | ||||||||||||||
| darkValue = darkLocal.ValueAccessor; | ||||||||||||||
| darkValue = GetNodeValueString(darkNode); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // At least one value must be set | ||||||||||||||
|
|
@@ -649,22 +673,13 @@ internal static bool ProvideValueForStaticResourceExtension(ElementNode node, In | |||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| var resource = GetResourceNode(eNode, context, (string)keyValueNode.Value); | ||||||||||||||
| if (resource != null && getNodeValue != null) | ||||||||||||||
| { | ||||||||||||||
| var lvalue = getNodeValue(resource, context.Compilation.ObjectType); | ||||||||||||||
| value = lvalue.ValueAccessor; | ||||||||||||||
| returnType = lvalue.Type; | ||||||||||||||
| return true; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if (resource is null || !context.Variables.TryGetValue(resource, out var variable)) | ||||||||||||||
| { | ||||||||||||||
| returnType = context.Compilation.ObjectType; | ||||||||||||||
| value = string.Empty; | ||||||||||||||
| return false; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| //if the resource is a string, try to convert it | ||||||||||||||
| if (resource.CollectionItems.Count == 1 && resource.CollectionItems[0] is ValueNode vn && vn.Value is string) | ||||||||||||||
| { | ||||||||||||||
|
|
@@ -676,6 +691,14 @@ internal static bool ProvideValueForStaticResourceExtension(ElementNode node, In | |||||||||||||
| var typeandconverter = bpFieldSymbol?.GetBPTypeAndConverter(context); | ||||||||||||||
|
|
||||||||||||||
| var propertyType = typeandconverter?.type ?? propertySymbol?.Type; | ||||||||||||||
| var converter = typeandconverter?.converter; | ||||||||||||||
|
|
||||||||||||||
| // If no converter from BP, check the property's TypeConverter attribute | ||||||||||||||
| if (converter == null && propertySymbol != null) | ||||||||||||||
| { | ||||||||||||||
| List<AttributeData> attributes = [.. propertySymbol.GetAttributes(), .. propertyType!.GetAttributes()]; | ||||||||||||||
|
Comment on lines
+697
to
+699
|
||||||||||||||
| if (converter == null && propertySymbol != null) | |
| { | |
| List<AttributeData> attributes = [.. propertySymbol.GetAttributes(), .. propertyType!.GetAttributes()]; | |
| if (converter == null && propertySymbol != null && propertyType != null) | |
| { | |
| List<AttributeData> attributes = [.. propertySymbol.GetAttributes(), .. propertyType.GetAttributes()]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Variable shadowing issue: The variable
pvis declared twice within the same scope using the patterncontext.Variables.TryGetValue(node.Parent, out var pv). While this compiles, it creates unnecessary variable declarations. Consider declaringpvonce before the if-else chain and reusing it.