RenameVariablePrefix examines each of the absolute traversals in the receiving expression to see if they have the given sequence of names as a prefix prefix. If so, they are updated in place to have the given replacement names instead of that prefix. This can be used to implement symbol renaming. T
(search, replacement []string)
| 151 | // method will panic. Only attribute access operations can be matched and |
| 152 | // replaced. Index steps never match the prefix. |
| 153 | func (e *Expression) RenameVariablePrefix(search, replacement []string) { |
| 154 | if len(search) != len(replacement) { |
| 155 | panic(fmt.Sprintf("search and replacement length mismatch (%d and %d)", len(search), len(replacement))) |
| 156 | } |
| 157 | Traversals: |
| 158 | for node := range e.absTraversals { |
| 159 | traversal := node.content.(*Traversal) |
| 160 | if len(traversal.steps) < len(search) { |
| 161 | // If it's shorter then it can't have our prefix |
| 162 | continue |
| 163 | } |
| 164 | |
| 165 | stepNodes := traversal.steps.List() |
| 166 | for i, name := range search { |
| 167 | step, isName := stepNodes[i].content.(*TraverseName) |
| 168 | if !isName { |
| 169 | continue Traversals // only name nodes can match |
| 170 | } |
| 171 | foundNameBytes := step.name.content.(*identifier).token.Bytes |
| 172 | if len(foundNameBytes) != len(name) { |
| 173 | continue Traversals |
| 174 | } |
| 175 | if string(foundNameBytes) != name { |
| 176 | continue Traversals |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | // If we get here then the prefix matched, so now we'll swap in |
| 181 | // the replacement strings. |
| 182 | for i, name := range replacement { |
| 183 | step := stepNodes[i].content.(*TraverseName) |
| 184 | token := step.name.content.(*identifier).token |
| 185 | token.Bytes = []byte(name) |
| 186 | } |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | // Traversal represents a sequence of variable, attribute, and/or index |
| 191 | // operations. |