vitess.io/vitess@v0.16.2/go/tools/asthelpergen/integration/test_helpers.go (about)

     1  /*
     2  Copyright 2021 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package integration
    18  
    19  import (
    20  	"strings"
    21  )
    22  
    23  // ast type helpers
    24  
    25  func sliceStringAST(els ...AST) string {
    26  	result := make([]string, len(els))
    27  	for i, el := range els {
    28  		result[i] = el.String()
    29  	}
    30  	return strings.Join(result, ", ")
    31  }
    32  func sliceStringLeaf(els ...*Leaf) string {
    33  	result := make([]string, len(els))
    34  	for i, el := range els {
    35  		result[i] = el.String()
    36  	}
    37  	return strings.Join(result, ", ")
    38  }
    39  
    40  // the methods below are what the generated code expected to be there in the package
    41  
    42  // ApplyFunc is apply function
    43  type ApplyFunc func(*Cursor) bool
    44  
    45  // Cursor is cursor
    46  type Cursor struct {
    47  	parent   AST
    48  	replacer replacerFunc
    49  	node     AST
    50  	// marks that the node has been replaced, and the new node should be visited
    51  	revisit bool
    52  }
    53  
    54  // Node returns the current Node.
    55  func (c *Cursor) Node() AST { return c.node }
    56  
    57  // Parent returns the parent of the current Node.
    58  func (c *Cursor) Parent() AST { return c.parent }
    59  
    60  // Replace replaces the current node in the parent field with this new object. The user needs to make sure to not
    61  // replace the object with something of the wrong type, or the visitor will panic.
    62  func (c *Cursor) Replace(newNode AST) {
    63  	c.replacer(newNode, c.parent)
    64  	c.node = newNode
    65  }
    66  
    67  // ReplaceAndRevisit replaces the current node in the parent field with this new object.
    68  // When used, this will abort the visitation of the current node - no post or children visited,
    69  // and the new node visited.
    70  func (c *Cursor) ReplaceAndRevisit(newNode AST) {
    71  	switch newNode.(type) {
    72  	case InterfaceSlice:
    73  	default:
    74  		// We need to add support to the generated code for when to look at the revisit flag. At the moment it is only
    75  		// there for slices of AST implementations
    76  		panic("no support added for this type yet")
    77  	}
    78  
    79  	c.replacer(newNode, c.parent)
    80  	c.node = newNode
    81  	c.revisit = true
    82  }
    83  
    84  type replacerFunc func(newNode, parent AST)
    85  
    86  // Rewrite is the api.
    87  func Rewrite(node AST, pre, post ApplyFunc) AST {
    88  	outer := &struct{ AST }{node}
    89  
    90  	a := &application{
    91  		pre:  pre,
    92  		post: post,
    93  	}
    94  
    95  	a.rewriteAST(outer, node, func(newNode, parent AST) {
    96  		outer.AST = newNode
    97  	})
    98  
    99  	return outer.AST
   100  }
   101  
   102  type (
   103  	cow struct {
   104  		pre    func(node, parent AST) bool
   105  		post   func(cursor *cursor)
   106  		cloned func(old, new AST)
   107  		cursor cursor
   108  	}
   109  	cursor struct {
   110  		stop bool
   111  	}
   112  )
   113  
   114  func (c *cow) postVisit(a, b AST, d bool) (AST, bool) {
   115  	return a, d
   116  }