Skip to content

Commit 8792538

Browse files
committed
Handle 'string.Empty' as default value
1 parent 109d346 commit 8792538

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

components/DependencyPropertyGenerator/CommunityToolkit.DependencyPropertyGenerator.SourceGenerators/Diagnostics/Analyzers/UseGeneratedDependencyPropertyOnManualPropertyAnalyzer.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,12 @@ void HandleSetAccessor(IPropertySymbol propertySymbol, PropertyFlags propertyFla
466466
}
467467
}
468468
}
469+
else if (conversionOperation.Operand is IFieldReferenceOperation { Field: { ContainingType.SpecialType: SpecialType.System_String, Name: "Empty" } })
470+
{
471+
// Special handling of the 'string.Empty' field. This is not a constant value, but we can still treat it as a constant, by just
472+
// pretending this were the empty string literal instead. This way we can still support the property and convert to an attribute.
473+
fieldFlags.DefaultValue = TypedConstantInfo.Primitive.String.Empty;
474+
}
469475
else
470476
{
471477
// If we don't have a constant, check if it's some constant value we can forward. In this case, we

components/DependencyPropertyGenerator/CommunityToolkit.DependencyPropertyGenerator.SourceGenerators/Models/TypedConstantInfo.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ public abstract record Primitive : TypedConstantInfo
7070
/// <param name="Value">The input <see cref="string"/> value.</param>
7171
public sealed record String(string Value) : TypedConstantInfo
7272
{
73+
/// <summary>
74+
/// The shared <see cref="String"/> instance for empty strings.
75+
/// </summary>
76+
public static String Empty { get; } = new("");
77+
7378
/// <inheritdoc/>
7479
public override string ToString()
7580
{

components/DependencyPropertyGenerator/CommunityToolkit.DependencyPropertyGenerator.Tests/Test_UseGeneratedDependencyPropertyOnManualPropertyCodeFixer.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,58 @@ public enum MyEnum { A }
321321
await test.RunAsync();
322322
}
323323

324+
[TestMethod]
325+
public async Task SimpleProperty_WithExplicitValue_EmptyString()
326+
{
327+
const string original = """
328+
using Windows.UI.Xaml;
329+
using Windows.UI.Xaml.Controls;
330+
331+
#nullable enable
332+
333+
namespace MyApp;
334+
335+
public partial class MyControl : Control
336+
{
337+
public static readonly DependencyProperty NameProperty = DependencyProperty.Register(
338+
name: "Name",
339+
propertyType: typeof(string),
340+
ownerType: typeof(MyControl),
341+
typeMetadata: new PropertyMetadata(string.Empty));
342+
343+
public string [|Name|]
344+
{
345+
get => (string)GetValue(NameProperty);
346+
set => SetValue(NameProperty, value);
347+
}
348+
}
349+
""";
350+
351+
const string @fixed = """
352+
using CommunityToolkit.WinUI;
353+
using Windows.UI.Xaml;
354+
using Windows.UI.Xaml.Controls;
355+
356+
#nullable enable
357+
358+
namespace MyApp;
359+
360+
public partial class MyControl : Control
361+
{
362+
[GeneratedDependencyProperty(DefaultValue = "")]
363+
public partial string {|CS9248:Name|} { get; set; }
364+
}
365+
""";
366+
367+
CSharpCodeFixTest test = new(LanguageVersion.Preview)
368+
{
369+
TestCode = original,
370+
FixedCode = @fixed
371+
};
372+
373+
await test.RunAsync();
374+
}
375+
324376
[TestMethod]
325377
public async Task SimpleProperty_WithExplicitValue_NotDefault_AddsNamespace()
326378
{

0 commit comments

Comments
 (0)