Removed unwrap doc

This commit is contained in:
Mike Farah 2023-06-07 10:45:42 -07:00
parent db8dddd2a9
commit 37489aef14
40 changed files with 3230 additions and 202 deletions

View File

@ -137,17 +137,6 @@ func (n *CandidateNode) GetKey() string {
return fmt.Sprintf("%v%v - %v", keyPrefix, n.GetDocument(), key) return fmt.Sprintf("%v%v - %v", keyPrefix, n.GetDocument(), key)
} }
func (n *CandidateNode) unwrapDocument() *CandidateNode {
// if n.Kind == DocumentNode {
// return n.Content[0]
// }
return n
}
func (n *CandidateNode) GetNiceTag() string {
return n.unwrapDocument().Tag
}
func (n *CandidateNode) getParsedKey() interface{} { func (n *CandidateNode) getParsedKey() interface{} {
if n.IsMapKey { if n.IsMapKey {
return n.Value return n.Value
@ -210,11 +199,11 @@ func (n *CandidateNode) SetParent(parent *CandidateNode) {
} }
func (n *CandidateNode) AddKeyValueChild(rawKey *CandidateNode, rawValue *CandidateNode) (*CandidateNode, *CandidateNode) { func (n *CandidateNode) AddKeyValueChild(rawKey *CandidateNode, rawValue *CandidateNode) (*CandidateNode, *CandidateNode) {
key := rawKey.unwrapDocument().Copy() key := rawKey.Copy()
key.SetParent(n) key.SetParent(n)
key.IsMapKey = true key.IsMapKey = true
value := rawValue.unwrapDocument().Copy() value := rawValue.Copy()
value.SetParent(n) value.SetParent(n)
value.Key = key value.Key = key
@ -223,7 +212,7 @@ func (n *CandidateNode) AddKeyValueChild(rawKey *CandidateNode, rawValue *Candid
} }
func (n *CandidateNode) AddChild(rawChild *CandidateNode) { func (n *CandidateNode) AddChild(rawChild *CandidateNode) {
value := rawChild.unwrapDocument().Copy() value := rawChild.Copy()
value.SetParent(n) value.SetParent(n)
if value.Key != nil { if value.Key != nil {
value.Key.SetParent(n) value.Key.SetParent(n)
@ -284,7 +273,7 @@ func (n *CandidateNode) guessTagFromCustomType() string {
log.Debug("guessTagFromCustomType: could not guess underlying tag type %v", errorReading) log.Debug("guessTagFromCustomType: could not guess underlying tag type %v", errorReading)
return n.Tag return n.Tag
} }
guessedTag := dataBucket.unwrapDocument().Tag guessedTag := dataBucket.Tag
log.Info("im guessing the tag %v is a %v", n.Tag, guessedTag) log.Info("im guessing the tag %v is a %v", n.Tag, guessedTag)
return guessedTag return guessedTag
} }

3111
pkg/yqlib/cover.out Normal file

File diff suppressed because it is too large Load Diff

View File

@ -26,11 +26,10 @@ func (e *base64Encoder) PrintLeadingContent(writer io.Writer, content string) er
return nil return nil
} }
func (e *base64Encoder) Encode(writer io.Writer, originalNode *CandidateNode) error { func (e *base64Encoder) Encode(writer io.Writer, node *CandidateNode) error {
node := originalNode.unwrapDocument()
if node.guessTagFromCustomType() != "!!str" { if node.guessTagFromCustomType() != "!!str" {
return fmt.Errorf("cannot encode %v as base64, can only operate on strings. Please first pipe through another encoding operator to convert the value to a string", node.Tag) return fmt.Errorf("cannot encode %v as base64, can only operate on strings. Please first pipe through another encoding operator to convert the value to a string", node.Tag)
} }
_, err := writer.Write([]byte(e.encoding.EncodeToString([]byte(originalNode.Value)))) _, err := writer.Write([]byte(e.encoding.EncodeToString([]byte(node.Value))))
return err return err
} }

View File

@ -100,16 +100,15 @@ func (e *csvEncoder) encodeObjects(csvWriter *csv.Writer, content []*CandidateNo
return nil return nil
} }
func (e *csvEncoder) Encode(writer io.Writer, originalNode *CandidateNode) error { func (e *csvEncoder) Encode(writer io.Writer, node *CandidateNode) error {
if originalNode.Kind == ScalarNode { if node.Kind == ScalarNode {
return writeString(writer, originalNode.Value+"\n") return writeString(writer, node.Value+"\n")
} }
csvWriter := csv.NewWriter(writer) csvWriter := csv.NewWriter(writer)
csvWriter.Comma = e.separator csvWriter.Comma = e.separator
// node must be a sequence // node must be a sequence
node := originalNode.unwrapDocument()
if node.Kind != SequenceNode { if node.Kind != SequenceNode {
return fmt.Errorf("csv encoding only works for arrays, got: %v", node.Tag) return fmt.Errorf("csv encoding only works for arrays, got: %v", node.Tag)
} else if len(node.Content) == 0 { } else if len(node.Content) == 0 {

View File

@ -29,13 +29,12 @@ func (e *shEncoder) PrintLeadingContent(writer io.Writer, content string) error
return nil return nil
} }
func (e *shEncoder) Encode(writer io.Writer, originalNode *CandidateNode) error { func (e *shEncoder) Encode(writer io.Writer, node *CandidateNode) error {
node := originalNode.unwrapDocument()
if node.guessTagFromCustomType() != "!!str" { if node.guessTagFromCustomType() != "!!str" {
return fmt.Errorf("cannot encode %v as URI, can only operate on strings. Please first pipe through another encoding operator to convert the value to a string", node.Tag) return fmt.Errorf("cannot encode %v as URI, can only operate on strings. Please first pipe through another encoding operator to convert the value to a string", node.Tag)
} }
return writeString(writer, e.encode(originalNode.Value)) return writeString(writer, e.encode(node.Value))
} }
// put any (shell-unsafe) characters into a single-quoted block, close the block lazily // put any (shell-unsafe) characters into a single-quoted block, close the block lazily

View File

@ -25,11 +25,10 @@ func (e *uriEncoder) PrintLeadingContent(writer io.Writer, content string) error
return nil return nil
} }
func (e *uriEncoder) Encode(writer io.Writer, originalNode *CandidateNode) error { func (e *uriEncoder) Encode(writer io.Writer, node *CandidateNode) error {
node := originalNode.unwrapDocument()
if node.guessTagFromCustomType() != "!!str" { if node.guessTagFromCustomType() != "!!str" {
return fmt.Errorf("cannot encode %v as URI, can only operate on strings. Please first pipe through another encoding operator to convert the value to a string", node.Tag) return fmt.Errorf("cannot encode %v as URI, can only operate on strings. Please first pipe through another encoding operator to convert the value to a string", node.Tag)
} }
_, err := writer.Write([]byte(url.QueryEscape(originalNode.Value))) _, err := writer.Write([]byte(url.QueryEscape(node.Value)))
return err return err
} }

View File

@ -46,12 +46,11 @@ func (e *xmlEncoder) Encode(writer io.Writer, node *CandidateNode) error {
encoder.Indent("", e.indentString) encoder.Indent("", e.indentString)
var newLine xml.CharData = []byte("\n") var newLine xml.CharData = []byte("\n")
mapNode := node.unwrapDocument() if node.Tag == "!!map" {
if mapNode.Tag == "!!map" {
// make sure <?xml .. ?> processing instructions are encoded first // make sure <?xml .. ?> processing instructions are encoded first
for i := 0; i < len(mapNode.Content); i += 2 { for i := 0; i < len(node.Content); i += 2 {
key := mapNode.Content[i] key := node.Content[i]
value := mapNode.Content[i+1] value := node.Content[i+1]
if key.Value == (e.prefs.ProcInstPrefix + "xml") { if key.Value == (e.prefs.ProcInstPrefix + "xml") {
name := strings.Replace(key.Value, e.prefs.ProcInstPrefix, "", 1) name := strings.Replace(key.Value, e.prefs.ProcInstPrefix, "", 1)

View File

@ -250,11 +250,10 @@ func parseSnippet(value string) (*CandidateNode, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
parsedNode, err := decoder.Decode() result, err := decoder.Decode()
if err != nil { if err != nil {
return nil, err return nil, err
} }
result := parsedNode.unwrapDocument()
result.Line = 0 result.Line = 0
result.Column = 0 result.Column = 0
return result, err return result, err

View File

@ -43,9 +43,6 @@ func addOperator(d *dataTreeNavigator, context Context, expressionNode *Expressi
} }
func add(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) { func add(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
lhs = lhs.unwrapDocument()
rhs = rhs.unwrapDocument()
lhsNode := lhs lhsNode := lhs
if lhsNode.Tag == "!!null" { if lhsNode.Tag == "!!null" {

View File

@ -9,7 +9,7 @@ type assignPreferences struct {
func assignUpdateFunc(prefs assignPreferences) crossFunctionCalculation { func assignUpdateFunc(prefs assignPreferences) crossFunctionCalculation {
return func(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) { return func(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
if !prefs.OnlyWriteNull || lhs.Tag == "!!null" { if !prefs.OnlyWriteNull || lhs.Tag == "!!null" {
lhs.UpdateFrom(rhs.unwrapDocument(), prefs) lhs.UpdateFrom(rhs, prefs)
} }
return lhs, nil return lhs, nil
} }
@ -59,7 +59,7 @@ func assignUpdateOperator(d *dataTreeNavigator, context Context, expressionNode
if first != nil { if first != nil {
rhsCandidate := first.Value.(*CandidateNode) rhsCandidate := first.Value.(*CandidateNode)
candidate.UpdateFrom(rhsCandidate.unwrapDocument(), prefs) candidate.UpdateFrom(rhsCandidate, prefs)
} }
} }

View File

@ -6,11 +6,10 @@ import (
"strings" "strings"
) )
func isTruthyNode(candidate *CandidateNode) bool { func isTruthyNode(node *CandidateNode) bool {
if candidate == nil { if node == nil {
return false return false
} }
node := candidate.unwrapDocument()
if node.Tag == "!!null" { if node.Tag == "!!null" {
return false return false
} }
@ -88,11 +87,10 @@ func allOperator(d *dataTreeNavigator, context Context, expressionNode *Expressi
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
candidateNode := candidate.unwrapDocument() if candidate.Kind != SequenceNode {
if candidateNode.Kind != SequenceNode { return Context{}, fmt.Errorf("any only supports arrays, was %v", candidate.Tag)
return Context{}, fmt.Errorf("any only supports arrays, was %v", candidateNode.Tag)
} }
booleanResult, err := findBoolean(false, d, context, expressionNode.RHS, candidateNode) booleanResult, err := findBoolean(false, d, context, expressionNode.RHS, candidate)
if err != nil { if err != nil {
return Context{}, err return Context{}, err
} }
@ -107,11 +105,10 @@ func anyOperator(d *dataTreeNavigator, context Context, expressionNode *Expressi
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
candidateNode := candidate.unwrapDocument() if candidate.Kind != SequenceNode {
if candidateNode.Kind != SequenceNode { return Context{}, fmt.Errorf("any only supports arrays, was %v", candidate.Tag)
return Context{}, fmt.Errorf("any only supports arrays, was %v", candidateNode.Tag)
} }
booleanResult, err := findBoolean(true, d, context, expressionNode.RHS, candidateNode) booleanResult, err := findBoolean(true, d, context, expressionNode.RHS, candidate)
if err != nil { if err != nil {
return Context{}, err return Context{}, err
} }

View File

@ -30,20 +30,17 @@ func compare(prefs compareTypePref) func(d *dataTreeNavigator, context Context,
return createBooleanCandidate(lhs, false), nil return createBooleanCandidate(lhs, false), nil
} }
lhsU := lhs.unwrapDocument() switch lhs.Kind {
rhsU := rhs.unwrapDocument()
switch lhsU.Kind {
case MappingNode: case MappingNode:
return nil, fmt.Errorf("maps not yet supported for comparison") return nil, fmt.Errorf("maps not yet supported for comparison")
case SequenceNode: case SequenceNode:
return nil, fmt.Errorf("arrays not yet supported for comparison") return nil, fmt.Errorf("arrays not yet supported for comparison")
default: default:
if rhsU.Kind != ScalarNode { if rhs.Kind != ScalarNode {
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhsU.Tag, rhs.GetNicePath(), lhsU.Tag) return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Tag, rhs.GetNicePath(), lhs.Tag)
} }
target := lhs.CopyWithoutContent() target := lhs.CopyWithoutContent()
boolV, err := compareScalars(context, prefs, lhsU, rhsU) boolV, err := compareScalars(context, prefs, lhs, rhs)
return createBooleanCandidate(target, boolV), err return createBooleanCandidate(target, boolV), err
} }

View File

@ -92,10 +92,7 @@ func contains(lhs *CandidateNode, rhs *CandidateNode) (bool, error) {
return false, fmt.Errorf("%v not yet supported for contains", lhs.Tag) return false, fmt.Errorf("%v not yet supported for contains", lhs.Tag)
} }
func containsWithNodes(d *dataTreeNavigator, context Context, lhsW *CandidateNode, rhsW *CandidateNode) (*CandidateNode, error) { func containsWithNodes(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
lhs := lhsW.unwrapDocument()
rhs := rhsW.unwrapDocument()
if lhs.Kind != rhs.Kind { if lhs.Kind != rhs.Kind {
return nil, fmt.Errorf("%v cannot check contained in %v", rhs.Tag, lhs.Tag) return nil, fmt.Errorf("%v cannot check contained in %v", rhs.Tag, lhs.Tag)
} }

View File

@ -50,9 +50,8 @@ func removeFromContext(context Context, candidate *CandidateNode) (Context, erro
return context.ChildContext(newResults), nil return context.ChildContext(newResults), nil
} }
func deleteFromMap(candidate *CandidateNode, childPath interface{}) { func deleteFromMap(node *CandidateNode, childPath interface{}) {
log.Debug("deleteFromMap") log.Debug("deleteFromMap")
node := candidate.unwrapDocument()
contents := node.Content contents := node.Content
newContents := make([]*CandidateNode, 0) newContents := make([]*CandidateNode, 0)
@ -71,9 +70,8 @@ func deleteFromMap(candidate *CandidateNode, childPath interface{}) {
node.Content = newContents node.Content = newContents
} }
func deleteFromArray(candidate *CandidateNode, childPath interface{}) { func deleteFromArray(node *CandidateNode, childPath interface{}) {
log.Debug("deleteFromArray") log.Debug("deleteFromArray")
node := candidate.unwrapDocument()
contents := node.Content contents := node.Content
newContents := make([]*CandidateNode, 0) newContents := make([]*CandidateNode, 0)

View File

@ -12,10 +12,7 @@ func divideOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
return crossFunction(d, context.ReadOnlyClone(), expressionNode, divide, false) return crossFunction(d, context.ReadOnlyClone(), expressionNode, divide, false)
} }
func divide(d *dataTreeNavigator, context Context, lhsW *CandidateNode, rhsW *CandidateNode) (*CandidateNode, error) { func divide(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
lhs := lhsW.unwrapDocument()
rhs := rhsW.unwrapDocument()
if lhs.Tag == "!!null" { if lhs.Tag == "!!null" {
return nil, fmt.Errorf("%v (%v) cannot be divided by %v (%v)", lhs.Tag, lhs.GetNicePath(), rhs.Tag, rhs.GetNicePath()) return nil, fmt.Errorf("%v (%v) cannot be divided by %v (%v)", lhs.Tag, lhs.GetNicePath(), rhs.Tag, rhs.GetNicePath())
} }

View File

@ -76,9 +76,8 @@ func encodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
if originalList != nil && originalList.Len() > 0 && hasOnlyOneNewLine.MatchString(stringValue) { if originalList != nil && originalList.Len() > 0 && hasOnlyOneNewLine.MatchString(stringValue) {
original := originalList.Front().Value.(*CandidateNode) original := originalList.Front().Value.(*CandidateNode)
originalNode := original.unwrapDocument()
// original block did not have a newline at the end, get rid of this one too // original block did not have a newline at the end, get rid of this one too
if !endWithNewLine.MatchString(originalNode.Value) { if !endWithNewLine.MatchString(original.Value) {
stringValue = chomper.ReplaceAllString(stringValue, "") stringValue = chomper.ReplaceAllString(stringValue, "")
} }
} }
@ -140,17 +139,15 @@ func decodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
log.Debugf("got: [%v]", candidate.Value) log.Debugf("got: [%v]", candidate.Value)
err := decoder.Init(strings.NewReader(candidate.unwrapDocument().Value)) err := decoder.Init(strings.NewReader(candidate.Value))
if err != nil { if err != nil {
return Context{}, err return Context{}, err
} }
decodedNode, errorReading := decoder.Decode() node, errorReading := decoder.Decode()
if errorReading != nil { if errorReading != nil {
return Context{}, errorReading return Context{}, errorReading
} }
//first node is a doc
node := decodedNode.unwrapDocument()
node.Key = candidate.Key node.Key = candidate.Key
node.Parent = candidate.Parent node.Parent = candidate.Parent

View File

@ -19,7 +19,7 @@ func entrySeqFor(key *CandidateNode, value *CandidateNode) *CandidateNode {
func toEntriesFromMap(candidateNode *CandidateNode) *CandidateNode { func toEntriesFromMap(candidateNode *CandidateNode) *CandidateNode {
var sequence = candidateNode.CreateReplacementWithComments(SequenceNode, "!!seq", 0) var sequence = candidateNode.CreateReplacementWithComments(SequenceNode, "!!seq", 0)
var contents = candidateNode.unwrapDocument().Content var contents = candidateNode.Content
for index := 0; index < len(contents); index = index + 2 { for index := 0; index < len(contents); index = index + 2 {
key := contents[index] key := contents[index]
value := contents[index+1] value := contents[index+1]
@ -32,7 +32,7 @@ func toEntriesFromMap(candidateNode *CandidateNode) *CandidateNode {
func toEntriesfromSeq(candidateNode *CandidateNode) *CandidateNode { func toEntriesfromSeq(candidateNode *CandidateNode) *CandidateNode {
var sequence = candidateNode.CreateReplacementWithComments(SequenceNode, "!!seq", 0) var sequence = candidateNode.CreateReplacementWithComments(SequenceNode, "!!seq", 0)
var contents = candidateNode.unwrapDocument().Content var contents = candidateNode.Content
for index := 0; index < len(contents); index = index + 1 { for index := 0; index < len(contents); index = index + 1 {
key := &CandidateNode{Kind: ScalarNode, Tag: "!!int", Value: fmt.Sprintf("%v", index)} key := &CandidateNode{Kind: ScalarNode, Tag: "!!int", Value: fmt.Sprintf("%v", index)}
value := contents[index] value := contents[index]
@ -46,16 +46,15 @@ func toEntriesOperator(d *dataTreeNavigator, context Context, expressionNode *Ex
var results = list.New() var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
candidateNode := candidate.unwrapDocument()
switch candidateNode.Kind { switch candidate.Kind {
case MappingNode: case MappingNode:
results.PushBack(toEntriesFromMap(candidate)) results.PushBack(toEntriesFromMap(candidate))
case SequenceNode: case SequenceNode:
results.PushBack(toEntriesfromSeq(candidate)) results.PushBack(toEntriesfromSeq(candidate))
default: default:
if candidateNode.Tag != "!!null" { if candidate.Tag != "!!null" {
return Context{}, fmt.Errorf("%v has no keys", candidate.Tag) return Context{}, fmt.Errorf("%v has no keys", candidate.Tag)
} }
} }
@ -88,9 +87,9 @@ func parseEntry(candidateNode *CandidateNode, position int) (*CandidateNode, *Ca
} }
func fromEntries(candidateNode *CandidateNode) (*CandidateNode, error) { func fromEntries(candidateNode *CandidateNode) (*CandidateNode, error) {
var node = candidateNode.unwrapDocument().CopyWithoutContent() var node = candidateNode.CopyWithoutContent()
var contents = candidateNode.unwrapDocument().Content var contents = candidateNode.Content
for index := 0; index < len(contents); index = index + 1 { for index := 0; index < len(contents); index = index + 1 {
key, value, err := parseEntry(contents[index], index) key, value, err := parseEntry(contents[index], index)
@ -109,9 +108,8 @@ func fromEntriesOperator(d *dataTreeNavigator, context Context, expressionNode *
var results = list.New() var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
candidateNode := candidate.unwrapDocument()
switch candidateNode.Kind { switch candidate.Kind {
case SequenceNode: case SequenceNode:
mapResult, err := fromEntries(candidate) mapResult, err := fromEntries(candidate)
if err != nil { if err != nil {

View File

@ -38,12 +38,12 @@ func envOperator(d *dataTreeNavigator, context Context, expressionNode *Expressi
if err := decoder.Init(strings.NewReader(rawValue)); err != nil { if err := decoder.Init(strings.NewReader(rawValue)); err != nil {
return Context{}, err return Context{}, err
} }
result, err := decoder.Decode() var err error
node, err = decoder.Decode()
if err != nil { if err != nil {
return Context{}, err return Context{}, err
} }
node = result.unwrapDocument()
} }
log.Debug("ENV tag", node.Tag) log.Debug("ENV tag", node.Tag)
@ -70,8 +70,7 @@ func envsubstOperator(d *dataTreeNavigator, context Context, expressionNode *Exp
} }
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) node := el.Value.(*CandidateNode)
node := candidate.unwrapDocument()
if node.Tag != "!!str" { if node.Tag != "!!str" {
log.Warning("EnvSubstOperator, env name:", node.Tag, node.Value) log.Warning("EnvSubstOperator, env name:", node.Tag, node.Value)
return Context{}, fmt.Errorf("cannot substitute with %v, can only substitute strings. Hint: Most often you'll want to use '|=' over '=' for this operation", node.Tag) return Context{}, fmt.Errorf("cannot substitute with %v, can only substitute strings. Hint: Most often you'll want to use '|=' over '=' for this operation", node.Tag)
@ -81,7 +80,7 @@ func envsubstOperator(d *dataTreeNavigator, context Context, expressionNode *Exp
if err != nil { if err != nil {
return Context{}, err return Context{}, err
} }
result := candidate.CreateReplacement(ScalarNode, "!!str", value) result := node.CreateReplacement(ScalarNode, "!!str", value)
results.PushBack(result) results.PushBack(result)
} }

View File

@ -15,29 +15,24 @@ func isEquals(flip bool) func(d *dataTreeNavigator, context Context, lhs *Candid
return createBooleanCandidate(owner, !flip), nil return createBooleanCandidate(owner, !flip), nil
} else if lhs == nil { } else if lhs == nil {
log.Debugf("lhs nil, but rhs is not") log.Debugf("lhs nil, but rhs is not")
rhsNode := rhs.unwrapDocument() value := rhs.Tag == "!!null"
value := rhsNode.Tag == "!!null"
if flip { if flip {
value = !value value = !value
} }
return createBooleanCandidate(rhs, value), nil return createBooleanCandidate(rhs, value), nil
} else if rhs == nil { } else if rhs == nil {
log.Debugf("lhs not nil, but rhs is") log.Debugf("lhs not nil, but rhs is")
lhsNode := lhs.unwrapDocument() value := lhs.Tag == "!!null"
value := lhsNode.Tag == "!!null"
if flip { if flip {
value = !value value = !value
} }
return createBooleanCandidate(lhs, value), nil return createBooleanCandidate(lhs, value), nil
} }
lhsNode := lhs.unwrapDocument() if lhs.Tag == "!!null" {
rhsNode := rhs.unwrapDocument() value = (rhs.Tag == "!!null")
} else if lhs.Kind == ScalarNode && rhs.Kind == ScalarNode {
if lhsNode.Tag == "!!null" { value = matchKey(lhs.Value, rhs.Value)
value = (rhsNode.Tag == "!!null")
} else if lhsNode.Kind == ScalarNode && rhsNode.Kind == ScalarNode {
value = matchKey(lhsNode.Value, rhsNode.Value)
} }
log.Debugf("%v == %v ? %v", NodeToString(lhs), NodeToString(rhs), value) log.Debugf("%v == %v ? %v", NodeToString(lhs), NodeToString(rhs), value)
if flip { if flip {

View File

@ -25,7 +25,7 @@ func filterOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
if err != nil { if err != nil {
return Context{}, err return Context{}, err
} }
collected.Style = candidate.unwrapDocument().Style collected.Style = candidate.Style
results.PushBack(collected) results.PushBack(collected)
} }
return context.ChildContext(results), nil return context.ChildContext(results), nil

View File

@ -39,12 +39,11 @@ func flattenOp(d *dataTreeNavigator, context Context, expressionNode *Expression
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
candidateNode := candidate.unwrapDocument() if candidate.Kind != SequenceNode {
if candidateNode.Kind != SequenceNode {
return Context{}, fmt.Errorf("only arrays are supported for flatten") return Context{}, fmt.Errorf("only arrays are supported for flatten")
} }
flatten(candidateNode, depth) flatten(candidate, depth)
} }

View File

@ -42,13 +42,12 @@ func groupBy(d *dataTreeNavigator, context Context, expressionNode *ExpressionNo
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
candidateNode := candidate.unwrapDocument()
if candidateNode.Kind != SequenceNode { if candidate.Kind != SequenceNode {
return Context{}, fmt.Errorf("only arrays are supported for group by") return Context{}, fmt.Errorf("only arrays are supported for group by")
} }
newMatches, err := processIntoGroups(d, context, expressionNode.RHS, candidateNode) newMatches, err := processIntoGroups(d, context, expressionNode.RHS, candidate)
if err != nil { if err != nil {
return Context{}, err return Context{}, err

View File

@ -26,10 +26,8 @@ func hasOperator(d *dataTreeNavigator, context Context, expressionNode *Expressi
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
// grab the first value var contents = candidate.Content
candidateNode := candidate.unwrapDocument() switch candidate.Kind {
var contents = candidateNode.Content
switch candidateNode.Kind {
case MappingNode: case MappingNode:
candidateHasKey := false candidateHasKey := false
for index := 0; index < len(contents) && !candidateHasKey; index = index + 2 { for index := 0; index < len(contents) && !candidateHasKey; index = index + 2 {

View File

@ -42,7 +42,7 @@ func keysOperator(d *dataTreeNavigator, context Context, expressionNode *Express
var results = list.New() var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode).unwrapDocument() candidate := el.Value.(*CandidateNode)
var targetNode *CandidateNode var targetNode *CandidateNode
if candidate.Kind == MappingNode { if candidate.Kind == MappingNode {

View File

@ -11,19 +11,18 @@ func lengthOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
targetNode := candidate.unwrapDocument()
var length int var length int
switch targetNode.Kind { switch candidate.Kind {
case ScalarNode: case ScalarNode:
if targetNode.Tag == "!!null" { if candidate.Tag == "!!null" {
length = 0 length = 0
} else { } else {
length = len(targetNode.Value) length = len(candidate.Value)
} }
case MappingNode: case MappingNode:
length = len(targetNode.Content) / 2 length = len(candidate.Content) / 2
case SequenceNode: case SequenceNode:
length = len(targetNode.Content) length = len(candidate.Content)
default: default:
length = 0 length = 0
} }

View File

@ -57,7 +57,7 @@ func loadYaml(filename string, decoder Decoder) (*CandidateNode, error) {
} else { } else {
sequenceNode := &CandidateNode{Kind: SequenceNode} sequenceNode := &CandidateNode{Kind: SequenceNode}
for doc := documents.Front(); doc != nil; doc = doc.Next() { for doc := documents.Front(); doc != nil; doc = doc.Next() {
sequenceNode.AddChild(doc.Value.(*CandidateNode).unwrapDocument()) sequenceNode.AddChild(doc.Value.(*CandidateNode))
} }
return sequenceNode, nil return sequenceNode, nil
} }

View File

@ -54,7 +54,7 @@ func mapOperator(d *dataTreeNavigator, context Context, expressionNode *Expressi
if err != nil { if err != nil {
return Context{}, err return Context{}, err
} }
collected.Style = candidate.unwrapDocument().Style collected.Style = candidate.Style
results.PushBack(collected) results.PushBack(collected)

View File

@ -13,10 +13,7 @@ func moduloOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
return crossFunction(d, context.ReadOnlyClone(), expressionNode, modulo, false) return crossFunction(d, context.ReadOnlyClone(), expressionNode, modulo, false)
} }
func modulo(d *dataTreeNavigator, context Context, lhsW *CandidateNode, rhsW *CandidateNode) (*CandidateNode, error) { func modulo(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
lhs := lhsW.unwrapDocument()
rhs := rhsW.unwrapDocument()
if lhs.Tag == "!!null" { if lhs.Tag == "!!null" {
return nil, fmt.Errorf("%v (%v) cannot modulo by %v (%v)", lhs.Tag, lhs.GetNicePath(), rhs.Tag, rhs.GetNicePath()) return nil, fmt.Errorf("%v (%v) cannot modulo by %v (%v)", lhs.Tag, lhs.GetNicePath(), rhs.Tag, rhs.GetNicePath())
} }

View File

@ -53,8 +53,6 @@ func multiply(preferences multiplyPreferences) func(d *dataTreeNavigator, contex
return func(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) { return func(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
// need to do this before unWrapping the potential document node // need to do this before unWrapping the potential document node
leadingContent, headComment, footComment := getComments(lhs, rhs) leadingContent, headComment, footComment := getComments(lhs, rhs)
lhs = lhs.unwrapDocument()
rhs = rhs.unwrapDocument()
log.Debugf("Multiplying LHS: %v", NodeToString(lhs)) log.Debugf("Multiplying LHS: %v", NodeToString(lhs))
log.Debugf("- RHS: %v", NodeToString(rhs)) log.Debugf("- RHS: %v", NodeToString(rhs))

View File

@ -61,8 +61,7 @@ func pickOperator(d *dataTreeNavigator, context Context, expressionNode *Express
var results = list.New() var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) node := el.Value.(*CandidateNode)
node := candidate.unwrapDocument()
var replacement *CandidateNode var replacement *CandidateNode
if node.Kind == MappingNode { if node.Kind == MappingNode {
@ -74,10 +73,10 @@ func pickOperator(d *dataTreeNavigator, context Context, expressionNode *Express
} }
} else { } else {
return Context{}, fmt.Errorf("cannot pick indicies from type %v (%v)", node.Tag, candidate.GetNicePath()) return Context{}, fmt.Errorf("cannot pick indices from type %v (%v)", node.Tag, node.GetNicePath())
} }
replacement.LeadingContent = candidate.LeadingContent replacement.LeadingContent = node.LeadingContent
results.PushBack(replacement) results.PushBack(replacement)
} }

View File

@ -11,17 +11,15 @@ func reverseOperator(d *dataTreeNavigator, context Context, expressionNode *Expr
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
candidateNode := candidate.unwrapDocument() if candidate.Kind != SequenceNode {
return context, fmt.Errorf("node at path [%v] is not an array (it's a %v)", candidate.GetNicePath(), candidate.Tag)
if candidateNode.Kind != SequenceNode {
return context, fmt.Errorf("node at path [%v] is not an array (it's a %v)", candidate.GetNicePath(), candidate.GetNiceTag())
} }
reverseList := candidate.CreateReplacementWithComments(SequenceNode, "!!seq", candidateNode.Style) reverseList := candidate.CreateReplacementWithComments(SequenceNode, "!!seq", candidate.Style)
reverseContent := make([]*CandidateNode, len(candidateNode.Content)) reverseContent := make([]*CandidateNode, len(candidate.Content))
for i, originalNode := range candidateNode.Content { for i, originalNode := range candidate.Content {
reverseContent[len(candidateNode.Content)-i-1] = originalNode reverseContent[len(candidate.Content)-i-1] = originalNode
} }
reverseList.AddChildren(reverseContent) reverseList.AddChildren(reverseContent)
results.PushBack(reverseList) results.PushBack(reverseList)

View File

@ -18,13 +18,11 @@ func shuffleOperator(d *dataTreeNavigator, context Context, expressionNode *Expr
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
candidateNode := candidate.unwrapDocument() if candidate.Kind != SequenceNode {
return context, fmt.Errorf("node at path [%v] is not an array (it's a %v)", candidate.GetNicePath(), candidate.Tag)
if candidateNode.Kind != SequenceNode {
return context, fmt.Errorf("node at path [%v] is not an array (it's a %v)", candidate.GetNicePath(), candidate.GetNiceTag())
} }
result := candidateNode.Copy() result := candidate.Copy()
a := result.Content a := result.Content

View File

@ -25,7 +25,7 @@ func sliceArrayOperator(d *dataTreeNavigator, context Context, expressionNode *E
results := list.New() results := list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
lhsNode := el.Value.(*CandidateNode).unwrapDocument() lhsNode := el.Value.(*CandidateNode)
firstNumber, err := getSliceNumber(d, context, lhsNode, expressionNode.LHS) firstNumber, err := getSliceNumber(d, context, lhsNode, expressionNode.LHS)

View File

@ -24,15 +24,13 @@ func sortByOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
candidateNode := candidate.unwrapDocument() if candidate.Kind != SequenceNode {
return context, fmt.Errorf("node at path [%v] is not an array (it's a %v)", candidate.GetNicePath(), candidate.Tag)
if candidateNode.Kind != SequenceNode {
return context, fmt.Errorf("node at path [%v] is not an array (it's a %v)", candidate.GetNicePath(), candidate.GetNiceTag())
} }
sortableArray := make(sortableNodeArray, len(candidateNode.Content)) sortableArray := make(sortableNodeArray, len(candidate.Content))
for i, originalNode := range candidateNode.Content { for i, originalNode := range candidate.Content {
compareContext, err := d.GetMatchingNodes(context.SingleReadonlyChildContext(originalNode), expressionNode.RHS) compareContext, err := d.GetMatchingNodes(context.SingleReadonlyChildContext(originalNode), expressionNode.RHS)
if err != nil { if err != nil {
@ -45,7 +43,7 @@ func sortByOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
sort.Stable(sortableArray) sort.Stable(sortableArray)
sortedList := candidate.CreateReplacementWithComments(SequenceNode, "!!seq", candidateNode.Style) sortedList := candidate.CreateReplacementWithComments(SequenceNode, "!!seq", candidate.Style)
for _, sortedNode := range sortableArray { for _, sortedNode := range sortableArray {
sortedList.AddChild(sortedNode.Node) sortedList.AddChild(sortedNode.Node)

View File

@ -14,7 +14,7 @@ func sortKeysOperator(d *dataTreeNavigator, context Context, expressionNode *Exp
} }
for childEl := rhs.MatchingNodes.Front(); childEl != nil; childEl = childEl.Next() { for childEl := rhs.MatchingNodes.Front(); childEl != nil; childEl = childEl.Next() {
node := childEl.Value.(*CandidateNode).unwrapDocument() node := childEl.Value.(*CandidateNode)
if node.Kind == MappingNode { if node.Kind == MappingNode {
sortKeys(node) sortKeys(node)
} }

View File

@ -14,15 +14,13 @@ type changeCasePrefs struct {
func trimSpaceOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) { func trimSpaceOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
results := list.New() results := list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) node := el.Value.(*CandidateNode)
node := candidate.unwrapDocument()
if node.guessTagFromCustomType() != "!!str" { if node.guessTagFromCustomType() != "!!str" {
return Context{}, fmt.Errorf("cannot trim %v, can only operate on strings. ", node.Tag) return Context{}, fmt.Errorf("cannot trim %v, can only operate on strings. ", node.Tag)
} }
newStringNode := candidate.CreateReplacement(ScalarNode, node.Tag, strings.TrimSpace(node.Value)) newStringNode := node.CreateReplacement(ScalarNode, node.Tag, strings.TrimSpace(node.Value))
newStringNode.Style = node.Style newStringNode.Style = node.Style
results.PushBack(newStringNode) results.PushBack(newStringNode)
@ -36,9 +34,7 @@ func changeCaseOperator(d *dataTreeNavigator, context Context, expressionNode *E
prefs := expressionNode.Operation.Preferences.(changeCasePrefs) prefs := expressionNode.Operation.Preferences.(changeCasePrefs)
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) node := el.Value.(*CandidateNode)
node := candidate.unwrapDocument()
if node.guessTagFromCustomType() != "!!str" { if node.guessTagFromCustomType() != "!!str" {
return Context{}, fmt.Errorf("cannot change case with %v, can only operate on strings. ", node.Tag) return Context{}, fmt.Errorf("cannot change case with %v, can only operate on strings. ", node.Tag)
@ -50,7 +46,7 @@ func changeCaseOperator(d *dataTreeNavigator, context Context, expressionNode *E
} else { } else {
value = strings.ToLower(node.Value) value = strings.ToLower(node.Value)
} }
newStringNode := candidate.CreateReplacement(ScalarNode, node.Tag, value) newStringNode := node.CreateReplacement(ScalarNode, node.Tag, value)
newStringNode.Style = node.Style newStringNode.Style = node.Style
results.PushBack(newStringNode) results.PushBack(newStringNode)
@ -110,14 +106,12 @@ func substituteStringOperator(d *dataTreeNavigator, context Context, expressionN
var results = list.New() var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) node := el.Value.(*CandidateNode)
node := candidate.unwrapDocument()
if node.guessTagFromCustomType() != "!!str" { if node.guessTagFromCustomType() != "!!str" {
return Context{}, fmt.Errorf("cannot substitute with %v, can only substitute strings. Hint: Most often you'll want to use '|=' over '=' for this operation", node.Tag) return Context{}, fmt.Errorf("cannot substitute with %v, can only substitute strings. Hint: Most often you'll want to use '|=' over '=' for this operation", node.Tag)
} }
result := candidate.CreateReplacement(substitute(node.Value, regEx, replacementText)) result := node.CreateReplacement(substitute(node.Value, regEx, replacementText))
results.PushBack(result) results.PushBack(result)
} }
@ -291,14 +285,12 @@ func matchOperator(d *dataTreeNavigator, context Context, expressionNode *Expres
var results = list.New() var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) node := el.Value.(*CandidateNode)
node := candidate.unwrapDocument()
if node.guessTagFromCustomType() != "!!str" { if node.guessTagFromCustomType() != "!!str" {
return Context{}, fmt.Errorf("cannot match with %v, can only match strings. Hint: Most often you'll want to use '|=' over '=' for this operation", node.Tag) return Context{}, fmt.Errorf("cannot match with %v, can only match strings. Hint: Most often you'll want to use '|=' over '=' for this operation", node.Tag)
} }
match(matchPrefs, regEx, candidate, node.Value, results) match(matchPrefs, regEx, node, node.Value, results)
} }
return context.ChildContext(results), nil return context.ChildContext(results), nil
@ -313,13 +305,11 @@ func captureOperator(d *dataTreeNavigator, context Context, expressionNode *Expr
var results = list.New() var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) node := el.Value.(*CandidateNode)
node := candidate.unwrapDocument()
if node.guessTagFromCustomType() != "!!str" { if node.guessTagFromCustomType() != "!!str" {
return Context{}, fmt.Errorf("cannot match with %v, can only match strings. Hint: Most often you'll want to use '|=' over '=' for this operation", node.Tag) return Context{}, fmt.Errorf("cannot match with %v, can only match strings. Hint: Most often you'll want to use '|=' over '=' for this operation", node.Tag)
} }
capture(matchPrefs, regEx, candidate, node.Value, results) capture(matchPrefs, regEx, node, node.Value, results)
} }
@ -335,14 +325,12 @@ func testOperator(d *dataTreeNavigator, context Context, expressionNode *Express
var results = list.New() var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) node := el.Value.(*CandidateNode)
node := candidate.unwrapDocument()
if node.guessTagFromCustomType() != "!!str" { if node.guessTagFromCustomType() != "!!str" {
return Context{}, fmt.Errorf("cannot match with %v, can only match strings. Hint: Most often you'll want to use '|=' over '=' for this operation", node.Tag) return Context{}, fmt.Errorf("cannot match with %v, can only match strings. Hint: Most often you'll want to use '|=' over '=' for this operation", node.Tag)
} }
matches := regEx.FindStringSubmatch(node.Value) matches := regEx.FindStringSubmatch(node.Value)
results.PushBack(createBooleanCandidate(candidate, len(matches) > 0)) results.PushBack(createBooleanCandidate(node, len(matches) > 0))
} }
@ -364,12 +352,11 @@ func joinStringOperator(d *dataTreeNavigator, context Context, expressionNode *E
var results = list.New() var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) node := el.Value.(*CandidateNode)
node := candidate.unwrapDocument()
if node.Kind != SequenceNode { if node.Kind != SequenceNode {
return Context{}, fmt.Errorf("cannot join with %v, can only join arrays of scalars", node.Tag) return Context{}, fmt.Errorf("cannot join with %v, can only join arrays of scalars", node.Tag)
} }
result := candidate.CreateReplacement(join(node.Content, joinStr)) result := node.CreateReplacement(join(node.Content, joinStr))
results.PushBack(result) results.PushBack(result)
} }
@ -404,8 +391,7 @@ func splitStringOperator(d *dataTreeNavigator, context Context, expressionNode *
var results = list.New() var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) node := el.Value.(*CandidateNode)
node := candidate.unwrapDocument()
if node.Tag == "!!null" { if node.Tag == "!!null" {
continue continue
} }
@ -414,7 +400,7 @@ func splitStringOperator(d *dataTreeNavigator, context Context, expressionNode *
return Context{}, fmt.Errorf("cannot split %v, can only split strings", node.Tag) return Context{}, fmt.Errorf("cannot split %v, can only split strings", node.Tag)
} }
kind, tag, content := split(node.Value, splitStr) kind, tag, content := split(node.Value, splitStr)
result := candidate.CreateReplacement(kind, tag, "") result := node.CreateReplacement(kind, tag, "")
result.AddChildren(content) result.AddChildren(content)
results.PushBack(result) results.PushBack(result)
} }

View File

@ -43,32 +43,27 @@ func subtractArray(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, erro
} }
func subtract(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) { func subtract(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
lhs = lhs.unwrapDocument() if lhs.Tag == "!!null" {
rhs = rhs.unwrapDocument()
lhsNode := lhs
if lhsNode.Tag == "!!null" {
return lhs.CopyAsReplacement(rhs), nil return lhs.CopyAsReplacement(rhs), nil
} }
target := lhs.CopyWithoutContent() target := lhs.CopyWithoutContent()
switch lhsNode.Kind { switch lhs.Kind {
case MappingNode: case MappingNode:
return nil, fmt.Errorf("maps not yet supported for subtraction") return nil, fmt.Errorf("maps not yet supported for subtraction")
case SequenceNode: case SequenceNode:
if rhs.Kind != SequenceNode { if rhs.Kind != SequenceNode {
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Tag, rhs.GetNicePath(), lhsNode.Tag) return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Tag, rhs.GetNicePath(), lhs.Tag)
} }
return subtractArray(lhs, rhs) return subtractArray(lhs, rhs)
case ScalarNode: case ScalarNode:
if rhs.Kind != ScalarNode { if rhs.Kind != ScalarNode {
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Tag, rhs.GetNicePath(), lhsNode.Tag) return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Tag, rhs.GetNicePath(), lhs.Tag)
} }
target.Kind = ScalarNode target.Kind = ScalarNode
target.Style = lhsNode.Style target.Style = lhs.Style
if err := subtractScalars(context, target, lhsNode, rhs); err != nil { if err := subtractScalars(context, target, lhs, rhs); err != nil {
return nil, err return nil, err
} }
} }

View File

@ -39,7 +39,7 @@ func assignTagOperator(d *dataTreeNavigator, context Context, expressionNode *Ex
tag = rhs.MatchingNodes.Front().Value.(*CandidateNode).Value tag = rhs.MatchingNodes.Front().Value.(*CandidateNode).Value
} }
} }
candidate.unwrapDocument().Tag = tag candidate.Tag = tag
} }
return context, nil return context, nil
@ -52,7 +52,7 @@ func getTagOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
result := candidate.CreateReplacement(ScalarNode, "!!str", candidate.unwrapDocument().Tag) result := candidate.CreateReplacement(ScalarNode, "!!str", candidate.Tag)
results.PushBack(result) results.PushBack(result)
} }

View File

@ -166,10 +166,9 @@ func traverseMapWithIndices(context Context, candidate *CandidateNode, indices [
return matchingNodeMap, nil return matchingNodeMap, nil
} }
func traverseArrayWithIndices(candidate *CandidateNode, indices []*CandidateNode, prefs traversePreferences) (*list.List, error) { func traverseArrayWithIndices(node *CandidateNode, indices []*CandidateNode, prefs traversePreferences) (*list.List, error) {
log.Debug("traverseArrayWithIndices") log.Debug("traverseArrayWithIndices")
var newMatches = list.New() var newMatches = list.New()
node := candidate.unwrapDocument()
if len(indices) == 0 { if len(indices) == 0 {
log.Debug("splatting") log.Debug("splatting")
var index int var index int

View File

@ -21,14 +21,13 @@ func uniqueBy(d *dataTreeNavigator, context Context, expressionNode *ExpressionN
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
candidateNode := candidate.unwrapDocument()
if candidateNode.Kind != SequenceNode { if candidate.Kind != SequenceNode {
return Context{}, fmt.Errorf("Only arrays are supported for unique") return Context{}, fmt.Errorf("Only arrays are supported for unique")
} }
var newMatches = orderedmap.NewOrderedMap() var newMatches = orderedmap.NewOrderedMap()
for _, child := range candidateNode.Content { for _, child := range candidate.Content {
rhs, err := d.GetMatchingNodes(context.SingleReadonlyChildContext(child), expressionNode.RHS) rhs, err := d.GetMatchingNodes(context.SingleReadonlyChildContext(child), expressionNode.RHS)
if err != nil { if err != nil {
@ -49,7 +48,7 @@ func uniqueBy(d *dataTreeNavigator, context Context, expressionNode *ExpressionN
newMatches.Set(keyValue, child) newMatches.Set(keyValue, child)
} }
} }
resultNode := candidate.CreateReplacementWithComments(SequenceNode, "!!seq", candidateNode.Style) resultNode := candidate.CreateReplacementWithComments(SequenceNode, "!!seq", candidate.Style)
for el := newMatches.Front(); el != nil; el = el.Next() { for el := newMatches.Front(); el != nil; el = el.Next() {
resultNode.AddChild(el.Value.(*CandidateNode)) resultNode.AddChild(el.Value.(*CandidateNode))
} }