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
8 changes: 4 additions & 4 deletions src/Controls/src/SourceGen/CodeBehindCodeWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ public static string GenerateXamlCodeBehind(XamlProjectItemForCB? xamlItem, Comp

var hintName = $"{(string.IsNullOrEmpty(Path.GetDirectoryName(projItem!.TargetPath)) ? "" : Path.GetDirectoryName(projItem.TargetPath) + Path.DirectorySeparatorChar)}{Path.GetFileNameWithoutExtension(projItem.TargetPath)}.{projItem.Kind.ToLowerInvariant()}.sg.cs".Replace(Path.DirectorySeparatorChar, '_');

if (projItem.ManifestResourceName != null && projItem.TargetPath != null)
if (projItem.ManifestResourceName != null && projItem.RelativePath != null)
{
sb.AppendLine($"[assembly: global::Microsoft.Maui.Controls.Xaml.XamlResourceId(\"{projItem.ManifestResourceName}\", \"{projItem.TargetPath.Replace('\\', '/')}\", {(rootType == null ? "null" : "typeof(global::" + rootClrNamespace + "." + rootType + ")")})]");
sb.AppendLine($"[assembly: global::Microsoft.Maui.Controls.Xaml.XamlResourceId(\"{projItem.ManifestResourceName}\", \"{projItem.RelativePath.Replace('\\', '/')}\", {(rootType == null ? "null" : "typeof(global::" + rootClrNamespace + "." + rootType + ")")})]");
}

if (XamlResourceIdOnly)
Expand All @@ -71,9 +71,9 @@ public static string GenerateXamlCodeBehind(XamlProjectItemForCB? xamlItem, Comp
var rootSymbol = compilation.GetTypeByMetadataName($"{rootClrNamespace}.{rootType}");
bool alreadyHasXamlCompilationAttribute = rootSymbol?.GetAttributes().Any(a => a.AttributeClass != null && a.AttributeClass.Equals(compilation.GetTypeByMetadataName("Microsoft.Maui.Controls.Xaml.XamlCompilationAttribute")!, SymbolEqualityComparer.Default)) ?? false;

var generateInflatorSwitch = compilation.AssemblyName == "Microsoft.Maui.Controls.Xaml.UnitTests";
var generateInflatorSwitch = compilation.AssemblyName == "Microsoft.Maui.Controls.Xaml.UnitTests" && !generateDefaultCtor;
var xamlInflators = projItem.Inflator;

//if there's only the XamlC inflator, prevent non-assigned errors
if (xamlInflators == XamlInflator.XamlC)
sb.AppendLine("#pragma warning disable CS0649");
Expand Down
3 changes: 2 additions & 1 deletion src/Controls/src/SourceGen/CodeBehindGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ static bool ShouldGenerateSourceGenInitializeComponent(XamlProjectItemForIC xaml
ITypeSymbol xamlResIdAttr = compilation.GetTypeByMetadataName("Microsoft.Maui.Controls.Xaml.XamlResourceIdAttribute")!;
INamedTypeSymbol? GetTypeForResourcePath(string resourcePath, IAssemblySymbol assembly)
{
var attr = assembly.GetAttributes(xamlResIdAttr).FirstOrDefault(attr => (string)attr.ConstructorArguments[1].Value! == resourcePath);
//XRID use paths with forward slashes. we can't change that it's used by HR
var attr = assembly.GetAttributes(xamlResIdAttr).FirstOrDefault(attr => ((string)attr.ConstructorArguments[1].Value!).Replace('/', Path.DirectorySeparatorChar) == resourcePath);
return attr?.ConstructorArguments[2].Value as INamedTypeSymbol;
}

Expand Down
8 changes: 6 additions & 2 deletions src/Controls/src/SourceGen/InitializeComponentCodeWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ PrePost newblock() =>
string accessModifier = "public";
INamedTypeSymbol? rootType = null;

var generatedDefaultCtor = false;
if (root.Properties.TryGetValue(XmlName.xClass, out var classNode))
{
if ((classNode as ValueNode)?.Value is not string rootClass)
Expand All @@ -55,10 +56,12 @@ PrePost newblock() =>
}
else
{ //no x:Class, but it can be an autogenerated type (starting with __Type, and with a XamlResourceId attribute)
generatedDefaultCtor = true;
ITypeSymbol xamlResIdAttr = compilation.GetTypeByMetadataName("Microsoft.Maui.Controls.Xaml.XamlResourceIdAttribute")!;
INamedTypeSymbol? GetTypeForResourcePath(string resourcePath, IAssemblySymbol assembly)
{
var attr = assembly.GetAttributes(xamlResIdAttr).FirstOrDefault(attr => (string)attr.ConstructorArguments[1].Value! == resourcePath);
//XRID use paths with forward slashes. we can't change that it's used by HR
var attr = assembly.GetAttributes(xamlResIdAttr).FirstOrDefault(attr => ((string)attr.ConstructorArguments[1].Value!).Replace('/', Path.DirectorySeparatorChar) == resourcePath);
return attr?.ConstructorArguments[2].Value as INamedTypeSymbol;
}

Expand All @@ -68,7 +71,8 @@ PrePost newblock() =>
if (rootType == null)
goto exit;

var genSwitch = compilation.AssemblyName == "Microsoft.Maui.Controls.Xaml.UnitTests";

var genSwitch = compilation.AssemblyName == "Microsoft.Maui.Controls.Xaml.UnitTests" && !generatedDefaultCtor;
var xamlInflators = xamlItem.ProjectItem.Inflator;

var generate = (xamlInflators & XamlInflator.SourceGen) == XamlInflator.SourceGen;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Linq;
using NUnit.Framework;

namespace Microsoft.Maui.Controls.SourceGen.UnitTests;

public class ResourceDictionary : SourceGenXamlInitializeComponentTestBase
{
[Test]
public void ResourceDictionaryWithoutXClass()
{
var xaml =
"""
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="using:Microsoft.Maui.Controls.Xaml.UnitTests">
<Color x:Key="AccentColor">#FF4B14</Color>
</ResourceDictionary>
""";
var expected =
"""

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a .NET MAUI source generator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable

namespace __XamlGeneratedCode__;

public partial class __TypeDBD64C1C77CDA760
{
private partial void InitializeComponent()
{
var color = global::Microsoft.Maui.Graphics.Color.FromArgb("#FF4B14");
global::Microsoft.Maui.VisualDiagnostics.RegisterSourceInfo(color!, new global::System.Uri(@"Styles.xaml;assembly=SourceGeneratorDriver.Generated", global::System.UriKind.Relative), 6, 4);
var __root = this;
global::Microsoft.Maui.VisualDiagnostics.RegisterSourceInfo(__root!, new global::System.Uri(@"Styles.xaml;assembly=SourceGeneratorDriver.Generated", global::System.UriKind.Relative), 2, 2);
#if !_MAUIXAML_SG_NAMESCOPE_DISABLE
global::Microsoft.Maui.Controls.Internals.INameScope iNameScope = new global::Microsoft.Maui.Controls.Internals.NameScope();
#endif
__root.Add("AccentColor", color);
}
}

""";

var (result, generated) = RunGenerator(xaml, "", path: "Styles.xaml");
Assert.IsFalse(result.Diagnostics.Any());

Assert.AreEqual(expected, generated);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ public class SourceGenXamlInitializeComponentTestBase : SourceGenTestsBase
protected record AdditionalXamlFile(string Path, string Content, string? RelativePath = null, string? TargetPath = null, string? ManifestResourceName = null, string? TargetFramework = null, string? NoWarn = null)
: AdditionalFile(Text: ToAdditionalText(Path, Content), Kind: "Xaml", RelativePath: RelativePath ?? Path, TargetPath: TargetPath, ManifestResourceName: ManifestResourceName, TargetFramework: TargetFramework, NoWarn: NoWarn);

protected (GeneratorDriverRunResult result, string? text) RunGenerator(string xaml, string code, string noWarn = "", string targetFramework = "")
protected (GeneratorDriverRunResult result, string? text) RunGenerator(string xaml, string code, string noWarn = "", string targetFramework = "", string? path = null)
{
var compilation = CreateMauiCompilation();
compilation = compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code));
var workingDirectory = Environment.CurrentDirectory;
var xamlFile = new AdditionalXamlFile(Path.Combine(workingDirectory, "Test.xaml"), xaml, RelativePath: "Test.xaml", TargetFramework: targetFramework, NoWarn: noWarn);
var xamlFile = new AdditionalXamlFile(Path.Combine(workingDirectory, path ?? "Test.xaml"), xaml, RelativePath: path ?? "Test.xaml", TargetFramework: targetFramework, NoWarn: noWarn, ManifestResourceName: $"{compilation.AssemblyName}.Test.xaml");
var result = RunGenerator<CodeBehindGenerator>(compilation, xamlFile);
var generated = result.Results.SingleOrDefault().GeneratedSources.SingleOrDefault(gs => gs.HintName.EndsWith(".xsg.cs")).SourceText?.ToString();

Expand Down
27 changes: 27 additions & 0 deletions src/Controls/tests/Xaml.UnitTests/AppResources/Colors.rt.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="using:Microsoft.Maui.Controls.Xaml.UnitTests">
<Color x:Key="AccentColor">#FF4B14</Color>
<Color x:Key="BlackOpacityColor">#99253748</Color>
<Color x:Key="BlackTextColor">#253748</Color>
<Color x:Key="BackgroundColor">#F8F8F8</Color>
<Color x:Key="PinkColor">#ED0241</Color>
<Color x:Key="GrayColor">#ACB1B4</Color>
<Color x:Key="DarkColor">#203446</Color>
<Color x:Key="WhiteColor">#FFFFFF</Color>
<Color x:Key="GreenColor">#368F95</Color>

<Color x:Key="Primary">#FF96F3</Color>
<Color x:Key="PrimaryDark">#1976D2</Color>
<Color x:Key="Accent">#96d1ff</Color>
<Color x:Key="LightBackgroundColor">#FAFAFA</Color>
<Color x:Key="DarkBackgroundColor">#C0C0C0</Color>
<Color x:Key="MediumGrayTextColor">#4d4d4d</Color>
<Color x:Key="LightTextColor">#999999</Color>

<Style TargetType="local:Gh7531" x:Key="style">
<Setter Property="BackgroundColor" Value="HotPink"/>
</Style>
</ResourceDictionary>
27 changes: 27 additions & 0 deletions src/Controls/tests/Xaml.UnitTests/AppResources/Colors.sgen.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="using:Microsoft.Maui.Controls.Xaml.UnitTests">
<Color x:Key="AccentColor">#FF4B14</Color>
<Color x:Key="BlackOpacityColor">#99253748</Color>
<Color x:Key="BlackTextColor">#253748</Color>
<Color x:Key="BackgroundColor">#F8F8F8</Color>
<Color x:Key="PinkColor">#ED0241</Color>
<Color x:Key="GrayColor">#ACB1B4</Color>
<Color x:Key="DarkColor">#203446</Color>
<Color x:Key="WhiteColor">#FFFFFF</Color>
<Color x:Key="GreenColor">#368F95</Color>

<Color x:Key="Primary">#FF96F3</Color>
<Color x:Key="PrimaryDark">#1976D2</Color>
<Color x:Key="Accent">#96d1ff</Color>
<Color x:Key="LightBackgroundColor">#FAFAFA</Color>
<Color x:Key="DarkBackgroundColor">#C0C0C0</Color>
<Color x:Key="MediumGrayTextColor">#4d4d4d</Color>
<Color x:Key="LightTextColor">#999999</Color>

<Style TargetType="local:Gh7531" x:Key="style">
<Setter Property="BackgroundColor" Value="HotPink"/>
</Style>
</ResourceDictionary>
27 changes: 27 additions & 0 deletions src/Controls/tests/Xaml.UnitTests/AppResources/Colors.xc.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="using:Microsoft.Maui.Controls.Xaml.UnitTests">
<Color x:Key="AccentColor">#FF4B14</Color>
<Color x:Key="BlackOpacityColor">#99253748</Color>
<Color x:Key="BlackTextColor">#253748</Color>
<Color x:Key="BackgroundColor">#F8F8F8</Color>
<Color x:Key="PinkColor">#ED0241</Color>
<Color x:Key="GrayColor">#ACB1B4</Color>
<Color x:Key="DarkColor">#203446</Color>
<Color x:Key="WhiteColor">#FFFFFF</Color>
<Color x:Key="GreenColor">#368F95</Color>

<Color x:Key="Primary">#FF96F3</Color>
<Color x:Key="PrimaryDark">#1976D2</Color>
<Color x:Key="Accent">#96d1ff</Color>
<Color x:Key="LightBackgroundColor">#FAFAFA</Color>
<Color x:Key="DarkBackgroundColor">#C0C0C0</Color>
<Color x:Key="MediumGrayTextColor">#4d4d4d</Color>
<Color x:Key="LightTextColor">#999999</Color>

<Style TargetType="local:Gh7531" x:Key="style">
<Setter Property="BackgroundColor" Value="HotPink"/>
</Style>
</ResourceDictionary>
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
<!-- We can't yet disable the namescope generation, ConstraintTypeConverter and ReferenceTypeConverter need to be ported to sourcegen
<DefineConstants>$(DefineConstants);_MAUIXAML_SG_NAMESCOPE_DISABLE</DefineConstants>
-->
<DefineConstants>$(DefineConstants);FIXME_BEFORE_PUBLIC_RELEASE</DefineConstants>

<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
<ResourceDictionary Source="./SharedResourceDictionary.xaml" x:Key="relURI"/>
<ResourceDictionary Source="/SharedResourceDictionary.xaml" x:Key="absURI"/>
<ResourceDictionary Source="SharedResourceDictionary.xaml" x:Key="shortURI"/>
<ResourceDictionary Source="./AppResources/Colors.rt.xaml" x:Key="Colors.rt" />
<ResourceDictionary Source="./AppResources/Colors.sgen.xaml" x:Key="Colors.sgen" />
<ResourceDictionary Source="./AppResources/Colors.xc.xaml" x:Key="Colors.xc" />
<ResourceDictionary Source="./AppResources/Colors.rtxc.xaml" x:Key="Colors" />
<ResourceDictionary Source="./AppResources/CompiledColors.rtxc.xaml" x:Key="CompiledColors" />
<ResourceDictionary Source="/AppResources/Colors.rtxc.xaml;assembly=Microsoft.Maui.Controls.Xaml.UnitTests" x:Key="inCurrentAssembly" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,51 @@ public void RelativeAndAbsoluteURI([Values] XamlInflator inflator)
}

[Test]
public void XRIDIsGeneratedForRDWithoutCodeBehind()
public void CanLoadInflatedResources([Values] XamlInflator from, [Values] XamlInflator rd)
{
var layout = new ResourceDictionaryWithSource(from);
var key = "Colors";
switch (rd)
{
case XamlInflator.Runtime:
key = "Colors.rt";
break;
case XamlInflator.SourceGen:
key = "Colors.sgen";
break;
case XamlInflator.XamlC:
key = "Colors.xc";
break;
}
var rdLoaded = layout.Resources[key] as ResourceDictionary;
Assert.That(rdLoaded, Is.Not.Null);
Assert.That(rdLoaded["MediumGrayTextColor"], Is.TypeOf<Color>());
Assert.That(rdLoaded["MediumGrayTextColor"] as Color, Is.EqualTo(Color.Parse("#ff4d4d4d")));
}

[Test]
public void XRIDIsGeneratedForRDWithoutCodeBehind([Values] XamlInflator rd)
{
var path = "AppResources/Colors.xaml";
switch (rd)
{
case XamlInflator.Runtime:
path = "AppResources/Colors.rt.xaml";
break;
case XamlInflator.SourceGen:
path = "AppResources/Colors.sgen.xaml";
break;
case XamlInflator.XamlC:
path = "AppResources/Colors.xc.xaml";
break;
}

var asm = typeof(ResourceDictionaryWithSource).Assembly;
var resourceId = XamlResourceIdAttribute.GetResourceIdForPath(asm, "AppResources/Colors.rtxc.xaml");
var resourceId = XamlResourceIdAttribute.GetResourceIdForPath(asm, path);
Assert.That(resourceId, Is.Not.Null);
var type = XamlResourceIdAttribute.GetTypeForResourceId(asm, resourceId);
Assert.That(type?.Name, Does.StartWith("__Type"), "xaml-comp default to true, this should have a type associated with it");
Assert.That(type?.Name, Does.StartWith("__Type"), "We add a type for all RD without Class, this should have a type associated with it");

#if !FIXME_BEFORE_PUBLIC_RELEASE
Assert.Fail(); //make sure to have the same default for sourcegen
#endif
}

[Test]
Expand Down
Loading