Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
57877ec
Extend BindableProperty source gen to handle partial property initial…
stephenquan Dec 5, 2025
a9085ef
Update CommonUsageTests.cs
TheCodeTraveler Dec 5, 2025
fba8b25
Only implement new initializer code for when initializers are present
stephenquan Dec 5, 2025
fd700dc
Revert IntegrationTests
stephenquan Dec 5, 2025
b2dc373
Revert setter accessibility changes
stephenquan Dec 5, 2025
30fabbd
Merge branch 'feature/bp-sourcegen-init' of github.com:stephenquan/Ma…
stephenquan Dec 5, 2025
6ddcd78
Corrected setter
stephenquan Dec 5, 2025
c4bda26
Refactor GetDefaultValueCreatorMethod. Update XML Doc. Apply to reado…
stephenquan Dec 5, 2025
06dd458
Include global root namespace for BindableObject
stephenquan Dec 5, 2025
825adf8
Corrected typo in GetDefautValueCreatorMethodName
stephenquan Dec 5, 2025
1727770
Revert initializer-setter changes (not needed). Refactor getter-initi…
stephenquan Dec 5, 2025
9d785b6
Remove unneeded test from BindablePropertyModelTests
stephenquan Dec 5, 2025
8c823de
Refctor EffectiveDefaultValueCreatorMethodName property (replacing Ge…
stephenquan Dec 6, 2025
ebab9e1
Update BindablePropertyName_WithInitializer_ReturnsCorrectEffectiveDe…
stephenquan Dec 6, 2025
c80418c
Corrected unit test name GenerateBindableProperty_WithInitializer_Gen…
stephenquan Dec 6, 2025
0aed7ad
Refactor InitializingPropertyName property
stephenquan Dec 6, 2025
1ba82b4
Add Edge Case Test `GenerateBindableProperty_WithBothInitializerAndDe…
TheCodeTraveler Dec 8, 2025
50b229b
Merge branch 'main' into feature/bp-sourcegen-init
TheCodeTraveler Dec 8, 2025
1ce2b6a
Merge branch 'main' into pr/2987
TheCodeTraveler Dec 8, 2025
07d0087
Use `"null"` instead of `string.IsNullOrEmpty()`
TheCodeTraveler Dec 8, 2025
45adcdf
Merge branch 'feature/bp-sourcegen-init' of https://github.com/stephe…
TheCodeTraveler Dec 8, 2025
3a642d0
Remove `DefaultValue`
TheCodeTraveler Dec 8, 2025
77b3fa5
Move out-of-scope variables to `file static class`
TheCodeTraveler Dec 8, 2025
fc82b82
Use raw string literal
TheCodeTraveler Dec 8, 2025
4060d68
Update variable name
TheCodeTraveler Dec 9, 2025
a382be9
Implement `[BindableProperty]` for `AvatarView`
TheCodeTraveler Dec 9, 2025
a7ad7bc
Include class name in `file static class`
TheCodeTraveler Dec 9, 2025
ead0fea
Use `[BindableProperty]` for AvatarView
TheCodeTraveler Dec 9, 2025
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
Expand Up @@ -38,7 +38,8 @@ public partial class {{defaultTestClassName}}
/// Backing BindableProperty for the <see cref = "Text"/> property.
/// </summary>
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, null);
public partial string Text { get => (string)GetValue(TextProperty); set => SetValue(TextProperty, value); }
bool __initializingText = false;
public partial string Text { get => __initializingText ? field : (string)GetValue(TextProperty); set => SetValue(TextProperty, field = value); }
}
""";

Expand Down Expand Up @@ -79,7 +80,8 @@ public partial class {{defaultTestClassName}}
/// Backing BindableProperty for the <see cref = "Text"/> property.
/// </summary>
public static readonly global::Microsoft.Maui.Controls.BindableProperty TextProperty = global::Microsoft.Maui.Controls.BindableProperty.Create("Text", typeof(string), typeof({{defaultTestNamespace}}.{{defaultTestClassName}}), (string)"Hello", Microsoft.Maui.Controls.BindingMode.OneWay, null, null, null, null, null);
public partial string Text { get => (string)GetValue(TextProperty); set => SetValue(TextProperty, value); }
bool __initializingText = false;
public partial string Text { get => __initializingText ? field : (string)GetValue(TextProperty); set => SetValue(TextProperty, field = value); }
}
""";

Expand Down Expand Up @@ -120,7 +122,8 @@ public partial class {{defaultTestClassName}}
/// Backing BindableProperty for the <see cref = "Text"/> property.
/// </summary>
public new 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, null);
public new partial string Text { get => (string)GetValue(TextProperty); set => SetValue(TextProperty, value); }
bool __initializingText = false;
public new partial string Text { get => __initializingText ? field : (string)GetValue(TextProperty); set => SetValue(TextProperty, field = value); }
}
""";

Expand Down Expand Up @@ -161,7 +164,8 @@ public partial class {{defaultTestClassName}}
/// Backing BindableProperty for the <see cref = "Text"/> property.
/// </summary>
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, null);
public partial string? Text { get => (string? )GetValue(TextProperty); set => SetValue(TextProperty, value); }
bool __initializingText = false;
public partial string? Text { get => __initializingText ? field : (string? )GetValue(TextProperty); set => SetValue(TextProperty, field = value); }
}
""";

Expand Down Expand Up @@ -205,13 +209,15 @@ public partial class {{defaultTestClassName}}
/// Backing BindableProperty for the <see cref = "Text"/> property.
/// </summary>
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, null);
public partial string Text { get => (string)GetValue(TextProperty); set => SetValue(TextProperty, value); }
bool __initializingText = false;
public partial string Text { get => __initializingText ? field : (string)GetValue(TextProperty); set => SetValue(TextProperty, field = value); }

/// <summary>
/// Backing BindableProperty for the <see cref = "Number"/> property.
/// </summary>
public static readonly global::Microsoft.Maui.Controls.BindableProperty NumberProperty = global::Microsoft.Maui.Controls.BindableProperty.Create("Number", typeof(int), typeof({{defaultTestNamespace}}.{{defaultTestClassName}}), null, Microsoft.Maui.Controls.BindingMode.OneWay, null, null, null, null, null);
public partial int Number { get => (int)GetValue(NumberProperty); set => SetValue(NumberProperty, value); }
bool __initializingNumber = false;
public partial int Number { get => __initializingNumber ? field : (int)GetValue(NumberProperty); set => SetValue(NumberProperty, field = value); }
}
""";

Expand Down Expand Up @@ -265,7 +271,8 @@ public partial class {{defaultTestClassName}}
/// Backing BindableProperty for the <see cref = "Value"/> property.
/// </summary>
public static readonly global::Microsoft.Maui.Controls.BindableProperty ValueProperty = global::Microsoft.Maui.Controls.BindableProperty.Create("Value", typeof(int), typeof({{defaultTestNamespace}}.{{defaultTestClassName}}), (int)42, (Microsoft.Maui.Controls.BindingMode)1, ValidateValue, OnPropertyChanged, OnPropertyChanging, CoerceValue, CreateDefaultValue);
public partial int Value { get => (int)GetValue(ValueProperty); set => SetValue(ValueProperty, value); }
bool __initializingValue = false;
public partial int Value { get => __initializingValue ? field : (int)GetValue(ValueProperty); set => SetValue(ValueProperty, field = value); }
}
""";

Expand Down Expand Up @@ -306,7 +313,8 @@ internal partial class TestView
/// Backing BindableProperty for the <see cref = "Text"/> property.
/// </summary>
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, null);
public partial string Text { get => (string)GetValue(TextProperty); set => SetValue(TextProperty, value); }
bool __initializingText = false;
public partial string Text { get => __initializingText ? field : (string)GetValue(TextProperty); set => SetValue(TextProperty, field = value); }
}
""";

Expand Down Expand Up @@ -386,7 +394,8 @@ public partial class {{defaultTestClassName}}
/// Backing BindableProperty for the <see cref = "Text"/> property.
/// </summary>
public static readonly global::Microsoft.Maui.Controls.BindableProperty TextProperty = global::Microsoft.Maui.Controls.BindableProperty.Create("Text", typeof(string), typeof(TestNamespace.TestView), null, Microsoft.Maui.Controls.BindingMode.OneWay, null, null, null, null, null);
public partial string Text { get => (string)GetValue(TextProperty); internal set => SetValue(TextProperty, value); }
bool __initializingText = false;
public partial string Text { get => __initializingText ? field : (string)GetValue(TextProperty); internal set => SetValue(TextProperty, field = value); }
}
""";

Expand Down Expand Up @@ -428,7 +437,8 @@ public partial class {{defaultTestClassName}}
/// </summary>
static readonly global::Microsoft.Maui.Controls.BindablePropertyKey textPropertyKey = global::Microsoft.Maui.Controls.BindableProperty.CreateReadOnly("Text", typeof(string), typeof(TestNamespace.TestView), null, Microsoft.Maui.Controls.BindingMode.OneWay, null, null, null, null, null);
public static readonly global::Microsoft.Maui.Controls.BindableProperty TextProperty = textPropertyKey.BindableProperty;
public partial string Text { get => (string)GetValue(TextProperty); private protected set => SetValue(textPropertyKey, value); }
bool __initializingText = false;
public partial string Text { get => __initializingText ? field : (string)GetValue(TextProperty); private protected set => SetValue(textPropertyKey, field = value); }
}
""";

Expand Down Expand Up @@ -469,7 +479,8 @@ public partial class {{defaultTestClassName}}
/// Backing BindableProperty for the <see cref = "Text"/> property.
/// </summary>
public static readonly global::Microsoft.Maui.Controls.BindableProperty TextProperty = global::Microsoft.Maui.Controls.BindableProperty.Create("Text", typeof(string), typeof(TestNamespace.TestView), null, Microsoft.Maui.Controls.BindingMode.OneWay, null, null, null, null, null);
public partial string Text { get => (string)GetValue(TextProperty); protected internal set => SetValue(TextProperty, value); }
bool __initializingText = false;
public partial string Text { get => __initializingText ? field : (string)GetValue(TextProperty); protected internal set => SetValue(TextProperty, field = value); }
}
""";

Expand Down Expand Up @@ -511,7 +522,8 @@ public partial class {{defaultTestClassName}}
/// </summary>
static readonly global::Microsoft.Maui.Controls.BindablePropertyKey textPropertyKey = global::Microsoft.Maui.Controls.BindableProperty.CreateReadOnly("Text", typeof(string), typeof(TestNamespace.TestView), null, Microsoft.Maui.Controls.BindingMode.OneWay, null, null, null, null, null);
public static readonly global::Microsoft.Maui.Controls.BindableProperty TextProperty = textPropertyKey.BindableProperty;
public partial string Text { get => (string)GetValue(TextProperty); protected set => SetValue(textPropertyKey, value); }
bool __initializingText = false;
public partial string Text { get => __initializingText ? field : (string)GetValue(TextProperty); protected set => SetValue(textPropertyKey, field = value); }
}
""";

Expand Down Expand Up @@ -553,7 +565,8 @@ public partial class {{defaultTestClassName}}
/// </summary>
static readonly global::Microsoft.Maui.Controls.BindablePropertyKey textPropertyKey = global::Microsoft.Maui.Controls.BindableProperty.CreateReadOnly("Text", typeof(string), typeof(TestNamespace.TestView), null, Microsoft.Maui.Controls.BindingMode.OneWay, null, null, null, null, null);
public static readonly global::Microsoft.Maui.Controls.BindableProperty TextProperty = textPropertyKey.BindableProperty;
public partial string Text { get => (string)GetValue(TextProperty); private set => SetValue(textPropertyKey, value); }
bool __initializingText = false;
public partial string Text { get => __initializingText ? field : (string)GetValue(TextProperty); private set => SetValue(textPropertyKey, field = value); }
}
""";

Expand Down Expand Up @@ -595,7 +608,8 @@ public partial class {{defaultTestClassName}}
/// </summary>
static readonly global::Microsoft.Maui.Controls.BindablePropertyKey textPropertyKey = global::Microsoft.Maui.Controls.BindableProperty.CreateReadOnly("Text", typeof(string), typeof({{defaultTestNamespace}}.{{defaultTestClassName}}), null, Microsoft.Maui.Controls.BindingMode.OneWay, null, null, null, null, null);
public static readonly global::Microsoft.Maui.Controls.BindableProperty TextProperty = textPropertyKey.BindableProperty;
public partial string Text { get => (string)GetValue(TextProperty); }
bool __initializingText = false;
public partial string Text { get => __initializingText ? field : (string)GetValue(TextProperty); }
}
""";

Expand Down Expand Up @@ -640,16 +654,69 @@ public partial class {{defaultTestClassName}}
/// Backing BindableProperty for the <see cref = "Position"/> property.
/// </summary>
public static readonly global::Microsoft.Maui.Controls.BindableProperty PositionProperty = global::Microsoft.Maui.Controls.BindableProperty.Create("Position", typeof(System.TimeSpan), typeof({{defaultTestNamespace}}.{{defaultTestClassName}}), global::System.TimeSpan.Zero, Microsoft.Maui.Controls.BindingMode.OneWay, null, null, null, null, null);
public partial System.TimeSpan Position { get => (System.TimeSpan)GetValue(PositionProperty); set => SetValue(PositionProperty, value); }
bool __initializingPosition = false;
public partial System.TimeSpan Position { get => __initializingPosition ? field : (System.TimeSpan)GetValue(PositionProperty); set => SetValue(PositionProperty, field = value); }

/// <summary>
/// Backing BindableProperty for the <see cref = "CustomDuration"/> property.
/// </summary>
public static readonly global::Microsoft.Maui.Controls.BindableProperty CustomDurationProperty = global::Microsoft.Maui.Controls.BindableProperty.Create("CustomDuration", typeof(System.TimeSpan), typeof({{defaultTestNamespace}}.{{defaultTestClassName}}), new global::System.TimeSpan(900000000), Microsoft.Maui.Controls.BindingMode.OneWay, null, null, null, null, null);
public partial System.TimeSpan CustomDuration { get => (System.TimeSpan)GetValue(CustomDurationProperty); set => SetValue(CustomDurationProperty, value); }
bool __initializingCustomDuration = false;
public partial System.TimeSpan CustomDuration { get => __initializingCustomDuration ? field : (System.TimeSpan)GetValue(CustomDurationProperty); set => SetValue(CustomDurationProperty, field = value); }
}
""";

await VerifySourceGeneratorAsync(source, expectedGenerated);
}

[Fact]
public async Task GenerateBindableProperty_WithInitializers_GeneratesCorrectCode()
{
const string source =
/* language=C#-test */
//lang=csharp
$$"""
using CommunityToolkit.Maui;
using Microsoft.Maui.Controls;

namespace {{defaultTestNamespace}};

public partial class {{defaultTestClassName}} : View
{
[BindablePropertyAttribute]
public partial string Text { get; set; } = "Initial Value";
}
""";

const string expectedGenerated =
/* language=C#-test */
//lang=csharp
$$"""
// <auto-generated>
// See: CommunityToolkit.Maui.SourceGenerators.Internal.BindablePropertyAttributeSourceGenerator
#pragma warning disable
#nullable enable
namespace {{defaultTestNamespace}};
public partial class {{defaultTestClassName}}
{
/// <summary>
/// Backing BindableProperty for the <see cref = "Text"/> property.
/// </summary>
public static readonly global::Microsoft.Maui.Controls.BindableProperty TextProperty = global::Microsoft.Maui.Controls.BindableProperty.Create("Text", typeof(string), typeof(TestNamespace.TestView), null, Microsoft.Maui.Controls.BindingMode.OneWay, null, null, null, null, __createDefaultText);
bool __initializingText = false;
public partial string Text { get => __initializingText ? field : (string)GetValue(TextProperty); set => SetValue(TextProperty, field = value); }

static object __createDefaultText(Microsoft.Maui.Controls.BindableObject bindable)
{
((TestView)bindable).__initializingText = true;
var defaultValue = ((TestView)bindable).Text;
((TestView)bindable).__initializingText = false;
return defaultValue;
}
}
""";

await VerifySourceGeneratorAsync(source, expectedGenerated);
}

}
Loading
Loading