private void EmitInterface(TransportModelInterface model, ICodeStream output)
        {
            var outputFile = (CodeFileCSharp)output.CreateCodeFile($"{CsEmitterHelper.GetCSharpModelShortName(model, ModelType.Transport)}.cs");

            var unit = CompilationUnit();

            unit = unit.AddUsings(
                UsingDirective(ParseName(nameof(System))));

            var entityInterface = InterfaceDeclaration(CsEmitterHelper.GetCSharpModelShortName(model, ModelType.Transport));

            entityInterface = entityInterface.AddModifiers(Token(SyntaxKind.PublicKeyword));

            if (model.GenericParameters.Count > 0)
            {
                entityInterface = entityInterface.WithTypeParameterList(TypeParameterList(SeparatedList <TypeParameterSyntax>(model.GenericParameters.Select(p => TypeParameter(p.Key)))));

                entityInterface = entityInterface.WithConstraintClauses(List <TypeParameterConstraintClauseSyntax>(
                                                                            model.GenericParameters.Select(p =>
                                                                                                           TypeParameterConstraintClause(
                                                                                                               IdentifierName(p.Key),
                                                                                                               SeparatedList <TypeParameterConstraintSyntax>(new[] { TypeConstraint(ParseTypeName(CsEmitterHelper.GetModelGenericParameterConstraintTypeName(p.Value, ModelType.Transport))) })))));
            }

            List <string> baseTypes = new List <string>();

            foreach (var interfaceModel in model.Interfaces)
            {
                baseTypes.Add(CsEmitterHelper.GetCSharpModelFullyQualifiedName(interfaceModel, this.settings, ModelType.Transport));
            }

            if (baseTypes.Count > 0)
            {
                entityInterface = entityInterface.WithBaseList(BaseList(SeparatedList <BaseTypeSyntax>(baseTypes.Select(t => SimpleBaseType(ParseTypeName(t))))));
            }

            entityInterface = entityInterface.WithMembers(List <MemberDeclarationSyntax>(model.Members.Select(m =>
                                                                                                              PropertyDeclaration(ParseTypeName(CsEmitterHelper.GetPropertyTypeName(m.Value, this.settings, ModelType.Transport)), NameHelper.GetSafeVariableName(m.Value.Name))
                                                                                                              .WithAccessorList(
                                                                                                                  SyntaxFactory.AccessorList(
                                                                                                                      SyntaxFactory.List <AccessorDeclarationSyntax>(new AccessorDeclarationSyntax[]
            {
                SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
                SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
            })))
                                                                                                              )));

            var nsContainer = NamespaceDeclaration(ParseName(this.settings.CsTransportModelNamespace));

            nsContainer           = nsContainer.AddMembers(entityInterface);
            unit                  = unit.AddMembers(nsContainer);
            outputFile.SyntaxTree = unit.SyntaxTree;
        }
        public void Emit(Parameters parameters, ICodeStream output)
        {
            var outputFile = (CodeFileCSharp)output.CreateCodeFile($"{ConverterClassName}.cs");

            var unit = CompilationUnit();

            unit = unit.AddUsings(
                UsingDirective(ParseName(nameof(System))));

            var converterClass = ClassDeclaration(ConverterClassName);

            converterClass = converterClass.AddModifiers(Token(SyntaxKind.PublicKeyword));

            var baseNodeEntity    = parameters.TransportModel.TransportModelEntities.First(e => e.Key == settings.AstNodeBaseTypeQualified.Split('.').Last());
            var baseNodeInterface = parameters.TransportModel.TransportModelInterfaces.First(e => e.Key == settings.AstNodeBaseTypeQualified.Split('.').Last());
            var syntaxKindEnum    = parameters.TransportModel.TransportModelEnums.First(e => e.Key == "SyntaxKind");

            var conversionMethod = MethodDeclaration(ParseTypeName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(baseNodeInterface.Value, this.settings, ModelType.Ast)), this.convertFromNodeMethodName)
                                   .AddModifiers(Token(SyntaxKind.PublicKeyword))
                                   .WithParameterList(ParameterList(SeparatedList <ParameterSyntax>(new[] { Parameter(Identifier(this.nodeParameterName)).WithType(ParseTypeName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(baseNodeInterface.Value, this.settings, ModelType.Transport))) })))
                                   .WithBody(Block());

            conversionMethod = conversionMethod.AddBodyStatements(
                IfStatement(
                    BinaryExpression(SyntaxKind.EqualsExpression, IdentifierName(this.nodeParameterName), IdentifierName("null")),
                    ReturnStatement(IdentifierName("null")))
                );

            foreach (var entityModel in parameters.TransportModel.TransportModelEntities.Where(e => e.Value.TsDiscriminant is TransportModelEntityTsDiscriminantSyntaxKind))
            {
                conversionMethod = conversionMethod.AddBodyStatements(this.EmitForEntity(entityModel.Value, syntaxKindEnum.Value));
            }

            conversionMethod = conversionMethod.AddBodyStatements(
                ExpressionStatement(
                    ThrowExpression(
                        ObjectCreationExpression(ParseTypeName(typeof(InvalidOperationException).FullName),
                                                 ArgumentList(SeparatedList <ArgumentSyntax>(new[] { Argument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal("Unable to convert node."))) })),
                                                 null
                                                 ))));

            converterClass = converterClass.AddMembers(conversionMethod);

            converterClass = converterClass.AddMembers(this.EmitCollectionConversionMethod(baseNodeInterface.Value));

            var nsContainer = NamespaceDeclaration(ParseName(this.settings.CsAstModelNamespace));

            nsContainer           = nsContainer.AddMembers(converterClass);
            unit                  = unit.AddMembers(nsContainer);
            outputFile.SyntaxTree = unit.SyntaxTree;
        }
コード例 #3
0
        public static string CreateModelTypeName(ITransportModelTypeReferenceTransportModelItem <TransportModelItem> reference, Settings settings, ModelType modelType, bool useSimpleCollections = false)
        {
            var typeName = CsEmitterHelper.GetCSharpModelFullyQualifiedName(reference.TransportModelItem, settings, modelType);

            if (reference.GenericArguments.Count > 0)
            {
                typeName += "<" + string.Join(",", reference.GenericArguments.Select(a => GetCSharpModelReferenceName(a, settings, modelType))) + ">";
            }

            if (reference.IsCollection)
            {
                string collectionType = settings.CsTransportModelCollectionType;

                if (!useSimpleCollections && modelType == ModelType.Ast && !(reference.TransportModelItem is TransportModelEnum))
                {
                    collectionType = settings.CsAstModelNodeCollectionType;
                }

                typeName = $"{collectionType}<{typeName}>";
            }

            return(typeName);
        }
        private void EmitEntity(TransportModelEntity entityModel, ICodeStream output)
        {
            var outputFile = (CodeFileCSharp)output.CreateCodeFile($"{CsEmitterHelper.GetCSharpModelShortName(entityModel, ModelType.Transport)}.cs");

            var unit = CompilationUnit();

            unit = unit.AddUsings(
                UsingDirective(ParseName(nameof(System))));

            var entityClass = ClassDeclaration(CsEmitterHelper.GetCSharpModelShortName(entityModel, ModelType.Transport));

            entityClass = entityClass.AddModifiers(Token(SyntaxKind.PublicKeyword));

            if (entityModel.TsDiscriminant is TransportModelEntityTsDiscriminantSyntaxKind kindDiscriminant)
            {
                entityClass = entityClass.AddMembers(
                    ConstructorDeclaration(CsEmitterHelper.GetCSharpModelShortName(entityModel, ModelType.Transport))
                    .AddModifiers(Token(SyntaxKind.PublicKeyword))
                    .WithBody(Block().AddStatements(
                                  ExpressionStatement(
                                      AssignmentExpression(
                                          SyntaxKind.SimpleAssignmentExpression,
                                          MemberAccessExpression(
                                              SyntaxKind.SimpleMemberAccessExpression,
                                              ThisExpression(),
                                              IdentifierName("kind")),
                                          MemberAccessExpression(
                                              SyntaxKind.SimpleMemberAccessExpression,
                                              IdentifierName($"{this.settings.CsTransportModelNamespace}.SyntaxKind"),
                                              IdentifierName(kindDiscriminant.SyntaxKindValueName)))))));
            }

            if (entityModel.GenericParameters.Count > 0)
            {
                entityClass = entityClass.WithTypeParameterList(TypeParameterList(SeparatedList <TypeParameterSyntax>(entityModel.GenericParameters.Select(p => TypeParameter(p.Key)))));

                entityClass = entityClass.WithConstraintClauses(List <TypeParameterConstraintClauseSyntax>(
                                                                    entityModel.GenericParameters.Select(p =>
                                                                                                         TypeParameterConstraintClause(
                                                                                                             IdentifierName(p.Key),
                                                                                                             SeparatedList <TypeParameterConstraintSyntax>(new[] { TypeConstraint(ParseTypeName(CsEmitterHelper.GetModelGenericParameterConstraintTypeName(p.Value, ModelType.Transport))) })))));
            }

            List <string> baseTypes = new List <string>();

            if (entityModel.BaseEntity != null)
            {
                baseTypes.Add(CsEmitterHelper.GetCSharpModelReferenceName(entityModel.BaseEntity, this.settings, ModelType.Transport));
            }

            foreach (var interfaceModel in entityModel.Interfaces)
            {
                baseTypes.Add(CsEmitterHelper.GetCSharpModelFullyQualifiedName(interfaceModel, this.settings, ModelType.Transport));
            }

            if (baseTypes.Count > 0)
            {
                entityClass = entityClass.WithBaseList(BaseList(SeparatedList <BaseTypeSyntax>(baseTypes.Select(t => SimpleBaseType(ParseTypeName(t))))));
            }

            entityClass = entityClass.AddMembers(entityModel.Members.Select(m =>
                                                                            PropertyDeclaration(ParseTypeName(CsEmitterHelper.GetPropertyTypeName(m.Value, this.settings, ModelType.Transport)), NameHelper.GetSafeVariableName(m.Value.Name))
                                                                            .WithAccessorList(
                                                                                SyntaxFactory.AccessorList(
                                                                                    SyntaxFactory.List <AccessorDeclarationSyntax>(new AccessorDeclarationSyntax[]
            {
                SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
                SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
            })))
                                                                            .AddModifiers(Token(SyntaxKind.PublicKeyword))
                                                                            ).ToArray <MemberDeclarationSyntax>());

            var nsContainer = NamespaceDeclaration(ParseName(this.settings.CsTransportModelNamespace));

            nsContainer           = nsContainer.AddMembers(entityClass);
            unit                  = unit.AddMembers(nsContainer);
            outputFile.SyntaxTree = unit.SyntaxTree;
        }
コード例 #5
0
        private MethodDeclarationSyntax GenerateConversionMethod(TransportModelEntity entityModel)
        {
            var members = CsEmitterHelper.GetMembers(entityModel, null, true);

            List <ExpressionSyntax> initializers = new List <ExpressionSyntax>();

            foreach (var member in members)
            {
                var propertyName = NameHelper.GetSafeVariableName(member.Key);

                if (member.Value.Type is ITransportModelTypeReferenceTransportModelItem <TransportModelItem> itemReference &&
                    !(itemReference.TransportModelItem is TransportModelEnum))
                {
                    if (itemReference.IsCollection)
                    {
                        initializers.Add(
                            AssignmentExpression(
                                SyntaxKind.SimpleAssignmentExpression,
                                IdentifierName(propertyName),
                                InvocationExpression(
                                    MemberAccessExpression(
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        ThisExpression(),
                                        GenericName(
                                            Identifier("GetTransportModelNodes"),
                                            TypeArgumentList(
                                                SeparatedList <TypeSyntax>(
                                                    new[]
                        {
                            ParseTypeName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(itemReference.TransportModelItem, this.settings, ModelType.Transport))
                        })))))
                                .WithArgumentList(ArgumentList(SeparatedList <ArgumentSyntax>(new[] { Argument(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(propertyName))) })))
                                ));
                    }
                    else
                    {
                        initializers.Add(
                            AssignmentExpression(
                                SyntaxKind.SimpleAssignmentExpression,
                                IdentifierName(propertyName),
                                ConditionalExpression(
                                    BinaryExpression(SyntaxKind.NotEqualsExpression, MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(propertyName)), IdentifierName("null")),
                                    CastExpression(ParseTypeName(CsEmitterHelper.GetPropertyTypeName(member.Value, this.settings, ModelType.Transport)),
                                                   InvocationExpression(
                                                       MemberAccessExpression(
                                                           SyntaxKind.SimpleMemberAccessExpression,
                                                           MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(propertyName)),
                                                           IdentifierName("GetTransportModelNode")))
                                                   .WithArgumentList(ArgumentList())),
                                    IdentifierName("null")
                                    )));
                    }
                }
                else
                {
                    initializers.Add(
                        AssignmentExpression(
                            SyntaxKind.SimpleAssignmentExpression,
                            IdentifierName(propertyName),
                            MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(propertyName))));
                }
            }

            return(MethodDeclaration(ParseTypeName(typeof(object).FullName), "GetTransportModelNode")
                   .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.OverrideKeyword)))
                   .WithParameterList(ParameterList())
                   .WithBody(
                       Block(
                           List <StatementSyntax>(
                               new[] {
                ReturnStatement(
                    ObjectCreationExpression(ParseTypeName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(entityModel, this.settings, ModelType.Transport)))
                    .WithArgumentList(ArgumentList())
                    .WithInitializer(
                        InitializerExpression(SyntaxKind.ObjectInitializerExpression, SeparatedList <ExpressionSyntax>(initializers))))
            }))));
        }
コード例 #6
0
        private void EmitEntity(TransportModelEntity entityModel, ICodeStream output)
        {
            var outputFile = (CodeFileCSharp)output.CreateCodeFile($"{CsEmitterHelper.GetCSharpModelShortName(entityModel, ModelType.Ast)}.cs");

            var unit = CompilationUnit();

            unit = unit.AddUsings(
                UsingDirective(ParseName(nameof(System))));

            var entityClass = ClassDeclaration(CsEmitterHelper.GetCSharpModelShortName(entityModel, ModelType.Ast));

            entityClass = entityClass.AddModifiers(Token(SyntaxKind.PublicKeyword));

            if (entityModel.TsDiscriminant == null || !(entityModel.TsDiscriminant is TransportModelEntityTsDiscriminantSyntaxKind))
            {
                entityClass = entityClass.AddModifiers(Token(SyntaxKind.AbstractKeyword));
            }

            List <StatementSyntax> propertyInitializers     = null;
            List <ArgumentSyntax>  baseConstructorArguments = null;

            var constructorDeclaration =
                ConstructorDeclaration(CsEmitterHelper.GetCSharpModelShortName(entityModel, ModelType.Ast))
                .AddModifiers(Token(SyntaxKind.PublicKeyword))
                .WithParameterList(ParameterList(SeparatedList <ParameterSyntax>(this.GetConstructorParameters(entityModel, out propertyInitializers, out baseConstructorArguments))));

            if (baseConstructorArguments != null && baseConstructorArguments.Count > 0)
            {
                constructorDeclaration = constructorDeclaration.WithInitializer(
                    ConstructorInitializer(SyntaxKind.BaseConstructorInitializer)
                    .AddArgumentListArguments(baseConstructorArguments.ToArray()));
            }

            var constructorBody = Block();

            constructorBody = this.PopulateRequiredConstructorBodyInitializers(constructorBody, entityModel);

            if (propertyInitializers != null && propertyInitializers.Count > 0)
            {
                constructorBody = constructorBody.AddStatements(propertyInitializers.ToArray());
            }

            constructorDeclaration = constructorDeclaration.WithBody(constructorBody);
            entityClass            = entityClass.AddMembers(constructorDeclaration);

            if (constructorDeclaration.ParameterList.Parameters.Count > 0)
            {
                var parameterlessConstructorDeclaration =
                    ConstructorDeclaration(CsEmitterHelper.GetCSharpModelShortName(entityModel, ModelType.Ast))
                    .AddModifiers(Token(SyntaxKind.PublicKeyword));
                var parameterlessConstructorBody = Block();
                parameterlessConstructorBody        = this.PopulateRequiredConstructorBodyInitializers(parameterlessConstructorBody, entityModel);
                parameterlessConstructorDeclaration = parameterlessConstructorDeclaration.WithBody(parameterlessConstructorBody);
                entityClass = entityClass.AddMembers(parameterlessConstructorDeclaration);
            }

            if (entityModel.GenericParameters.Count > 0)
            {
                entityClass = entityClass.WithTypeParameterList(TypeParameterList(SeparatedList <TypeParameterSyntax>(entityModel.GenericParameters.Select(p => TypeParameter(p.Key)))));

                entityClass = entityClass.WithConstraintClauses(List <TypeParameterConstraintClauseSyntax>(
                                                                    entityModel.GenericParameters.Select(p =>
                                                                                                         TypeParameterConstraintClause(
                                                                                                             IdentifierName(p.Key),
                                                                                                             SeparatedList <TypeParameterConstraintSyntax>(new[] { TypeConstraint(ParseTypeName(CsEmitterHelper.GetModelGenericParameterConstraintTypeName(p.Value, ModelType.Ast))) })))));
            }

            List <string> baseTypes = new List <string>();

            if (entityModel.Name == this.settings.AstNodeBaseTypeQualified.Split('.').Last())
            {
                baseTypes.Add($"{settings.CsAstModelNamespace}.{baseNodeType}");
            }

            if (entityModel.BaseEntity != null)
            {
                baseTypes.Add(CsEmitterHelper.GetCSharpModelReferenceName(entityModel.BaseEntity, this.settings, ModelType.Ast));
            }

            foreach (var interfaceModel in entityModel.Interfaces)
            {
                baseTypes.Add(CsEmitterHelper.GetCSharpModelFullyQualifiedName(interfaceModel, this.settings, ModelType.Ast));
            }

            if (baseTypes.Count > 0)
            {
                entityClass = entityClass.WithBaseList(BaseList(SeparatedList <BaseTypeSyntax>(baseTypes.Select(t => SimpleBaseType(ParseTypeName(t))))));
            }

            entityClass = entityClass.AddMembers(
                entityModel
                .Members
                .Where(m => !CsEmitterHelper.IsNodeCollection(m.Value.Type))
                .Select(m =>
                        FieldDeclaration(VariableDeclaration(ParseTypeName(CsEmitterHelper.GetAstModelPropertyTypeName(m.Value, this.settings)), SeparatedList <VariableDeclaratorSyntax>(new[] { VariableDeclarator(this.GetFieldName(m.Key)) })))
                        ).ToArray <MemberDeclarationSyntax>());

            entityClass = entityClass.AddMembers(entityModel.Members.Select(m => this.CreatePropertyDeclaration(m.Value)).ToArray <MemberDeclarationSyntax>());

            if (entityModel.TsDiscriminant is TransportModelEntityTsDiscriminantSyntaxKind)
            {
                entityClass = entityClass.AddMembers(this.GenerateConversionMethod(entityModel));
            }

            var nsContainer = NamespaceDeclaration(ParseName(this.settings.CsAstModelNamespace));

            nsContainer           = nsContainer.AddMembers(entityClass);
            unit                  = unit.AddMembers(nsContainer);
            outputFile.SyntaxTree = unit.SyntaxTree;
        }
        private void EmitTypeMarkerFunction(Parameters parameters, CodeFileTs output)
        {
            var name = "TypeMarker";
            var nodeParameterName    = "node";
            var typescriptModuleName = "typescript";
            var typescriptAliasName  = "T";
            var typePropertyName     = "$type";

            var importStatement = new StImportDeclaration()
                                  .WithModuleSpecifier(new StStringLiteral().WithText(typescriptModuleName))
                                  .WithImportClause(c =>
                                                    c
                                                    .WithNamedBindings(new StNamespaceImport().WithName(new StIdentifier().WithEscapedText(typescriptAliasName)))
                                                    );

            var classDefinition = new StClassDeclaration()
                                  .WithModifier(new StExportKeywordToken())
                                  .WithName(new StIdentifier().WithEscapedText(name));

            var markerFunction = new StMethodDeclaration()
                                 .WithName(new StIdentifier().WithEscapedText("Mark"))
                                 .WithModifier(new StPublicKeywordToken())
                                 .WithType(new StKeywordTypeNodeBooleanKeyword())
                                 .WithBody(b => b)
                                 .WithParameter(p =>
                                                p
                                                .WithName(new StIdentifier().WithEscapedText(nodeParameterName))
                                                .WithType(new StKeywordTypeNodeAnyKeyword()));

            foreach (var entity in parameters.TransportModel.TransportModelEntities.Where(e => e.Value.TsDiscriminant is TransportModelEntityTsDiscriminantSyntaxKind))
            {
                markerFunction.body.WithStatement(
                    new StIfStatement()
                    .WithExpression(
                        new StBinaryExpression()
                        .WithLeft(new StPropertyAccessExpression()
                                  .WithExpression(new StIdentifier().WithEscapedText(nodeParameterName))
                                  .WithName(new StIdentifier().WithEscapedText("kind")))
                        .WithOperatorToken(new StEqualsEqualsTokenToken())
                        .WithRight(new StPropertyAccessExpression()
                                   .WithExpression(new StPropertyAccessExpression().WithExpression(new StIdentifier().WithEscapedText(typescriptAliasName)).WithName(new StIdentifier().WithEscapedText("SyntaxKind")))
                                   .WithName(new StIdentifier().WithEscapedText(((TransportModelEntityTsDiscriminantSyntaxKind)entity.Value.TsDiscriminant).SyntaxKindValueName))))
                    .WithThenStatement(new StBlock()
                                       .WithStatement(
                                           new StExpressionStatement()
                                           .WithExpression(
                                               new StBinaryExpression()
                                               .WithLeft(
                                                   new StPropertyAccessExpression()
                                                   .WithExpression(new StIdentifier().WithEscapedText(nodeParameterName))
                                                   .WithName(new StIdentifier().WithEscapedText(typePropertyName)))
                                               .WithOperatorToken(new StEqualsTokenToken())
                                               .WithRight(new StStringLiteral()
                                                          .WithText($"{CsEmitterHelper.GetCSharpModelFullyQualifiedName(entity.Value, this.settings, ModelType.Transport)}, {this.settings.CsTransportModelAssemblyName}"))))
                                       .WithStatement(
                                           new StReturnStatement()
                                           .WithExpression(new StBooleanLiteralTrueKeyword()))));
            }

            markerFunction.body
            .WithStatement(new StReturnStatement()
                           .WithExpression(new StBooleanLiteralFalseKeyword()));

            classDefinition.members.Add(markerFunction);

            output.Model = new StRoot()
                           .WithStatement(importStatement)
                           .WithStatement(classDefinition);
        }
        private MethodDeclarationSyntax EmitCollectionConversionMethod(TransportModelInterface baseNodeInterface)
        {
            var resultVarName = "result";

            var astNodeCollection = $"{this.settings.CsTransportModelCollectionType}<T>";

            var ienumerableTypeName = typeof(IEnumerable <>).FullName.Substring(0, typeof(IEnumerable <>).FullName.IndexOf('`'));
            var baseNodeIEnumerable = $"{ienumerableTypeName}<{CsEmitterHelper.GetCSharpModelFullyQualifiedName(baseNodeInterface, this.settings, ModelType.Transport)}>";

            var conversionMethod = MethodDeclaration(ParseTypeName(astNodeCollection), this.convertFromNodeCollectionMethodName)
                                   .AddModifiers(Token(SyntaxKind.PublicKeyword))
                                   .WithParameterList(ParameterList(SeparatedList <ParameterSyntax>(new[] { Parameter(Identifier(this.nodesParameterName)).WithType(ParseTypeName(baseNodeIEnumerable)) })))
                                   .WithTypeParameterList(TypeParameterList(SeparatedList <TypeParameterSyntax>(new[] { TypeParameter("T") })))
                                   .WithConstraintClauses(List <TypeParameterConstraintClauseSyntax>(new[]
            {
                TypeParameterConstraintClause(
                    IdentifierName("T"),
                    SeparatedList <TypeParameterConstraintSyntax>(new [] { TypeConstraint(ParseTypeName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(baseNodeInterface, this.settings, ModelType.Ast))) }))
            }))
                                   .WithBody(Block());

            conversionMethod = conversionMethod.AddBodyStatements(
                IfStatement(
                    BinaryExpression(SyntaxKind.EqualsExpression, IdentifierName(this.nodesParameterName), IdentifierName("null")),
                    ReturnStatement(IdentifierName("null")))
                );

            conversionMethod = conversionMethod.AddBodyStatements(
                LocalDeclarationStatement(
                    VariableDeclaration(
                        ParseTypeName(astNodeCollection),
                        SeparatedList <VariableDeclaratorSyntax>(
                            new[]
            {
                VariableDeclarator(resultVarName)
                .WithInitializer(
                    EqualsValueClause(ObjectCreationExpression(ParseTypeName(astNodeCollection)).WithArgumentList(ArgumentList())))
            })
                        ))
                );

            var iteratorVarName = "node";

            conversionMethod = conversionMethod.AddBodyStatements(
                ForEachStatement(
                    ParseTypeName("var"),
                    iteratorVarName,
                    IdentifierName(this.nodesParameterName),
                    Block().AddStatements(
                        ExpressionStatement(
                            InvocationExpression(
                                MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(resultVarName), IdentifierName("Add")),
                                ArgumentList(SeparatedList <ArgumentSyntax>(
                                                 new []
            {
                Argument(
                    CastExpression(
                        ParseTypeName("T"),
                        InvocationExpression(
                            MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(this.convertFromNodeMethodName)),
                            ArgumentList(SeparatedList <ArgumentSyntax>(new [] { Argument(IdentifierName(iteratorVarName)) }))
                            )))
            })))
                            )
                        )));

            conversionMethod = conversionMethod.AddBodyStatements(ReturnStatement(IdentifierName(resultVarName)));

            return(conversionMethod);
        }
        public StatementSyntax EmitForEntity(TransportModelEntity entity, TransportModelEnum syntaxKindEnum)
        {
            var discriminant = entity.TsDiscriminant as TransportModelEntityTsDiscriminantSyntaxKind;

            var recognizedNodeVarName = "concreteNode";

            var block = Block();
            List <ArgumentSyntax> constructorArguments = new List <ArgumentSyntax>();

            block = block.AddStatements(
                LocalDeclarationStatement(
                    VariableDeclaration(
                        ParseTypeName("var"),
                        SeparatedList <VariableDeclaratorSyntax>(new[]
            {
                VariableDeclarator(recognizedNodeVarName)
                .WithInitializer(EqualsValueClause(CastExpression(ParseTypeName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(entity, this.settings, ModelType.Transport)), IdentifierName(this.nodeParameterName))))
            })))
                );

            foreach (var member in CsEmitterHelper.GetMembers(entity))
            {
                if (member.Key != "kind")
                {
                    if (CsEmitterHelper.IsNode(member.Value.Type))
                    {
                        if (member.Value.Type.IsCollection)
                        {
                            constructorArguments.Add(
                                Argument(
                                    InvocationExpression(
                                        MemberAccessExpression(
                                            SyntaxKind.SimpleMemberAccessExpression,
                                            ThisExpression(),
                                            GenericName(
                                                Identifier(this.convertFromNodeCollectionMethodName),
                                                TypeArgumentList(SeparatedList <TypeSyntax>(new[]
                            {
                                ParseTypeName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(((ITransportModelTypeReferenceTransportModelItem <TransportModelItem>)member.Value.Type).TransportModelItem, this.settings, ModelType.Ast))
                            })))),
                                        ArgumentList(SeparatedList <ArgumentSyntax>(new[]
                            {
                                Argument(
                                    MemberAccessExpression(
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        IdentifierName(recognizedNodeVarName),
                                        IdentifierName(NameHelper.GetSafeVariableName(member.Key))))
                            })))
                                    ));
                        }
                        else
                        {
                            constructorArguments.Add(
                                Argument(
                                    CastExpression(
                                        ParseTypeName(CsEmitterHelper.GetAstModelPropertyTypeName(member.Value, this.settings, true)),
                                        InvocationExpression(
                                            MemberAccessExpression(
                                                SyntaxKind.SimpleMemberAccessExpression,
                                                ThisExpression(),
                                                IdentifierName(this.convertFromNodeMethodName)),
                                            ArgumentList(SeparatedList <ArgumentSyntax>(new[]
                            {
                                Argument(
                                    MemberAccessExpression(
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        IdentifierName(recognizedNodeVarName),
                                        IdentifierName(NameHelper.GetSafeVariableName(member.Key))))
                            })))
                                        )
                                    ));
                        }
                    }
                    else
                    {
                        constructorArguments.Add(
                            Argument(
                                CastExpression(
                                    ParseTypeName(CsEmitterHelper.GetAstModelPropertyTypeName(member.Value, this.settings, true)),
                                    MemberAccessExpression(
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        IdentifierName(recognizedNodeVarName),
                                        IdentifierName(NameHelper.GetSafeVariableName(member.Key))))));
                    }
                }
            }

            block = block.AddStatements(
                LocalDeclarationStatement(
                    VariableDeclaration(
                        ParseTypeName("var"),
                        SeparatedList <VariableDeclaratorSyntax>(new[]
            {
                VariableDeclarator("result")
                .WithInitializer(
                    EqualsValueClause(
                        ObjectCreationExpression(ParseTypeName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(entity, this.settings, ModelType.Ast)))
                        .WithArgumentList(ArgumentList(SeparatedList <ArgumentSyntax>(constructorArguments)))))
            }))
                    ));

            block = block.AddStatements(ReturnStatement(IdentifierName("result")));

            var result = IfStatement(
                BinaryExpression(
                    SyntaxKind.EqualsExpression,
                    MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(this.nodeParameterName), IdentifierName("kind")),
                    MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        IdentifierName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(syntaxKindEnum, this.settings, ModelType.Transport)),
                        IdentifierName(discriminant.SyntaxKindValueName))),
                block);

            return(result);
        }