private void GenerateVisitMethod(SyntaxNodeTypeInfo type) { this.writer.WriteLine($"\t\tpublic override SyntaxNode Visit{type.NodeType.Name.Replace("Syntax", string.Empty)}({type.NodeType.Name} node)"); this.writer.WriteLine("\t\t{"); foreach (var property in type.Properties.Where(p => p.Kind != SyntaxNodePropertyKind.NonSyntactic)) { this.writer.Write("\t\t\tnode = "); switch (property.Kind) { case SyntaxNodePropertyKind.Node: case SyntaxNodePropertyKind.Token: var visitMethod = property.Kind == SyntaxNodePropertyKind.Node ? "TypedVisit" : "VisitToken"; this.writer.WriteLine($"node.{property.Wither.Name}(this.{visitMethod}(node.{property.Property.Name}));"); break; case SyntaxNodePropertyKind.NodeList: case SyntaxNodePropertyKind.SeparatedNodeList: case SyntaxNodePropertyKind.TokenList: var listName = property.Kind == SyntaxNodePropertyKind.NodeList ? "Syntax" : property.Kind == SyntaxNodePropertyKind.SeparatedNodeList ? "SeparatedSyntax" : "SyntaxToken"; this.writer.WriteLine($"this.IncrementalVisit{listName}List(node, n => n.{property.Property.Name}, (n, list) => n.{property.Wither.Name}(list));"); break; } } this.writer.WriteLine("\t\t\treturn node;"); this.writer.WriteLine("\t\t}"); }
private void Generate(SyntaxNodeTypeInfo typeInfo) { this.writer.WriteLine($"\t#region ---- {typeInfo.NodeType.Name} ----"); this.writer.WriteLine($"\tinternal static class {typeInfo.NodeType.Name.Replace("Syntax", string.Empty)}Info"); this.writer.WriteLine("\t{"); var properties = typeInfo.Properties.Where(p => p.Kind != SyntaxNodePropertyKind.NonSyntactic); foreach (var property in properties) { var fieldAndPropertyType = $"SyntaxNodeProperty<{typeInfo.NodeType.Name}, {GetName(property.Property.PropertyType)}>"; string propertyImplementationType; switch (property.Kind) { case SyntaxNodePropertyKind.Node: propertyImplementationType = $"NodeProperty<{typeInfo.NodeType.Name}, {property.Property.PropertyType.Name}>"; break; case SyntaxNodePropertyKind.NodeList: propertyImplementationType = $"ListProperty<{typeInfo.NodeType.Name}, {property.Property.PropertyType.GetGenericArguments().Single().Name}>"; break; case SyntaxNodePropertyKind.SeparatedNodeList: propertyImplementationType = $"SeparatedListProperty<{typeInfo.NodeType.Name}, {property.Property.PropertyType.GetGenericArguments().Single().Name}>"; break; case SyntaxNodePropertyKind.Token: propertyImplementationType = $"TokenProperty<{typeInfo.NodeType.Name}>"; break; case SyntaxNodePropertyKind.TokenList: propertyImplementationType = $"TokenListProperty<{typeInfo.NodeType.Name}>"; break; default: throw new InvalidOperationException(); } this.writer.WriteLine( $"\t\tprivate static readonly {fieldAndPropertyType} {property.Property.Name}Property = new {propertyImplementationType}(\"{property.Property.Name}\", n => n.{property.Property.Name}, (n, v) => n.{property.Wither.Name}(v));" ); this.writer.WriteLine(); this.writer.WriteLine($"\t\tpublic static {fieldAndPropertyType} {property.Property.Name} => {property.Property.Name}Property;"); this.writer.WriteLine(); } var propertiesListElementType = $"ISyntaxNodePropertyWithTypedNode<{typeInfo.NodeType.Name}>"; this.writer.WriteLine($"\t\tprivate static readonly {propertiesListElementType}[] PropertiesArray = new {propertiesListElementType}[] {{ {string.Join(", ", properties.Select(p => p.Property.Name))} }};"); this.writer.WriteLine(); this.writer.WriteLine($"\t\tpublic static IReadOnlyList<{propertiesListElementType}> Properties => PropertiesArray;"); this.writer.WriteLine("\t}"); this.writer.WriteLine("\t#endregion"); }