From 6aa11ba7c0ff647768498ee9323311599270efdc Mon Sep 17 00:00:00 2001 From: Mikhail Mitrofanov Date: Sat, 8 Mar 2025 12:10:12 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BA=D0=BE=D0=B4=D0=B3=D0=B5=D0=BD=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=BF=D1=80=D0=BE=D0=BA=D1=81=D0=B8=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D1=81=D0=B2=D0=BE=D0=B9=D1=81=D1=82=D0=B2=20=D0=B8=20?= =?UTF-8?q?=D0=B8=D0=BD=D0=B4=D0=B5=D0=BA=D1=81=D0=B0=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Example.Backend/PagesList.cs | 16 +++++- mROA.Codegen/mROASourceGenerator.cs | 81 +++++++++++++++++++++-------- 2 files changed, 73 insertions(+), 24 deletions(-) diff --git a/Example.Backend/PagesList.cs b/Example.Backend/PagesList.cs index 3e02b77..1ce6be0 100644 --- a/Example.Backend/PagesList.cs +++ b/Example.Backend/PagesList.cs @@ -1,11 +1,21 @@ using System; using System.Collections.Generic; using Example.Shared; +using mROA.Abstract; +using mROA.Implementation; namespace Example.Backend { - public class PagesList : IPagesList + public class PagesList : RemoteObjectBase, IPagesList { + public IReadOnlyList Collection { get; } + + public Example.Shared.IPage this[int index] + { + get => GetResultAsync(3, new object[] { index }).GetAwaiter().GetResult(); + set => CallAsync(5, new object[] { index, value }).Wait(); + } + public IPage Get(int index) { throw new System.NotImplementedException(); @@ -28,5 +38,9 @@ namespace Example.Backend { // TODO release managed resources here } + + public PagesList(int id, IRepresentationModule representationModule) : base(id, representationModule) + { + } } } \ No newline at end of file diff --git a/mROA.Codegen/mROASourceGenerator.cs b/mROA.Codegen/mROASourceGenerator.cs index 2c31e16..22a53ab 100644 --- a/mROA.Codegen/mROASourceGenerator.cs +++ b/mROA.Codegen/mROASourceGenerator.cs @@ -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().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().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 = $@"// @@ -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(); 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 ParameterFilter = + i => i.Type.Name is "CancellationToken" or "RequestContext"; + public void GeneratePropertyMethod(IMethodSymbol method, List 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));