diff --git a/src/Controls/src/SourceGen/CodeBehindCodeWriter.cs b/src/Controls/src/SourceGen/CodeBehindCodeWriter.cs
index 94292cee8001..479ddbc0586a 100644
--- a/src/Controls/src/SourceGen/CodeBehindCodeWriter.cs
+++ b/src/Controls/src/SourceGen/CodeBehindCodeWriter.cs
@@ -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)
@@ -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");
diff --git a/src/Controls/src/SourceGen/CodeBehindGenerator.cs b/src/Controls/src/SourceGen/CodeBehindGenerator.cs
index e6b5aab713dc..0d8e5e99125c 100644
--- a/src/Controls/src/SourceGen/CodeBehindGenerator.cs
+++ b/src/Controls/src/SourceGen/CodeBehindGenerator.cs
@@ -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;
}
diff --git a/src/Controls/src/SourceGen/InitializeComponentCodeWriter.cs b/src/Controls/src/SourceGen/InitializeComponentCodeWriter.cs
index b015cd985be6..9c85f09b7c4d 100644
--- a/src/Controls/src/SourceGen/InitializeComponentCodeWriter.cs
+++ b/src/Controls/src/SourceGen/InitializeComponentCodeWriter.cs
@@ -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)
@@ -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;
}
@@ -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;
diff --git a/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/ResourceDictionary.cs b/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/ResourceDictionary.cs
new file mode 100644
index 000000000000..05c5d756eacc
--- /dev/null
+++ b/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/ResourceDictionary.cs
@@ -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 =
+"""
+
+
+ #FF4B14
+
+""";
+ var expected =
+"""
+
+//------------------------------------------------------------------------------
+//
+// 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.
+//
+//------------------------------------------------------------------------------
+#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);
+
+ }
+}
diff --git a/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/SourceGenXamlInitializeComponentTests.cs b/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/SourceGenXamlInitializeComponentTests.cs
index 887984940dde..3deaba327972 100644
--- a/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/SourceGenXamlInitializeComponentTests.cs
+++ b/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/SourceGenXamlInitializeComponentTests.cs
@@ -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(compilation, xamlFile);
var generated = result.Results.SingleOrDefault().GeneratedSources.SingleOrDefault(gs => gs.HintName.EndsWith(".xsg.cs")).SourceText?.ToString();
diff --git a/src/Controls/tests/Xaml.UnitTests/AppResources/Colors.rt.xaml b/src/Controls/tests/Xaml.UnitTests/AppResources/Colors.rt.xaml
new file mode 100644
index 000000000000..1d3f438a83d4
--- /dev/null
+++ b/src/Controls/tests/Xaml.UnitTests/AppResources/Colors.rt.xaml
@@ -0,0 +1,27 @@
+
+
+ #FF4B14
+ #99253748
+ #253748
+ #F8F8F8
+ #ED0241
+ #ACB1B4
+ #203446
+ #FFFFFF
+ #368F95
+
+ #FF96F3
+ #1976D2
+ #96d1ff
+ #FAFAFA
+ #C0C0C0
+ #4d4d4d
+ #999999
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/Xaml.UnitTests/AppResources/Colors.sgen.xaml b/src/Controls/tests/Xaml.UnitTests/AppResources/Colors.sgen.xaml
new file mode 100644
index 000000000000..1d3f438a83d4
--- /dev/null
+++ b/src/Controls/tests/Xaml.UnitTests/AppResources/Colors.sgen.xaml
@@ -0,0 +1,27 @@
+
+
+ #FF4B14
+ #99253748
+ #253748
+ #F8F8F8
+ #ED0241
+ #ACB1B4
+ #203446
+ #FFFFFF
+ #368F95
+
+ #FF96F3
+ #1976D2
+ #96d1ff
+ #FAFAFA
+ #C0C0C0
+ #4d4d4d
+ #999999
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/Xaml.UnitTests/AppResources/Colors.xc.xaml b/src/Controls/tests/Xaml.UnitTests/AppResources/Colors.xc.xaml
new file mode 100644
index 000000000000..1d3f438a83d4
--- /dev/null
+++ b/src/Controls/tests/Xaml.UnitTests/AppResources/Colors.xc.xaml
@@ -0,0 +1,27 @@
+
+
+ #FF4B14
+ #99253748
+ #253748
+ #F8F8F8
+ #ED0241
+ #ACB1B4
+ #203446
+ #FFFFFF
+ #368F95
+
+ #FF96F3
+ #1976D2
+ #96d1ff
+ #FAFAFA
+ #C0C0C0
+ #4d4d4d
+ #999999
+
+
+
\ No newline at end of file
diff --git a/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj b/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj
index 291df11afb77..d94f31522672 100644
--- a/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj
+++ b/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj
@@ -14,7 +14,6 @@
- $(DefineConstants);FIXME_BEFORE_PUBLIC_RELEASE
true
Generated
diff --git a/src/Controls/tests/Xaml.UnitTests/ResourceDictionaryWithSource.xaml b/src/Controls/tests/Xaml.UnitTests/ResourceDictionaryWithSource.xaml
index 32645e01336a..9c9f26851263 100644
--- a/src/Controls/tests/Xaml.UnitTests/ResourceDictionaryWithSource.xaml
+++ b/src/Controls/tests/Xaml.UnitTests/ResourceDictionaryWithSource.xaml
@@ -8,6 +8,9 @@
+
+
+
diff --git a/src/Controls/tests/Xaml.UnitTests/ResourceDictionaryWithSource.xaml.cs b/src/Controls/tests/Xaml.UnitTests/ResourceDictionaryWithSource.xaml.cs
index 6488b7b641db..8ab6713cccf5 100644
--- a/src/Controls/tests/Xaml.UnitTests/ResourceDictionaryWithSource.xaml.cs
+++ b/src/Controls/tests/Xaml.UnitTests/ResourceDictionaryWithSource.xaml.cs
@@ -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());
+ 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]