コード例 #1
0
        public void Test()
        {
            GeneratedCodeForLang ret = GenerateCodes();

            Console.WriteLine(ret.TypeScript.ToString());

            return;

            var model = cs_types.Model;

            var type_classes = cs_types.Root.DescendantNodes()
                               .OfType <ClassDeclarationSyntax>();

            foreach (ClassDeclarationSyntax v in type_classes)
            {
                WriteLine(v.Identifier.Text);

                var info = model.GetDeclaredSymbol(v);

                var x = info.GetMembers();

                foreach (var y in x)
                {
                    WriteLine(y.Name);
                }

                break;
            }

            Console.WriteLine();
        }
コード例 #2
0
        void generate_tests(GeneratedCodeForLang ret)
        {
            var test_class = cs_tests.Root.DescendantNodes().OfType <ClassDeclarationSyntax>().Where(c => c.Identifier.Text == "VPNRPCTest").First();

            CcWalker w = new CcWalker(cs_tests, TargetLang.TypeScript);

            //CcWalker w = new CcWalker(cs_tests, TargetLang.CSharp);
            w.Visit(test_class);

            WriteLine(w.ToString());
        }
コード例 #3
0
        public GeneratedCodeForLang GenerateCodes()
        {
            GeneratedCodeForLang ret = new GeneratedCodeForLang();

            generate_types(ret);

            generate_stubs(ret);

            generate_tests(ret);

            return(ret);
        }
コード例 #4
0
        void generate_stubs(GeneratedCodeForLang ret)
        {
            var model = cs_stubs.Model;

            var rpc_class = cs_stubs.Root.DescendantNodes().OfType <ClassDeclarationSyntax>().Where(c => c.Identifier.Text == "VpnServerRpc").First();

            var members = model.GetDeclaredSymbol(rpc_class).GetMembers();

            var methods = members.Where(m => m is IMethodSymbol).Select(m => m as IMethodSymbol).Where(m => m.IsStatic == false)
                          .Where(m => m.IsAsync).Where(m => m.Name != "CallAsync");

            foreach (var method in methods)
            {
                string method_name = method.Name;
                if (method_name.EndsWith("Async") == false)
                {
                    throw new ApplicationException($"{method.Name}: method_name = {method_name}");
                }
                method_name = method_name.Substring(0, method_name.Length - 5);

                INamedTypeSymbol ret_type = (INamedTypeSymbol)method.ReturnType;
                if (ret_type.Name != "Task")
                {
                    throw new ApplicationException($"{method.Name}: ret_type.Name = {ret_type.Name}");
                }

                var ret_type_args = ret_type.TypeArguments;
                if (ret_type_args.Length != 1)
                {
                    throw new ApplicationException($"{method.Name}: type_args.Length = {ret_type_args.Length}");
                }

                var ret_type_name = ret_type_args[0].Name;

                if (method.Parameters.Length >= 2)
                {
                    throw new ApplicationException($"{method.Name}: method.Parameters.Length = {method.Parameters.Length}");
                }

                if (method.DeclaringSyntaxReferences.Length != 1)
                {
                    throw new ApplicationException($"{method.Name}: method.DeclaringSyntaxReferences.Length = {method.DeclaringSyntaxReferences.Length}");
                }

                MethodDeclarationSyntax syntax = (MethodDeclarationSyntax)method.DeclaringSyntaxReferences[0].GetSyntax();
                if (syntax.Body != null)
                {
                    throw new ApplicationException($"{method.Name}: syntax.Body != null");
                }
                if (syntax.ExpressionBody == null)
                {
                    throw new ApplicationException($"{method.Name}: syntax.ExpressionBody == null");
                }

                ArrowExpressionClauseSyntax body   = syntax.ExpressionBody;
                InvocationExpressionSyntax  invoke = body.DescendantNodes().OfType <InvocationExpressionSyntax>().Single();

                if (model.GetSymbolInfo(invoke.Expression).Symbol.Name != "CallAsync")
                {
                    throw new ApplicationException($"{method.Name}: model.GetSymbolInfo(invoke.Expression).Symbol.Name = {model.GetSymbolInfo(invoke.Expression).Symbol.Name}");
                }

                if (invoke.ArgumentList.Arguments.Count != 2)
                {
                    throw new ApplicationException($"{method.Name}: invoke.ArgumentList.Arguments.Count = {invoke.ArgumentList.Arguments.Count}");
                }

                LiteralExpressionSyntax str_syntax = (LiteralExpressionSyntax)invoke.ArgumentList.Arguments[0].Expression;

                string str = str_syntax.Token.Text;

                StringWriter ts = new StringWriter();

                string doc2 = method.GetDocumentStr();
                if (string.IsNullOrEmpty(doc2) == false)
                {
                    ts.WriteLine($"    /** {doc2} */");
                }

                if (method.Parameters.Length == 0)
                {
                    ts.WriteLine($"    public {method_name} = (): Promise<{ret_type_name}> =>");
                    ts.WriteLine("    {");
                    ts.WriteLine($"        return this.CallAsync<{ret_type_name}>({str}, new {ret_type_name}());");
                    ts.WriteLine("    }");
                    ts.WriteLine("    ");
                }
                else
                {
                    ts.WriteLine($"    public {method_name} = (in_param: {ret_type_name}): Promise<{ret_type_name}> =>");
                    ts.WriteLine("    {");
                    ts.WriteLine($"        return this.CallAsync<{ret_type_name}>({str}, in_param);");
                    ts.WriteLine("    }");
                    ts.WriteLine("    ");
                }

                ret.TypeScript.Stubs.AddPart(method.DeclaringSyntaxReferences[0].Span.Start, ts.ToString());
            }
        }
コード例 #5
0
        void generate_types(GeneratedCodeForLang ret)
        {
            var model = cs_types.Model;

            var class_list = cs_types.Root.DescendantNodes().OfType <ClassDeclarationSyntax>();

            foreach (ClassDeclarationSyntax c in class_list)
            {
                StringWriter ts = new StringWriter();

                string doc = model.GetDeclaredSymbol(c).GetDocumentStr();
                if (string.IsNullOrEmpty(doc) == false)
                {
                    ts.WriteLine($"/** {doc} */");
                }

                ts.WriteLine($"export class {c.Identifier.Text}");
                ts.WriteLine("{");

                foreach (var member in model.GetDeclaredSymbol(c).GetMembers())
                {
                    string json_name = "";
                    bool   json_name_has_special_char = false;
                    var    atts = member.GetAttributes();
                    var    y    = atts.Where(x => x.AttributeClass.Name == "JsonPropertyAttribute").FirstOrDefault();
                    if (y != null)
                    {
                        json_name = y.ConstructorArguments.FirstOrDefault().Value.ToString();
                        if (json_name.IndexOf(':') != -1 || json_name.IndexOf('.') != -1)
                        {
                            json_name_has_special_char = true;
                        }
                    }

                    string default_value = "\"\"";

                    switch (member)
                    {
                    case IFieldSymbol field:
                        string      ts_type = "";
                        ITypeSymbol type    = field.Type;
                        switch (type.Kind)
                        {
                        case SymbolKind.NamedType:
                            switch (type.Name)
                            {
                            case "UInt32":
                            case "UInt64":
                                ts_type       = "number";
                                default_value = "0";
                                break;

                            case "String":
                                ts_type = "string";
                                break;

                            case "Boolean":
                                ts_type       = "boolean";
                                default_value = "false";
                                break;

                            case "DateTime":
                                ts_type       = "Date";
                                default_value = "new Date()";
                                break;

                            default:
                                if (type.TypeKind == TypeKind.Enum)
                                {
                                    ts_type       = type.Name;
                                    default_value = "0";
                                    break;
                                }
                                throw new ApplicationException($"{c.Identifier}.{member.Name}: type.Name = {type.Name}");
                            }
                            break;

                        case SymbolKind.ArrayType:
                            ITypeSymbol type2 = ((IArrayTypeSymbol)type).ElementType;

                            default_value = "[]";

                            switch (type2.Kind)
                            {
                            case SymbolKind.NamedType:
                                switch (type2.Name)
                                {
                                case "UInt32":
                                case "UInt64":
                                    ts_type = "number[]";
                                    break;

                                case "String":
                                    ts_type = "string[]";
                                    break;

                                case "Boolean":
                                    ts_type = "boolean[]";
                                    break;

                                case "Byte":
                                    ts_type       = "Uint8Array";
                                    default_value = "new Uint8Array([])";
                                    break;

                                default:
                                    if (type2.ContainingAssembly.Name == csc.AssemblyName)
                                    {
                                        ts_type = type2.Name + "[]";
                                        break;
                                    }
                                    throw new ApplicationException($"{c.Identifier}.{member.Name}: type2.Name = {type2.Name}");
                                }
                                break;

                            default:
                                throw new ApplicationException($"{c.Identifier}.{member.Name}: type2.Kind = {type2.Kind}");
                            }

                            break;

                        default:
                            throw new ApplicationException($"{c.Identifier}.{member.Name}: type.Kind = {type.Kind}");
                        }

                        if (string.IsNullOrEmpty(ts_type) == false)
                        {
                            string field_name = field.Name;

                            if (string.IsNullOrEmpty(json_name) == false)
                            {
                                field_name = json_name;
                            }
                            if (json_name_has_special_char)
                            {
                                field_name = $"[\"{json_name}\"]";
                            }

                            string doc2 = member.GetDocumentStr();
                            if (string.IsNullOrEmpty(doc2) == false)
                            {
                                ts.WriteLine($"    /** {doc2} */");
                            }

                            ts.WriteLine($"    public {field_name}: {ts_type} = {default_value};");

                            ts.WriteLine();
                        }
                        break;

                    case IMethodSymbol method when method.MethodKind == MethodKind.Constructor:
                        break;

                    default:
                        throw new ApplicationException($"{c.Identifier}.{member.Name}: type = {member.GetType()}");
                    }
                }

                if (string.IsNullOrEmpty(doc) == false)
                {
                    ts.WriteLine($"    /** Constructor for the '{c.Identifier.Text}' class: {doc} */");
                }
                ts.WriteLine($"    public constructor(init?: Partial<{c.Identifier.Text}>)");
                ts.WriteLine("    {");
                ts.WriteLine("        Object.assign(this, init);");
                ts.WriteLine("    }");

                ts.WriteLine("}");
                ts.WriteLine();

                ret.TypeScript.Types.AddPart(c.SpanStart, ts.ToString());
            }

            var enum_list = cs_types.Root.DescendantNodes().OfType <EnumDeclarationSyntax>();

            foreach (EnumDeclarationSyntax e in enum_list)
            {
                StringWriter ts = new StringWriter();

                string doc = model.GetDeclaredSymbol(e).GetDocumentStr();
                if (string.IsNullOrEmpty(doc) == false)
                {
                    ts.WriteLine($"/** {doc} */");
                }

                ts.WriteLine($"export enum {e.Identifier.Text}");
                ts.WriteLine("{");

                foreach (var member in model.GetDeclaredSymbol(e).GetMembers())
                {
                    switch (member)
                    {
                    case IFieldSymbol field:
                        if (field.IsConst && field.IsDefinition)
                        {
                            string doc2 = member.GetDocumentStr();
                            if (string.IsNullOrEmpty(doc2) == false)
                            {
                                ts.WriteLine($"    /** {doc2} */");
                            }

                            ts.WriteLine($"    {field.Name} = {field.ConstantValue},");

                            ts.WriteLine();
                        }
                        break;
                    }
                }

                ts.WriteLine("}");
                ts.WriteLine();

                ret.TypeScript.Types.AddPart(e.SpanStart, ts.ToString());
            }
        }
コード例 #6
0
        void generate_types(GeneratedCodeForLang ret)
        {
            var model = cs_types.Model;

            var class_list = cs_types.Root.DescendantNodes().OfType <ClassDeclarationSyntax>();

            foreach (ClassDeclarationSyntax c in class_list)
            {
                StringWriter ts = new StringWriter();

                ts.WriteLine($"export class {c.Identifier.Text}");
                ts.WriteLine("{");

                foreach (var member in model.GetDeclaredSymbol(c).GetMembers())
                {
                    switch (member)
                    {
                    case IFieldSymbol field:
                        string      ts_type = "";
                        ITypeSymbol type    = field.Type;
                        switch (type.Kind)
                        {
                        case SymbolKind.NamedType:
                            switch (type.Name)
                            {
                            case "UInt32":
                            case "UInt64":
                                ts_type = "number";
                                break;

                            case "String":
                                ts_type = "string";
                                break;

                            case "Boolean":
                                ts_type = "boolean";
                                break;

                            case "DateTime":
                                ts_type = "Date";
                                break;

                            default:
                                if (type.TypeKind == TypeKind.Enum)
                                {
                                    ts_type = type.Name;
                                    break;
                                }
                                throw new ApplicationException($"{c.Identifier}.{member.Name}: type.Name = {type.Name}");
                            }
                            break;

                        case SymbolKind.ArrayType:
                            ITypeSymbol type2 = ((IArrayTypeSymbol)type).ElementType;

                            switch (type2.Kind)
                            {
                            case SymbolKind.NamedType:
                                switch (type2.Name)
                                {
                                case "UInt32":
                                case "UInt64":
                                    ts_type = "number[]";
                                    break;

                                case "String":
                                    ts_type = "string[]";
                                    break;

                                case "Boolean":
                                    ts_type = "boolean[]";
                                    break;

                                case "Byte":
                                    ts_type = "Uint8Array";
                                    break;

                                default:
                                    if (type2.ContainingAssembly.Name == csc.AssemblyName)
                                    {
                                        ts_type = type2.Name + "[]";
                                        break;
                                    }
                                    throw new ApplicationException($"{c.Identifier}.{member.Name}: type2.Name = {type2.Name}");
                                }
                                break;

                            default:
                                throw new ApplicationException($"{c.Identifier}.{member.Name}: type2.Kind = {type2.Kind}");
                            }

                            break;

                        default:
                            throw new ApplicationException($"{c.Identifier}.{member.Name}: type.Kind = {type.Kind}");
                        }

                        if (string.IsNullOrEmpty(ts_type) == false)
                        {
                            ts.WriteLine($"    {field.Name}?: {ts_type};");
                        }
                        break;

                    case IMethodSymbol method when method.MethodKind == MethodKind.Constructor:
                        break;

                    default:
                        throw new ApplicationException($"{c.Identifier}.{member.Name}: type = {member.GetType()}");
                    }
                }

                ts.WriteLine("}");
                ts.WriteLine();

                ret.TypeScript.Types.AddPart(c.SpanStart, ts.ToString());
            }

            var enum_list = cs_types.Root.DescendantNodes().OfType <EnumDeclarationSyntax>();

            foreach (EnumDeclarationSyntax e in enum_list)
            {
                StringWriter ts = new StringWriter();

                ts.WriteLine($"export enum {e.Identifier.Text}");
                ts.WriteLine("{");

                foreach (var member in model.GetDeclaredSymbol(e).GetMembers())
                {
                    switch (member)
                    {
                    case IFieldSymbol field:
                        if (field.IsConst && field.IsDefinition)
                        {
                            ts.WriteLine($"    {field.Name} = {field.ConstantValue},");
                        }
                        break;
                    }
                }

                ts.WriteLine("}");
                ts.WriteLine();

                ret.TypeScript.Types.AddPart(e.SpanStart, ts.ToString());
            }
        }