cue: add API for merged doc comments

field doc for Value
pkg docs for an Instance

Fixes #36

Change-Id: I45bf4604aafa235bdd987a449184b99b2a084db7
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2020
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/cue/ast.go b/cue/ast.go
index 1485a2a..7f00b4e 100644
--- a/cue/ast.go
+++ b/cue/ast.go
@@ -50,6 +50,13 @@
 type astVisitor struct {
 	*astState
 	object *structLit
+	// For single line fields, the doc comment is applied to the inner-most
+	// field value.
+	//
+	//   // This comment is for bar.
+	//   foo bar: value
+	//
+	doc *docNode
 
 	inSelector int
 }
@@ -187,6 +194,10 @@
 			astState: v.astState,
 			object:   obj,
 		}
+		passDoc := len(n.Elts) == 1 && !n.Lbrace.IsValid() && v.doc != nil
+		if passDoc {
+			v1.doc = v.doc
+		}
 		for _, e := range n.Elts {
 			switch x := e.(type) {
 			case *ast.EmitDecl:
@@ -198,6 +209,9 @@
 				v1.walk(x)
 			}
 		}
+		if passDoc {
+			v.doc = v1.doc // signal usage of document back to parent.
+		}
 		value = obj
 
 	case *ast.ComprehensionDecl:
@@ -274,7 +288,7 @@
 
 			sig := &params{}
 			sig.add(f, &basicType{newNode(n.Label), stringKind})
-			template := &lambdaExpr{newExpr(n.Value), sig, nil}
+			template := &lambdaExpr{newNode(n), sig, nil}
 
 			v.setScope(n, template)
 			template.value = v.walk(n.Value)
@@ -298,7 +312,17 @@
 				return v.error(n.Label, "invalid field name: %v", n.Label)
 			}
 			if f != 0 {
-				v.object.insertValue(v.ctx(), f, opt, v.walk(n.Value), attrs)
+				var leftOverDoc *docNode
+				for _, c := range n.Comments() {
+					if c.Position == 0 {
+						leftOverDoc = v.doc
+						v.doc = &docNode{n: n}
+						break
+					}
+				}
+				val := v.walk(n.Value)
+				v.object.insertValue(v.ctx(), f, opt, val, attrs, v.doc)
+				v.doc = leftOverDoc
 			}
 
 		default: