public static SyntaxNode CreateGreenNode(SyntaxGenerator generator, Node node, Options options) { List <SyntaxNode> classContents = new List <SyntaxNode>(); foreach (Member type in node.Members) { classContents.Add(CreateMember(generator, type)); } classContents.Add(CreateConstructor(generator, node, options)); classContents.Add(CreateGetChild(generator, node, options)); if (!node.Abstract) { classContents.Add(CreateCreateRed(generator, node, options)); } classContents.Add(CreateRepaceChild(generator, node, options)); return(generator.ClassDeclaration( SharedGeneratorion.GreenNodeName(node.Name), modifiers: DeclarationModifiers.None.WithIsAbstract(node.Abstract), accessibility: Accessibility.Internal, baseType: SyntaxFactory.ParseTypeName(SharedGeneratorion.GreenNodeName(node.BaseClass)), members: classContents )); }
private static SyntaxNode CreateMethod(SyntaxGenerator generator, Node node, Options options, List <ParameterGenerationInfo> param) { return(generator.MethodDeclaration(node.Name == "Type" ? "TypeNode" : node.Name, param.SelectMany(x => x.Parameters), null, SyntaxFactory.ParseTypeName(SharedGeneratorion.RedNodeName(node.Name)), Accessibility.Public, DeclarationModifiers.Static, param.SelectMany(x => x.Code) .Concat(new[] { generator.LocalDeclarationStatement("__green", generator.ObjectCreationExpression( SyntaxFactory.ParseTypeName(SharedGeneratorion.GreenNodeName(node.Name)), param.Select(x => generator.IdentifierName(x.FinalIdentifier)))), generator.LocalDeclarationStatement("__red", generator.CastExpression( SyntaxFactory.ParseTypeName(SharedGeneratorion.RedNodeName(node.Name)), generator.InvocationExpression( generator.MemberAccessExpression(generator.IdentifierName("__green"), options.CreateRed), generator.LiteralExpression(null), generator.LiteralExpression(0)))), generator.ReturnStatement(generator.IdentifierName("__red")) }) )); }
private static SyntaxNode CreateCreateRed(SyntaxGenerator generator, Node node, Options options) { return(generator.MethodDeclaration( options.CreateRed, new[] { generator.ParameterDeclaration( options.Parent, options.RedBase()), generator.ParameterDeclaration( options.IndexInParent, generator.TypeExpression(SpecialType.System_Int32)) }, null, options.RedBase(), Accessibility.Internal, DeclarationModifiers.Override, new[] { generator.ReturnStatement(generator.ObjectCreationExpression( SyntaxFactory.ParseTypeName(SharedGeneratorion.RedNodeName(node.Name)), generator.IdentifierName(options.Parent), generator.ThisExpression(), generator.IdentifierName(options.IndexInParent) )) } )); }
private static SyntaxNode CreateRepaceChild(SyntaxGenerator generator, Node node, Options options) { List <SyntaxNode> cases = new List <SyntaxNode>(); cases.AddRange(node.AllChildren() .Select((c, i) => generator.SwitchSection( generator.LiteralExpression(i), new[] { generator.ReturnStatement( generator.ObjectCreationExpression( SyntaxFactory.ParseTypeName(SharedGeneratorion.GreenNodeName(node.Name)), node.AllProperties() .Select(x => generator.Argument(generator.IdentifierName(x.Name))) .Concat(node.AllChildren() .Select((q, z) => generator.Argument( z == i ? generator.CastExpression( SyntaxFactory.ParseTypeName( SharedGeneratorion.GreenNodeName(q.Type)), generator.IdentifierName(options.NewChild)) : generator.IdentifierName(q.Name) ))) ) ) } ))); cases.Add(generator.DefaultSwitchSection(new[] { generator.ThrowStatement(generator.ObjectCreationExpression( SyntaxFactory.ParseTypeName(options.InvalidChildReplace))) })); SyntaxNode switchStatement = generator.SwitchStatement(generator.IdentifierName(options.Index), cases); return(generator.MethodDeclaration( options.WithReplacedChild, new[] { generator.ParameterDeclaration(options.NewChild, options.GreenBase()), generator.ParameterDeclaration(options.Index, generator.TypeExpression(SpecialType.System_Int32)) }, null, options.GreenBase(), Accessibility.Internal, DeclarationModifiers.Override, new[] { switchStatement } )); }
protected override SyntaxNode VisitMethod(Node node) { int childCount = node.AllChildren().Count(); if (childCount == 0) { return(Generator.MethodDeclaration(Options.Visit + node.Name, new[] { Generator.ParameterDeclaration(Options.Node.StartingWithLowercase(), SyntaxFactory.ParseTypeName(SharedGeneratorion.RedNodeName(node.Name))) }, null, ReturnType(), Accessibility.Protected, DeclarationModifiers.Virtual, new[] { Generator.ReturnStatement(Generator.DefaultExpression(SyntaxFactory.ParseTypeName("T"))) })); } else if (childCount == 1) { return(Generator.MethodDeclaration(Options.Visit + node.Name, new[] { Generator.ParameterDeclaration(Options.Node.StartingWithLowercase(), SyntaxFactory.ParseTypeName(SharedGeneratorion.RedNodeName(node.Name))) }, null, ReturnType(), Accessibility.Protected, DeclarationModifiers.Virtual, new [] { Generator.ReturnStatement(Generator.InvocationExpression( Generator.IdentifierName(Options.Visit), Generator.MemberAccessExpression( Generator.IdentifierName(Options.Node.StartingWithLowercase()), node.AllChildren().First().Name))) })); } else { return(Generator.MethodDeclaration(Options.Visit + node.Name, new[] { Generator.ParameterDeclaration(Options.Node.StartingWithLowercase(), SyntaxFactory.ParseTypeName(SharedGeneratorion.RedNodeName(node.Name))) }, null, ReturnType(), Accessibility.Protected, DeclarationModifiers.Abstract, null)); } }
protected override SyntaxNode VisitMethod(Node node) { return(Generator.MethodDeclaration(Options.Visit + node.Name, new[] { Generator.ParameterDeclaration(Options.Node.StartingWithLowercase(), SyntaxFactory.ParseTypeName(SharedGeneratorion.RedNodeName(node.Name))) }, null, null, Accessibility.Protected, DeclarationModifiers.Virtual, node.AllChildren() .Select( x => Generator.InvocationExpression( Generator.IdentifierName(Options.Visit), Generator.MemberAccessExpression( Generator.IdentifierName(Options.Node.StartingWithLowercase()), x.Name))))); }
private static SyntaxNode CreateMember(SyntaxGenerator generator, Member type) { return(SharedGeneratorion.GetOnlyAccessor(type.PropertyName(), type.GetRepresentation(TypeClassContext.None))); }
public static TypeSyntax RedBase(this Options options) { return(SyntaxFactory.ParseTypeName(SharedGeneratorion.RedNodeName(options.BaseName))); }
/*List<SyntaxNode> declerations = new List<SyntaxNode>(); * * declerations.AddRange(SharedGeneratorion.UsingDirectives()); * * declerations.Add(generator.NamespaceDeclaration(options.NameSpace + ".Internal", * ((ClassDeclarationSyntax) ).AddAttributeLists( * SharedGeneratorion.AutoGenerated(generator) * )));*/ public static void Main(string[] args) { Console.WriteLine("Code generator started with arguments " + string.Join(", ", args.Select(x => '"' + x + '"'))); if (args.Length != 5) { Environment.Exit(-1); } string xmlPath = args[0]; string nodesSavePath = args[1]; //Where we want the red nodes string factorySavePath = args[2]; //Where we want the factory string internalNodesSavePath = args[3]; //Where we want the green ones string visitorsSavePath = args[4]; //Where we want the visitors Model model = ReadDefinition(xmlPath); Workspace workspace = new AdhocWorkspace(); SyntaxGenerator generator = SyntaxGenerator.GetGenerator(workspace, LanguageNames.CSharp); List <SyntaxNode> redNodes = new List <SyntaxNode>(); List <SyntaxNode> factoryMethods = new List <SyntaxNode>(); List <SyntaxNode> greenNodes = new List <SyntaxNode>(); List <SyntaxNode> visitors = new List <SyntaxNode> { new VoidVisitorGenerator(generator, model).CreateVisitor("SyntaxVisitor"), new SimpleTVisitorGenerator(generator, model).CreateVisitor("SyntaxVisitor"), new ComplexTVisitorGenerator( generator, model, SyntaxFactory.ParseTypeName("SyntaxVisitor<T>") ).CreateVisitor("SimpleSyntaxVisitor"), new SyntaxRewriterGenerator( generator, model, SyntaxFactory.ParseTypeName($"SyntaxVisitor<{SharedGeneratorion.RedNodeName(model.Options.BaseName)}>") ).CreateVisitor("SyntaxRewriter") }; foreach (Node node in model.Nodes) { if (node.Manual) { continue; } redNodes.Add(RedNodeGenerator.CreateRedNode(generator, node, model.Options)); greenNodes.Add(GreenNodeGenerator.CreateGreenNode(generator, node, model.Options)); if (node.Abstract) { continue; } factoryMethods.AddRange(Factory.CreateFactoryFor(generator, node, model.Options)); } //Every red node is partial and has 3 parts: The node itself, a static factory node, and the internal green node. var factoryMethodsPartOfRedNode = new[] { generator.ClassDeclaration( SharedGeneratorion.RedNodeName(model.Options.BaseName), null, Accessibility.Public, DeclarationModifiers.Partial, null, null, factoryMethods ) }; var greenNodesPartOfRedNodes = new[] { generator.ClassDeclaration( SharedGeneratorion.RedNodeName(model.Options.BaseName), null, Accessibility.Public, DeclarationModifiers.Partial, null, null, greenNodes ) }; //Generated enum for all NodeTypes redNodes.Add(GeneratedTypeEnum(generator, model.Nodes)); Save(Finalize(generator, model.Options.NameSpace, workspace, redNodes), nodesSavePath); Save(Finalize(generator, model.Options.NameSpace, workspace, visitors), visitorsSavePath); Save(Finalize(generator, model.Options.NameSpace, workspace, factoryMethodsPartOfRedNode), factorySavePath); Save(Finalize(generator, model.Options.NameSpace, workspace, greenNodesPartOfRedNodes), internalNodesSavePath); Console.WriteLine("Finished"); }