Skip to content
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

fix(xamlgenerator): fix syntax error when using x:Uid #18880

Merged
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
@@ -0,0 +1,60 @@
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.Testing;
using Uno.UI.SourceGenerators.Tests.Verifiers;

namespace Uno.UI.SourceGenerators.Tests.XamlCodeGeneratorTests;

using Verify = XamlSourceGeneratorVerifier;

[TestClass]
public class Given_Xuid
{
[TestMethod]
public async Task When_Xuid_Basic()
{
var xamlFile = new XamlFile("ContentDialog1.xaml", """
<ContentDialog
x:Class="TestRepro.XuidGeneratorError"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Uid="XuidGeneratorErrorUid">
</ContentDialog>
""");

var resourceFile = new ResourceFile("en", "Resources.resw",
"""
<?xml version="1.0" encoding="utf-8"?>
<root>
<data name="XuidGeneratorErrorUid.PrimaryButtonText" xml:space="preserve">
<value>SomeValue</value>
</data>
</root>
""");

var test = new Verify.Test([xamlFile], [resourceFile])
{
TestState =
{
Sources =
{
"""
using Microsoft.UI.Xaml.Controls;

namespace TestRepro;
public sealed partial class XuidGeneratorError : ContentDialog
{
public XuidGeneratorError()
{
this.InitializeComponent();
}
}
"""
}
},
ReferenceAssemblies = ReferenceAssemblies.Net.Net80Android.AddPackages(ImmutableArray.Create(new PackageIdentity("Uno.WinUI", "5.0.118"))),
DisableBuildReferences = true,
}.AddGeneratedSources();

await test.RunAsync();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// <autogenerated />
#pragma warning disable CS0114
#pragma warning disable CS0108
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Uno.UI;
using Uno.UI.Xaml;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Documents;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Animation;
using Microsoft.UI.Xaml.Shapes;
using Windows.UI.Text;
using Uno.Extensions;
using Uno;
using Uno.UI.Helpers;
using Uno.UI.Helpers.Xaml;
using MyProject;

#if __ANDROID__
using _View = Android.Views.View;
#elif __IOS__
using _View = UIKit.UIView;
#elif __MACOS__
using _View = AppKit.NSView;
#else
using _View = Microsoft.UI.Xaml.UIElement;
#endif

namespace TestRepro
{
partial class XuidGeneratorError : global::Microsoft.UI.Xaml.Controls.ContentDialog
{
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
private const string __baseUri_prefix_ContentDialog1_4483f06b3f5899cc3b98f0345eeea8e5 = "ms-appx:///TestProject/";
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
private const string __baseUri_ContentDialog1_4483f06b3f5899cc3b98f0345eeea8e5 = "ms-appx:///TestProject/";
private global::Microsoft.UI.Xaml.NameScope __nameScope = new global::Microsoft.UI.Xaml.NameScope();
private void InitializeComponent()
{
NameScope.SetNameScope(this, __nameScope);
var __that = this;
base.IsParsing = true;
// Source 0\ContentDialog1.xaml (Line 1:2)
;

PrimaryButtonText = global::Uno.UI.Helpers.MarkupHelper.GetResourceStringForXUid("TestProject/Resources", "XuidGeneratorErrorUid/PrimaryButtonText");

this
.GenericApply(((c0) =>
{
// Source 0\ContentDialog1.xaml (Line 1:2)

// WARNING Property c0.base does not exist on {http://schemas.microsoft.com/winfx/2006/xaml/presentation}ContentDialog, the namespace is http://www.w3.org/XML/1998/namespace. This error was considered irrelevant by the XamlFileGenerator
}
))
.GenericApply(((c1) =>
{
// Class TestRepro.XuidGeneratorError
global::Uno.UI.Helpers.MarkupHelper.SetXUid(c1, "XuidGeneratorErrorUid");
global::Uno.UI.FrameworkElementHelper.SetBaseUri(c1, __baseUri_ContentDialog1_4483f06b3f5899cc3b98f0345eeea8e5);
c1.CreationComplete();
}
))
;
OnInitializeCompleted();

}
partial void OnInitializeCompleted();
}
}
namespace MyProject
{
static class ContentDialog1_4483f06b3f5899cc3b98f0345eeea8e5XamlApplyExtensions
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// <autogenerated />
namespace MyProject
{
/// <summary>
/// Contains all the static resources defined for the application
/// </summary>
public sealed partial class GlobalStaticResources
{
static bool _initialized;
private static bool _stylesRegistered;
private static bool _dictionariesRegistered;
internal static global::Uno.UI.Xaml.XamlParseContext __ParseContext_ { get; } = new global::Uno.UI.Xaml.XamlParseContext()
{
AssemblyName = "TestProject",
}
;

static GlobalStaticResources()
{
Initialize();
}
public static void Initialize()
{
if (!_initialized)
{
_initialized = true;
global::Uno.UI.GlobalStaticResources.Initialize();
global::Uno.UI.Toolkit.GlobalStaticResources.Initialize();
global::Uno.UI.GlobalStaticResources.RegisterDefaultStyles();
global::Uno.UI.Toolkit.GlobalStaticResources.RegisterDefaultStyles();
global::Uno.UI.GlobalStaticResources.RegisterResourceDictionariesBySource();
global::Uno.UI.Toolkit.GlobalStaticResources.RegisterResourceDictionariesBySource();
}
}
public static void RegisterDefaultStyles()
{
if(!_stylesRegistered)
{
_stylesRegistered = true;
RegisterDefaultStyles_ContentDialog1_4483f06b3f5899cc3b98f0345eeea8e5();
}
}
// Register ResourceDictionaries using ms-appx:/// syntax, this is called for external resources
public static void RegisterResourceDictionariesBySource()
{
if(!_dictionariesRegistered)
{
_dictionariesRegistered = true;
}
}
// Register ResourceDictionaries using ms-resource:/// syntax, this is called for local resources
internal static void RegisterResourceDictionariesBySourceLocal()
{
}
static partial void RegisterDefaultStyles_ContentDialog1_4483f06b3f5899cc3b98f0345eeea8e5();

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// <auto-generated />
[assembly: global::System.Reflection.AssemblyMetadata("UnoHasLocalizationResources", "True")]
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ namespace Uno.UI.SourceGenerators.Tests.Verifiers
{
public record struct XamlFile(string FileName, string Contents);

public record struct ResourceFile(string Locale, string FileName, string Contents);

public class TestSetup
{
public TestSetup(string xamlFileName, string subFolder)
Expand Down Expand Up @@ -66,6 +68,11 @@ public Test(XamlFile[] xamlFiles, [CallerFilePath] string testFilePath = "", [Ca
{
}

public Test(XamlFile[] xamlFiles, ResourceFile[] resourceFiles, [CallerFilePath] string testFilePath = "", [CallerMemberName] string testMethodName = "")
: base(xamlFiles, resourceFiles, testFilePath, ShortName(testMethodName))
{
}

private static string ShortName(string name)
=> new string(name.Where(char.IsUpper).ToArray()); // We use only upper-cased char to reduce length of filename push to git
}
Expand All @@ -77,6 +84,7 @@ public abstract class TestBase : CSharpSourceGeneratorVerifier<XamlCodeGenerator
private const string TestOutputFolderName = "Out";

private readonly XamlFile[] _xamlFiles;
private readonly ResourceFile[] _resourceFiles;

public bool EnableFuzzyMatching { get; set; } = true;
public bool DisableBuildReferences { get; set; }
Expand All @@ -88,8 +96,14 @@ protected TestBase(XamlFile xamlFile, [CallerFilePath] string testFilePath = "",
}

protected TestBase(XamlFile[] xamlFiles, string testFilePath, string testMethodName)
: this(xamlFiles, [], testFilePath, testMethodName)
{
}

protected TestBase(XamlFile[] xamlFiles, ResourceFile[] resourceFiles, string testFilePath, string testMethodName)
{
_xamlFiles = xamlFiles;
_resourceFiles = resourceFiles;
_testFilePath = testFilePath;
_testMethodName = testMethodName;

Expand Down Expand Up @@ -172,6 +186,14 @@ protected override async Task RunImplAsync(CancellationToken cancellationToken)
TestState.AdditionalFiles.Add(($"C:/Project/0/{xamlFile.FileName}", xamlFile.Contents));
}

foreach (var resourceFile in _resourceFiles)
{
globalConfigBuilder.Append($@"[C:/Project/0/Strings/{resourceFile.Locale}/{resourceFile.FileName}]
build_metadata.AdditionalFiles.SourceItemGroup = PRIResource
");
TestState.AdditionalFiles.Add(($"C:/Project/0/Strings/{resourceFile.Locale}/{resourceFile.FileName}", resourceFile.Contents));
}

TestState.AnalyzerConfigFiles.Add(("/.globalconfig", globalConfigBuilder.ToString()));
await base.RunImplAsync(cancellationToken);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -782,13 +782,17 @@ private void BuildGenericControlInitializerBody(IndentedStringBuilder writer, Xa
{
RegisterAndBuildResources(writer, topLevelControl, isInInitializer: false);
BuildProperties(writer, topLevelControl, isInline: false, useBase: true);
BuildInlineLocalizedProperties(writer, topLevelControl, topLevelControlType, isInInitializer: false);

writer.AppendLineIndented(";");

writer.AppendLineIndented("");
writer.AppendLineIndented("this");

if (BuildInlineLocalizedProperties(writer, topLevelControl, topLevelControlType,
isInInitializer: false))
{
writer.AppendLineIndented("");
}

writer.AppendLineIndented("this");

using (var blockWriter = CreateApplyBlock(writer, null, out var closure))
{
Expand Down Expand Up @@ -3781,11 +3785,12 @@ IMethodSymbol FindTargetMethodSymbol(INamedTypeSymbol? sourceType)
/// <summary>
/// Build localized properties which have not been set in the xaml.
/// </summary>
private void BuildInlineLocalizedProperties(IIndentedStringBuilder writer, XamlObjectDefinition objectDefinition, INamedTypeSymbol? objectDefinitionType, bool isInInitializer = true)
private bool BuildInlineLocalizedProperties(IIndentedStringBuilder writer, XamlObjectDefinition objectDefinition, INamedTypeSymbol? objectDefinitionType, bool isInInitializer = true)
{
TryAnnotateWithGeneratorSource(writer);
var objectUid = GetObjectUid(objectDefinition);

var ret = false;
if (objectUid != null)
{
var candidateProperties = FindLocalizableProperties(objectDefinitionType)
Expand All @@ -3795,6 +3800,7 @@ private void BuildInlineLocalizedProperties(IIndentedStringBuilder writer, XamlO
var localizedValue = BuildLocalizedResourceValue(null, prop, objectUid);
if (localizedValue != null)
{
ret = true;
if (isInInitializer)
{
writer.AppendLineInvariantIndented("{0} = {1},", prop, localizedValue);
Expand All @@ -3806,6 +3812,8 @@ private void BuildInlineLocalizedProperties(IIndentedStringBuilder writer, XamlO
}
}
}

return ret;
}

/// <summary>
Expand Down
Loading