diff --git a/src/Maui.BindableProperty.Generator/Core/BindableProperty/AutoBindableConstants.cs b/src/Maui.BindableProperty.Generator/Core/BindableProperty/AutoBindableConstants.cs index 471b4b1..01c069f 100644 --- a/src/Maui.BindableProperty.Generator/Core/BindableProperty/AutoBindableConstants.cs +++ b/src/Maui.BindableProperty.Generator/Core/BindableProperty/AutoBindableConstants.cs @@ -2,12 +2,22 @@ { public class AutoBindableConstants { + public const string FullNameMauiControls = "Microsoft.Maui.Controls"; + public const string ProjectName = "Maui.BindableProperty.Generator"; - public const string AutoBindableAttributeName = "AutoBindableAttribute"; + public const string AttrName = "AutoBindableAttribute"; + + public const string AttrClassDisplayString = @$"{ProjectName}.Core.{AttrName}"; + + public const string AttrGeneratedCodeString = @$"[global::System.CodeDom.Compiler.GeneratedCode(""{ProjectName}"", null)]"; + + public const string AttrPropertyName = "PropertyName"; + + public const string AttrOnChanged = "OnChanged"; - public const string AttributeClassDisplayString = @$"{ProjectName}.Core.{AutoBindableAttributeName}"; + public const string AttrDefaultValue = "DefaultValue"; - public const string AttributeGeneratedCodeString = @$"[global::System.CodeDom.Compiler.GeneratedCode(""{ProjectName}"", null)]"; + public const string AttrDefaultBindingMode = "DefaultBindingMode"; } } diff --git a/src/Maui.BindableProperty.Generator/Core/BindableProperty/AutoBindablePropertyGenerator.cs b/src/Maui.BindableProperty.Generator/Core/BindableProperty/AutoBindablePropertyGenerator.cs index 7c5e462..94500d7 100644 --- a/src/Maui.BindableProperty.Generator/Core/BindableProperty/AutoBindablePropertyGenerator.cs +++ b/src/Maui.BindableProperty.Generator/Core/BindableProperty/AutoBindablePropertyGenerator.cs @@ -36,7 +36,7 @@ public AutoBindableAttribute(){} public void Execute(GeneratorExecutionContext context) { - context.EachField(AutoBindableConstants.AttributeClassDisplayString, (attributeSymbol, group) => { + context.EachField(AutoBindableConstants.AttrClassDisplayString, (attributeSymbol, group) => { var classSource = this.ProcessClass(group.Key, group.ToList(), attributeSymbol, context); context.AddSource($"{group.Key.Name}.generated.cs", SourceText.From(classSource, Encoding.UTF8)); }); @@ -53,7 +53,7 @@ private string ProcessClass(INamedTypeSymbol classSymbol, List fie var w = new CodeWriter(CodeWriterSettings.CSharpDefault); using (w.B(@$"namespace {namespaceName}")) { - w._(AutoBindableConstants.AttributeGeneratedCodeString); + w._(AutoBindableConstants.AttrGeneratedCodeString); using (w.B(@$"public partial class {classSymbol.Name}")) { // Create properties for each field @@ -84,9 +84,9 @@ private void ProcessBindableProperty(CodeWriter w, IFieldSymbol fieldSymbol, ISy var bindablePropertyName = $@"{propertyName}Property"; var customParameters = this.ProcessBindableParameters(); - w._(AutoBindableConstants.AttributeGeneratedCodeString); - w._($@"public static readonly Microsoft.Maui.Controls.BindableProperty {bindablePropertyName} = Microsoft.Maui.Controls.BindableProperty.Create(nameof({propertyName}), typeof({fieldType}), typeof({classSymbol.Name}){customParameters});"); - w._(AutoBindableConstants.AttributeGeneratedCodeString); + w._(AutoBindableConstants.AttrGeneratedCodeString); + w._($@"public static readonly {AutoBindableConstants.FullNameMauiControls}.BindableProperty {bindablePropertyName} = {AutoBindableConstants.FullNameMauiControls}.BindableProperty.Create(nameof({propertyName}), typeof({fieldType}), typeof({classSymbol.Name}){customParameters});"); + w._(AutoBindableConstants.AttrGeneratedCodeString); using (w.B(@$"public {fieldType} {propertyName}")) { w._($@"get => ({fieldType})GetValue({bindablePropertyName});"); @@ -109,7 +109,7 @@ private void ProcessBindableProperty(CodeWriter w, IFieldSymbol fieldSymbol, ISy private void InitializeAttrProperties(IFieldSymbol fieldSymbol, ISymbol attributeSymbol, INamedTypeSymbol classSymbol) { - this.NameProperty = fieldSymbol.GetTypedConstant(attributeSymbol, "PropertyName"); + this.NameProperty = fieldSymbol.GetTypedConstant(attributeSymbol, AutoBindableConstants.AttrPropertyName); this.CustomImplementations.ForEach(i => i.Initialize(this.NameProperty, fieldSymbol, attributeSymbol, classSymbol)); } @@ -159,7 +159,7 @@ private string ChooseName(string fieldName, TypedConstant overridenNameOpt) public void Initialize(GeneratorInitializationContext context) { // Register the attribute source - context.RegisterForPostInitialization((i) => i.AddSource("AutoBindableAttribute", attributeText)); + context.RegisterForPostInitialization((i) => i.AddSource(AutoBindableConstants.AttrName, attributeText)); // Register a syntax receiver that will be created for each generation pass context.RegisterForSyntaxNotifications(() => new AutoBindableSyntaxReceiver()); diff --git a/src/Maui.BindableProperty.Generator/Core/BindableProperty/AutoBindableSyntaxReceiver.cs b/src/Maui.BindableProperty.Generator/Core/BindableProperty/AutoBindableSyntaxReceiver.cs index 25a9dcc..8b9b59d 100644 --- a/src/Maui.BindableProperty.Generator/Core/BindableProperty/AutoBindableSyntaxReceiver.cs +++ b/src/Maui.BindableProperty.Generator/Core/BindableProperty/AutoBindableSyntaxReceiver.cs @@ -20,7 +20,7 @@ public void OnVisitSyntaxNode(GeneratorSyntaxContext context) { // Get the symbol being declared by the field, and keep it if its annotated if (context.SemanticModel.GetDeclaredSymbol(variable) is IFieldSymbol fieldSymbol && - fieldSymbol.GetAttributes().Any(ad => ad?.AttributeClass?.ToDisplayString() == AutoBindableConstants.AttributeClassDisplayString)) + fieldSymbol.GetAttributes().Any(ad => ad?.AttributeClass?.ToDisplayString() == AutoBindableConstants.AttrClassDisplayString)) { Fields.Add(fieldSymbol); } diff --git a/src/Maui.BindableProperty.Generator/Core/BindableProperty/Implementation/DefaultBindingMode.cs b/src/Maui.BindableProperty.Generator/Core/BindableProperty/Implementation/DefaultBindingMode.cs index 1291f97..630b6e6 100644 --- a/src/Maui.BindableProperty.Generator/Core/BindableProperty/Implementation/DefaultBindingMode.cs +++ b/src/Maui.BindableProperty.Generator/Core/BindableProperty/Implementation/DefaultBindingMode.cs @@ -6,7 +6,7 @@ namespace Maui.BindableProperty.Generator.Core.BindableProperty.Implementation { public class DefaultBindingMode : IImplementation { - private const string FullNameSpaceBindingMode = "Microsoft.Maui.Controls.BindingMode"; + private const string FullNameSpaceBindingMode = $"{AutoBindableConstants.FullNameMauiControls}.BindingMode"; private TypedConstant DefaultBindingModeValueProperty { get; set; } private IFieldSymbol FieldSymbol { get; set; } private ISymbol AttributeSymbol { get; set; } @@ -14,7 +14,7 @@ public class DefaultBindingMode : IImplementation public void Initialize(TypedConstant nameProperty, IFieldSymbol fieldSymbol, ISymbol attributeSymbol, INamedTypeSymbol classSymbol) { - this.DefaultBindingModeValueProperty = fieldSymbol.GetTypedConstant(attributeSymbol, "DefaultBindingMode"); + this.DefaultBindingModeValueProperty = fieldSymbol.GetTypedConstant(attributeSymbol, AutoBindableConstants.AttrDefaultBindingMode); this.FieldSymbol = fieldSymbol; this.AttributeSymbol = attributeSymbol; this.ClassSymbol = classSymbol; @@ -28,7 +28,7 @@ public bool SetterImplemented() public string ProcessBindableParameters() { var fieldType = this.FieldSymbol.Type; - var defaultValue = this.DefaultBindingModeValueProperty.Validate(value => + var defaultValue = this.DefaultBindingModeValueProperty.GetValue(value => { if (!value.Contains(FullNameSpaceBindingMode)) { diff --git a/src/Maui.BindableProperty.Generator/Core/BindableProperty/Implementation/DefaultValue.cs b/src/Maui.BindableProperty.Generator/Core/BindableProperty/Implementation/DefaultValue.cs index e54fde1..eace92e 100644 --- a/src/Maui.BindableProperty.Generator/Core/BindableProperty/Implementation/DefaultValue.cs +++ b/src/Maui.BindableProperty.Generator/Core/BindableProperty/Implementation/DefaultValue.cs @@ -13,7 +13,7 @@ public class DefaultValue : IImplementation public void Initialize(TypedConstant nameProperty, IFieldSymbol fieldSymbol, ISymbol attributeSymbol, INamedTypeSymbol classSymbol) { - this.DefaultValueProperty = fieldSymbol.GetTypedConstant(attributeSymbol, "DefaultValue"); + this.DefaultValueProperty = fieldSymbol.GetTypedConstant(attributeSymbol, AutoBindableConstants.AttrDefaultValue); this.FieldSymbol = fieldSymbol; this.AttributeSymbol = attributeSymbol; this.ClassSymbol = classSymbol; @@ -27,7 +27,7 @@ public bool SetterImplemented() public string ProcessBindableParameters() { var fieldType = this.FieldSymbol.Type; - var defaultValue = this.DefaultValueProperty.Validate(value => + var defaultValue = this.DefaultValueProperty.GetValue(value => { if (value != null) { diff --git a/src/Maui.BindableProperty.Generator/Core/BindableProperty/Implementation/PropertyChanged.cs b/src/Maui.BindableProperty.Generator/Core/BindableProperty/Implementation/PropertyChanged.cs index f53f2ac..20846cb 100644 --- a/src/Maui.BindableProperty.Generator/Core/BindableProperty/Implementation/PropertyChanged.cs +++ b/src/Maui.BindableProperty.Generator/Core/BindableProperty/Implementation/PropertyChanged.cs @@ -15,7 +15,7 @@ public class PropertyChanged : IImplementation public void Initialize(TypedConstant nameProperty, IFieldSymbol fieldSymbol, ISymbol attributeSymbol, INamedTypeSymbol classSymbol) { this.NameProperty = nameProperty; - this.OnChangedProperty = fieldSymbol.GetTypedConstant(attributeSymbol, "OnChanged"); + this.OnChangedProperty = fieldSymbol.GetTypedConstant(attributeSymbol, AutoBindableConstants.AttrOnChanged); this.FieldSymbol = fieldSymbol; this.AttributeSymbol = attributeSymbol; this.ClassSymbol = classSymbol; @@ -28,7 +28,7 @@ public bool SetterImplemented() public string ProcessBindableParameters() { - return this.OnChangedProperty.Validate(methodName => { + return this.OnChangedProperty.GetValue(methodName => { return $@"propertyChanged: __{methodName}"; }); } @@ -40,13 +40,13 @@ public void ProcessBodyStter(CodeWriter w) public void ProcessImplementationLogic(CodeWriter w) { - this.OnChangedProperty.Validate(methodName => { + this.OnChangedProperty.GetValue(methodName => { var methodDefinition = @$"private static void __{methodName}(Microsoft.Maui.Controls.BindableObject bindable, object oldValue, object newValue)"; if (w.ToString().Contains(methodDefinition)) return default; - w._(AutoBindableConstants.AttributeGeneratedCodeString); + w._(AutoBindableConstants.AttrGeneratedCodeString); using (w.B(methodDefinition)) { var methods = this.GetMethodsToCall(methodName); diff --git a/src/Maui.BindableProperty.Generator/Helpers/SymbolExtensions.cs b/src/Maui.BindableProperty.Generator/Helpers/SymbolExtensions.cs index f5124dc..cc0f9b3 100644 --- a/src/Maui.BindableProperty.Generator/Helpers/SymbolExtensions.cs +++ b/src/Maui.BindableProperty.Generator/Helpers/SymbolExtensions.cs @@ -20,12 +20,28 @@ public static bool IsStringType(this ITypeSymbol type) return type.SpecialType == SpecialType.System_String; } - public static string Validate(this TypedConstant TypedConstant, Func onSuccess) + public static T GetValue( + this IFieldSymbol fieldSymbol, + ISymbol attributeSymbol, + string key, + Func onSuccess = null) + { + var typeConstant = fieldSymbol.GetTypedConstant(attributeSymbol, key); + return typeConstant.GetValue(onSuccess); + } + + public static T GetValue( + this TypedConstant TypedConstant, + Func onSuccess = null) { if (!TypedConstant.IsNull) { - var value = TypedConstant.Value?.ToString(); - return onSuccess.Invoke(value); + + var value = TypedConstant.Value; + if (value.GetType() == typeof(T)) + { + return onSuccess.Invoke((T)value); + } } return default; diff --git a/src/Maui.BindableProperty.Generator/Maui.BindableProperty.Generator.csproj b/src/Maui.BindableProperty.Generator/Maui.BindableProperty.Generator.csproj index e441540..09826f4 100644 --- a/src/Maui.BindableProperty.Generator/Maui.BindableProperty.Generator.csproj +++ b/src/Maui.BindableProperty.Generator/Maui.BindableProperty.Generator.csproj @@ -10,7 +10,7 @@ Source generator that automatically transforms fields into BindableProperties that can be used in MAUI MAUI;BindableProperty;Source Generator README.md - 0.5.0 + 0.6.0 https://github.com/rrmanzano/maui-bindableproperty-generator https://github.com/rrmanzano/maui-bindableproperty-generator M.BindableProperty.Generator