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 }