Upstream itchyny/gojq state of the touched files before f68bda411a
This commit is contained in:
1 parent
a7ed5ccbe9
commit
b18851b748
3 files changed
+35
-128
No files matched your search
+2
-83
@@ -2407,29 +2407,6 @@
|
|||||||
"/a,b/c/d/e,f/"
|
"/a,b/c/d/e,f/"
|
||||||
",/ /a/,/b/,/ /c/,/ /d/,/ /e/,/f/,/ "
|
",/ /a/,/b/,/ /c/,/ /d/,/ /e/,/f/,/ "
|
||||||
|
|
||||||
- name: split/1 function against empty string
|
|
||||||
args:
|
|
||||||
- -c
|
|
||||||
- '.[] as $t | .[] as $s | $s | split($t)'
|
|
||||||
input: '["abc", "a", "b", ""]'
|
|
||||||
expected: |
|
|
||||||
["",""]
|
|
||||||
["a"]
|
|
||||||
["b"]
|
|
||||||
[]
|
|
||||||
["","bc"]
|
|
||||||
["",""]
|
|
||||||
["b"]
|
|
||||||
[]
|
|
||||||
["a","c"]
|
|
||||||
["a"]
|
|
||||||
["",""]
|
|
||||||
[]
|
|
||||||
["a","b","c"]
|
|
||||||
["a"]
|
|
||||||
["b"]
|
|
||||||
[]
|
|
||||||
|
|
||||||
- name: join function
|
- name: join function
|
||||||
args:
|
args:
|
||||||
- 'join(",")'
|
- 'join(",")'
|
||||||
@@ -3608,16 +3585,6 @@
|
|||||||
expected: |
|
expected: |
|
||||||
8
|
8
|
||||||
|
|
||||||
- name: reduce with assignment of multiple paths in update
|
|
||||||
args:
|
|
||||||
- -c
|
|
||||||
- 'reduce (1,2) as $i (.; (.[0], .[.[0]]) = $i),
|
|
||||||
reduce (1,2) as $i (.; (.[0], .[.[0]]) |= $i)'
|
|
||||||
input: '[0,0,0]'
|
|
||||||
expected: |
|
|
||||||
[2,2,0]
|
|
||||||
[2,2,0]
|
|
||||||
|
|
||||||
- name: reduce with query in start
|
- name: reduce with query in start
|
||||||
args:
|
args:
|
||||||
- 'reduce range(5) as $x (range(3); . + $x)'
|
- 'reduce range(5) as $x (range(3); . + $x)'
|
||||||
@@ -5022,46 +4989,6 @@
|
|||||||
expected: |
|
expected: |
|
||||||
{"a":[{},{"b":[1,2,3]}]}
|
{"a":[{},{"b":[1,2,3]}]}
|
||||||
|
|
||||||
- name: getpath function against string
|
|
||||||
args:
|
|
||||||
- -c
|
|
||||||
- '[getpath([{"start":1,"end":3}]), getpath([{"start":-2,"end":null}]), getpath([1]), getpath([])]'
|
|
||||||
input: '"abcde"'
|
|
||||||
expected: |
|
|
||||||
["bc","de","b","abcde"]
|
|
||||||
|
|
||||||
- name: getpath function against string in a container
|
|
||||||
args:
|
|
||||||
- -c
|
|
||||||
- 'getpath(["a",{"start":0,"end":2}]), getpath(["a",1])'
|
|
||||||
input: '{"a":"abc"}'
|
|
||||||
expected: |
|
|
||||||
"ab"
|
|
||||||
"b"
|
|
||||||
|
|
||||||
- name: getpath function against string round trip with path function
|
|
||||||
args:
|
|
||||||
- -c
|
|
||||||
- '[getpath(path(.[1:3])), getpath(path(.[1]))]'
|
|
||||||
input: '"abcde"'
|
|
||||||
expected: |
|
|
||||||
["bc","b"]
|
|
||||||
|
|
||||||
- name: getpath function against string round trip in a container
|
|
||||||
args:
|
|
||||||
- -c
|
|
||||||
- '. as $d | [path(.a[0:2]), path(.b[1])] | map(. as $p | $d | getpath($p))'
|
|
||||||
input: '{"a":"abc","b":"xyz"}'
|
|
||||||
expected: |
|
|
||||||
["ab","y"]
|
|
||||||
|
|
||||||
- name: getpath function against string with object key
|
|
||||||
args:
|
|
||||||
- 'getpath(["k"])'
|
|
||||||
input: '"abc"'
|
|
||||||
error: |
|
|
||||||
getpath(["k"]) cannot be applied to "abc": expected an object but got: string ("abc")
|
|
||||||
|
|
||||||
- name: getpath function error
|
- name: getpath function error
|
||||||
args:
|
args:
|
||||||
- 'getpath(["a",1,"b","c"])'
|
- 'getpath(["a",1,"b","c"])'
|
||||||
@@ -5094,9 +5021,9 @@
|
|||||||
expected: |
|
expected: |
|
||||||
{"a":[{"b":5}]}
|
{"a":[{"b":5}]}
|
||||||
{"a":[{"b":5}],"b":0}
|
{"a":[{"b":5}],"b":0}
|
||||||
"getpath([\"a\",0,\"b\"]) cannot be applied to {\"a\":0}: expected an array but got: number (0)"
|
"getpath([\"a\",0,\"b\"]) cannot be applied to: object ({\"a\":0})"
|
||||||
{"a":[{"b":5}]}
|
{"a":[{"b":5}]}
|
||||||
"getpath([\"a\",0,\"b\"]) cannot be applied to {\"a\":[0,1]}: expected an object but got: number (0)"
|
"getpath([\"a\",0,\"b\"]) cannot be applied to: object ({\"a\":[0,1]})"
|
||||||
"getpath([\"a\",0,\"b\"]) cannot be applied to {\"a\":{\"b\":1}}: expected an array but got: object ({\"b\":1})"
|
"getpath([\"a\",0,\"b\"]) cannot be applied to {\"a\":{\"b\":1}}: expected an array but got: object ({\"b\":1})"
|
||||||
{"a":[{"b":5}]}
|
{"a":[{"b":5}]}
|
||||||
{"a":[{"b":5,"c":3}]}
|
{"a":[{"b":5,"c":3}]}
|
||||||
@@ -5502,14 +5429,6 @@
|
|||||||
expected: |
|
expected: |
|
||||||
[1,3,6,5,5]
|
[1,3,6,5,5]
|
||||||
|
|
||||||
- name: update-assignment operator against object with overlapping paths
|
|
||||||
args:
|
|
||||||
- -c
|
|
||||||
- '(.a.b,.a,.a.p.z) |= {p: ., q: .}'
|
|
||||||
input: '{"a":{"b":1}}'
|
|
||||||
expected: |
|
|
||||||
{"a":{"p":{"b":{"p":1,"q":1},"z":{"p":null,"q":null}},"q":{"b":{"p":1,"q":1}}}}
|
|
||||||
|
|
||||||
- name: update-assignment operator with optional operator
|
- name: update-assignment operator with optional operator
|
||||||
args:
|
args:
|
||||||
- -c
|
- -c
|
||||||
|
|||||||
+17
-10
@@ -132,13 +132,18 @@ func (c *compiler) compile(q *Query) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *compiler) compileImport(i *Import) error {
|
func (c *compiler) compileImport(i *Import) error {
|
||||||
path, alias := cmp.Or(i.ImportPath, i.IncludePath), i.ImportAlias
|
var path, alias string
|
||||||
|
var err error
|
||||||
|
if i.ImportPath != "" {
|
||||||
|
path, alias = i.ImportPath, i.ImportAlias
|
||||||
|
} else {
|
||||||
|
path = i.IncludePath
|
||||||
|
}
|
||||||
if c.moduleLoader == nil {
|
if c.moduleLoader == nil {
|
||||||
return fmt.Errorf("cannot load module: %q", path)
|
return fmt.Errorf("cannot load module: %q", path)
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(alias, "$") {
|
if strings.HasPrefix(alias, "$") {
|
||||||
var vals any
|
var vals any
|
||||||
var err error
|
|
||||||
if moduleLoader, ok := c.moduleLoader.(interface {
|
if moduleLoader, ok := c.moduleLoader.(interface {
|
||||||
LoadJSONWithMeta(string, map[string]any) (any, error)
|
LoadJSONWithMeta(string, map[string]any) (any, error)
|
||||||
}); ok {
|
}); ok {
|
||||||
@@ -161,7 +166,6 @@ func (c *compiler) compileImport(i *Import) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var q *Query
|
var q *Query
|
||||||
var err error
|
|
||||||
if moduleLoader, ok := c.moduleLoader.(interface {
|
if moduleLoader, ok := c.moduleLoader.(interface {
|
||||||
LoadModuleWithMeta(string, map[string]any) (*Query, error)
|
LoadModuleWithMeta(string, map[string]any) (*Query, error)
|
||||||
}); ok {
|
}); ok {
|
||||||
@@ -1093,7 +1097,7 @@ func (c *compiler) compileModify() {
|
|||||||
&code{op: opcall, v: [3]any{funcAllocator, 0, "_allocator"}},
|
&code{op: opcall, v: [3]any{funcAllocator, 0, "_allocator"}},
|
||||||
&code{op: opstore, v: a},
|
&code{op: opstore, v: a},
|
||||||
&code{op: opload, v: v},
|
&code{op: opload, v: v},
|
||||||
&code{op: opfork, v: len(c.codes) + 40}, // reduce [L1]
|
&code{op: opfork, v: len(c.codes) + 39}, // reduce [L1]
|
||||||
&code{op: oppathbegin}, // path(p)
|
&code{op: oppathbegin}, // path(p)
|
||||||
&code{op: opload, v: p},
|
&code{op: opload, v: p},
|
||||||
&code{op: opcallpc},
|
&code{op: opcallpc},
|
||||||
@@ -1102,13 +1106,12 @@ func (c *compiler) compileModify() {
|
|||||||
&code{op: opstore, v: p}, // as $p (.;
|
&code{op: opstore, v: p}, // as $p (.;
|
||||||
&code{op: opforklabel, v: l}, // label $l |
|
&code{op: opforklabel, v: l}, // label $l |
|
||||||
&code{op: opload, v: v}, //
|
&code{op: opload, v: v}, //
|
||||||
&code{op: opfork, v: len(c.codes) + 37}, // [L2]
|
&code{op: opfork, v: len(c.codes) + 36}, // [L2]
|
||||||
&code{op: oppop}, // (getpath($p) |
|
&code{op: oppop}, // (getpath($p) |
|
||||||
&code{op: opload, v: a},
|
&code{op: opload, v: a},
|
||||||
&code{op: opload, v: a},
|
|
||||||
&code{op: opload, v: p},
|
&code{op: opload, v: p},
|
||||||
&code{op: opload, v: v},
|
&code{op: opload, v: v},
|
||||||
&code{op: opcall, v: [3]any{funcGetpathWithAllocator, 2, "getpath"}},
|
&code{op: opcall, v: [3]any{internalFuncs["getpath"].callback, 1, "getpath"}},
|
||||||
&code{op: opload, v: f}, // f)
|
&code{op: opload, v: f}, // f)
|
||||||
&code{op: opcallpc},
|
&code{op: opcallpc},
|
||||||
&code{op: opload, v: p}, // setpath($p; ...)
|
&code{op: opload, v: p}, // setpath($p; ...)
|
||||||
@@ -1116,8 +1119,8 @@ func (c *compiler) compileModify() {
|
|||||||
&code{op: opcall, v: [3]any{funcSetpathWithAllocator, 3, "_setpath"}},
|
&code{op: opcall, v: [3]any{funcSetpathWithAllocator, 3, "_setpath"}},
|
||||||
&code{op: opstore, v: v},
|
&code{op: opstore, v: v},
|
||||||
&code{op: opload, v: v}, // ., break $l
|
&code{op: opload, v: v}, // ., break $l
|
||||||
&code{op: opfork, v: len(c.codes) + 35}, // [L4]
|
&code{op: opfork, v: len(c.codes) + 34}, // [L4]
|
||||||
&code{op: opjump, v: len(c.codes) + 39}, // [L3]
|
&code{op: opjump, v: len(c.codes) + 38}, // [L3]
|
||||||
&code{op: opload, v: l}, // [L4]
|
&code{op: opload, v: l}, // [L4]
|
||||||
&code{op: opcall, v: [3]any{funcBreak(""), 0, "_break"}},
|
&code{op: opcall, v: [3]any{funcBreak(""), 0, "_break"}},
|
||||||
&code{op: opload, v: p}, // append $p to $d [L2]
|
&code{op: opload, v: p}, // append $p to $d [L2]
|
||||||
@@ -1270,7 +1273,11 @@ func listModuleDeps(q *Query) []any {
|
|||||||
if v == nil {
|
if v == nil {
|
||||||
v = make(map[string]any)
|
v = make(map[string]any)
|
||||||
}
|
}
|
||||||
v["relpath"] = cmp.Or(i.ImportPath, i.IncludePath)
|
relpath := i.ImportPath
|
||||||
|
if relpath == "" {
|
||||||
|
relpath = i.IncludePath
|
||||||
|
}
|
||||||
|
v["relpath"] = relpath
|
||||||
if i.ImportAlias != "" {
|
if i.ImportAlias != "" {
|
||||||
v["as"] = strings.TrimPrefix(i.ImportAlias, "$")
|
v["as"] = strings.TrimPrefix(i.ImportAlias, "$")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"slices"
|
"slices"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -437,7 +438,9 @@ func add(xs iter.Seq[any]) any {
|
|||||||
case []any:
|
case []any:
|
||||||
switch w := v.(type) {
|
switch w := v.(type) {
|
||||||
case nil:
|
case nil:
|
||||||
v = slices.Clone(x)
|
s := make([]any, len(x))
|
||||||
|
copy(s, x)
|
||||||
|
v = s
|
||||||
continue
|
continue
|
||||||
case []any:
|
case []any:
|
||||||
v = append(w, x...)
|
v = append(w, x...)
|
||||||
@@ -766,13 +769,6 @@ func funcSplit(v, x any) any {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return &func0TypeError{"split", x}
|
return &func0TypeError{"split", x}
|
||||||
}
|
}
|
||||||
return splitString(s, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func splitString(s, t string) []any {
|
|
||||||
if s == "" {
|
|
||||||
return []any{}
|
|
||||||
}
|
|
||||||
ss := strings.Split(s, t)
|
ss := strings.Split(s, t)
|
||||||
xs := make([]any, len(ss))
|
xs := make([]any, len(ss))
|
||||||
for i, s := range ss {
|
for i, s := range ss {
|
||||||
@@ -1488,17 +1484,6 @@ func (a allocator) allocated(v any) bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// release forgets every allocated address when the value is one of them, so
|
|
||||||
// that a value handed to a query is copied on update again.
|
|
||||||
func (a allocator) release(v any) {
|
|
||||||
switch v.(type) {
|
|
||||||
case map[string]any, []any:
|
|
||||||
if a.allocated(v) {
|
|
||||||
clear(a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a allocator) makeObject(l int) map[string]any {
|
func (a allocator) makeObject(l int) map[string]any {
|
||||||
v := make(map[string]any, l)
|
v := make(map[string]any, l)
|
||||||
if a != nil {
|
if a != nil {
|
||||||
@@ -1525,15 +1510,6 @@ func funcSetpathWithAllocator(v any, args []any) any {
|
|||||||
return setpath(v, args[0], args[1], args[2].(allocator))
|
return setpath(v, args[0], args[1], args[2].(allocator))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used in compiler#compileModify: the update function may store the value
|
|
||||||
// anywhere, so it must not be modified in place afterwards. Registered as
|
|
||||||
// getpath to keep tracking paths through the call.
|
|
||||||
func funcGetpathWithAllocator(v any, args []any) any {
|
|
||||||
w := funcGetpath(v, args[0])
|
|
||||||
args[1].(allocator).release(w)
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
func setpath(v, p, n any, a allocator) any {
|
func setpath(v, p, n any, a allocator) any {
|
||||||
path, ok := p.([]any)
|
path, ok := p.([]any)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -1611,8 +1587,6 @@ func update(v any, path []any, n any, a allocator) (any, error) {
|
|||||||
return nil, &expectedArrayError{v}
|
return nil, &expectedArrayError{v}
|
||||||
}
|
}
|
||||||
case map[string]any:
|
case map[string]any:
|
||||||
// A slice bound stays reachable through the path.
|
|
||||||
a.release(p)
|
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
case nil:
|
case nil:
|
||||||
return updateArraySlice(nil, p, path[1:], n, a)
|
return updateArraySlice(nil, p, path[1:], n, a)
|
||||||
@@ -1805,9 +1779,14 @@ func funcGetpath(v, p any) any {
|
|||||||
}
|
}
|
||||||
u := v
|
u := v
|
||||||
for _, x := range path {
|
for _, x := range path {
|
||||||
v = funcIndex2(nil, v, x)
|
switch v.(type) {
|
||||||
if err, ok := v.(error); ok {
|
case nil, []any, map[string]any:
|
||||||
return &func1WrapError{"getpath", u, p, err}
|
v = funcIndex2(nil, v, x)
|
||||||
|
if err, ok := v.(error); ok {
|
||||||
|
return &func1WrapError{"getpath", u, p, err}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return &func1TypeError{"getpath", u, p}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
@@ -1851,8 +1830,10 @@ func funcBsearch(v, t any) any {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return &func1TypeError{"bsearch", v, t}
|
return &func1TypeError{"bsearch", v, t}
|
||||||
}
|
}
|
||||||
i, ok := slices.BinarySearchFunc(vs, t, Compare)
|
i := sort.Search(len(vs), func(i int) bool {
|
||||||
if ok {
|
return Compare(vs[i], t) >= 0
|
||||||
|
})
|
||||||
|
if i < len(vs) && Compare(vs[i], t) == 0 {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
return -i - 1
|
return -i - 1
|
||||||
|
|||||||
Reference in new issue
Block a user