This commit is contained in:
Mike Farah 2023-04-10 14:13:28 +10:00
parent 4c6c653d25
commit fe8f46d475
8 changed files with 65 additions and 59 deletions

View File

@ -81,8 +81,7 @@ type CandidateNode struct {
LeadingContent string
TrailingContent string
Path []interface{} /// the path we took to get to this node
Document uint // the document index of this node
Document uint // the document index of this node
Filename string
Line int
@ -95,13 +94,13 @@ type CandidateNode struct {
IsMapKey bool
}
func (n *CandidateNode) GetKey() string {
keyPrefix := ""
if n.IsMapKey {
keyPrefix = "key-"
}
return fmt.Sprintf("%v%v - %v", keyPrefix, n.Document, n.Path)
}
// func (n *CandidateNode) GetKey() string {
// keyPrefix := ""
// if n.IsMapKey {
// keyPrefix = "key-"
// }
// return fmt.Sprintf("%v%v - %v", keyPrefix, n.Document, n.Path)
// }
func (n *CandidateNode) unwrapDocument() *CandidateNode {
if n.Kind == DocumentNode {
@ -114,15 +113,47 @@ func (n *CandidateNode) GetNiceTag() string {
return n.unwrapDocument().Tag
}
func (n *CandidateNode) GetNicePath() string {
if n.Path != nil && len(n.Path) >= 0 {
pathStr := make([]string, len(n.Path))
for i, v := range n.Path {
pathStr[i] = fmt.Sprintf("%v", v)
}
return strings.Join(pathStr, ".")
func (n *CandidateNode) getParsedKey() interface{} {
if n.Key == nil {
return nil
}
return ""
if n.Key.Tag == "!!str" {
return n.Key.Value
}
index, err := parseInt(n.Key.Value)
if err != nil {
return n.Key.Value
}
return index
}
func (n *CandidateNode) GetPath() []interface{} {
if n.Parent != nil {
return append(n.Parent.GetPath(), n.getParsedKey())
}
return []interface{}{n.getParsedKey()}
}
func (n *CandidateNode) GetNicePath() string {
var sb strings.Builder
path := n.GetPath()
for i, element := range path {
elementStr := fmt.Sprintf("%v", element)
switch element.(type) {
case int:
sb.WriteString("[" + elementStr + "]")
default:
if i == 0 {
sb.WriteString(elementStr)
} else if strings.ContainsRune(elementStr, '.') {
sb.WriteString("[" + elementStr + "]")
} else {
sb.WriteString("." + elementStr)
}
}
}
return sb.String()
}
func (n *CandidateNode) AsList() *list.List {
@ -178,7 +209,6 @@ func (n *CandidateNode) guessTagFromCustomType() string {
func (n *CandidateNode) CreateReplacement(kind Kind, tag string, value string) *CandidateNode {
return &CandidateNode{
Path: n.createChildPath(nil),
Parent: n.Parent,
Key: n.Key,
IsMapKey: n.IsMapKey,
@ -199,20 +229,6 @@ func (n *CandidateNode) CreateReplacementWithDocWrappers(kind Kind, tag string,
return replacement
}
func (n *CandidateNode) createChildPath(path interface{}) []interface{} {
if path == nil {
newPath := make([]interface{}, len(n.Path))
copy(newPath, n.Path)
return newPath
}
//don't use append as they may actually modify the path of the orignal node!
newPath := make([]interface{}, len(n.Path)+1)
copy(newPath, n.Path)
newPath[len(n.Path)] = path
return newPath
}
func (n *CandidateNode) CopyChildren() []*CandidateNode {
clonedKids := make([]*CandidateNode, len(n.Content))
for i, child := range n.Content {
@ -258,7 +274,6 @@ func (n *CandidateNode) doCopy(cloneContent bool) *CandidateNode {
LeadingContent: n.LeadingContent,
TrailingContent: n.TrailingContent,
Path: n.Path,
Document: n.Document,
Filename: n.Filename,
@ -290,7 +305,7 @@ func (n *CandidateNode) UpdateFrom(other *CandidateNode, prefs assignPreferences
}
func (n *CandidateNode) UpdateAttributesFrom(other *CandidateNode, prefs assignPreferences) {
log.Debug("UpdateAttributesFrom: n: %v other: %v", n.GetKey(), other.GetKey())
log.Debug("UpdateAttributesFrom: n: %v other: %v", n.Key.Value, other.Key.Value)
if n.Kind != other.Kind {
// clear out the contents when switching to a different type
// e.g. map to array

View File

@ -12,7 +12,7 @@ type DataTreeNavigator interface {
// a new context of matching candidates
GetMatchingNodes(context Context, expressionNode *ExpressionNode) (Context, error)
DeeplyAssign(context Context, rhsNode *CandidateNode) error
DeeplyAssign(context Context, path []interface{}, rhsNode *CandidateNode) error
}
type dataTreeNavigator struct {
@ -22,7 +22,7 @@ func NewDataTreeNavigator() DataTreeNavigator {
return &dataTreeNavigator{}
}
func (d *dataTreeNavigator) DeeplyAssign(context Context, rhsCandidateNode *CandidateNode) error {
func (d *dataTreeNavigator) DeeplyAssign(context Context, path []interface{}, rhsCandidateNode *CandidateNode) error {
assignmentOp := &Operation{OperationType: assignOpType, Preferences: assignPreferences{}}
@ -30,7 +30,7 @@ func (d *dataTreeNavigator) DeeplyAssign(context Context, rhsCandidateNode *Cand
assignmentOpNode := &ExpressionNode{
Operation: assignmentOp,
LHS: createTraversalTree(rhsCandidateNode.Path, traversePreferences{}, false),
LHS: createTraversalTree(path, traversePreferences{}, false),
RHS: &ExpressionNode{Operation: rhsOp},
}

View File

@ -51,7 +51,6 @@ func (dec *propertiesDecoder) applyPropertyComments(context Context, path []inte
assignmentOp := &Operation{OperationType: assignOpType, Preferences: assignPreferences{}}
rhsCandidateNode := &CandidateNode{
Path: path,
Tag: "!!str",
Value: fmt.Sprintf("%v", path[len(path)-1]),
HeadComment: dec.processComment(strings.Join(comments, "\n")),
@ -86,9 +85,8 @@ func (dec *propertiesDecoder) applyProperty(context Context, properties *propert
rhsNode := createStringScalarNode(value)
rhsNode.Tag = rhsNode.guessTagFromCustomType()
rhsNode.Path = path
return dec.d.DeeplyAssign(context, rhsNode)
return dec.d.DeeplyAssign(context, path, rhsNode)
}
func (dec *propertiesDecoder) Decode() (*CandidateNode, error) {

View File

@ -62,12 +62,11 @@ func (dec *tomlDecoder) processKeyValueIntoMap(rootMap *CandidateNode, tomlNode
if err != nil {
return err
}
valueNode.Path = path
context := Context{}
context = context.SingleChildContext(rootMap)
return dec.d.DeeplyAssign(context, valueNode)
return dec.d.DeeplyAssign(context, path, valueNode)
}
func (dec *tomlDecoder) decodeKeyValuesIntoMap(rootMap *CandidateNode, tomlNode *toml.Node) (bool, error) {
@ -279,7 +278,6 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
tableNodeValue := &CandidateNode{
Kind: MappingNode,
Tag: "!!map",
Path: fullPath,
}
tableValue := dec.parser.Expression()
@ -296,7 +294,7 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
c := Context{}
c = c.SingleChildContext(dec.rootMap)
err = dec.d.DeeplyAssign(c, tableNodeValue)
err = dec.d.DeeplyAssign(c, fullPath, tableNodeValue)
if err != nil {
return false, err
}
@ -305,7 +303,6 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
func (dec *tomlDecoder) arrayAppend(context Context, path []interface{}, rhsNode *CandidateNode) error {
rhsCandidateNode := &CandidateNode{
Path: path,
Kind: SequenceNode,
Tag: "!!seq",
Content: []*CandidateNode{rhsNode},
@ -341,7 +338,6 @@ func (dec *tomlDecoder) processArrayTable(currentNode *toml.Node) (bool, error)
tableNodeValue := &CandidateNode{
Kind: MappingNode,
Tag: "!!map",
Path: fullPath,
}
tableValue := dec.parser.Expression()

View File

@ -10,8 +10,6 @@ func createMapOperator(d *dataTreeNavigator, context Context, expressionNode *Ex
//each matchingNodes entry should turn into a sequence of keys to create.
//then collect object should do a cross function of the same index sequence for all matches.
var path []interface{}
var document uint
sequences := list.New()
@ -36,19 +34,16 @@ func createMapOperator(d *dataTreeNavigator, context Context, expressionNode *Ex
node := listToNodeSeq(sequences)
node.Document = document
node.Path = path
return context.SingleChildContext(node), nil
}
func sequenceFor(d *dataTreeNavigator, context Context, matchingNode *CandidateNode, expressionNode *ExpressionNode) (*CandidateNode, error) {
var path []interface{}
var document uint
var matches = list.New()
if matchingNode != nil {
path = matchingNode.Path
document = matchingNode.Document
matches.PushBack(matchingNode)
}
@ -63,7 +58,6 @@ func sequenceFor(d *dataTreeNavigator, context Context, matchingNode *CandidateN
rhs.unwrapDocument(),
}
node.Document = document
node.Path = path
return &node, nil
}, false)
@ -74,7 +68,6 @@ func sequenceFor(d *dataTreeNavigator, context Context, matchingNode *CandidateN
innerList := listToNodeSeq(mapPairs.MatchingNodes)
innerList.Style = FlowStyle
innerList.Document = document
innerList.Path = path
return innerList, nil
}

View File

@ -88,8 +88,9 @@ func formatDateTime(d *dataTreeNavigator, context Context, expressionNode *Expre
}
}
node.Document = candidate.Document
node.Parent = candidate.Parent
node.Key = candidate.Key
node.FileIndex = candidate.FileIndex
node.Path = candidate.Path
results.PushBack(node)
}

View File

@ -35,7 +35,8 @@ func deleteChildOperator(d *dataTreeNavigator, context Context, expressionNode *
}
parentNode := candidate.Parent
childPath := candidate.Path[len(candidate.Path)-1]
parentPath := parentNode.GetPath()
childPath := parentPath[len(parentPath)-1]
if parentNode.Kind == MappingNode {
deleteFromMap(candidate.Parent, childPath)
@ -60,7 +61,7 @@ func deleteFromMap(candidate *CandidateNode, childPath interface{}) {
shouldDelete := key.Value == childPath
log.Debugf("shouldDelete %v ? %v", value.GetKey(), shouldDelete)
log.Debugf("shouldDelete %v ? %v", value.ToDebugString(), shouldDelete)
if !shouldDelete {
newContents = append(newContents, key, value)

View File

@ -156,9 +156,11 @@ func getPathOperator(d *dataTreeNavigator, context Context, expressionNode *Expr
candidate := el.Value.(*CandidateNode)
node := candidate.CreateReplacement(SequenceNode, "!!seq", "")
content := make([]*CandidateNode, len(candidate.Path))
for pathIndex := 0; pathIndex < len(candidate.Path); pathIndex++ {
path := candidate.Path[pathIndex]
path := candidate.GetPath()
content := make([]*CandidateNode, len(path))
for pathIndex := 0; pathIndex < len(path); pathIndex++ {
path := path[pathIndex]
content[pathIndex] = createPathNodeFor(path)
}
node.Content = content