Skip to content

Commit

Permalink
ast/astutil: use more generics to reduce duplication
Browse files Browse the repository at this point in the history
Now all lists are handled consistently as well.

Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
Change-Id: I4c5f0759e4bcdd516340fc968777ce60a1da6392
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1194007
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
Reviewed-by: Roger Peppe <rogpeppe@gmail.com>
  • Loading branch information
mvdan committed Apr 30, 2024
1 parent bf733fb commit d696e44
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 67 deletions.
54 changes: 21 additions & 33 deletions cue/ast/astutil/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,19 +199,6 @@ type applyVisitor interface {

// Helper functions for common node lists. They may be empty.

func applyExprList(v applyVisitor, parent Cursor, list []ast.Expr) {
c := newCursor(parent, nil, nil)
for i, x := range list {
c.index = i
c.node = x
c.typ = &list[i]
applyCursor(v, c)
if x != c.node {
list[i] = c.node.(ast.Expr)
}
}
}

type declsCursor struct {
*cursor
decls, after, process []ast.Decl
Expand Down Expand Up @@ -295,6 +282,19 @@ func apply[N ast.Node](v applyVisitor, parent Cursor, nodePtr *N) {
}
}

func applyList[N ast.Node](v applyVisitor, parent Cursor, list []N) {
c := newCursor(parent, nil, nil)
for i, node := range list {
c.index = i
c.node = node
c.typ = &list[i]
applyCursor(v, c)
if ast.Node(node) != c.node {
list[i] = c.node.(N)
}
}
}

// applyCursor traverses an AST in depth-first order: It starts by calling
// v.Visit(node); node must not be nil. If the visitor w returned by
// v.Visit(node) is not nil, apply is invoked recursively with visitor
Expand All @@ -309,10 +309,7 @@ func applyCursor(v applyVisitor, c Cursor) {

// TODO: record the comment groups and interleave with the values like for
// parsing and printing?
comments := node.Comments()
for _, cm := range comments {
apply(v, c, &cm)
}
applyList(v, c, ast.Comments(node))

// apply children
// (the order of the cases matches the order
Expand All @@ -323,9 +320,7 @@ func applyCursor(v applyVisitor, c Cursor) {
// nothing to do

case *ast.CommentGroup:
for _, cg := range n.List {
apply(v, c, &cg)
}
applyList(v, c, n.List)

case *ast.Attribute:
// nothing to do
Expand All @@ -335,9 +330,7 @@ func applyCursor(v applyVisitor, c Cursor) {
if n.Value != nil {
apply(v, c, &n.Value)
}
for _, a := range n.Attrs {
apply(v, c, &a)
}
applyList(v, c, n.Attrs)

case *ast.StructLit:
n.Elts = applyDeclList(v, c, n.Elts)
Expand All @@ -347,10 +340,10 @@ func applyCursor(v applyVisitor, c Cursor) {
// nothing to do

case *ast.Interpolation:
applyExprList(v, c, n.Elts)
applyList(v, c, n.Elts)

case *ast.ListLit:
applyExprList(v, c, n.Elts)
applyList(v, c, n.Elts)

case *ast.Ellipsis:
if n.Type != nil {
Expand Down Expand Up @@ -379,7 +372,7 @@ func applyCursor(v applyVisitor, c Cursor) {

case *ast.CallExpr:
apply(v, c, &n.Fun)
applyExprList(v, c, n.Args)
applyList(v, c, n.Args)

case *ast.UnaryExpr:
apply(v, c, &n.X)
Expand All @@ -399,9 +392,7 @@ func applyCursor(v applyVisitor, c Cursor) {
// nothing to do

case *ast.ImportDecl:
for _, s := range n.Specs {
apply(v, c, &s)
}
applyList(v, c, n.Specs)

case *ast.EmbedDecl:
apply(v, c, &n.Expr)
Expand All @@ -415,10 +406,7 @@ func applyCursor(v applyVisitor, c Cursor) {
apply(v, c, &n.Expr)

case *ast.Comprehension:
clauses := n.Clauses
for i := range n.Clauses {
apply(v, c, &clauses[i])
}
applyList(v, c, n.Clauses)
apply(v, c, &n.Value)

// Files and packages
Expand Down
48 changes: 14 additions & 34 deletions cue/ast/walk.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,9 @@ type Visitor interface {
After(node Node)
}

// Helper functions for common node lists. They may be empty.

func walkExprList(v Visitor, list []Expr) {
for _, x := range list {
walk(v, x)
}
}

func walkDeclList(v Visitor, list []Decl) {
for _, x := range list {
walk(v, x)
func walkList[N Node](v Visitor, list []N) {
for _, node := range list {
walk(v, node)
}
}

Expand All @@ -67,9 +59,7 @@ func walk(v Visitor, node Node) {

// TODO: record the comment groups and interleave with the values like for
// parsing and printing?
for _, c := range Comments(node) {
walk(v, c)
}
walkList(v, Comments(node))

// walk children
// (the order of the cases matches the order
Expand All @@ -80,9 +70,7 @@ func walk(v Visitor, node Node) {
// nothing to do

case *CommentGroup:
for _, c := range n.List {
walk(v, c)
}
walkList(v, n.List)

case *Attribute:
// nothing to do
Expand All @@ -92,28 +80,24 @@ func walk(v Visitor, node Node) {
if n.Value != nil {
walk(v, n.Value)
}
for _, a := range n.Attrs {
walk(v, a)
}
walkList(v, n.Attrs)

case *Func:
walkExprList(v, n.Args)
walkList(v, n.Args)
walk(v, n.Ret)

case *StructLit:
walkDeclList(v, n.Elts)
walkList(v, n.Elts)

// Expressions
case *BottomLit, *BadExpr, *Ident, *BasicLit:
// nothing to do

case *Interpolation:
for _, e := range n.Elts {
walk(v, e)
}
walkList(v, n.Elts)

case *ListLit:
walkExprList(v, n.Elts)
walkList(v, n.Elts)

case *Ellipsis:
if n.Type != nil {
Expand Down Expand Up @@ -142,7 +126,7 @@ func walk(v Visitor, node Node) {

case *CallExpr:
walk(v, n.Fun)
walkExprList(v, n.Args)
walkList(v, n.Args)

case *UnaryExpr:
walk(v, n.X)
Expand All @@ -162,9 +146,7 @@ func walk(v Visitor, node Node) {
// nothing to do

case *ImportDecl:
for _, s := range n.Specs {
walk(v, s)
}
walkList(v, n.Specs)

case *EmbedDecl:
walk(v, n.Expr)
Expand All @@ -178,14 +160,12 @@ func walk(v Visitor, node Node) {
walk(v, n.Expr)

case *Comprehension:
for _, c := range n.Clauses {
walk(v, c)
}
walkList(v, n.Clauses)
walk(v, n.Value)

// Files and packages
case *File:
walkDeclList(v, n.Decls)
walkList(v, n.Decls)

case *Package:
walk(v, n.Name)
Expand Down

0 comments on commit d696e44

Please sign in to comment.