Skip to content

Commit 1ba82b4

Browse files
Add Edge Case Test GenerateBindableProperty_WithBothInitializerAndDefault_GeneratedCodeDefaultsToUseDefaultValueCreatorMethod
1 parent 0aed7ad commit 1ba82b4

File tree

3 files changed

+62
-4
lines changed

3 files changed

+62
-4
lines changed

src/CommunityToolkit.Maui.SourceGenerators.Internal.UnitTests/BindablePropertyAttributeSourceGeneratorTests/EdgeCaseTests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,4 +456,51 @@ public partial class {{defaultTestClassName}}
456456

457457
await VerifySourceGeneratorAsync(source, expectedGenerated);
458458
}
459+
460+
[Fact]
461+
public async Task GenerateBindableProperty_WithBothInitializerAndDefault_GeneratedCodeDefaultsToUseDefaultValueCreatorMethod()
462+
{
463+
const string source =
464+
/* language=C#-test */
465+
//lang=csharp
466+
$$"""
467+
using CommunityToolkit.Maui;
468+
using Microsoft.Maui.Controls;
469+
using System;
470+
471+
namespace {{defaultTestNamespace}};
472+
473+
public partial class {{defaultTestClassName}} : View
474+
{
475+
[BindablePropertyAttribute(DefaultValueCreatorMethodName = nameof(CreateDefaultText))]
476+
public partial string Text { get; set; } = "Initial Value";
477+
478+
static string CreateDefaultText(BindableObject bindable)
479+
{
480+
return "Initial Value";
481+
}
482+
}
483+
""";
484+
485+
const string expectedGenerated =
486+
/* language=C#-test */
487+
//lang=csharp
488+
$$"""
489+
// <auto-generated>
490+
// See: CommunityToolkit.Maui.SourceGenerators.Internal.BindablePropertyAttributeSourceGenerator
491+
#pragma warning disable
492+
#nullable enable
493+
namespace {{defaultTestNamespace}};
494+
public partial class {{defaultTestClassName}}
495+
{
496+
/// <summary>
497+
/// Backing BindableProperty for the <see cref = "Text"/> property.
498+
/// </summary>
499+
public static readonly global::Microsoft.Maui.Controls.BindableProperty TextProperty = global::Microsoft.Maui.Controls.BindableProperty.Create("Text", typeof(string), typeof({{defaultTestNamespace}}.{{defaultTestClassName}}), null, Microsoft.Maui.Controls.BindingMode.OneWay, null, null, null, null, CreateDefaultText);
500+
public partial string Text { get => false ? field : (string)GetValue(TextProperty); set => SetValue(TextProperty, value); }
501+
}
502+
""";
503+
504+
await VerifySourceGeneratorAsync(source, expectedGenerated);
505+
}
459506
}

src/CommunityToolkit.Maui.SourceGenerators.Internal/Generators/BindablePropertyAttributeSourceGenerator.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ static string GenerateSource(SemanticValues value)
183183
GenerateBindableProperty(sb, in info);
184184
}
185185

186-
if (info.HasInitializer)
186+
if (info.ShouldUsePropertyInitializer)
187187
{
188188
GenerateInitializingProperty(sb, in info);
189189
GenerateDefaultValueMethod(sb, in info, classNameWithGenerics);
@@ -320,8 +320,16 @@ static void GenerateProperty(StringBuilder sb, in BindablePropertyModel info)
320320

321321
if (info.HasInitializer)
322322
{
323-
sb.Append(info.InitializingPropertyName)
324-
.Append(" ? field : ");
323+
if (info.ShouldUsePropertyInitializer)
324+
{
325+
sb.Append(info.InitializingPropertyName);
326+
}
327+
else
328+
{
329+
sb.Append("false");
330+
}
331+
332+
sb.Append(" ? field : ");
325333
}
326334

327335
sb.Append("(")

src/CommunityToolkit.Maui.SourceGenerators.Internal/Models/Records.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ namespace CommunityToolkit.Maui.SourceGenerators.Internal.Models;
55

66
record BindablePropertyModel(string PropertyName, ITypeSymbol ReturnType, ITypeSymbol DeclaringType, string DefaultValue, string DefaultBindingMode, string ValidateValueMethodName, string PropertyChangedMethodName, string PropertyChangingMethodName, string CoerceValueMethodName, string DefaultValueCreatorMethodName, string NewKeywordText, bool IsReadOnlyBindableProperty, string? SetterAccessibility, bool HasInitializer)
77
{
8+
// When both a DefaultValueCreatorMethodName and an initializer are provided, we implement the DefaultValueCreator method and the ignore the partial Property initializer
9+
public bool ShouldUsePropertyInitializer => HasInitializer && string.IsNullOrEmpty(DefaultValueCreatorMethodName);
810
public string BindablePropertyName => $"{PropertyName}Property";
911
public string BindablePropertyKeyName => $"{char.ToLower(PropertyName[0])}{PropertyName[1..]}PropertyKey";
10-
public string EffectiveDefaultValueCreatorMethodName => HasInitializer ? $"__createDefault{PropertyName}" : DefaultValueCreatorMethodName;
12+
public string EffectiveDefaultValueCreatorMethodName => ShouldUsePropertyInitializer ? $"__createDefault{PropertyName}" : DefaultValueCreatorMethodName;
1113
public string InitializingPropertyName => $"__initializing{PropertyName}";
14+
1215
}
1316

1417
record SemanticValues(ClassInformation ClassInformation, EquatableArray<BindablePropertyModel> BindableProperties);

0 commit comments

Comments
 (0)