From 8d8e4f44a622cc308a72421f7aa3f5d20bb32825 Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Sun, 16 Mar 2025 16:18:15 +0100 Subject: [PATCH] fix(source-generators): namof issues --- .../FrameworkElementBuilderExtensions.cs | 2 +- .../Builder/ViewModelBuilderExtensions.cs | 29 ++++++++++++++++--- .../CodeAnalysis/AttributeDataExtensions.cs | 4 +-- .../Extensions/ObjectExtensions.cs | 22 +++++++++++++- .../Extensions/StringExtensions.cs | 24 +++++++++++++++ 5 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/Atc.Wpf.SourceGenerators/Extensions/Builder/FrameworkElementBuilderExtensions.cs b/src/Atc.Wpf.SourceGenerators/Extensions/Builder/FrameworkElementBuilderExtensions.cs index cf262660..fa29d49d 100644 --- a/src/Atc.Wpf.SourceGenerators/Extensions/Builder/FrameworkElementBuilderExtensions.cs +++ b/src/Atc.Wpf.SourceGenerators/Extensions/Builder/FrameworkElementBuilderExtensions.cs @@ -91,7 +91,7 @@ private static void GenerateDependencyPropertyHeader( builder.AppendLine($"public static readonly DependencyProperty {p.Name}Property = DependencyProperty.{registerMethod}("); builder.IncreaseIndent(); - builder.AppendLine(isAttached ? $"\"{p.Name}\"," : $"nameof({p.Name}),"); + builder.AppendLine(isAttached ? $"\"{p.Name}\"," : $"{p.Name.EnsureNameofContent()},"); builder.AppendLine($"typeof({p.Type}),"); } diff --git a/src/Atc.Wpf.SourceGenerators/Extensions/Builder/ViewModelBuilderExtensions.cs b/src/Atc.Wpf.SourceGenerators/Extensions/Builder/ViewModelBuilderExtensions.cs index d9047639..8ccb9fa8 100644 --- a/src/Atc.Wpf.SourceGenerators/Extensions/Builder/ViewModelBuilderExtensions.cs +++ b/src/Atc.Wpf.SourceGenerators/Extensions/Builder/ViewModelBuilderExtensions.cs @@ -67,19 +67,23 @@ private static void GenerateProperty( builder.AppendLine($"var oldValue = {p.BackingFieldName};"); } + var nameofName = p.Name.EnsureNameofContent(); + builder.AppendLine($"{p.BackingFieldName} = value;"); - builder.AppendLine($"RaisePropertyChanged(nameof({p.Name}));"); + builder.AppendLine($"RaisePropertyChanged({nameofName});"); if (p.PropertyNamesToInvalidate is not null) { foreach (var propertyNameToInvalidate in p.PropertyNamesToInvalidate) { - builder.AppendLine($"RaisePropertyChanged(nameof({propertyNameToInvalidate}));"); + var nameofPropertyNameToInvalidate = propertyNameToInvalidate.EnsureNameofContent(); + + builder.AppendLine($"RaisePropertyChanged({nameofPropertyNameToInvalidate});"); } } if (p.BroadcastOnChange) { - builder.AppendLine($"Broadcast(nameof({p.Name}), oldValue, value);"); + builder.AppendLine($"Broadcast({nameofName}, oldValue, value);"); } if (p.AfterChangedCallback is not null) @@ -101,7 +105,24 @@ private static void GenerateCallbackInlineCode( if (value.StartsWith("nameof(", StringComparison.Ordinal) && value.EndsWith(")", StringComparison.Ordinal)) { - builder.AppendLine(value.ExtractInnerContent() + "();"); + var valueContent = value.ExtractInnerContent(); + var sa = valueContent.Split([';'], StringSplitOptions.RemoveEmptyEntries); + foreach (var s in sa) + { + var line = s.Trim(); + if (line.EndsWith("();", StringComparison.Ordinal)) + { + builder.AppendLine(line); + } + else if (line.EndsWith("()", StringComparison.Ordinal)) + { + builder.AppendLine(line + ";"); + } + else + { + builder.AppendLine(line + "();"); + } + } } else { diff --git a/src/Atc.Wpf.SourceGenerators/Extensions/CodeAnalysis/AttributeDataExtensions.cs b/src/Atc.Wpf.SourceGenerators/Extensions/CodeAnalysis/AttributeDataExtensions.cs index dabd7717..1b7e5871 100644 --- a/src/Atc.Wpf.SourceGenerators/Extensions/CodeAnalysis/AttributeDataExtensions.cs +++ b/src/Atc.Wpf.SourceGenerators/Extensions/CodeAnalysis/AttributeDataExtensions.cs @@ -94,14 +94,14 @@ public static string ExtractClassFirstArgumentType( arrayIndex++; result.Add( arrayIndex.ToString(CultureInfo.InvariantCulture), - typedConstant.Value.ToString()); + $"nameof({typedConstant.Value})"); } } else { result.Add( arg.Key, - arg.Value.Value?.ToString()); + $"nameof({arg.Value.Value})"); } } diff --git a/src/Atc.Wpf.SourceGenerators/Extensions/ObjectExtensions.cs b/src/Atc.Wpf.SourceGenerators/Extensions/ObjectExtensions.cs index 1be359c1..e15a7da0 100644 --- a/src/Atc.Wpf.SourceGenerators/Extensions/ObjectExtensions.cs +++ b/src/Atc.Wpf.SourceGenerators/Extensions/ObjectExtensions.cs @@ -2,6 +2,7 @@ namespace Atc.Wpf.SourceGenerators.Extensions; internal static class ObjectExtensions { + [SuppressMessage("Design", "MA0051:Method is too long", Justification = "OK.")] public static string? TransformDefaultValueIfNeeded( this object? defaultValue, string type) @@ -11,7 +12,11 @@ internal static class ObjectExtensions return null; } - var strDefaultValue = defaultValue.ToString(); + var strDefaultValue = defaultValue + .ToString()? + .EnsureNoNameof()? + .ToString() ?? string.Empty; + if (!type.IsSimpleType()) { return strDefaultValue; @@ -64,4 +69,19 @@ internal static class ObjectExtensions return strDefaultValue; } + + public static object? EnsureNoNameof( + this object? value) + { + if (value is null || + !value.ToString().StartsWith("nameof", StringComparison.Ordinal)) + { + return value; + } + + return value + .ToString() + .Replace("nameof(", string.Empty) + .Replace(")", string.Empty); + } } \ No newline at end of file diff --git a/src/Atc.Wpf.SourceGenerators/Extensions/StringExtensions.cs b/src/Atc.Wpf.SourceGenerators/Extensions/StringExtensions.cs index 14c8d1e5..8dba74be 100644 --- a/src/Atc.Wpf.SourceGenerators/Extensions/StringExtensions.cs +++ b/src/Atc.Wpf.SourceGenerators/Extensions/StringExtensions.cs @@ -27,6 +27,30 @@ public static class StringExtensions { nameof(String), "string" }, }; + public static string EnsureNameofContent( + this string value) + { + if (value is null) + { + throw new ArgumentNullException(nameof(value)); + } + + if (!value.StartsWith("nameof(", StringComparison.Ordinal) || + !value.EndsWith(")", StringComparison.Ordinal)) + { + return $"nameof({value})"; + } + + if (value.StartsWith("nameof(nameof(", StringComparison.Ordinal)) + { + value = value + .Replace("nameof(nameof(", "nameof(") + .Replace("))", ")"); + } + + return value; + } + public static string EnsureFirstCharacterToUpper( this string value) {