Skip to content
This repository has been archived by the owner on Nov 18, 2021. It is now read-only.

Commit

Permalink
cue: flx bug for len on non-concrete values
Browse files Browse the repository at this point in the history
Change-Id: I7925132f01ada119a039cdec7d2a8c891f76fdc3
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3022
Reviewed-by: Marcel van Lohuizen <[email protected]>
  • Loading branch information
mpvl committed Aug 29, 2019
1 parent 8f3347f commit f40ecd9
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 9 deletions.
37 changes: 30 additions & 7 deletions cue/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

"cuelang.org/go/cue/errors"
"cuelang.org/go/cue/parser"
"cuelang.org/go/cue/token"
"cuelang.org/go/internal"
"github.com/cockroachdb/apd/v2"
)
Expand Down Expand Up @@ -118,22 +119,41 @@ var lenBuiltin = &builtin{
Result: intKind,
Func: func(c *callCtxt) {
v := c.value(0)
switch v.Kind() {
switch k := v.IncompleteKind(); k {
case StructKind:
s, _ := v.structValData(c.ctx)
s, err := v.structValData(c.ctx)
if err != nil {
c.ret = err
break
}
c.ret = s.Len()
case ListKind:
i := 0
iter, _ := v.List()
iter, err := v.List()
if err != nil {
c.ret = err
break
}
for ; iter.Next(); i++ {
}
c.ret = i
case BytesKind:
b, _ := v.Bytes()
b, err := v.Bytes()
if err != nil {
c.ret = err
break
}
c.ret = len(b)
case StringKind:
s, _ := v.String()
s, err := v.String()
if err != nil {
c.ret = err
break
}
c.ret = len(s)
default:
c.ret = errors.Newf(token.NoPos,
"invalid argument type %v", k)
}
},
}
Expand Down Expand Up @@ -268,8 +288,11 @@ func (x *builtin) call(ctx *context, src source, args ...evaluated) (ret value)
}
}()
x.Func(&call)
if e, ok := call.ret.(value); ok {
return e
switch v := call.ret.(type) {
case value:
return v
case *valueError:
return v.err
}
return convert(ctx, x, false, call.ret)
}
Expand Down
47 changes: 47 additions & 0 deletions cue/resolve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2182,6 +2182,43 @@ func TestFullEval(t *testing.T) {
`str: string, ` +
`s2: strings.ContainsAny ("dd"), ` +
`s3: <4>.ContainsAny (<3>.str,"dd")}`,
}, {
desc: "len of incomplete types",
in: `
args: *[] | [...string]
v1: len(args)
v2: len([])
v3: len({})
v4: len({a: 3})
v5: len({a: 3} | {a: 4})
v6: len('sf' | 'dd')
v7: len([2] | *[1, 2])
v8: len([2] | [1, 2])
v9: len("😂")
v10: len("")
`,
out: `<0>{` +
`args: [], ` +
`v1: 0, ` +
`v2: 0, ` +
`v3: 0, ` +
`v4: 1, ` +
`v5: len ((<1>{a: 3} | <2>{a: 4})), ` +
`v6: len (('sf' | 'dd')), ` +
`v7: 2, ` +
`v8: len (([2] | [1,2])), ` +
`v9: 4, ` +
`v10: 0}`,
}, {
desc: "slice rewrite bug",
in: `
fn: {
arg: [...int] & [1]
out: arg[1:]
}
fn1: fn & {arg: [1]}
`,
out: `<0>{fn: <1>{arg: [1], out: []}, fn1: <2>{arg: [1], out: []}}`,
}}
rewriteHelper(t, testCases, evalFull)
}
Expand All @@ -2192,6 +2229,16 @@ func TestX(t *testing.T) {
// Don't remove. For debugging.
testCases := []testCase{{
in: `
fnRec: {nn: [...int], out: (fn & {arg: nn}).out}
fn: {
arg: [...int]
out: arg[0] + (fnRec & {nn: arg[1:]}).out if len(arg) > 0
out: 0 if len(arg) == 0
}
fn7: (fn & {arg: [1, 2, 3]}).out
`,
}}
rewriteHelper(t, testCases, evalFull)
Expand Down
9 changes: 7 additions & 2 deletions cue/rewrite.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,13 @@ func (x *list) rewrite(ctx *context, fn rewriteFunc) value {

func (x *sliceExpr) rewrite(ctx *context, fn rewriteFunc) value {
v := rewrite(ctx, x.x, fn)
lo := rewrite(ctx, x.lo, fn)
hi := rewrite(ctx, x.hi, fn)
var lo, hi value
if x.lo != nil {
lo = rewrite(ctx, x.lo, fn)
}
if x.hi != nil {
hi = rewrite(ctx, x.hi, fn)
}
if v == x.x && lo == x.lo && hi == x.hi {
return x
}
Expand Down

0 comments on commit f40ecd9

Please sign in to comment.