Добавлен кодген для прокси для свойств и индексаторов
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
// #define DONT_ADD
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
@@ -41,11 +43,13 @@ namespace mROA.Codegen
|
||||
|
||||
var namespaceName = classSymbol.ContainingNamespace.ToDisplayString();
|
||||
var className = classDeclarationSyntax.Identifier.Text;
|
||||
innerMethods = CollectMembers(classSymbol)
|
||||
.Where(i => i.MethodKind != MethodKind.EventAdd || i.MethodKind != MethodKind.EventRemove)
|
||||
innerMethods = CollectMembers(classSymbol);
|
||||
var associated = innerMethods.Select(i => i.AssociatedSymbol).Where(i => i != null)
|
||||
.Distinct(SymbolEqualityComparer.Default).Cast<ISymbol>().ToList();
|
||||
|
||||
innerMethods = innerMethods.Where(i =>
|
||||
i.MethodKind != MethodKind.EventAdd && i.MethodKind != MethodKind.EventRemove)
|
||||
.ToList();
|
||||
var associated = innerMethods.Select(i => i.AssociatedSymbol as IPropertySymbol).Where(i => i != null)
|
||||
.Select(i => i!).Distinct(SymbolEqualityComparer.Default).Cast<IPropertySymbol>().ToList();
|
||||
|
||||
var originalName = className;
|
||||
|
||||
@@ -68,9 +72,35 @@ namespace mROA.Codegen
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var prop in associated)
|
||||
foreach (var symbol in associated)
|
||||
{
|
||||
var start = $"public {prop.Type.ToDisplayString()} {prop.Name}";
|
||||
switch (symbol)
|
||||
{
|
||||
case IPropertySymbol propertySymbol:
|
||||
|
||||
var setter = propertiesAccessMethods.FirstOrDefault(i =>
|
||||
i.Item2.AssociatedSymbol!.Name == propertySymbol.Name && i.Item2.ReturnsVoid);
|
||||
var getter = propertiesAccessMethods.FirstOrDefault(i =>
|
||||
i.Item2.AssociatedSymbol!.Name == propertySymbol.Name && !i.Item2.ReturnsVoid);
|
||||
string impl;
|
||||
if (propertySymbol.IsIndexer)
|
||||
{
|
||||
impl =
|
||||
$"public {propertySymbol.Type.ToDisplayString()} this[{string.Join(", ", propertySymbol.Parameters.Select(p => p.ToDisplayString()))}] {{ {getter.Item1} {setter.Item1} }}";
|
||||
}
|
||||
else
|
||||
{
|
||||
impl =
|
||||
$"public {propertySymbol.Type.ToDisplayString()} {symbol.Name} {{ {getter.Item1} {setter.Item1} }}";
|
||||
}
|
||||
|
||||
declaredMethods.Add(impl);
|
||||
break;
|
||||
case IEventSymbol eventSymbol:
|
||||
declaredMethods.Add(
|
||||
$"public event {eventSymbol.Type.ToDisplayString()}? {eventSymbol.Name};");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var code = $@"// <auto-generated/>
|
||||
@@ -89,15 +119,16 @@ namespace {namespaceName}
|
||||
{{
|
||||
}}
|
||||
|
||||
{string.Join("\r\n\t", declaredMethods)}
|
||||
{string.Join("\r\n\t\t", declaredMethods)}
|
||||
}}
|
||||
}}
|
||||
";
|
||||
|
||||
|
||||
// Add the source code to the compilation.
|
||||
// context.AddSource($"{className}.g.cs", SourceText.From(code, Encoding.UTF8));
|
||||
|
||||
#if !DONT_ADD
|
||||
context.AddSource($"{className}.g.cs", SourceText.From(code, Encoding.UTF8));
|
||||
#endif
|
||||
frontendContextRepo.Add(
|
||||
$"{{ typeof({classSymbol.ToDisplayString()}), typeof({namespaceName}.{className}) }}");
|
||||
}
|
||||
@@ -161,7 +192,9 @@ namespace mROA.Codegen
|
||||
}}
|
||||
}}
|
||||
";
|
||||
// context.AddSource("RemoteTypeBinder.g.cs", SourceText.From(fronendRepoCode, Encoding.UTF8));
|
||||
#if !DONT_ADD
|
||||
context.AddSource("RemoteTypeBinder.g.cs", SourceText.From(fronendRepoCode, Encoding.UTF8));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,12 +217,13 @@ namespace mROA.Codegen
|
||||
isAsync = namedType.Name == "Task";
|
||||
isVoid = isAsync && namedType.TypeParameters.Length == 0 || namedType.Name == "Void";
|
||||
parameters = method.Parameters.ToList();
|
||||
parameters.RemoveAll(i => i.Type.Name is "CancellationToken" or "RequestContext");
|
||||
parameters.RemoveAll(ParameterFilter);
|
||||
isParametrized = parameters.Count != 0;
|
||||
break;
|
||||
case IArrayTypeSymbol:
|
||||
isAsync = false;
|
||||
isVoid = false;
|
||||
parameters = new List<IParameterSymbol>();
|
||||
isParametrized = method.Parameters.Length != 0;
|
||||
break;
|
||||
default:
|
||||
@@ -206,12 +240,11 @@ namespace mROA.Codegen
|
||||
var prefix = isAsync ? "await " : "";
|
||||
var postfix = !isAsync ? isVoid ? ".Wait()" : ".GetAwaiter().GetResult()" : "";
|
||||
var parameterLink = isParametrized
|
||||
? ", new object[] {" + string.Join(", ", method.Parameters.Select(i => i.Name)) + "}"
|
||||
? ", new object[] {" + string.Join(", ", parameters.Select(i => i.Name)) + "}"
|
||||
: string.Empty;
|
||||
var tokenInsert = isAsync
|
||||
? isParametrized
|
||||
? ", cancellationToken : " + method.Parameters[1].Name
|
||||
: ", cancellationToken : " + method.Parameters[0].Name
|
||||
var tokenInsert = isAsync && method.Parameters.FirstOrDefault(i => i.Type.Name == "CancellationToken") is
|
||||
{ } tokenSymbol
|
||||
? ", cancellationToken : " + tokenSymbol.Name
|
||||
: String.Empty;
|
||||
var caller = isVoid
|
||||
? $"CallAsync({index}{parameterLink}{tokenInsert})"
|
||||
@@ -229,11 +262,14 @@ namespace mROA.Codegen
|
||||
declaretedMethods.Add(sb.ToString());
|
||||
}
|
||||
|
||||
private static Predicate<IParameterSymbol> ParameterFilter =
|
||||
i => i.Type.Name is "CancellationToken" or "RequestContext";
|
||||
|
||||
public void GeneratePropertyMethod(IMethodSymbol method, List<IMethodSymbol> methods,
|
||||
List<(string, IMethodSymbol)> propsCollection)
|
||||
{
|
||||
var index = methods.IndexOf(method);
|
||||
var sb = new StringBuilder();
|
||||
var sb = "";
|
||||
if (method.MethodKind == MethodKind.PropertyGet)
|
||||
{
|
||||
var parametersArray = "";
|
||||
@@ -242,19 +278,18 @@ namespace mROA.Codegen
|
||||
parametersArray = $", new object[] {{{string.Join(", ", method.Parameters.Select(p => p.Name))}}}";
|
||||
}
|
||||
|
||||
sb.AppendLine(
|
||||
$"get => GetResultAsync<{method.ReturnType.ToDisplayString()}>({index}{parametersArray}).Wait();");
|
||||
sb =
|
||||
$"get => GetResultAsync<{method.ReturnType.ToDisplayString()}>({index}{parametersArray}).GetAwaiter().GetResult();";
|
||||
}
|
||||
else
|
||||
{
|
||||
var parametersArray = "";
|
||||
var parametersArray = "value";
|
||||
if (method.Parameters.Length != 0)
|
||||
{
|
||||
parametersArray = ", " + string.Join(", ", method.Parameters.Select(p => p.Name));
|
||||
parametersArray = string.Join(", ", method.Parameters.Select(p => p.Name));
|
||||
}
|
||||
|
||||
sb.AppendLine(
|
||||
$"set => CallAsync({index}, new object[] {{ value{parametersArray} }}).GetAwaiter().GetResult();");
|
||||
sb = $"set => CallAsync({index}, new object[] {{ {parametersArray} }}).Wait();";
|
||||
}
|
||||
|
||||
propsCollection.Add((sb.ToString(), method));
|
||||
|
||||
Reference in New Issue
Block a user