Skip to content

Commit

Permalink
internal/core/export: fix decl export printing and extraction
Browse files Browse the repository at this point in the history
Fixes #894

A few related fixes:

- Extract from all evaluated structs, not just unevaluated
conjuncts, which results in dropping merged values.
(Note that unlike with fields attributes, the the declaration
attributes are value-bound, and thus need to be included.)

- Decl attrs were not always printed in export. This has now
been fixed.

- Changed the (internal) API to accept a Vertex, instead
of a list of conjuncts, which is a better abstraction.

Change-Id: Id598fefa88aff88aefd126fb80f1637b3f50c7fb
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9382
Reviewed-by: CUE cueckoo <[email protected]>
Reviewed-by: Paul Jolly <[email protected]>
Reviewed-by: Marcel van Lohuizen <[email protected]>
  • Loading branch information
mpvl committed Apr 11, 2021
1 parent c8b7fe0 commit f1d3d81
Show file tree
Hide file tree
Showing 7 changed files with 277 additions and 28 deletions.
6 changes: 3 additions & 3 deletions cue/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2111,7 +2111,7 @@ func (v Value) Attribute(key string) Attribute {
return nonExistAttr(key)
}
// look up the attributes
for _, a := range export.ExtractFieldAttrs(v.v.Conjuncts) {
for _, a := range export.ExtractFieldAttrs(v.v) {
k, _ := a.Split()
if key != k {
continue
Expand Down Expand Up @@ -2149,13 +2149,13 @@ func (v Value) Attributes(mask AttrKind) []Attribute {
attrs := []Attribute{}

if mask&FieldAttr != 0 {
for _, a := range export.ExtractFieldAttrs(v.v.Conjuncts) {
for _, a := range export.ExtractFieldAttrs(v.v) {
attrs = append(attrs, newAttr(internal.FieldAttr, a))
}
}

if mask&DeclAttr != 0 {
for _, a := range export.ExtractDeclAttrs(v.v.Conjuncts) {
for _, a := range export.ExtractDeclAttrs(v.v) {
attrs = append(attrs, newAttr(internal.DeclAttr, a))
}
}
Expand Down
23 changes: 20 additions & 3 deletions internal/core/export/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,16 +137,31 @@ func (x *exporter) mergeValues(label adt.Feature, src *adt.Vertex, a []conjunct,
if len(e.fields) == 0 && !e.hasEllipsis {
switch len(e.embed) + len(e.conjuncts) {
case 0:
if len(e.attrs) > 0 {
break
}
if len(e.structs) > 0 {
return s
}
return ast.NewIdent("_")
case 1:
var x ast.Expr
if len(e.conjuncts) == 1 {
return e.conjuncts[0]
x = e.conjuncts[0]
} else {
x = e.embed[0]
}
if len(e.attrs) == 0 {
return x
}
if st, ok := x.(*ast.StructLit); ok {
s.Elts = append(s.Elts, st.Elts...)
return s
}
return e.embed[0]
case 2:
if len(e.attrs) > 0 {
break
}
// Simplify.
e.conjuncts = append(e.conjuncts, e.embed...)
return ast.NewBinExpr(token.AND, e.conjuncts...)
Expand Down Expand Up @@ -195,7 +210,9 @@ func (x *exporter) mergeValues(label adt.Feature, src *adt.Vertex, a []conjunct,
ast.SetComments(d, docs)
}
if x.cfg.ShowAttributes {
d.Attrs = ExtractFieldAttrs(a)
for _, c := range a {
d.Attrs = extractFieldAttrs(d.Attrs, c)
}
}
s.Elts = append(s.Elts, d)
}
Expand Down
23 changes: 14 additions & 9 deletions internal/core/export/extract.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,15 @@ func containsDoc(a []*ast.CommentGroup, cg *ast.CommentGroup) bool {
return false
}

func ExtractFieldAttrs(a []adt.Conjunct) (attrs []*ast.Attribute) {
for _, x := range a {
f, ok := x.Source().(*ast.Field)
if !ok {
continue
}
func ExtractFieldAttrs(v *adt.Vertex) (attrs []*ast.Attribute) {
for _, x := range v.Conjuncts {
attrs = extractFieldAttrs(attrs, x)
}
return attrs
}

func extractFieldAttrs(attrs []*ast.Attribute, c adt.Conjunct) []*ast.Attribute {
if f, ok := c.Source().(*ast.Field); ok {
for _, a := range f.Attrs {
if !containsAttr(attrs, a) {
attrs = append(attrs, a)
Expand All @@ -152,9 +155,11 @@ func ExtractFieldAttrs(a []adt.Conjunct) (attrs []*ast.Attribute) {
return attrs
}

func ExtractDeclAttrs(a []adt.Conjunct) (attrs []*ast.Attribute) {
for _, c := range a {
attrs = extractDeclAttrs(attrs, c.Expr().Source())
func ExtractDeclAttrs(v *adt.Vertex) (attrs []*ast.Attribute) {
for _, st := range v.Structs {
if src := st.StructLit; src != nil {
attrs = extractDeclAttrs(attrs, src.Src)
}
}
return attrs
}
Expand Down
1 change: 1 addition & 0 deletions internal/core/export/testdata/adt.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ errorListDef: {
-- out/definition --
import mystrings "strings"

@foo(bar)
p1: {
[X=string]: {
name: X
Expand Down
221 changes: 221 additions & 0 deletions internal/core/export/testdata/attrs.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,33 @@ a: {

a: {} @field(1) @field(3)

doNotPropagate: {
#A: { } @attr1()
a: #A

// Do not accumulated field attributes in embedding.
#B: { } @attr1()
b: { #B }
}

embedScalarField: {
a: { 2 } @attr1()
a: { _ } @attr2()
}

embedScalarDecl: {
b0: { 2, @attr1() }
b1: b0
b2: { 2, b0, @attr2() }
}

dontMergeForDef: {
a: { @decl1() }
b: a & { x: 1, @decl2() }
c: a & { @decl2() }
d: { a, @decl2() }
}

-- b.cue --
@package("b")

Expand All @@ -42,21 +69,143 @@ a: {
@decl(3)
@decl(5)
} @field(2) @field(1) @field(4) @field(3) @field(5)
doNotPropagate: {
#A: {} @attr1()
a: #A

// Do not accumulated field attributes in embedding.
#B: {} @attr1()
b: #B
}
embedScalarField: {
a: 2 @attr1() @attr2()
}
embedScalarDecl: {
b0: {
@attr1()
2
}
b1: b0
b2: {
@attr2()
b0
2
}
}
dontMergeForDef: {
a: {
@decl1()
}
b: a & {
@decl2()
x: 1
}
c: a & {
@decl2()
}
d: {
@decl2()
a
}
}
-- out/doc --
[]
[a]
[doNotPropagate]
[doNotPropagate #A]
[doNotPropagate a]
[doNotPropagate #B]
- Do not accumulated field attributes in embedding.

[doNotPropagate b]
[embedScalarField]
[embedScalarField a]
[embedScalarDecl]
[embedScalarDecl b0]
[embedScalarDecl b1]
[embedScalarDecl b2]
[dontMergeForDef]
[dontMergeForDef a]
[dontMergeForDef b]
[dontMergeForDef b x]
[dontMergeForDef c]
[dontMergeForDef d]
-- out/value --
== Simplified
{
a: {}
doNotPropagate: {
a: {}
b: {}
}
embedScalarField: {
a: 2
}
embedScalarDecl: {
b0: 2
b1: 2
b2: 2
}
dontMergeForDef: {
a: {}
b: {
x: 1
}
c: {}
d: {}
}
}
== Raw
{
a: {}
doNotPropagate: {
#A: {}
a: {}

// Do not accumulated field attributes in embedding.
#B: {}
b: {}
}
embedScalarField: {
a: 2
}
embedScalarDecl: {
b0: 2
b1: 2
b2: 2
}
dontMergeForDef: {
a: {}
b: {
x: 1
}
c: {}
d: {}
}
}
== Final
{
a: {}
doNotPropagate: {
a: {}
b: {}
}
embedScalarField: {
a: 2
}
embedScalarDecl: {
b0: 2
b1: 2
b2: 2
}
dontMergeForDef: {
a: {}
b: {
x: 1
}
c: {}
d: {}
}
}
== All
{
Expand All @@ -69,6 +218,43 @@ a: {
@decl(3)
@decl(5)
} @field(2) @field(1) @field(4) @field(3) @field(5)
doNotPropagate: {
#A: {} @attr1()
a: {}

// Do not accumulated field attributes in embedding.
#B: {} @attr1()
b: {}
}
embedScalarField: {
a: 2 @attr1() @attr2()
}
embedScalarDecl: {
b0: {
2, @attr1()
}
b1: {
2, @attr1()
}
b2: {
2, @attr2(), @attr1()
}
}
dontMergeForDef: {
a: {
@decl1()
}
b: {
@decl1(), @decl2()
x: 1
}
c: {
@decl1(), @decl2()
}
d: {
@decl2(), @decl1()
}
}
}
== Eval
{
Expand All @@ -81,4 +267,39 @@ a: {
@decl(3)
@decl(5)
} @field(2) @field(1) @field(4) @field(3) @field(5)
doNotPropagate: {
#A: {} @attr1()
a: {}
#B: {} @attr1()
b: {}
}
embedScalarField: {
a: 2 @attr1() @attr2()
}
embedScalarDecl: {
b0: {
2, @attr1()
}
b1: {
2, @attr1()
}
b2: {
2, @attr2(), @attr1()
}
}
dontMergeForDef: {
a: {
@decl1()
}
b: {
@decl1(), @decl2()
x: 1
}
c: {
@decl1(), @decl2()
}
d: {
@decl2(), @decl1()
}
}
}
Loading

0 comments on commit f1d3d81

Please sign in to comment.