cue/parser: allow attributes before package and import clauses
This is to facilitate "build tags".
Change-Id: I8ea85d4f1339a3584e7763d342715b8fad2fe48f
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7062
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/cue/parser/parser.go b/cue/parser/parser.go
index 9d96e8f..2e24158 100644
--- a/cue/parser/parser.go
+++ b/cue/parser/parser.go
@@ -1606,6 +1606,11 @@
var decls []ast.Decl
+ for p.tok == token.ATTRIBUTE {
+ decls = append(decls, p.parseAttribute())
+ p.consumeDeclComma()
+ }
+
// The package clause is not a declaration: it does not appear in any
// scope.
if p.tok == token.IDENT && p.lit == "package" {
@@ -1628,6 +1633,11 @@
c.closeNode(p, pkg)
}
+ for p.tok == token.ATTRIBUTE {
+ decls = append(decls, p.parseAttribute())
+ p.consumeDeclComma()
+ }
+
if p.mode&packageClauseOnlyMode == 0 {
// import decls
for p.tok == token.IDENT && p.lit == "import" {
diff --git a/cue/parser/parser_test.go b/cue/parser/parser_test.go
index 20d3e1b..6ec737d 100644
--- a/cue/parser/parser_test.go
+++ b/cue/parser/parser_test.go
@@ -410,6 +410,20 @@
`,
`<[l5// d] a: 1 @a() @b()>`,
}, {
+ "attribute declarations",
+ `
+ @foo()
+
+ package bar
+
+ @bar()
+
+ import "strings"
+
+ @baz()
+ `,
+ `@foo(), package bar, @bar(), import "strings", @baz()`,
+ }, {
"comprehension comments",
`
if X {
diff --git a/doc/ref/spec.md b/doc/ref/spec.md
index f7f0326..8d7f2eb 100644
--- a/doc/ref/spec.md
+++ b/doc/ref/spec.md
@@ -2899,7 +2899,7 @@
to a data format
```
-SourceFile = [ PackageClause "," ] { ImportDecl "," } { Declaration "," } .
+SourceFile = { attribute "," } [ PackageClause "," ] { ImportDecl "," } { Declaration "," } .
```
```
diff --git a/internal/internal.go b/internal/internal.go
index 934c455..066d26f 100644
--- a/internal/internal.go
+++ b/internal/internal.go
@@ -131,6 +131,7 @@
for _, d := range f.Decls {
switch x := d.(type) {
case *ast.CommentGroup:
+ case *ast.Attribute:
case *ast.Package:
if x.Name == nil {
break