blob: 8739f0a1d4f81d365cda4350e7cafc7e374a9c1c [file] [log] [blame]
Marcel van Lohuizen17157ea2018-12-11 10:41:10 +01001// Copyright 2018 The CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cue
16
17import (
18 "fmt"
19 "strconv"
20
21 "cuelang.org/go/cue/ast"
22 "cuelang.org/go/cue/build"
23 "cuelang.org/go/cue/token"
24)
25
26// insertFile inserts the given file at the root of the instance.
27//
28// The contents will be merged (unified) with any pre-existing value. In this
29// case an error may be reported, but only if the merge failed at the top-level.
30// Other errors will be recorded at the respective values in the tree.
31//
32// There should be no unresolved identifiers in file, meaning the Node field
33// of all identifiers should be set to a non-nil value.
34func (inst *Instance) insertFile(f *ast.File) error {
35 // TODO: insert by converting to value first so that the trim command can
36 // also remove top-level fields.
37 // First process single file.
38 v := newVisitor(inst.index, inst.inst, inst.rootStruct, inst.scope)
39 v.astState.astMap[f] = inst.rootStruct
40 result := v.walk(f)
41 if isBottom(result) {
42 return result.(*bottom)
43 }
44
45 for _, c := range v.comprehensions {
46 inst.rootValue = mkBin(v.ctx(), token.NoPos, opUnify, inst.rootValue, c)
47 }
48
49 return nil
50}
51
52type astVisitor struct {
53 *astState
54 object *structLit
55 comprehensions []*structComprehension
56
57 inSelector int
58}
59
60func (v *astVisitor) ctx() *context {
61 return v.astState.ctx
62}
63
64type astState struct {
65 ctx *context
66 *index
67 inst *build.Instance
68
69 litParser *litParser
70 resolveRoot *structLit
71
72 // make unique per level to avoid reuse of structs being an issue.
73 astMap map[ast.Node]scope
74}
75
76func (s *astState) mapScope(n ast.Node) (m scope) {
77 if m = s.astMap[n]; m == nil {
78 m = newStruct(newNode(n))
79 s.astMap[n] = m
80 }
81 return m
82}
83
84func (s *astState) setScope(n ast.Node, v scope) {
85 if m, ok := s.astMap[n]; ok && m != v {
86 panic("already defined")
87 }
88 s.astMap[n] = v
89}
90
91func newVisitor(idx *index, inst *build.Instance, obj, resolveRoot *structLit) *astVisitor {
92 ctx := idx.newContext()
93 v := &astVisitor{
94 object: obj,
95 }
96 v.astState = &astState{
97 ctx: ctx,
98 index: ctx.index,
99 inst: inst,
100 litParser: &litParser{ctx: ctx},
101 resolveRoot: resolveRoot,
102 astMap: map[ast.Node]scope{},
103 }
104 return v
105}
106
107func (v *astVisitor) error(n ast.Node, args ...interface{}) value {
108 return v.mkErr(newNode(n), args...)
109}
110
111func (v *astVisitor) resolve(n *ast.Ident) value {
112 ctx := v.ctx()
113 label := v.label(n.Name, true)
114 if r := v.resolveRoot; r != nil {
115 if value, _ := r.lookup(v.ctx(), label); value != nil {
116 return &selectorExpr{newExpr(n),
117 &nodeRef{baseValue: newExpr(n), node: r}, label}
118 }
119 if v.inSelector > 0 {
120 if p := getBuiltinShorthandPkg(ctx, n.Name); p != nil {
121 return &nodeRef{baseValue: newExpr(n), node: p}
122 }
123 }
124 }
125 return nil
126}
127
128func (v *astVisitor) loadImport(imp *ast.ImportSpec) evaluated {
129 ctx := v.ctx()
130 val := lookupBuiltinPkg(ctx, imp)
131 if !isBottom(val) {
132 return val
133 }
134 path, err := strconv.Unquote(imp.Path.Value)
135 if err != nil {
136 return ctx.mkErr(newNode(imp), "illformed import spec")
137 }
138 bimp := v.inst.LookupImport(path)
139 if bimp == nil {
140 return ctx.mkErr(newNode(imp), "package %q not found", path)
141 }
142 impInst := v.index.loadInstance(bimp)
143 return impInst.rootValue.evalPartial(ctx)
144}
145
146// We probably don't need to call Walk.s
147func (v *astVisitor) walk(astNode ast.Node) (value value) {
148 switch n := astNode.(type) {
149 case *ast.File:
150 obj := v.object
151 v1 := &astVisitor{
152 astState: v.astState,
153 object: obj,
154 }
155 for _, e := range n.Decls {
156 switch x := e.(type) {
157 case *ast.EmitDecl:
158 if v1.object.emit == nil {
159 v1.object.emit = v1.walk(x.Expr)
160 } else {
161 v1.object.emit = mkBin(v.ctx(), token.NoPos, opUnify, v1.object.emit, v1.walk(x.Expr))
162 }
163 default:
164 v1.walk(e)
165 }
166 }
167 for _, c := range v1.comprehensions {
168 v.comprehensions = append(v.comprehensions, c)
169 }
170 value = obj
171
172 case *ast.ImportDecl:
173 for _, s := range n.Specs {
174 v.walk(s)
175 }
176
177 case *ast.ImportSpec:
178 val := v.loadImport(n)
179 if !isBottom(val) {
180 v.setScope(n, val.(*structLit))
181 }
182
183 case *ast.StructLit:
184 obj := v.mapScope(n).(*structLit)
185 v1 := &astVisitor{
186 astState: v.astState,
187 object: obj,
188 }
189 for _, e := range n.Elts {
190 switch x := e.(type) {
191 case *ast.EmitDecl:
192 // Only allowed at top-level.
193 v1.error(x, "emitting values is only allowed at top level")
194 case *ast.Field, *ast.Alias:
195 v1.walk(e)
196 case *ast.ComprehensionDecl:
197 v1.walk(x)
198 }
199 }
200 value = obj
201 for i, c := range v1.comprehensions {
202 if i == 0 && obj.template == nil && len(obj.arcs) == 0 {
203 value = c
204 continue
205 }
206 value = mkBin(v.ctx(), token.NoPos, opUnify, value, c)
207 }
208
209 case *ast.ComprehensionDecl:
210 yielder := &yield{baseValue: newExpr(n.Field.Value)}
211 sc := &structComprehension{
212 baseValue: newDecl(n),
213 clauses: wrapClauses(v, yielder, n.Clauses),
214 }
215 field := n.Field
216 switch x := field.Label.(type) {
217 case *ast.Interpolation:
218 yielder.key = v.walk(x)
219 yielder.value = v.walk(field.Value)
220
221 case *ast.ExprLabel:
222 yielder.key = v.walk(x.Label)
223 yielder.value = v.walk(field.Value)
224
225 case *ast.TemplateLabel:
226 f := v.label(x.Ident.Name, true)
227
228 sig := &params{}
229 sig.add(f, &basicType{newNode(field.Label), stringKind})
230 template := &lambdaExpr{newExpr(field.Value), sig, nil}
231
232 v.setScope(field, template)
233 template.value = v.walk(field.Value)
234 yielder.value = template
235 sc.isTemplate = true
236
237 case *ast.BasicLit, *ast.Ident:
238 name, ok := ast.LabelName(x)
239 if !ok {
240 return v.error(x, "invalid field name: %v", x)
241 }
242 if name != "" {
243 yielder.key = &stringLit{newNode(x), name}
244 yielder.value = v.walk(field.Value)
245 }
246
247 default:
248 panic("cue: unknown label type")
249 }
250 // yielder.key = v.walk(n.Field.Label)
251 // yielder.value = v.walk(n.Field.Value)
252 v.comprehensions = append(v.comprehensions, sc)
253
254 case *ast.Field:
255 switch x := n.Label.(type) {
256 case *ast.Interpolation:
257 yielder := &yield{baseValue: newNode(x)}
258 sc := &structComprehension{
259 baseValue: newDecl(n),
260 clauses: yielder,
261 }
262 yielder.key = v.walk(x)
263 yielder.value = v.walk(n.Value)
264 v.comprehensions = append(v.comprehensions, sc)
265
266 case *ast.ExprLabel:
267 yielder := &yield{baseValue: newNode(x.Label)}
268 sc := &structComprehension{
269 baseValue: newDecl(n),
270 clauses: yielder,
271 }
272 yielder.key = v.walk(x.Label)
273 yielder.value = v.walk(n.Value)
274 v.comprehensions = append(v.comprehensions, sc)
275
276 case *ast.TemplateLabel:
277 f := v.label(x.Ident.Name, true)
278
279 sig := &params{}
280 sig.add(f, &basicType{newNode(n.Label), stringKind})
281 template := &lambdaExpr{newExpr(n.Value), sig, nil}
282
283 v.setScope(n, template)
284 template.value = v.walk(n.Value)
285
286 if v.object.template == nil {
287 v.object.template = template
288 } else {
289 v.object.template = mkBin(v.ctx(), token.NoPos, opUnify, v.object.template, template)
290 }
291
292 case *ast.BasicLit, *ast.Ident:
293 f, ok := v.nodeLabel(x)
294 if !ok {
295 return v.error(n.Label, "invalid field name: %v", n.Label)
296 }
297 if f != 0 {
298 v.object.insertValue(v.ctx(), f, v.walk(n.Value))
299 }
300
301 default:
302 panic("cue: unknown label type")
303 }
304
305 case *ast.Alias:
306 // parsed verbatim at reference.
307
308 case *ast.LambdaExpr:
309 sig := &params{}
310 lambda := &lambdaExpr{newExpr(n), sig, nil}
311 v.setScope(n, lambda)
312
313 for _, p := range n.Params {
314 f, _ := v.nodeLabel(p.Label)
315 if p.Value != nil {
316 sig.add(f, v.walk(p.Value))
317 } else {
318 src := &ast.Ident{NamePos: p.Pos(), Name: "_"}
319 sig.add(f, &top{baseValue: newExpr(src)})
320 }
321 }
322 lambda.value = v.walk(n.Expr)
323 return lambda
324
325 case *ast.ListComprehension:
326 yielder := &yield{baseValue: newExpr(n.Expr)}
327 lc := &listComprehension{
328 newExpr(n),
329 wrapClauses(v, yielder, n.Clauses),
330 }
331 // we don't support key for lists (yet?)
332 yielder.value = v.walk(n.Expr)
333 return lc
334
335 case *ast.ExprLabel:
336
337 // Expressions
338 case *ast.Ident:
339 if n.Node == nil {
340 if value = v.resolve(n); value != nil {
341 break
342 }
343
344 switch n.Name {
345 case "_":
346 return &top{newExpr(n)}
347 case "string":
348 return &basicType{newExpr(n), stringKind}
349 case "bytes":
350 return &basicType{newExpr(n), bytesKind}
351 case "bool":
352 return &basicType{newExpr(n), boolKind}
353 case "int":
354 return &basicType{newExpr(n), intKind}
355 case "float":
356 return &basicType{newExpr(n), floatKind}
357 case "number":
358 return &basicType{newExpr(n), numKind}
359 case "duration":
360 return &basicType{newExpr(n), durationKind}
361
362 case "len":
363 return lenBuiltin
364 }
365 if r, ok := predefinedRanges[n.Name]; ok {
366 return r
367 }
368
369 value = v.error(n, "reference %q not found", n.Name)
370 break
371 }
372
373 if a, ok := n.Node.(*ast.Alias); ok {
374 value = v.walk(a.Expr)
375 break
376 }
377
378 label := v.label(n.Name, true)
379 if n.Scope != nil {
380 n2 := v.mapScope(n.Scope)
381 value = &nodeRef{baseValue: newExpr(n), node: n2}
382 value = &selectorExpr{newExpr(n), value, label}
383 } else {
384 n2 := v.mapScope(n.Node)
385 value = &nodeRef{baseValue: newExpr(n), node: n2}
386 }
387
388 case *ast.BottomLit:
389 value = v.error(n, "from source")
390
391 case *ast.BadDecl:
392 // nothing to do
393
394 case *ast.BadExpr:
395 value = v.error(n, "invalid expression")
396
397 case *ast.BasicLit:
398 value = v.litParser.parse(n)
399
400 case *ast.Interpolation:
401 if len(n.Elts) == 0 {
402 return v.error(n, "invalid interpolation")
403 }
404 first, ok1 := n.Elts[0].(*ast.BasicLit)
405 last, ok2 := n.Elts[len(n.Elts)-1].(*ast.BasicLit)
406 if !ok1 || !ok2 {
407 return v.error(n, "invalid interpolation")
408 }
409 if len(n.Elts) == 1 {
410 value = v.walk(n.Elts[0])
411 break
412 }
413 lit := &interpolation{baseValue: newExpr(n), k: stringKind}
414 value = lit
415 quote, err := stringType(first.Value)
416 if err != nil {
417 return v.error(n, "invalid interpolation: %v", err)
418 }
419 if quote[0] == '\'' {
420 return v.error(n, "interpolation not implemented for bytes: %v", err)
421 }
422 ws, err := wsPrefix(last.Value, quote)
423 if err != nil {
424 return v.error(n, "invalid interpolation: %v", err)
425 }
426 prefix := quote
427 multi := len(quote) == 3
428 p := v.litParser
429 for i := 0; i < len(n.Elts); i += 2 {
430 l, ok := n.Elts[i].(*ast.BasicLit)
431 if !ok {
432 return v.error(n, "invalid interpolation")
433 }
434 if err := p.init(l); err != nil {
435 return v.error(n, "invalid interpolation: %v", err)
436 }
437 if i+1 < len(n.Elts) {
438 x := p.parseString(prefix, `\(`, ws, multi, quote[0])
439 lit.parts = append(lit.parts, x, v.walk(n.Elts[i+1]))
440 } else {
441 x := p.parseString(prefix, quote, ws, multi, quote[0])
442 lit.parts = append(lit.parts, x)
443 }
444 prefix = ")"
445 }
446
447 case *ast.ListLit:
448 list := &list{baseValue: newExpr(n)}
449 for _, e := range n.Elts {
450 list.a = append(list.a, v.walk(e))
451 }
452 list.initLit()
453 if n.Ellipsis != token.NoPos || n.Type != nil {
454 list.len = &rangeLit{list.baseValue, list.len, &top{list.baseValue}}
455 if n.Type != nil {
456 list.typ = v.walk(n.Type)
457 }
458 }
459 value = list
460
461 case *ast.ParenExpr:
462 value = v.walk(n.X)
463
464 case *ast.SelectorExpr:
465 v.inSelector++
466 value = &selectorExpr{
467 newExpr(n),
468 v.walk(n.X),
469 v.label(n.Sel.Name, true),
470 }
471 v.inSelector--
472
473 case *ast.IndexExpr:
474 value = &indexExpr{newExpr(n), v.walk(n.X), v.walk(n.Index)}
475
476 case *ast.SliceExpr:
477 slice := &sliceExpr{baseValue: newExpr(n), x: v.walk(n.X)}
478 if n.Low != nil {
479 slice.lo = v.walk(n.Low)
480 }
481 if n.High != nil {
482 slice.hi = v.walk(n.High)
483 }
484 value = slice
485
486 case *ast.CallExpr:
487 call := &callExpr{baseValue: newExpr(n), x: v.walk(n.Fun)}
488 for _, a := range n.Args {
489 call.args = append(call.args, v.walk(a))
490 }
491 value = call
492
493 case *ast.UnaryExpr:
494 value = &unaryExpr{
495 newExpr(n),
496 tokenMap[n.Op],
497 v.walk(n.X),
498 }
499
500 case *ast.BinaryExpr:
501 switch n.Op {
502 case token.DISJUNCTION:
503 value = makeDisjunction(v.ctx(), n, v.walk(n.X), v.walk(n.Y))
504 case token.RANGE:
505 value = &rangeLit{
506 newExpr(n),
507 v.walk(n.X), // from
508 v.walk(n.Y), // to
509 }
510 default:
511 value = &binaryExpr{
512 newExpr(n),
513 tokenMap[n.Op], // op
514 v.walk(n.X), // left
515 v.walk(n.Y), // right
516 }
517 }
518
519 // nothing to do
520 // case *syntax.EmitDecl:
521 default:
522 // TODO: unhandled node.
523 // value = ctx.mkErr(n, "unknown node type %T", n)
524 panic(fmt.Sprintf("unimplemented %T", n))
525
526 }
527 return value
528}
529
530func wrapClauses(v *astVisitor, y yielder, clauses []ast.Clause) yielder {
531 for _, c := range clauses {
532 if n, ok := c.(*ast.ForClause); ok {
533 params := &params{}
534 fn := &lambdaExpr{newExpr(n.Source), params, nil}
535 v.setScope(n, fn)
536 }
537 }
538 for i := len(clauses) - 1; i >= 0; i-- {
539 switch n := clauses[i].(type) {
540 case *ast.ForClause:
541 fn := v.mapScope(n).(*lambdaExpr)
542 fn.value = y
543
544 key := "_"
545 if n.Key != nil {
546 key = n.Key.Name
547 }
548 f := v.label(key, true)
549 fn.add(f, &basicType{newExpr(n.Key), stringKind | intKind})
550
551 f = v.label(n.Value.Name, true)
552 fn.add(f, &top{})
553
554 y = &feed{newExpr(n.Source), v.walk(n.Source), fn}
555
556 case *ast.IfClause:
557 y = &guard{newExpr(n.Condition), v.walk(n.Condition), y}
558 }
559 }
560 return y
561}