Skip to content

Commit

Permalink
feat: Add partial methos generation for changed and changing events
Browse files Browse the repository at this point in the history
  • Loading branch information
paulvarache committed Apr 21, 2023
1 parent 8ae3ab8 commit 3a94d20
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,17 @@ private void OnDateTimeChanged(string oldValue)
{
// This method never will fired becuse the parameter is a different type
}

partial void OnDisplayNameChanging(string value)
{
System.Diagnostics.Debug.WriteLine("Method OnDisplayNameChanging fired");
System.Diagnostics.Debug.WriteLine(value);
}

partial void OnDisplayNameChanged(string value)
{
System.Diagnostics.Debug.WriteLine("Method OnDisplayNameChanged fired");
System.Diagnostics.Debug.WriteLine(value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class AutoBindablePropertyGenerator : IncrementalGeneratorBase, IIncremen
private readonly List<Type> TypeImplementations = new() {
typeof(DefaultValue),
typeof(PropertyChanged),
typeof(PropertyChanging),
typeof(DefaultBindingMode),
typeof(ValidateValue)
};
Expand Down Expand Up @@ -169,7 +170,7 @@ private void ProcessBindableProperty(
var nameProperty = fieldSymbol.GetTypedConstant(attributeSymbol, AutoBindableConstants.AttrPropertyName);
this.InitializeImplementations(fieldSymbol, attributeSymbol, classSymbol);

var propertyName = this.ChooseName(fieldName, nameProperty);
var propertyName = ChooseName(fieldName, nameProperty);
if (propertyName?.Length == 0 || propertyName == fieldName)
{
context.ReportDiagnostic(
Expand Down Expand Up @@ -231,6 +232,9 @@ private void ProcessBindableProperty(
}
}

w._($@"partial void On{propertyName}Changed({declaringType.ToDisplayString(CommonSymbolDisplayFormat.DefaultFormat)} value);");
w._($@"partial void On{propertyName}Changing({declaringType.ToDisplayString(CommonSymbolDisplayFormat.DefaultFormat)} value);");

this.ProcessImplementationLogic(w);
}

Expand Down Expand Up @@ -273,7 +277,7 @@ private bool ExistsBodySetter()
return this.Implementations.Any(i => i.SetterImplemented());
}

private string ChooseName(string fieldName, TypedConstant overridenNameOpt)
internal static string ChooseName(string fieldName, TypedConstant overridenNameOpt)
{
if (!overridenNameOpt.IsNull)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@ namespace Maui.BindableProperty.Generator.Core.BindableProperty.Implementation;
public class PropertyChanged : IImplementation
{
private TypedConstant OnChangedProperty { get; set; }

protected string PropertyName { get; set; }

private IFieldSymbol FieldSymbol { get; set; }
private INamedTypeSymbol ClassSymbol { get; set; }

public PropertyChanged(IFieldSymbol fieldSymbol, ISymbol attributeSymbol, INamedTypeSymbol classSymbol)
{
this.OnChangedProperty = fieldSymbol.GetTypedConstant(attributeSymbol, AutoBindableConstants.AttrOnChanged);
var nameProperty = fieldSymbol.GetTypedConstant(attributeSymbol, AutoBindableConstants.AttrPropertyName);

this.PropertyName = AutoBindablePropertyGenerator.ChooseName(fieldSymbol.Name, nameProperty);
this.FieldSymbol = fieldSymbol;
this.ClassSymbol = classSymbol;
}
Expand All @@ -22,50 +28,63 @@ public bool SetterImplemented()
return false;
}

public string ProcessBindableParameters()
public virtual string ProcessBindableParameters()
{
return this.OnChangedProperty.GetValue<string>(methodName => {
return $@"propertyChanged: __{methodName}";
});
return $@"propertyChanged: {GetInternalMethodName()}";
}

public void ProcessBodySetter(CodeWriter w)
{
// Not implemented
}

protected virtual string GetInternalMethodName()
{
return $@"__{this.PropertyName}Changed";
}

protected virtual string GetMethodName()
{
return $@"On{this.PropertyName}Changed";
}

public void ProcessImplementationLogic(CodeWriter w)
{
this.OnChangedProperty.GetValue<string>(methodName => {
var methodDefinition = @$"private static void __{methodName}({AutoBindableConstants.FullNameMauiControls}.BindableObject bindable, object oldValue, object newValue)";
var innerMethodName = GetInternalMethodName();

if (w.ToString().Contains(methodDefinition))
return default;
var methodName = GetMethodName();
var methodDefinition = @$"private static void {innerMethodName}({AutoBindableConstants.FullNameMauiControls}.BindableObject bindable, object oldValue, object newValue)";

AttributeBuilder.WriteAllAttrGeneratedCodeStrings(w);
using (w.B(methodDefinition))
if (w.ToString().Contains(methodDefinition))
return;

AttributeBuilder.WriteAllAttrGeneratedCodeStrings(w);
using (w.B(methodDefinition))
{
w._($@"var ctrl = ({this.ClassSymbol.ToDisplayString(CommonSymbolDisplayFormat.DefaultFormat)})bindable;");
this.OnChangedProperty.GetValue<string>((customMethodName) =>
{
var methods = this.GetMethodsToCall(methodName);
var methods = this.GetMethodsToCall(customMethodName);
if (methods.Any())
{
w._($@"var ctrl = ({this.ClassSymbol.ToDisplayString(CommonSymbolDisplayFormat.DefaultFormat)})bindable;");
methods.ToList().ForEach(m => {
methods.ToList().ForEach(m =>
{
var count = m.Parameters.Count();
if (count == 0)
w._($@"ctrl.{methodName}();");
w._($@"ctrl.{customMethodName}();");
else if (count == 1)
w._($@"ctrl.{methodName}(({this.FieldSymbol.Type})newValue);");
w._($@"ctrl.{customMethodName}(({this.FieldSymbol.Type})newValue);");
else if (count == 2)
w._($@"ctrl.{methodName}(({this.FieldSymbol.Type})oldValue, ({this.FieldSymbol.Type})newValue);");
w._($@"ctrl.{customMethodName}(({this.FieldSymbol.Type})oldValue, ({this.FieldSymbol.Type})newValue);");
});
}
}
return default;
});
return default;
});
w._($@"ctrl.{methodName}(({this.FieldSymbol.Type})newValue);");
}
}

private IEnumerable<IMethodSymbol> GetMethodsToCall(string methodName)
protected virtual IEnumerable<IMethodSymbol> GetMethodsToCall(string methodName)
{
var typeSymbol = this.FieldSymbol.Type;
var methods = this.ClassSymbol.GetMembers(methodName)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Microsoft.CodeAnalysis;

namespace Maui.BindableProperty.Generator.Core.BindableProperty.Implementation;

public class PropertyChanging : PropertyChanged
{
public PropertyChanging(IFieldSymbol fieldSymbol, ISymbol attributeSymbol, INamedTypeSymbol classSymbol): base(fieldSymbol, attributeSymbol, classSymbol)
{

}

public override string ProcessBindableParameters()
{
return $@"propertyChanging: {GetInternalMethodName()}";
}

protected override string GetInternalMethodName()
{
return $@"__{this.PropertyName}Changing";
}

protected override string GetMethodName()
{
return $@"On{this.PropertyName}Changing";
}

protected override IEnumerable<IMethodSymbol> GetMethodsToCall(string methodName)
{
return Enumerable.Empty<IMethodSymbol>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,19 @@
<RepositoryUrl>https://github.com/rrmanzano/maui-bindableproperty-generator</RepositoryUrl>
<PackageId>M.BindableProperty.Generator</PackageId>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
<IsRoslynComponent>true</IsRoslynComponent>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.3.1" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>

<ItemGroup>
<None Include="..\..\README.md">
<Pack>True</Pack>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"profiles": {
"Debug": {
"commandName": "DebugRoslynComponent",
"targetProject": "..\\Maui.BindableProperty.Generator.Demo\\Maui.BindableProperty.Generator.Demo.csproj"
}
}
}

0 comments on commit 3a94d20

Please sign in to comment.