refactor: generate node functions instead of manual

Easier to update now, also more reliable (nothing to forget)
This commit is contained in:
Laytan Laats 2023-03-25 21:53:52 +01:00
parent 702cadceab
commit 3ba9118676
4 changed files with 1749 additions and 1328 deletions

View File

@ -2,6 +2,15 @@ package ast
import "github.com/VKCOM/php-parser/pkg/position"
// The edge-case/overwrites, from node type name to their visitor function name.
var TypeToVisitorNameMap = map[string]string{
"Name": "NameName",
"NamePart": "NameNamePart",
"StmtGroupUseList": "StmtGroupUse",
"StmtUseList": "StmtUse",
"StmtUse": "StmtUseDeclaration",
}
type Vertex interface {
Accept(v Visitor)
GetPosition() *position.Position

File diff suppressed because it is too large Load Diff

1665
pkg/ast/node_funcs.go Normal file

File diff suppressed because it is too large Load Diff

73
pkg/ast/node_funcs_gen.go Normal file
View File

@ -0,0 +1,73 @@
//go:build ignore
// +build ignore
package main
import (
"fmt"
"os"
"regexp"
"text/template"
"github.com/VKCOM/php-parser/pkg/ast"
)
type templData struct {
Types []nodeType
}
type nodeType struct {
Name string
FuncName string
}
var fileTempl = template.Must(
template.New("").
Parse(`// Code generated by "go generate go run node_funcs_gen.go"; DO NOT EDIT.
package ast
import "github.com/VKCOM/php-parser/pkg/position"
{{range $typ := .Types}}
var _ Vertex = &{{$typ.Name}}{}
func (n *{{$typ.Name}}) Accept(v Visitor) {
v.{{$typ.FuncName}}(n)
}
func (n *{{$typ.Name}}) GetPosition() *position.Position {
return n.Position
}
{{end}}`),
)
var typesRgx = regexp.MustCompile(`type ([a-zA-Z]+) struct`)
func main() {
content, err := os.ReadFile("node.go")
if err != nil {
panic(fmt.Errorf("reading 'ast.go': %w", err))
}
matches := typesRgx.FindAllSubmatch(content, -1)
types := make([]nodeType, 0, len(matches))
for _, match := range matches {
name := string(match[1])
funcName := name
if overwrite, ok := ast.TypeToVisitorNameMap[name]; ok {
funcName = overwrite
}
types = append(types, nodeType{
Name: name,
FuncName: funcName,
})
}
f, err := os.Create("node_funcs.go")
if err != nil {
panic(fmt.Errorf("creating/opening 'node_funcs.go': %w", err))
}
fileTempl.Execute(f, templData{types})
}