diff --git a/Generators/Bindings/BindingEmitter.cs b/Generators/Bindings/BindingEmitter.cs
index cebf152..cd905de 100644
--- a/Generators/Bindings/BindingEmitter.cs
+++ b/Generators/Bindings/BindingEmitter.cs
@@ -24,6 +24,8 @@ internal static void Emit(SourceProductionContext context, BindingTransformation
private static string GenerateSource(BindingTransformationResult result)
{
var scopePrinter = new SyntaxNodeScopePrinter(Printer.Default, result.SyntaxNode.Parent);
+ scopePrinter.Printer.PrintLine("// ");
+ scopePrinter.Printer.PrintLine("#pragma warning disable CS0109 // Member does not hide an inherited member; new keyword is not required");
scopePrinter.PrintOpen();
var printer = scopePrinter.Printer;
@@ -66,6 +68,7 @@ private static string GenerateSource(BindingTransformationResult result)
}
printer.CloseScope("};");
PrintCreateMemberBinding(printer, className, result);
+ PrintCreateFieldBindings(printer, className, result);
PrintCreatePropertyBindings(printer, className, result);
PrintCreateMethodBindings(printer, className, result);
}
@@ -85,7 +88,7 @@ private static void PrintFactoryClass(Printer printer, string className, Binding
printer.PrintLine($"public static {className} {CreateInstanceMethodName}(object[] args)");
printer.OpenScope();
{
- // Constructor that takes a single object[] parameter.
+ // Constructor that takes a single object[] or CLParams parameter.
IMethodSymbol paramsConstructor = null;
foreach (var method in result.Methods)
@@ -93,7 +96,9 @@ private static void PrintFactoryClass(Printer printer, string className, Binding
if (method.AttributeData.AttributeClass.Is(Types.Attributes.CLConstructor) == false)
continue;
- if (method.Symbol.Parameters.Length == 1 && method.Symbol.Parameters[0].Type.ToFullName() == "object[]")
+ if (method.Symbol.Parameters.Length == 1 && (
+ method.Symbol.Parameters[0].Type.ToFullName() == "object[]" ||
+ method.Symbol.Parameters[0].Type.ToFullName() == Types.CLParams))
{
paramsConstructor = method.Symbol;
break;
@@ -102,8 +107,12 @@ private static void PrintFactoryClass(Printer printer, string className, Binding
foreach (var method in result.Methods)
{
- if (method.AttributeData.AttributeClass.Is(Types.Attributes.CLConstructor) == false
- || SymbolEqualityComparer.Default.Equals(method.Symbol, paramsConstructor))
+ if (method.AttributeData.AttributeClass.Is(Types.Attributes.CLConstructor) == false)
+ continue;
+
+ if (method.Symbol.Parameters.Length == 1 && (
+ method.Symbol.Parameters[0].Type.ToFullName() == "object[]" ||
+ method.Symbol.Parameters[0].Type.ToFullName() == Types.CLParams))
continue;
printer.PrintLine($"if (args.Length == {method.Symbol.Parameters.Length})");
@@ -117,8 +126,11 @@ private static void PrintFactoryClass(Printer printer, string className, Binding
if (paramsConstructor != null)
{
- var paramName = paramsConstructor.Parameters[0].Name;
- printer.PrintLine($"object[] {paramName} = args;");
+ var paramName = GetParameterName(paramsConstructor.Parameters[0]);
+ var paramType = paramsConstructor.Parameters[0].Type.ToFullName();
+ printer.PrintLine(paramType == "object[]"
+ ? $"{paramType} {paramName} = args;"
+ : $"{paramType} {paramName} = new {Types.CLParams}(0, args);");
printer.PrintLine($"return new {className}({paramName});");
}
else
@@ -136,6 +148,12 @@ private static void PrintCreateMemberBinding(Printer printer, string className,
{
printer.PrintLine("return name switch");
printer.OpenScope();
+
+ foreach (var field in result.Fields)
+ {
+ var name = field.SpecifiedName;
+ printer.PrintLine($"\"{name}\" => __CreatePropertyBinding__{name}(),");
+ }
foreach (var property in result.Properties)
{
@@ -158,7 +176,43 @@ private static void PrintCreateMemberBinding(Printer printer, string className,
printer.CloseScope();
}
- // todo: PrintCreateFieldBindings
+ private static void PrintCreateFieldBindings(Printer printer, string className, BindingTransformationResult result)
+ {
+ const string instanceParamName = "__i";
+ const string valueParamName = "__v";
+
+ const string getterName = "__getter";
+ const string setterName = "__setter";
+
+ foreach (var field in result.Fields)
+ {
+ var exposedName = field.SpecifiedName;
+ var actualName = field.ActualName;
+ var type = field.Symbol.Type.ToFullName();
+ var isReadonly = Types.Attributes.GetIsReadOnlyOrDefault(field.AttributeData, false);
+
+ printer.PrintLine($"public static {Types.CLPropertyBinding}<{className}> __CreatePropertyBinding__{exposedName}()");
+ printer.OpenScope();
+ {
+ var instance = field.Symbol.IsStatic ? className : instanceParamName;
+
+ var getter = getterName;
+ printer.PrintBeginLine($"static object {getterName}({className} {instanceParamName})");
+ printer.PrintEndLine($" => {instance}.{actualName};");
+
+ var setter = "null";
+ if (field.Symbol.IsReadOnly == false && isReadonly == false)
+ {
+ setter = setterName;
+ printer.PrintBeginLine($"static void {setterName}({className} {instanceParamName}, object {valueParamName})");
+ printer.PrintEndLine($" => {instance}.{actualName} = global::CustomLogic.CustomLogicEvaluator.ConvertTo<{type}>({valueParamName});");
+ }
+
+ printer.PrintLine($"return new {Types.CLPropertyBinding}<{className}>({getter}, {setter});");
+ }
+ printer.CloseScope();
+ }
+ }
private static void PrintCreatePropertyBindings(Printer printer, string className, BindingTransformationResult result)
{
@@ -243,61 +297,82 @@ private static void PrintCreateMethodBindings(Printer printer, string className,
private static string PrintParameters(Printer printer, MemberInfo method, string argsParamName)
{
- if (method.Symbol.Parameters.Length == 1 && method.Symbol.Parameters[0].Type.ToFullName() == "object[]")
+ if (method.Symbol.Parameters.Length == 1)
{
- var paramName = method.Symbol.Parameters[0].Name;
- printer.PrintLine($"object[] {paramName} = {argsParamName};");
+ var paramName = GetParameterName(method.Symbol.Parameters[0]);
+ var type = method.Symbol.Parameters[0].Type.ToFullName();
+ var isObjectArr = type == "object[]";
+ var isCLParams = type == Types.CLParams;
+
+ if (isObjectArr || isCLParams)
+ {
+ printer.PrintLine(isObjectArr
+ ? $"{type} {paramName} = {argsParamName};"
+ : $"{type} {paramName} = new {Types.CLParams}(0, {argsParamName});");
+
+ return argsParamName;
+ }
}
- else
+
+ for (var i = 0; i < method.Symbol.Parameters.Length; i++)
{
- foreach (var parameter in method.Symbol.Parameters)
+ var parameter = method.Symbol.Parameters[i];
+ var name = GetParameterName(parameter);
+
+ var type = parameter.Type.ToFullName();
+ var value = "default";
+
+ if (i == method.Symbol.Parameters.Length - 1 && type == Types.CLParams)
{
- var name = parameter.Name;
- var type = parameter.Type.ToFullName();
- var value = "default";
-
- if (parameter.IsOptional == false)
- {
- value = type != "object"
- ? $"{Types.Evaluator}.ConvertTo<{type}>({argsParamName}[{parameter.Ordinal}])"
- : $"{argsParamName}[{parameter.Ordinal}]";
- }
- else if (parameter.HasExplicitDefaultValue)
+ value = $"new {Types.CLParams}({parameter.Ordinal}, {argsParamName})";
+ }
+ else if (parameter.IsOptional == false)
+ {
+ value = type != "object"
+ ? $"{Types.Evaluator}.ConvertTo<{type}>({argsParamName}[{parameter.Ordinal}])"
+ : $"{argsParamName}[{parameter.Ordinal}]";
+ }
+ else if (parameter.HasExplicitDefaultValue)
+ {
+ if (parameter.ExplicitDefaultValue != null)
{
- if (parameter.ExplicitDefaultValue != null)
- {
- value = SymbolDisplay.FormatPrimitive(parameter.ExplicitDefaultValue, true, false);
- if (type == "float")
- value += "f";
- }
- else
- value = "null";
+ value = SymbolDisplay.FormatPrimitive(parameter.ExplicitDefaultValue, true, false);
+ if (type == "float")
+ value += "f";
}
-
- printer.PrintLine($"{type} {name} = {value};");
+ else
+ value = "null";
}
- foreach (var parameter in method.Symbol.Parameters)
- {
- var type = parameter.Type.ToFullName();
+ printer.PrintLine($"{type} {name} = {value};");
+ }
+
+ foreach (var parameter in method.Symbol.Parameters)
+ {
+ var paramName = GetParameterName(parameter);
+ var type = parameter.Type.ToFullName();
- if (parameter.IsOptional)
+ if (parameter.IsOptional)
+ {
+ printer.PrintLine($"if ({argsParamName}.Length > {parameter.Ordinal})");
+ printer.OpenScope();
{
- printer.PrintLine($"if ({argsParamName}.Length > {parameter.Ordinal})");
- printer.OpenScope();
- {
- var value = type != "object"
- ? $"{Types.Evaluator}.ConvertTo<{type}>({argsParamName}[{parameter.Ordinal}])"
- : $"{argsParamName}[{parameter.Ordinal}]";
- printer.PrintLine($"{parameter.Name} = {value};");
- }
- printer.CloseScope();
+ var value = type != "object"
+ ? $"{Types.Evaluator}.ConvertTo<{type}>({argsParamName}[{parameter.Ordinal}])"
+ : $"{argsParamName}[{parameter.Ordinal}]";
+ printer.PrintLine($"{paramName} = {value};");
}
+ printer.CloseScope();
}
}
- var parameters = string.Join(", ", method.Symbol.Parameters.Select(x => x.Name));
+ var parameters = string.Join(", ", method.Symbol.Parameters.Select(GetParameterName));
return parameters;
}
+
+ private static string GetParameterName(IParameterSymbol symbol)
+ {
+ return $"{symbol.Name}__{symbol.Ordinal}";
+ }
}
}
\ No newline at end of file
diff --git a/Types.cs b/Types.cs
index 6f00e8d..e25a319 100644
--- a/Types.cs
+++ b/Types.cs
@@ -14,6 +14,8 @@ public static class Types
public const string CLPropertyBinding = CLRootNamespace + "CLPropertyBinding";
public const string CLMethodBinding = CLRootNamespace + "CLMethodBinding";
+ public const string CLParams = CLRootNamespace + "CLParams";
+
public const string BuiltinClassInstance = CLRootNamespace + "BuiltinClassInstance";
public static class Attributes