internal: factor out FileComment code

Change-Id: I8480431e1c4e2314af91ec775a72cb817e6bf4a5
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5743
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/instance.go b/cue/instance.go
index d26b496..5cf2e9f 100644
--- a/cue/instance.go
+++ b/cue/instance.go
@@ -170,32 +170,8 @@
 		return nil
 	}
 	for _, f := range inst.inst.Files {
-		pkg, _, _ := internal.PackageInfo(f)
-		var cgs []*ast.CommentGroup
-		if pkg != nil {
-			cgs = pkg.Comments()
-		} else if cgs = f.Comments(); len(cgs) > 0 {
-			// Use file comment.
-		} else {
-			// Use first comment declaration before any package or import.
-			for _, d := range f.Decls {
-				switch x := d.(type) {
-				case *ast.Attribute:
-					continue
-				case *ast.CommentGroup:
-					cgs = append(cgs, x)
-				}
-				break
-			}
-		}
-		var cg *ast.CommentGroup
-		for _, c := range cgs {
-			if c.Position == 0 {
-				cg = c
-			}
-		}
-		if cg != nil {
-			docs = append(docs, cg)
+		if c := internal.FileComment(f); c != nil {
+			docs = append(docs, c)
 		}
 	}
 	return docs
diff --git a/internal/internal.go b/internal/internal.go
index 06545b9..58b69ee 100644
--- a/internal/internal.go
+++ b/internal/internal.go
@@ -154,6 +154,36 @@
 	return cg
 }
 
+func FileComment(f *ast.File) *ast.CommentGroup {
+	pkg, _, _ := PackageInfo(f)
+	var cgs []*ast.CommentGroup
+	if pkg != nil {
+		cgs = pkg.Comments()
+	} else if cgs = f.Comments(); len(cgs) > 0 {
+		// Use file comment.
+	} else {
+		// Use first comment before any declaration.
+		for _, d := range f.Decls {
+			if cg, ok := d.(*ast.CommentGroup); ok {
+				return cg
+			}
+			if cgs = ast.Comments(d); cgs != nil {
+				break
+			}
+			if _, ok := d.(*ast.Attribute); !ok {
+				break
+			}
+		}
+	}
+	var cg *ast.CommentGroup
+	for _, c := range cgs {
+		if c.Position == 0 {
+			cg = c
+		}
+	}
+	return cg
+}
+
 func NewAttr(name, str string) *ast.Attribute {
 	buf := &strings.Builder{}
 	buf.WriteByte('@')