Пример #1
0
        public static PropertyDeclarationSyntax CreatePropertyDeclaration(string typeName, string name, string description, bool optional = false,
                                                                          bool nullable   = false,
                                                                          bool addPostfix = false)
        {
            nullable = optional || nullable;

            var attributes = new List <AttributeSyntax>
            {
                Attribute(IdentifierName($"JsonPropertyName(\"{name}\")"))
            };

            //todo: problem with nullable properties in netcoreapp3.1 see test TypeWithNullableProperties
            //if (nullable) attributes.Add(Attribute(IdentifierName("JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)")));

            AccessorListSyntax accessorListSyntax = AccessorList(
                List(new[]
            {
                AccessorDeclaration(
                    SyntaxKind.GetAccessorDeclaration)
                .WithSemicolonToken(
                    Token(SyntaxKind.SemicolonToken)),
                AccessorDeclaration(
                    SyntaxKind.SetAccessorDeclaration)
                .WithSemicolonToken(
                    Token(SyntaxKind.SemicolonToken))
            }));

            return(PropertyDeclaration(IdentifierName($"{typeName}{(optional ? "?" : null)}"),
                                       NamingConventions.Normalize($"{name}{(addPostfix ? "Accessor" : null)}"))
                   .AddAttributeLists(AttributeList(SeparatedList(attributes))
                                      .WithLeadingTrivia(CommentsHelpers.BuildCommentTrivia(description)))
                   .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
                   .WithAccessorList(accessorListSyntax));
        }
Пример #2
0
        public static void CreateUnit(string unitName, Func <string, NamespaceDeclarationSyntax> nsFactory, string filePathFactory,
                                      params string[] usings)
        {
            unitName = NamingConventions.Normalize(unitName);

            CompilationUnitSyntax cu = SyntaxFactory.CompilationUnit();

            cu = cu.AddUsings(usings.OrderBy(s => s)
                              .Select(u => SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(u)))
                              .ToArray());

            var cw = new AdhocWorkspace();

            cw.Options.WithChangedOption(CSharpFormattingOptions.IndentBlock, true);
            SyntaxNode formattedNode = Formatter.Format(cu.AddMembers(nsFactory(unitName)), cw, cw.Options);

            var           file = new FileInfo(filePathFactory);
            DirectoryInfo dir  = file.Directory;

            if (!dir !.Exists)
            {
                dir.Create();
            }

            using FileStream fileStream = file.Exists ? file.Open(FileMode.Truncate) : file.Create();
            using var sw = new StreamWriter(fileStream);
            formattedNode.WriteTo(sw);
        }
Пример #3
0
        public static string GetMethodReturnType(this Result result)
        {
            if (result.GenericName != ResultGenericName.ClientResult)
            {
                throw new ArgumentOutOfRangeException(nameof(result.GenericName), result.GenericName, "Unsupported method result generic name");
            }
            if (result.Type != ParamType.Generic)
            {
                throw new ArgumentOutOfRangeException(nameof(Result.Type), result.Type, "Unsupported method result type");
            }
            if (result.GenericArgs.Length != 1)
            {
                throw new ArgumentException("Result should contains only one generic argument");
            }

            GenericArg genericArg = result.GenericArgs[0];

            switch (genericArg.Type)
            {
            case GenericArgType.None:
                return(null);

            case GenericArgType.Ref:
                return(NamingConventions.Normalize(genericArg.RefName));

            default:
                throw new ArgumentOutOfRangeException(nameof(Type), genericArg.Type, "Unsupported generic type");
            }
        }
Пример #4
0
        public static NamespaceDeclarationSyntax CreateTonClientClass(string unitName, TonApi tonApi)
        {
            var propertyDeclarationSyntaxes = GetProperties(tonApi);
            var moduleNames = tonApi.Modules.Select(m => m.Name).ToArray();

            VariableDeclarationSyntax variableDeclaration = VariableDeclaration(ParseTypeName("ServiceProvider"))
                                                            .AddVariables(VariableDeclarator("_serviceProvider"));
            FieldDeclarationSyntax fieldDeclaration = FieldDeclaration(variableDeclaration)
                                                      .AddModifiers(Token(SyntaxKind.PrivateKeyword), Token(SyntaxKind.ReadOnlyKeyword));

            var statementSyntax =
                new[]
            {
                ParseStatement("_serviceProvider = TonClientServiceProviderBuilder.BuildTonClientServiceProvider(serviceProvider);")
            }
            .Union(moduleNames
                   .Select(m => ParseStatement(
                               $"{NamingConventions.Normalize(m)} = _serviceProvider.GetRequiredService<{NamingConventions.ToInterfaceName(m)}Module>();")))
            .ToArray();

            MethodDeclarationSyntax disposeMethod = MethodDeclaration(ParseTypeName("void"), "Dispose")
                                                    .AddModifiers(Token(SyntaxKind.PublicKeyword))
                                                    .AddBodyStatements(ParseStatement("_serviceProvider?.Dispose();"));

            ConstructorDeclarationSyntax constructorDeclaration = ConstructorDeclaration(unitName)
                                                                  .AddParameterListParameters(Parameter(Identifier("serviceProvider = null")).WithType(IdentifierName("IServiceProvider")))
                                                                  .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
                                                                  .WithBody(Block(statementSyntax));

            ClassDeclarationSyntax item = ClassDeclaration(unitName)
                                          .AddModifiers(Token(SyntaxKind.PublicKeyword))
                                          .AddBaseListTypes(SimpleBaseType(IdentifierName("ITonClient")), SimpleBaseType(IdentifierName("IDisposable")))
                                          .AddMembers(fieldDeclaration)
                                          .AddMembers(constructorDeclaration)
                                          .AddMembers(propertyDeclarationSyntaxes)
                                          .AddMembers(disposeMethod);

            return(NamespaceDeclaration(IdentifierName(ClientGenerator.Namespace))
                   .AddMembers(item));
        }
Пример #5
0
        private static MemberDeclarationSyntax[] GetProperties(TonApi tonApi)
        {
            MemberDeclarationSyntax[] propertyDeclarationSyntaxes = tonApi.Modules
                                                                    .Select(module =>
            {
                var formattedName = NamingConventions.Normalize(module.Name);

                var summary = module.Summary + (module.Description != null ? $"\n{module.Description}" : null);

                return(PropertyDeclaration(IdentifierName($"I{formattedName}Module"), formattedName)
                       .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword).WithLeadingTrivia(CommentsHelpers.BuildCommentTrivia(summary))))
                       .WithAccessorList(
                           AccessorList(
                               List(new[]
                {
                    AccessorDeclaration(
                        SyntaxKind.GetAccessorDeclaration)
                    .WithSemicolonToken(
                        Token(SyntaxKind.SemicolonToken))
                }))));
            })
                                                                    .ToArray();
            return(propertyDeclarationSyntaxes);
        }
Пример #6
0
 public static Dictionary <string, string> MapNumericTypes(IEnumerable <Module> module)
 {
     return(module.SelectMany(m => m.Types).Where(t => t.Type == TypeType.Number)
            .Select(t => new { typeName = NamingConventions.Normalize(t.Name), sharpType = ConvertToSharpNumeric(t.NumberType, t.NumberSize) })
            .ToDictionary(kv => kv.typeName, kv => kv.sharpType));
 }
        private static MemberDeclarationSyntax GetMethodDeclaration(Module module, Function function, bool withBody)
        {
            var responseType        = function.Result.GetMethodReturnType();
            var responseDeclaration = responseType == null ? "Task" : $"Task<{responseType}>";
            var requestParam        = new { name = default(string), type = default(string) };
            var callbackParam       = new { name = default(string), nameWithNull = default(string), type = default(string) };

            foreach (Param param in function.Params)
            {
                if (param.Type == ParamType.Generic && param.GenericName == ParamGenericName.Arc)
                {
                    GenericArg arcArg = param.GenericArgs[0];
                    if (arcArg.Type == GenericArgType.Ref && arcArg.RefName == "Request")
                    {
                        var name = StringUtils.EscapeReserved(function.Params[2].Name.GetEnumMemberValueOrString());
                        callbackParam = new
                        {
                            name,
                            nameWithNull = $"{name} = null",
                            type         = string.Equals(module.Name, "net", StringComparison.OrdinalIgnoreCase)
                                ? "JsonElement"
                                : NamingConventions.EventFormatter(module.Name)
                        };
                    }
                }

                if (param.Type == ParamType.Generic && param.GenericName == ParamGenericName.AppObject)
                {
                    callbackParam = new
                    {
                        name         = "appObject",
                        nameWithNull = "appObject = null",
                        type         = "JsonElement"
                    }
                }
                ;

                if (param.Name == Name.Params)
                {
                    requestParam = new
                    {
                        name = StringUtils.EscapeReserved(function.Params[1].Name.GetEnumMemberValueOrString()),
                        type = GetParamType(function.Params[1])
                    }
                }
                ;
            }

            var functionSummary = function.Summary + (function.Description != null ? $"\n{function.Description}" : null);
            var modifiers       = new List <SyntaxToken> {
                Token(SyntaxKind.PublicKeyword).WithLeadingTrivia(CommentsHelpers.BuildCommentTrivia(functionSummary))
            };

            if (withBody)
            {
                modifiers.Add(Token(SyntaxKind.AsyncKeyword));
            }

            var @params = new List <ParameterSyntax>();
            var methodDeclarationParams = new List <ParameterSyntax>();

            if (requestParam.name != default)
            {
                ParameterSyntax param = Parameter(Identifier(requestParam.name)).WithType(IdentifierName(requestParam.type));
                methodDeclarationParams.Add(param);
                @params.Add(param);
            }

            if (callbackParam.name != default)
            {
                methodDeclarationParams.Add(Parameter(Identifier(callbackParam.nameWithNull)).WithType(IdentifierName($"Action<{callbackParam.type},uint>")));
                @params.Add(Parameter(Identifier(callbackParam.name)).WithType(IdentifierName($"Action<{callbackParam.type},uint>")));
            }

            MethodDeclarationSyntax method =
                MethodDeclaration(ParseTypeName(responseDeclaration), NamingConventions.Normalize(function.Name))
                .AddParameterListParameters(methodDeclarationParams.ToArray())
                .AddParameterListParameters(Parameter(Identifier("cancellationToken"))
                                            .WithType(IdentifierName(nameof(CancellationToken)))
                                            .WithDefault(EqualsValueClause(IdentifierName("default"))))
                .AddModifiers(modifiers.ToArray());

            if (withBody)
            {
                var arguments = new List <ArgumentSyntax>
                {
                    Argument(IdentifierName($"\"{module.Name}.{function.Name}\""))
                };
                arguments.AddRange(
                    @params
                    .Select(p => Argument(IdentifierName(p.Identifier.Text))));
                arguments.Add(Argument(IdentifierName("cancellationToken")));

                var genericParametersDeclaration =
                    StringUtils.GetGenericParametersDeclaration(requestParam?.type, responseType, callbackParam?.type);

                AwaitExpressionSyntax awaitExpression = AwaitExpression(
                    InvocationExpression(IdentifierName($"_tonClientAdapter.Request{genericParametersDeclaration}"))
                    .AddArgumentListArguments(arguments.ToArray()));


                StatementSyntax ex = responseType == null
                    ? ExpressionStatement(awaitExpression)
                    : ReturnStatement(awaitExpression);

                BlockSyntax blockSyntax = Block(ex);
                return(method.WithBody(blockSyntax));
            }

            return(method.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
        }
        public static NamespaceDeclarationSyntax CreateTonModuleClass(string unitName, Module module)
        {
            var moduleName = $"{unitName}Module";

            StatementSyntax statementSyntax = ParseStatement("_tonClientAdapter = tonClientAdapter;");

            VariableDeclarationSyntax variableDeclaration = VariableDeclaration(ParseTypeName("ITonClientAdapter"))
                                                            .AddVariables(VariableDeclarator("_tonClientAdapter"));
            FieldDeclarationSyntax fieldDeclaration = FieldDeclaration(variableDeclaration)
                                                      .AddModifiers(Token(SyntaxKind.PrivateKeyword), Token(SyntaxKind.ReadOnlyKeyword));

            ConstructorDeclarationSyntax constructorDeclaration = ConstructorDeclaration(moduleName)
                                                                  .AddParameterListParameters(
                Parameter(Identifier("tonClientAdapter")).WithType(IdentifierName("ITonClientAdapter")))
                                                                  .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
                                                                  .WithBody(Block(statementSyntax));

            var methods = module
                          .Functions
                          .Select(f => GetMethodDeclaration(module, f, true))
                          .ToArray();

            ClassDeclarationSyntax item = ClassDeclaration(moduleName)
                                          .AddModifiers(Token(SyntaxKind.PublicKeyword))
                                          .AddBaseListTypes(SimpleBaseType(IdentifierName(NamingConventions.ToInterfaceName(moduleName))))
                                          .AddMembers(fieldDeclaration)
                                          .AddMembers(constructorDeclaration)
                                          .AddMembers(methods);

            return(NamespaceDeclaration(IdentifierName(ClientGenerator.NamespaceModules))
                   .AddMembers(item));
        }
 private static string GetParamType(Param param)
 {
     return(NamingConventions.Normalize(param.RefName));
 }