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

Commit

Permalink
internal/core/adt: distinguish dynamic fields from pattern constraints
Browse files Browse the repository at this point in the history
Change-Id: I3a6418ebb6493c48f10b70670d3178dc69ecf886
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/6652
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
  • Loading branch information
mpvl committed Jul 23, 2020
1 parent 7504519 commit 88b4b1f
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 6 deletions.
9 changes: 5 additions & 4 deletions internal/core/adt/composite.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,10 +378,11 @@ type Acceptor interface {
type OptionalType int

const (
HasField OptionalType = 1 << iota
HasPattern
HasAdditional
IsOpen
HasField OptionalType = 1 << iota // X: T
HasDynamic // (X): T or "\(X)": T
HasPattern // [X]: T
HasAdditional // ...T
IsOpen // Defined for all fields
)

func (v *Vertex) Kind() Kind {
Expand Down
8 changes: 6 additions & 2 deletions internal/core/eval/optionals.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,12 @@ func (o *fieldSet) OptionalTypes() (mask adt.OptionalType) {
break
}
}
if o.bulk != nil {
mask |= adt.HasPattern
for _, b := range o.bulk {
if b.expr == nil {
mask |= adt.HasDynamic
} else {
mask |= adt.HasPattern
}
}
if o.additional != nil {
mask |= adt.HasAdditional
Expand Down
76 changes: 76 additions & 0 deletions internal/core/eval/optionals_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright 2020 CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package eval_test

import (
"testing"

"cuelang.org/go/cue/parser"
"cuelang.org/go/internal/core/adt"
"cuelang.org/go/internal/core/compile"
"cuelang.org/go/internal/core/eval"
"cuelang.org/go/internal/core/runtime"
)

func TestOptionalTypes(t *testing.T) {
testCases := []struct {
in string
out adt.OptionalType
}{{
in: `
...
`,
out: adt.HasAdditional | adt.IsOpen,
}, {
in: `
[string]: int
`,
// adt.IsOpen means fully defined in this context, which this is not.
out: adt.HasPattern,
}, {
in: `
bar: 3 // Not counted, as it is not optional.
{[string]: int} // embedded into end result.
"\(bar)": int
`,
out: adt.HasPattern | adt.HasDynamic,
}, {
in: `
bar?: 3
`,
out: adt.HasField,
}}
for _, tc := range testCases {
t.Run("", func(t *testing.T) {
ctx := eval.NewContext(runtime.New(), nil)
f, err := parser.ParseFile("opt", tc.in)
if err != nil {
t.Fatal(err)
}

v, errs := compile.Files(nil, ctx, f)
if errs != nil {
t.Fatal(errs)
}

v.Finalize(ctx)

got := v.OptionalTypes()
if got != tc.out {
t.Errorf("got %x; want %x", got, tc.out)
}
})
}
}

0 comments on commit 88b4b1f

Please sign in to comment.