Skip to content

Commit

Permalink
Merge pull request #252 from goccy/feature/support-path-from-node
Browse files Browse the repository at this point in the history
Support getting YAMLPath from ast.Node
  • Loading branch information
goccy committed Sep 7, 2021
2 parents cb71dc9 + 99b4a89 commit e9d5e8f
Show file tree
Hide file tree
Showing 4 changed files with 226 additions and 9 deletions.
49 changes: 49 additions & 0 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ type Node interface {
SetComment(*CommentGroupNode) error
// Comment returns comment token instance
GetComment() *CommentGroupNode
// GetPath returns YAMLPath for the current node
GetPath() string
// SetPath set YAMLPath for the current node
SetPath(string)
// MarshalYAML
MarshalYAML() ([]byte, error)
// already read length
Expand All @@ -198,6 +202,7 @@ type ScalarNode interface {
}

type BaseNode struct {
Path string
Comment *CommentGroupNode
read int
}
Expand All @@ -218,6 +223,22 @@ func (n *BaseNode) addReadLen(len int) {
n.read += len
}

// GetPath returns YAMLPath for the current node.
func (n *BaseNode) GetPath() string {
if n == nil {
return ""
}
return n.Path
}

// SetPath set YAMLPath for the current node.
func (n *BaseNode) SetPath(path string) {
if n == nil {
return
}
n.Path = path
}

// GetComment returns comment token instance
func (n *BaseNode) GetComment() *CommentGroupNode {
return n.Comment
Expand Down Expand Up @@ -1916,42 +1937,70 @@ func Walk(v Visitor, node Node) {
switch n := node.(type) {
case *CommentNode:
case *NullNode:
walkComment(v, n.BaseNode)
case *IntegerNode:
walkComment(v, n.BaseNode)
case *FloatNode:
walkComment(v, n.BaseNode)
case *StringNode:
walkComment(v, n.BaseNode)
case *MergeKeyNode:
walkComment(v, n.BaseNode)
case *BoolNode:
walkComment(v, n.BaseNode)
case *InfinityNode:
walkComment(v, n.BaseNode)
case *NanNode:
walkComment(v, n.BaseNode)
case *LiteralNode:
walkComment(v, n.BaseNode)
Walk(v, n.Value)
case *DirectiveNode:
walkComment(v, n.BaseNode)
Walk(v, n.Value)
case *TagNode:
walkComment(v, n.BaseNode)
Walk(v, n.Value)
case *DocumentNode:
walkComment(v, n.BaseNode)
Walk(v, n.Body)
case *MappingNode:
walkComment(v, n.BaseNode)
for _, value := range n.Values {
Walk(v, value)
}
case *MappingKeyNode:
walkComment(v, n.BaseNode)
Walk(v, n.Value)
case *MappingValueNode:
walkComment(v, n.BaseNode)
Walk(v, n.Key)
Walk(v, n.Value)
case *SequenceNode:
walkComment(v, n.BaseNode)
for _, value := range n.Values {
Walk(v, value)
}
case *AnchorNode:
walkComment(v, n.BaseNode)
Walk(v, n.Name)
Walk(v, n.Value)
case *AliasNode:
walkComment(v, n.BaseNode)
Walk(v, n.Value)
}
}

func walkComment(v Visitor, base *BaseNode) {
if base == nil {
return
}
if base.Comment == nil {
return
}
Walk(v, base.Comment)
}

type filterWalker struct {
typ NodeType
results []Node
Expand Down
60 changes: 59 additions & 1 deletion parser/context.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,64 @@
package parser

import "github.com/goccy/go-yaml/token"
import (
"fmt"
"strings"

"github.com/goccy/go-yaml/token"
)

// context context at parsing
type context struct {
parent *context
idx int
size int
tokens token.Tokens
mode Mode
path string
}

var pathSpecialChars = []string{
"$", "*", ".", "[", "]",
}

func containsPathSpecialChar(path string) bool {
for _, char := range pathSpecialChars {
if strings.Contains(path, char) {
return true
}
}
return false
}

func normalizePath(path string) string {
if containsPathSpecialChar(path) {
return fmt.Sprintf("'%s'", path)
}
return path
}

func (c *context) withChild(path string) *context {
ctx := c.copy()
path = normalizePath(path)
ctx.path += fmt.Sprintf(".%s", path)
return ctx
}

func (c *context) withIndex(idx uint) *context {
ctx := c.copy()
ctx.path += fmt.Sprintf("[%d]", idx)
return ctx
}

func (c *context) copy() *context {
return &context{
parent: c,
idx: c.idx,
size: c.size,
tokens: append(token.Tokens{}, c.tokens...),
mode: c.mode,
path: c.path,
}
}

func (c *context) next() bool {
Expand All @@ -22,6 +73,9 @@ func (c *context) previousToken() *token.Token {
}

func (c *context) insertToken(idx int, tk *token.Token) {
if c.parent != nil {
c.parent.insertToken(idx, tk)
}
if c.size < idx {
return
}
Expand Down Expand Up @@ -104,6 +158,9 @@ func (c *context) isCurrentCommentToken() bool {
}

func (c *context) progressIgnoreComment(num int) {
if c.parent != nil {
c.parent.progressIgnoreComment(num)
}
if c.size <= c.idx+num {
c.idx = c.size
} else {
Expand Down Expand Up @@ -135,5 +192,6 @@ func newContext(tokens token.Tokens, mode Mode) *context {
size: len(filteredTokens),
tokens: filteredTokens,
mode: mode,
path: "$",
}
}

0 comments on commit e9d5e8f

Please sign in to comment.