private void WriteType(TreeType node) { if (node is AbstractNode) { AbstractNode nd = (AbstractNode)node; _writer.WriteLine(" public abstract partial class {0} : {1}", node.Name, node.Base); _writer.WriteLine(" {"); for (int i = 0, n = nd.Fields.Count; i < n; i++) { var field = nd.Fields[i]; if (IsNodeOrNodeList(field.Type)) { _writer.WriteLine(" public abstract {0}{1} {2} {{ get; }}", "", field.Type, field.Name); } } _writer.WriteLine(" }"); } else if (node is Node) { Node nd = (Node)node; _writer.WriteLine(" public partial class {0} : {1}", node.Name, node.Base); _writer.WriteLine(" {"); WriteKinds(nd.Kinds); var valueFields = nd.Fields.Where(n => !IsNodeOrNodeList(n.Type)).ToList(); var nodeFields = nd.Fields.Where(n => IsNodeOrNodeList(n.Type)).ToList(); for (int i = 0, n = nodeFields.Count; i < n; i++) { var field = nodeFields[i]; _writer.WriteLine(" public {0}{1}{2} {3} {{ get; }}", "", "", field.Type, field.Name); } for (int i = 0, n = valueFields.Count; i < n; i++) { var field = valueFields[i]; _writer.WriteLine(" public {0}{1}{2} {3} {{ get; }}", "", "", field.Type, field.Name); } _writer.WriteLine(" }"); } }
private void WriteRedType(TreeType node) { WriteComment(node.TypeComment, " "); if (node is AbstractNode) { AbstractNode nd = (AbstractNode)node; WriteLine(" public abstract partial class {0} : {1}", node.Name, node.Base); WriteLine(" {"); WriteLine(" internal {0}(Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.CSharpSyntaxNode green, SyntaxNode parent, int position)", node.Name); WriteLine(" : base(green, parent, position)"); WriteLine(" {"); WriteLine(" }"); var valueFields = nd.Fields.Where(n => !IsNodeOrNodeList(n.Type)).ToList(); var nodeFields = nd.Fields.Where(n => IsNodeOrNodeList(n.Type)).ToList(); for (int i = 0, n = nodeFields.Count; i < n; i++) { var field = nodeFields[i]; if (IsNodeOrNodeList(field.Type)) { //red SyntaxLists can't contain tokens, so we switch to SyntaxTokenList var fieldType = field.Type == "SyntaxList<SyntaxToken>" ? "SyntaxTokenList" : field.Type; WriteLine(); WriteComment(field.PropertyComment, " "); WriteLine(" {0} abstract {1}{2} {3} {{ get; }}", "public", (IsNew(field) ? "new " : ""), fieldType, field.Name); } } for (int i = 0, n = valueFields.Count; i < n; i++) { var field = valueFields[i]; WriteLine(); WriteComment(field.PropertyComment, " "); WriteLine(" {0} abstract {1}{2} {3} {{ get; }}", "public", (IsNew(field) ? "new " : ""), field.Type, field.Name); } WriteLine(" }"); } else if (node is Node) { Node nd = (Node)node; WriteLine(" public sealed partial class {0} : {1}", node.Name, node.Base); WriteLine(" {"); var valueFields = nd.Fields.Where(n => !IsNodeOrNodeList(n.Type)).ToList(); var nodeFields = nd.Fields.Where(n => IsNodeOrNodeList(n.Type)).ToList(); for (int i = 0, n = nodeFields.Count; i < n; i++) { var field = nodeFields[i]; if (field.Type != "SyntaxToken" && field.Type != "SyntaxList<SyntaxToken>" ) { if (IsSeparatedNodeList(field.Type) || field.Type == "SyntaxNodeOrTokenList") { WriteLine(" private SyntaxNode {0};", CamelCase(field.Name)); } else { var type = GetFieldType(field, green: false); WriteLine(" private {0} {1};", type, CamelCase(field.Name)); } } } // write constructor WriteLine(); WriteLine(" internal {0}(Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.CSharpSyntaxNode green, SyntaxNode parent, int position)", node.Name); WriteLine(" : base(green, parent, position)"); WriteLine(" {"); WriteLine(" }"); WriteLine(); // property accessors for (int i = 0, n = nodeFields.Count; i < n; i++) { var field = nodeFields[i]; if (field.Type == "SyntaxToken") { WriteComment(field.PropertyComment, " "); WriteLine(" {0} {1}{2} {3} ", "public", OverrideOrNewModifier(field), field.Type, field.Name); WriteLine(" {"); if (IsOptional(field)) { WriteLine(" get"); WriteLine(" {"); WriteLine(" var slot = ((Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.{0})this.Green).{1};", node.Name, CamelCase(field.Name)); WriteLine(" if (slot != null)"); WriteLine(" return new SyntaxToken(this, slot, {0}, {1});", GetChildPosition(i), GetChildIndex(i)); WriteLine(); WriteLine(" return default(SyntaxToken);"); WriteLine(" }"); } else { WriteLine(" get {{ return new SyntaxToken(this, ((Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.{0})this.Green).{1}, {2}, {3}); }}", node.Name, CamelCase(field.Name), GetChildPosition(i), GetChildIndex(i)); } WriteLine(" }"); } else if (field.Type == "SyntaxList<SyntaxToken>") { WriteComment(field.PropertyComment, " "); WriteLine(" {0} {1}SyntaxTokenList {2} ", "public", OverrideOrNewModifier(field), field.Name); WriteLine(" {"); WriteLine(" get"); WriteLine(" {"); WriteLine(" var slot = this.Green.GetSlot({0});", i); WriteLine(" if (slot != null)"); WriteLine(" return new SyntaxTokenList(this, slot, {0}, {1});", GetChildPosition(i), GetChildIndex(i)); WriteLine(); WriteLine(" return default(SyntaxTokenList);"); WriteLine(" }"); WriteLine(" }"); } else { WriteComment(field.PropertyComment, " "); WriteLine(" {0} {1}{2} {3} ", "public", OverrideOrNewModifier(field), field.Type, field.Name); WriteLine(" {"); WriteLine(" get"); WriteLine(" {"); if (IsNodeList(field.Type)) { WriteLine(" return new {0}(this.GetRed(ref this.{1}, {2}));", field.Type, CamelCase(field.Name), i); } else if (IsSeparatedNodeList(field.Type)) { WriteLine(" var red = this.GetRed(ref this.{0}, {1});", CamelCase(field.Name), i); WriteLine(" if (red != null)", i); WriteLine(" return new {0}(red, {1});", field.Type, GetChildIndex(i)); WriteLine(); WriteLine(" return default({0});", field.Type); } else if (field.Type == "SyntaxNodeOrTokenList") { throw new InvalidOperationException("field cannot be a random SyntaxNodeOrTokenList"); } else { if (i == 0) { WriteLine(" return this.GetRedAtZero(ref this.{0});", CamelCase(field.Name)); } else { WriteLine(" return this.GetRed(ref this.{0}, {1});", CamelCase(field.Name), i); } } WriteLine(" }"); WriteLine(" }"); } WriteLine(); } for (int i = 0, n = valueFields.Count; i < n; i++) { var field = valueFields[i]; WriteComment(field.PropertyComment, " "); WriteLine(" {0} {1}{2} {3} {{ get {{ return ((Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.{4})this.Green).{3}; }} }}", "public", OverrideOrNewModifier(field), field.Type, field.Name, node.Name ); WriteLine(); } //GetNodeSlot forces creation of a red node. WriteLine(" internal override SyntaxNode GetNodeSlot(int index)"); WriteLine(" {"); WriteLine(" switch (index)"); WriteLine(" {"); for (int i = 0, n = nodeFields.Count; i < n; i++) { var field = nodeFields[i]; if (field.Type != "SyntaxToken" && field.Type != "SyntaxList<SyntaxToken>") { if (i == 0) { WriteLine(" case {0}: return this.GetRedAtZero(ref this.{1});", i, CamelCase(field.Name)); } else { WriteLine(" case {0}: return this.GetRed(ref this.{1}, {0});", i, CamelCase(field.Name)); } } } WriteLine(" default: return null;"); WriteLine(" }"); WriteLine(" }"); //GetCachedSlot returns a red node if we have it. WriteLine(" internal override SyntaxNode GetCachedSlot(int index)"); WriteLine(" {"); WriteLine(" switch (index)"); WriteLine(" {"); for (int i = 0, n = nodeFields.Count; i < n; i++) { var field = nodeFields[i]; if (field.Type != "SyntaxToken" && field.Type != "SyntaxList<SyntaxToken>") { WriteLine(" case {0}: return this.{1};", i, CamelCase(field.Name)); } } WriteLine(" default: return null;"); WriteLine(" }"); WriteLine(" }"); this.WriteRedAcceptMethods(nd); this.WriteRedUpdateMethod(nd); // this.WriteRedWithMethod(nd); this.WriteRedSetters(nd); this.WriteRedListHelperMethods(nd); WriteLine(" }"); } }
private void WriteGreenType(TreeType node) { WriteComment(node.TypeComment, " "); if (node is AbstractNode) { AbstractNode nd = (AbstractNode)node; WriteLine(" internal abstract partial class {0} : {1}", node.Name, node.Base); WriteLine(" {"); // ctor with diagnostics and annotations WriteLine(" internal {0}(SyntaxKind kind, DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations)", node.Name); WriteLine(" : base(kind, diagnostics, annotations)"); WriteLine(" {"); if (node.Name == "DirectiveTriviaSyntax") { WriteLine(" this.flags |= NodeFlags.ContainsDirectives;"); } WriteLine(" }"); // ctor without diagnostics and annotations WriteLine(" internal {0}(SyntaxKind kind)", node.Name); WriteLine(" : base(kind)"); WriteLine(" {"); if (node.Name == "DirectiveTriviaSyntax") { WriteLine(" this.flags |= NodeFlags.ContainsDirectives;"); } WriteLine(" }"); // object reader constructor WriteLine(); WriteLine(" protected {0}(ObjectReader reader)", node.Name); WriteLine(" : base(reader)"); WriteLine(" {"); if (node.Name == "DirectiveTriviaSyntax") { WriteLine(" this.flags |= NodeFlags.ContainsDirectives;"); } WriteLine(" }"); var valueFields = nd.Fields.Where(n => !IsNodeOrNodeList(n.Type)).ToList(); var nodeFields = nd.Fields.Where(n => IsNodeOrNodeList(n.Type)).ToList(); for (int i = 0, n = nodeFields.Count; i < n; i++) { var field = nodeFields[i]; if (IsNodeOrNodeList(field.Type)) { WriteLine(); WriteComment(field.PropertyComment, " "); if (IsSeparatedNodeList(field.Type) || IsNodeList(field.Type)) { WriteLine(" public abstract {0}Microsoft.CodeAnalysis.Syntax.InternalSyntax.{1} {2} {{ get; }}", (IsNew(field) ? "new " : ""), field.Type, field.Name); } else { WriteLine(" public abstract {0}{1} {2} {{ get; }}", (IsNew(field) ? "new " : ""), field.Type, field.Name); } } } for (int i = 0, n = valueFields.Count; i < n; i++) { var field = valueFields[i]; WriteLine(); WriteComment(field.PropertyComment, " "); WriteLine(" public abstract {0}{1} {2} {{ get; }}", (IsNew(field) ? "new " : ""), field.Type, field.Name); } WriteLine(" }"); } else if (node is Node) { Node nd = (Node)node; WriteLine(" internal sealed partial class {0} : {1}", node.Name, node.Base); WriteLine(" {"); var valueFields = nd.Fields.Where(n => !IsNodeOrNodeList(n.Type)).ToList(); var nodeFields = nd.Fields.Where(n => IsNodeOrNodeList(n.Type)).ToList(); for (int i = 0, n = nodeFields.Count; i < n; i++) { var field = nodeFields[i]; var type = GetFieldType(field, green: true); WriteLine(" internal readonly {0} {1};", type, CamelCase(field.Name)); } for (int i = 0, n = valueFields.Count; i < n; i++) { var field = valueFields[i]; WriteLine(" internal readonly {0} {1};", field.Type, CamelCase(field.Name)); } // write constructor with diagnostics and annotations WriteLine(); Write(" internal {0}(SyntaxKind kind", node.Name); WriteGreenNodeConstructorArgs(nodeFields, valueFields); WriteLine(", DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations)"); WriteLine(" : base(kind, diagnostics, annotations)"); WriteLine(" {"); WriteCtorBody(valueFields, nodeFields); WriteLine(" }"); WriteLine(); // write constructor with async WriteLine(); Write(" internal {0}(SyntaxKind kind", node.Name); WriteGreenNodeConstructorArgs(nodeFields, valueFields); WriteLine(", SyntaxFactoryContext context)"); WriteLine(" : base(kind)"); WriteLine(" {"); WriteLine(" this.SetFactoryContext(context);"); WriteCtorBody(valueFields, nodeFields); WriteLine(" }"); WriteLine(); // write constructor without diagnostics and annotations WriteLine(); Write(" internal {0}(SyntaxKind kind", node.Name); WriteGreenNodeConstructorArgs(nodeFields, valueFields); WriteLine(")"); WriteLine(" : base(kind)"); WriteLine(" {"); WriteCtorBody(valueFields, nodeFields); WriteLine(" }"); WriteLine(); // property accessors for (int i = 0, n = nodeFields.Count; i < n; i++) { var field = nodeFields[i]; WriteComment(field.PropertyComment, " "); if (IsNodeList(field.Type)) { WriteLine(" public {0}Microsoft.CodeAnalysis.Syntax.InternalSyntax.{1} {2} {{ get {{ return new Microsoft.CodeAnalysis.Syntax.InternalSyntax.{1}(this.{3}); }} }}", OverrideOrNewModifier(field), field.Type, field.Name, CamelCase(field.Name) ); } else if (IsSeparatedNodeList(field.Type)) { WriteLine(" public {0}Microsoft.CodeAnalysis.Syntax.InternalSyntax.{1} {2} {{ get {{ return new Microsoft.CodeAnalysis.Syntax.InternalSyntax.{1}(new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList<CSharpSyntaxNode>(this.{3})); }} }}", OverrideOrNewModifier(field), field.Type, field.Name, CamelCase(field.Name), i ); } else if (field.Type == "SyntaxNodeOrTokenList") { WriteLine(" public {0}Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList<CSharpSyntaxNode> {1} {{ get {{ return new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList<CSharpSyntaxNode>(this.{2}); }} }}", OverrideOrNewModifier(field), field.Name, CamelCase(field.Name) ); } else { WriteLine(" public {0}{1} {2} {{ get {{ return this.{3}; }} }}", OverrideOrNewModifier(field), field.Type, field.Name, CamelCase(field.Name) ); } } for (int i = 0, n = valueFields.Count; i < n; i++) { var field = valueFields[i]; WriteComment(field.PropertyComment, " "); WriteLine(" public {0}{1} {2} {{ get {{ return this.{3}; }} }}", OverrideOrNewModifier(field), field.Type, field.Name, CamelCase(field.Name) ); } // GetSlot WriteLine(); WriteLine(" internal override GreenNode GetSlot(int index)"); WriteLine(" {"); WriteLine(" switch (index)"); WriteLine(" {"); for (int i = 0, n = nodeFields.Count; i < n; i++) { var field = nodeFields[i]; WriteLine(" case {0}: return this.{1};", i, CamelCase(field.Name)); } WriteLine(" default: return null;"); WriteLine(" }"); WriteLine(" }"); WriteLine(); WriteLine(" internal override SyntaxNode CreateRed(SyntaxNode parent, int position)"); WriteLine(" {"); WriteLine(" return new CSharp.Syntax.{0}(this, parent, position);", node.Name); WriteLine(" }"); this.WriteGreenAcceptMethods(nd); this.WriteGreenUpdateMethod(nd); this.WriteSetDiagnostics(nd); this.WriteSetAnnotations(nd); this.WriteGreenSerialization(nd); WriteLine(" }"); } }
private void WriteType(TreeType node) { if (node is AbstractNode) { AbstractNode nd = (AbstractNode)node; _writer.WriteLine( " public abstract partial class {0} : {1}", node.Name, node.Base ); _writer.WriteLine(" {"); for (int i = 0, n = nd.Fields.Count; i < n; i++) { var field = nd.Fields[i]; if (IsNodeOrNodeList(field.Type)) { _writer.WriteLine( " public abstract {0}{1} {2} {{ get; }}", "", field.Type, field.Name ); } } _writer.WriteLine(" }"); } else if (node is Node) { Node nd = (Node)node; _writer.WriteLine(" public partial class {0} : {1}", node.Name, node.Base); _writer.WriteLine(" {"); WriteKinds(nd.Kinds); var valueFields = nd.Fields.Where(n => !IsNodeOrNodeList(n.Type)).ToList(); var nodeFields = nd.Fields.Where(n => IsNodeOrNodeList(n.Type)).ToList(); for (int i = 0, n = nodeFields.Count; i < n; i++) { var field = nodeFields[i]; _writer.WriteLine( " public {0}{1}{2} {3} {{ get; }}", "", "", field.Type, field.Name ); } for (int i = 0, n = valueFields.Count; i < n; i++) { var field = valueFields[i]; _writer.WriteLine( " public {0}{1}{2} {3} {{ get; }}", "", "", field.Type, field.Name ); } _writer.WriteLine(" }"); } }