Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ static bool IsOfAnyType(XmlType xmlType, params string[] types)
return true;
return false;
}

public FieldReference GetBindablePropertyFieldReference(string value, ILContext context, ModuleDefinition module, BaseNode node)
{
FieldReference bpRef = null;
string typeName = null, propertyName = null;
XmlType typeName = null;
string propertyName = null;

var parts = value.Split('.');
if (parts.Length == 1)
Expand All @@ -54,7 +56,7 @@ public FieldReference GetBindablePropertyFieldReference(string value, ILContext
}
else if (IsOfAnyType(parent.XmlType, nameof(VisualState)))
{
typeName = FindTypeNameForVisualState(parent, node);
typeName = FindTypeNameForVisualState(parent, node, context);
}
}
else if (IsOfAnyType((node.Parent as ElementNode)?.XmlType, nameof(Trigger)))
Expand All @@ -65,7 +67,8 @@ public FieldReference GetBindablePropertyFieldReference(string value, ILContext
}
else if (parts.Length == 2)
{
typeName = parts[0];
var targetType = parts[0];
typeName = TypeArgumentsParser.ParseSingle(targetType, node.NamespaceResolver, (IXmlLineInfo)node);
propertyName = parts[1];
}
else
Expand All @@ -74,7 +77,7 @@ public FieldReference GetBindablePropertyFieldReference(string value, ILContext
if (typeName == null || propertyName == null)
throw new BuildException(Conversion, node, null, value, typeof(BindableProperty));

var typeRef = XmlTypeExtensions.GetTypeReference(context.Cache, typeName, module, node);
var typeRef = typeName.GetTypeReference(context.Cache, module, node);
if (typeRef == null)
throw new BuildException(TypeResolution, node, null, typeName);

Expand All @@ -83,11 +86,14 @@ public FieldReference GetBindablePropertyFieldReference(string value, ILContext
throw new BuildException(PropertyResolution, node, null, propertyName, typeRef.Name);
return bpRef;

static string GetTargetTypeName(INode node)
=> ((node as ElementNode).Properties[new XmlName("", "TargetType")] as ValueNode)?.Value as string;
static XmlType GetTargetTypeName(INode node)
{
var targetType = ((node as ElementNode).Properties[new XmlName("", "TargetType")] as ValueNode)?.Value as string;
return TypeArgumentsParser.ParseSingle(targetType, node.NamespaceResolver, (IXmlLineInfo)node);
}
}

static string FindTypeNameForVisualState(IElementNode parent, IXmlLineInfo lineInfo)
static XmlType FindTypeNameForVisualState(IElementNode parent, IXmlLineInfo lineInfo, ILContext context)
{
//1. parent is VisualState, don't check that

Expand All @@ -105,9 +111,12 @@ static string FindTypeNameForVisualState(IElementNode parent, IXmlLineInfo lineI

//4. target is now a Setter in a Style, or a VE
if (IsOfAnyType(target.XmlType, nameof(Setter)))
return ((target?.Parent as IElementNode)?.Properties[new XmlName("", "TargetType")] as ValueNode)?.Value as string;
{
var targetType = ((target?.Parent as IElementNode)?.Properties[new XmlName("", "TargetType")] as ValueNode)?.Value as string;
return TypeArgumentsParser.ParseSingle(targetType, parent.NamespaceResolver, lineInfo);
}
else
return target.XmlType.Name;
return target.XmlType;
}

public static FieldReference GetBindablePropertyFieldReference(XamlCache cache, TypeReference typeRef, string propertyName, ModuleDefinition module)
Expand Down
2 changes: 1 addition & 1 deletion src/Controls/src/Build.Tasks/XamlCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static TValue GetOrAdd<TKey, TValue>(Dictionary<TKey, TValue> dictionary, TKey k
return value;
}

public IList<XmlnsDefinitionAttribute> GetXmlsDefinitions(ModuleDefinition module, Func<ModuleDefinition, IList<XmlnsDefinitionAttribute>> valueFactory) =>
public IList<XmlnsDefinitionAttribute> GetXmlnsDefinitions(ModuleDefinition module, Func<ModuleDefinition, IList<XmlnsDefinitionAttribute>> valueFactory) =>
GetOrAdd(_xmlnsDefinitions, module, valueFactory);

public TypeDefinition Resolve(TypeReference typeReference) =>
Expand Down
2 changes: 1 addition & 1 deletion src/Controls/src/Build.Tasks/XmlTypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public static TypeReference GetTypeReference(XamlCache cache, string namespaceUR

public static bool TryGetTypeReference(this XmlType xmlType, XamlCache cache, ModuleDefinition module, IXmlLineInfo xmlInfo, bool expandToExtension, out TypeReference typeReference)
{
IList<XmlnsDefinitionAttribute> xmlnsDefinitions = cache.GetXmlsDefinitions(module, GatherXmlnsDefinitionAttributes);
IList<XmlnsDefinitionAttribute> xmlnsDefinitions = cache.GetXmlnsDefinitions(module, GatherXmlnsDefinitionAttributes);

var typeArguments = xmlType.TypeArguments;

Expand Down
11 changes: 7 additions & 4 deletions src/Controls/src/SourceGen/NodeSGExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -625,14 +625,17 @@ public static IFieldSymbol GetBindableProperty(this ValueNode node, SourceGenCon
else
target = (IElementNode)target.Parent;

string? typeName = null;
XmlType? typeName = null;
//4. target is now a Setter in a Style, or a VE
if (IsOfAnyType(target.XmlType, "Setter"))
typeName = ((target?.Parent as IElementNode)?.Properties[new XmlName("", "TargetType")] as ValueNode)?.Value as string;
{
var targetType = ((target?.Parent as IElementNode)?.Properties[new XmlName("", "TargetType")] as ValueNode)?.Value as string;
typeName = TypeArgumentsParser.ParseSingle(targetType, parent.NamespaceResolver, lineInfo);
}
else
typeName = target.XmlType.Name;
typeName = target.XmlType;

return XmlTypeExtensions.GetTypeSymbol(typeName!, context.ReportDiagnostic, context.Compilation, context.XmlnsCache, parent);
return typeName!.GetTypeSymbol(context.ReportDiagnostic, context.Compilation, context.XmlnsCache);
}

public static bool RepresentsType(this INode node, string namespaceUri, string name)
Expand Down
24 changes: 24 additions & 0 deletions src/Controls/tests/Xaml.UnitTests/Issues/Maui31186.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Microsoft.Maui.Controls.Xaml.UnitTests"
x:Class="Microsoft.Maui.Controls.Xaml.UnitTests.Maui31186"
Title="Maui31186">
<local:MyButton
x:Name="CounterBtn"
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Clicked="OnCounterClicked"
HorizontalOptions="Fill">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="LightBlue"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</local:MyButton>
</ContentPage>
86 changes: 86 additions & 0 deletions src/Controls/tests/Xaml.UnitTests/Issues/Maui31186.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System;
using Microsoft.Maui.Graphics;
using NUnit.Framework;

using static Microsoft.Maui.Controls.Xaml.UnitTests.MockSourceGenerator;

namespace Microsoft.Maui.Controls.Xaml.UnitTests;

public class MyButton : Button
{

}

[XamlProcessing(XamlInflator.Default, true)]
public partial class Maui31186 : ContentPage
{
public Maui31186()
{
InitializeComponent();
}
int count = 0;

void OnCounterClicked(object sender, EventArgs e)
{
count++;

if (count == 1)
CounterBtn.Text = $"Clicked {count} time";
else
CounterBtn.Text = $"Clicked {count} times";
}

[TestFixture]
class Tests
{
[Test]
public void XmlnsResolutionForVisualState([Values] XamlInflator inflator)
{
if (inflator == XamlInflator.SourceGen)
{
var result = CreateMauiCompilation()
.WithAdditionalSource(
"""
using System;
using Microsoft.Maui.Graphics;
using NUnit.Framework;

using static Microsoft.Maui.Controls.Xaml.UnitTests.MockSourceGenerator;

namespace Microsoft.Maui.Controls.Xaml.UnitTests;

public class MyButton : Button
{

}

[XamlProcessing(XamlInflator.Runtime, true)]
public partial class Maui31186 : ContentPage
{
public Maui31186()
{
InitializeComponent();
}
int count = 0;

void OnCounterClicked(object sender, EventArgs e)
{
count++;

if (count == 1)
CounterBtn.Text = $"Clicked {count} time";
else
CounterBtn.Text = $"Clicked {count} times";
}
}
""")
.RunMauiSourceGenerator(typeof(Maui31186));
Assert.That(result.Diagnostics, Is.Empty);
}
var page = new Maui31186(inflator);
Assert.That(page, Is.Not.Null);
VisualStateManager.GoToState(page.CounterBtn, "Disabled");
Assert.That(page.CounterBtn.BackgroundColor, Is.EqualTo(Colors.LightBlue));
}
}
}
Loading