cue/ast: add PackageName method

Getting the package name is not entirely trivial.

Change-Id: If223bddd70dc749263fa01b127524b2d098ceb3f
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/4560
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/ast/ast.go b/cue/ast/ast.go
index 7d91328..9a4441e 100644
--- a/cue/ast/ast.go
+++ b/cue/ast/ast.go
@@ -824,6 +824,21 @@
 	comments
 }
 
+// PackageName returns the package name associated with this file or "" if no
+// package is associated.
+func (f *File) PackageName() string {
+	for _, d := range f.Decls {
+		switch x := d.(type) {
+		case *Package:
+			return x.Name.Name
+		case *CommentGroup:
+		default:
+			return ""
+		}
+	}
+	return ""
+}
+
 func (f *File) Pos() token.Pos {
 	if len(f.Decls) > 0 {
 		return f.Decls[0].Pos()
diff --git a/cue/ast/ast_test.go b/cue/ast/ast_test.go
index 4272ffe..aaa7aa6 100644
--- a/cue/ast/ast_test.go
+++ b/cue/ast/ast_test.go
@@ -12,10 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package ast
+package ast_test
 
 import (
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+
+	"cuelang.org/go/cue/ast"
+	"cuelang.org/go/cue/parser"
 )
 
 func TestCommentText(t *testing.T) {
@@ -47,14 +52,47 @@
 	}
 
 	for i, c := range testCases {
-		list := make([]*Comment, len(c.list))
+		list := make([]*ast.Comment, len(c.list))
 		for i, s := range c.list {
-			list[i] = &Comment{Text: s}
+			list[i] = &ast.Comment{Text: s}
 		}
 
-		text := (&CommentGroup{List: list}).Text()
+		text := (&ast.CommentGroup{List: list}).Text()
 		if text != c.text {
 			t.Errorf("case %d: got %q; expected %q", i, text, c.text)
 		}
 	}
 }
+
+func TestPackageName(t *testing.T) {
+	testCases := []struct {
+		input string
+		pkg   string
+	}{{
+		input: `
+		package foo
+		`,
+		pkg: "foo",
+	}, {
+		input: `
+		a: 2
+		`,
+	}, {
+		input: `
+		// Comment
+
+		// Package foo ...
+		package foo
+		`,
+		pkg: "foo",
+	}}
+	for _, tc := range testCases {
+		t.Run("", func(t *testing.T) {
+			f, err := parser.ParseFile("test", tc.input)
+			if err != nil {
+				t.Fatal(err)
+			}
+			assert.Equal(t, f.PackageName(), tc.pkg)
+		})
+	}
+}