From 5c4115365fed58147a578a5266ad00cb48bd8860 Mon Sep 17 00:00:00 2001 From: Stephane Delcroix Date: Thu, 4 Sep 2025 15:49:19 +0200 Subject: [PATCH 1/4] [XSG] make sure RD are properly inflated, and loaded MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this fixes the latest known failing test with XSG. 🎉 --- .../src/SourceGen/CodeBehindCodeWriter.cs | 4 +- .../InitializeComponentCodeWriter.cs | 4 +- .../AppResources/Colors.rt.xaml | 27 +++++++++++ .../AppResources/Colors.sgen.xaml | 27 +++++++++++ .../AppResources/Colors.xc.xaml | 27 +++++++++++ .../Controls.Xaml.UnitTests.csproj | 1 - .../ResourceDictionaryWithSource.xaml | 3 ++ .../ResourceDictionaryWithSource.xaml.cs | 46 ++++++++++++++++--- 8 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 src/Controls/tests/Xaml.UnitTests/AppResources/Colors.rt.xaml create mode 100644 src/Controls/tests/Xaml.UnitTests/AppResources/Colors.sgen.xaml create mode 100644 src/Controls/tests/Xaml.UnitTests/AppResources/Colors.xc.xaml diff --git a/src/Controls/src/SourceGen/CodeBehindCodeWriter.cs b/src/Controls/src/SourceGen/CodeBehindCodeWriter.cs index 94292cee8001..4e423aa29586 100644 --- a/src/Controls/src/SourceGen/CodeBehindCodeWriter.cs +++ b/src/Controls/src/SourceGen/CodeBehindCodeWriter.cs @@ -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/InitializeComponentCodeWriter.cs b/src/Controls/src/SourceGen/InitializeComponentCodeWriter.cs index b015cd985be6..43d495c6cf36 100644 --- a/src/Controls/src/SourceGen/InitializeComponentCodeWriter.cs +++ b/src/Controls/src/SourceGen/InitializeComponentCodeWriter.cs @@ -68,7 +68,9 @@ PrePost newblock() => if (rootType == null) goto exit; - var genSwitch = compilation.AssemblyName == "Microsoft.Maui.Controls.Xaml.UnitTests"; + var generatedDefaultCtor = rootType.Constructors.Any(c => c.Parameters.Length == 0 && c.GetAttributes().Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, compilation.GetTypeByMetadataName("System.CodeDom.Compiler.GeneratedCodeAttribute")))); + + 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/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] From f905df4a36e1fa9af06d0f9740d359bf91d911b7 Mon Sep 17 00:00:00 2001 From: Stephane Delcroix Date: Fri, 5 Sep 2025 10:13:58 +0200 Subject: [PATCH 2/4] try a different heuristic --- src/Controls/src/SourceGen/InitializeComponentCodeWriter.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Controls/src/SourceGen/InitializeComponentCodeWriter.cs b/src/Controls/src/SourceGen/InitializeComponentCodeWriter.cs index 43d495c6cf36..a66457641beb 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,6 +56,7 @@ 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) { @@ -68,7 +70,6 @@ PrePost newblock() => if (rootType == null) goto exit; - var generatedDefaultCtor = rootType.Constructors.Any(c => c.Parameters.Length == 0 && c.GetAttributes().Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, compilation.GetTypeByMetadataName("System.CodeDom.Compiler.GeneratedCodeAttribute")))); var genSwitch = compilation.AssemblyName == "Microsoft.Maui.Controls.Xaml.UnitTests" && !generatedDefaultCtor; var xamlInflators = xamlItem.ProjectItem.Inflator; From d4032300bbba9562119058d88b3c5b877469970c Mon Sep 17 00:00:00 2001 From: Stephane Delcroix Date: Tue, 16 Sep 2025 13:12:27 +0200 Subject: [PATCH 3/4] replace directory separator before comparing --- .../src/SourceGen/CodeBehindGenerator.cs | 3 +- .../InitializeComponentCodeWriter.cs | 3 +- .../InitializeComponent/ResourceDictionary.cs | 59 +++++++++++++++++++ .../SourceGenXamlInitializeComponentTests.cs | 4 +- 4 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 src/Controls/tests/SourceGen.UnitTests/InitializeComponent/ResourceDictionary.cs 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 a66457641beb..9c85f09b7c4d 100644 --- a/src/Controls/src/SourceGen/InitializeComponentCodeWriter.cs +++ b/src/Controls/src/SourceGen/InitializeComponentCodeWriter.cs @@ -60,7 +60,8 @@ PrePost newblock() => 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/tests/SourceGen.UnitTests/InitializeComponent/ResourceDictionary.cs b/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/ResourceDictionary.cs new file mode 100644 index 000000000000..2f37cf64935a --- /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.Parse("#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..260c98f09e56 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, "Test.xaml"), xaml, RelativePath: "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(); From 64e66cfecdf55081f4946b98604d636c77513e42 Mon Sep 17 00:00:00 2001 From: Stephane Delcroix Date: Wed, 17 Sep 2025 17:08:56 +0200 Subject: [PATCH 4/4] fix for relpath --- src/Controls/src/SourceGen/CodeBehindCodeWriter.cs | 4 ++-- .../InitializeComponent/ResourceDictionary.cs | 2 +- .../SourceGenXamlInitializeComponentTests.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Controls/src/SourceGen/CodeBehindCodeWriter.cs b/src/Controls/src/SourceGen/CodeBehindCodeWriter.cs index 4e423aa29586..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) diff --git a/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/ResourceDictionary.cs b/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/ResourceDictionary.cs index 2f37cf64935a..05c5d756eacc 100644 --- a/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/ResourceDictionary.cs +++ b/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/ResourceDictionary.cs @@ -37,7 +37,7 @@ public partial class __TypeDBD64C1C77CDA760 { private partial void InitializeComponent() { - var color = global::Microsoft.Maui.Graphics.Color.Parse("#FF4B14"); + 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); diff --git a/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/SourceGenXamlInitializeComponentTests.cs b/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/SourceGenXamlInitializeComponentTests.cs index 260c98f09e56..3deaba327972 100644 --- a/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/SourceGenXamlInitializeComponentTests.cs +++ b/src/Controls/tests/SourceGen.UnitTests/InitializeComponent/SourceGenXamlInitializeComponentTests.cs @@ -19,7 +19,7 @@ protected record AdditionalXamlFile(string Path, string Content, string? Relativ 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, ManifestResourceName: $"{compilation.AssemblyName}.Test.xaml"); + 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();