hclwrite: Parsing of absolute traversals in expressions
This will allow for use-cases such as renaming a variable (changing the content of the first token) and replacing variable references with constant values that they evaluate to for debug purposes.
This commit is contained in:
parent
1718a963e6
commit
d6367b5f96
@ -162,12 +162,12 @@ func (n *Block) Tokens() *TokenSeq {
|
||||
}
|
||||
|
||||
type Expression struct {
|
||||
AllTokens *TokenSeq
|
||||
VarRefs []*VarRef
|
||||
AllTokens *TokenSeq
|
||||
AbsTraversals []*Traversal
|
||||
}
|
||||
|
||||
func (n *Expression) walkChildNodes(w internalWalkFunc) {
|
||||
for _, name := range n.VarRefs {
|
||||
for _, name := range n.AbsTraversals {
|
||||
w(name)
|
||||
}
|
||||
}
|
||||
@ -176,16 +176,30 @@ func (n *Expression) Tokens() *TokenSeq {
|
||||
return n.AllTokens
|
||||
}
|
||||
|
||||
type VarRef struct {
|
||||
// Tokens alternate between TokenIdent and TokenDot, with the first
|
||||
// and last elements always being TokenIdent.
|
||||
type Traversal struct {
|
||||
AllTokens *TokenSeq
|
||||
Steps []*Traverser
|
||||
}
|
||||
|
||||
func (n *VarRef) walkChildNodes(w internalWalkFunc) {
|
||||
// no child nodes of a variable name
|
||||
func (n *Traversal) walkChildNodes(w internalWalkFunc) {
|
||||
for _, step := range n.Steps {
|
||||
w(step)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *VarRef) Tokens() *TokenSeq {
|
||||
func (n *Traversal) Tokens() *TokenSeq {
|
||||
return n.AllTokens
|
||||
}
|
||||
|
||||
type Traverser struct {
|
||||
AllTokens *TokenSeq
|
||||
Logical hcl.Traverser
|
||||
}
|
||||
|
||||
func (n *Traverser) Tokens() *TokenSeq {
|
||||
return n.AllTokens
|
||||
}
|
||||
|
||||
func (n *Traverser) walkChildNodes(w internalWalkFunc) {
|
||||
// No child nodes for a traversal step
|
||||
}
|
||||
|
@ -327,9 +327,54 @@ func parseBlock(nativeBlock *hclsyntax.Block, from, leadComments, lineComments,
|
||||
}
|
||||
|
||||
func parseExpression(nativeExpr hclsyntax.Expression, from inputTokens) *Expression {
|
||||
// TODO: Populate VarRefs by analyzing the result of nativeExpr.Variables()
|
||||
var allTokens TokenSeq
|
||||
nativeVars := nativeExpr.Variables()
|
||||
var absTraversals []*Traversal
|
||||
for _, nativeTraversal := range nativeVars {
|
||||
var traversalTokens TokenSeq
|
||||
var before, traversalFrom inputTokens
|
||||
before, traversalFrom, from = from.Partition(nativeTraversal.SourceRange())
|
||||
if before.Len() > 0 {
|
||||
allTokens = append(allTokens, before.Seq())
|
||||
}
|
||||
|
||||
var steps []*Traverser
|
||||
|
||||
for _, nativeStep := range nativeTraversal {
|
||||
var stepFrom inputTokens
|
||||
before, stepFrom, traversalFrom = traversalFrom.Partition(nativeStep.SourceRange())
|
||||
stepTokens := stepFrom.Seq()
|
||||
if before.Len() > 0 {
|
||||
traversalTokens = append(traversalTokens, before.Seq())
|
||||
}
|
||||
traversalTokens = append(traversalTokens, stepTokens)
|
||||
step := &Traverser{
|
||||
AllTokens: stepTokens,
|
||||
Logical: nativeStep,
|
||||
}
|
||||
steps = append(steps, step)
|
||||
}
|
||||
// Attach any straggler that don't belong to a step to the traversal itself.
|
||||
if traversalFrom.Len() > 0 {
|
||||
traversalTokens = append(traversalTokens, traversalFrom.Seq())
|
||||
}
|
||||
allTokens = append(allTokens, &traversalTokens)
|
||||
|
||||
absTraversals = append(absTraversals, &Traversal{
|
||||
AllTokens: &traversalTokens,
|
||||
Steps: steps,
|
||||
})
|
||||
}
|
||||
// Attach any stragglers that don't belong to a traversal to the expression
|
||||
// itself. In an expression with no traversals at all, this is just the
|
||||
// entirety of "from".
|
||||
if from.Len() > 0 {
|
||||
allTokens = append(allTokens, from.Seq())
|
||||
}
|
||||
|
||||
return &Expression{
|
||||
AllTokens: from.Seq(),
|
||||
AllTokens: &allTokens,
|
||||
AbsTraversals: absTraversals,
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user