3a567abb51
This uses a separate, lower-level AST than the parser so that it can retain the raw tokens and make surgical changes. As a consequence it has much less semantic detail than the parser AST, and in particular doesn't represent the structure of expressions except to retain variable references to enable global rename operations.
108 lines
2.1 KiB
Go
108 lines
2.1 KiB
Go
package zclwrite
|
|
|
|
type Node interface {
|
|
walkChildNodes(w internalWalkFunc)
|
|
Tokens() *TokenSeq
|
|
}
|
|
|
|
type internalWalkFunc func(Node)
|
|
|
|
type File struct {
|
|
Name string
|
|
Bytes []byte
|
|
|
|
Body Body
|
|
}
|
|
|
|
type Body struct {
|
|
// Items may contain Attribute, Block and Unstructured instances.
|
|
Items []Node
|
|
AllTokens *TokenSeq
|
|
|
|
// IndentLevel is the number of spaces that should appear at the start
|
|
// of lines added within this body.
|
|
IndentLevel int
|
|
}
|
|
|
|
func (n *Body) walkChildNodes(w internalWalkFunc) {
|
|
for _, item := range n.Items {
|
|
w(item)
|
|
}
|
|
}
|
|
|
|
func (n *Body) Tokens() *TokenSeq {
|
|
return n.AllTokens
|
|
}
|
|
|
|
type Attribute struct {
|
|
AllTokens *TokenSeq
|
|
|
|
LeadCommentTokens *TokenSeq
|
|
NameToken *Token
|
|
EqualsToken *Token
|
|
Value *Expression
|
|
LineCommentTokens *TokenSeq
|
|
EOLToken *Token
|
|
}
|
|
|
|
func (a *Attribute) walkChildNodes(w internalWalkFunc) {
|
|
w(a.Value)
|
|
}
|
|
|
|
type Block struct {
|
|
AllTokens *TokenSeq
|
|
|
|
LeadCommentTokens *TokenSeq
|
|
TypeToken *Token
|
|
LabelTokens []*TokenSeq
|
|
LabelTokensFlat *TokenSeq
|
|
OBraceToken *Token
|
|
Body *Body
|
|
CBraceToken *Token
|
|
EOLToken *Token
|
|
}
|
|
|
|
func (n *Block) walkChildNodes(w internalWalkFunc) {
|
|
w(n.Body)
|
|
}
|
|
|
|
// Unstructured represents consecutive sets of tokens within a Body that
|
|
// aren't part of any particular construct. This includes blank lines
|
|
// and comments that aren't immediately before an attribute or nested block.
|
|
type Unstructured struct {
|
|
AllTokens *TokenSeq
|
|
}
|
|
|
|
func (n *Unstructured) Tokens() *TokenSeq {
|
|
return n.AllTokens
|
|
}
|
|
|
|
type Expression struct {
|
|
AllTokens *TokenSeq
|
|
VarRefs []*VarRef
|
|
}
|
|
|
|
func (n *Expression) walkChildNodes(w internalWalkFunc) {
|
|
for _, name := range n.VarRefs {
|
|
w(name)
|
|
}
|
|
}
|
|
|
|
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.
|
|
AllTokens *TokenSeq
|
|
}
|
|
|
|
func (n *VarRef) walkChildNodes(w internalWalkFunc) {
|
|
// no child nodes of a variable name
|
|
}
|
|
|
|
func (n *VarRef) Tokens() *TokenSeq {
|
|
return n.AllTokens
|
|
}
|