// Copyright 2018 The CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cue

import (
	"fmt"
	"strconv"
	"strings"

	"golang.org/x/xerrors"

	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/build"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/literal"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/internal"
)

// insertFile inserts the given file at the root of the instance.
//
// The contents will be merged (unified) with any pre-existing value. In this
// case an error may be reported, but only if the merge failed at the top-level.
// Other errors will be recorded at the respective values in the tree.
//
// There should be no unresolved identifiers in file, meaning the Node field
// of all identifiers should be set to a non-nil value.
func (inst *Instance) insertFile(f *ast.File) errors.Error {
	// TODO: insert by converting to value first so that the trim command can
	// also remove top-level fields.
	// First process single file.
	v := newVisitor(inst.index, inst.inst, inst.rootStruct, inst.scope, false)
	v.astState.astMap[f] = inst.rootStruct
	// TODO: fix cmd/import to resolve references in the AST before
	// inserting. For now, we accept errors that did not make it up to the tree.
	result := v.walk(f)
	if isBottom(result) {
		val := newValueRoot(v.ctx(), result)
		v.errors = errors.Append(v.errors, val.toErr(result.(*bottom)))
	}
	return v.errors
}

type astVisitor struct {
	*astState
	object *structLit

	parent *astVisitor
	sel    string // label or index; may be '*'
	// 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
}

func (v *astVisitor) ctx() *context {
	return v.astState.ctx
}

type astState struct {
	ctx *context
	*index
	inst *build.Instance

	litParser   *litParser
	resolveRoot *structLit
	allowAuto   bool // allow builtin packages without import

	// make unique per level to avoid reuse of structs being an issue.
	astMap   map[ast.Node]scope
	aliasMap map[ast.Node]value

	errors errors.Error
}

func (s *astState) mapScope(n ast.Node) (m scope) {
	if m = s.astMap[n]; m == nil {
		m = newStruct(newNode(n))
		s.astMap[n] = m
	}
	return m
}

func (s *astState) setScope(n ast.Node, v scope) {
	if m, ok := s.astMap[n]; ok && m != v {
		panic("already defined")
	}
	s.astMap[n] = v
}

func newVisitor(idx *index, inst *build.Instance, obj, resolveRoot *structLit, allowAuto bool) *astVisitor {
	ctx := idx.newContext()
	return newVisitorCtx(ctx, inst, obj, resolveRoot, allowAuto)
}

func newVisitorCtx(ctx *context, inst *build.Instance, obj, resolveRoot *structLit, allowAuto bool) *astVisitor {
	v := &astVisitor{
		object: obj,
	}
	v.astState = &astState{
		ctx:         ctx,
		index:       ctx.index,
		inst:        inst,
		litParser:   &litParser{ctx: ctx},
		resolveRoot: resolveRoot,
		allowAuto:   allowAuto,
		astMap:      map[ast.Node]scope{},
		aliasMap:    map[ast.Node]value{},
	}
	return v
}

func (v *astVisitor) errf(n ast.Node, format string, args ...interface{}) evaluated {
	v.astState.errors = errors.Append(v.astState.errors, &nodeError{
		path:    v.appendPath(nil),
		n:       n,
		Message: errors.NewMessage(format, args),
	})
	arguments := append([]interface{}{format}, args...)
	return v.mkErr(newNode(n), arguments...)
}

func (v *astVisitor) appendPath(a []string) []string {
	if v.parent != nil {
		a = v.parent.appendPath(a)
	}
	if v.sel != "" {
		a = append(a, v.sel)
	}
	return a
}

func (v *astVisitor) resolve(n *ast.Ident) value {
	ctx := v.ctx()
	name := v.ident(n)
	label := v.Label(name, true)
	if r := v.resolveRoot; r != nil {
		for _, a := range r.Arcs {
			if a.Label == label {
				return &selectorExpr{newExpr(n),
					&nodeRef{baseValue: newExpr(n), node: r, label: label}, label}
			}
		}
		if v.inSelector > 0 && v.allowAuto {
			if p := getBuiltinShorthandPkg(ctx, name); p != nil {
				return &nodeRef{newExpr(n), p, label}
			}
		}
	}
	return nil
}

func (v *astVisitor) loadImport(imp *ast.ImportSpec) evaluated {
	ctx := v.ctx()
	path, err := literal.Unquote(imp.Path.Value)
	if err != nil {
		return v.errf(imp, "illformed import spec")
	}
	// TODO: allow builtin *and* imported package. The result is a unified
	// struct.
	if p := getBuiltinPkg(ctx, path); p != nil {
		return p
	}
	bimp := v.inst.LookupImport(path)
	if bimp == nil {
		return v.errf(imp, "package %q not found", path)
	}
	impInst := v.index.loadInstance(bimp)
	return impInst.rootValue.evalPartial(ctx)
}

func (v *astVisitor) ident(n *ast.Ident) string {
	str, err := ast.ParseIdent(n)
	if err != nil {
		v.errf(n, "invalid literal: %v", err)
		return n.Name
	}
	return str
}

// We probably don't need to call Walk.s
func (v *astVisitor) walk(astNode ast.Node) (ret value) {
	switch n := astNode.(type) {
	case *ast.File:
		obj := v.object
		v1 := &astVisitor{
			astState: v.astState,
			object:   obj,
		}
		for _, e := range n.Decls {
			switch x := e.(type) {
			case *ast.EmbedDecl:
				if v1.object.emit == nil {
					v1.object.emit = v1.walk(x.Expr)
				} else {
					v1.object.emit = mkBin(v.ctx(), token.NoPos, opUnify, v1.object.emit, v1.walk(x.Expr))
				}
			case *ast.Ellipsis:
				// handled elsewhere

			default:
				v1.walk(e)
			}
		}
		ret = obj

	case *ast.Package:
		// NOTE: Do NOT walk the identifier of the package here, as it is not
		// supposed to resolve to anything.

	case *ast.ImportDecl:
		for _, s := range n.Specs {
			v.walk(s)
		}

	case *ast.ImportSpec:
		val := v.loadImport(n)
		if !isBottom(val) {
			v.setScope(n, val.(*structLit))
		}

	case *ast.StructLit:
		obj := v.mapScope(n).(*structLit)
		v1 := &astVisitor{
			astState: v.astState,
			object:   obj,
			parent:   v,
		}
		passDoc := len(n.Elts) == 1 && !n.Lbrace.IsValid() && v.doc != nil
		if passDoc {
			v1.doc = v.doc
		}
		ret = obj
		for i, e := range n.Elts {
			switch x := e.(type) {
			case *ast.Ellipsis:
				if i != len(n.Elts)-1 {
					return v1.walk(x.Type) // Generate an error
				}
				f := v.ctx().Label("_", true)
				sig := &params{}
				sig.add(f, &basicType{newNode(x), stringKind})
				template := &lambdaExpr{newNode(x), sig, &top{newNode(x)}}
				v1.object.addTemplate(v.ctx(), x.Pos(), nil, template)

			case *ast.EmbedDecl:
				old := v.ctx().inDefinition
				v.ctx().inDefinition = 0
				e := v1.walk(x.Expr)
				v.ctx().inDefinition = old
				if isBottom(e) {
					return e
				}
				if e.Kind()&structKind == 0 {
					return v1.errf(x, "can only embed structs (found %v)", e.Kind())
				}
				ret = mkBin(v1.ctx(), x.Pos(), opUnifyUnchecked, ret, e)
				// TODO: preserve order of embedded fields. We cannot split into
				// separate unifications here, as recursive references point to
				// obj and would have to be dereferenced and copied.
				// Solving this is best done with a generic topological sort
				// mechanism.

			case *ast.Field, *ast.Alias, *ast.LetClause:
				v1.walk(e)

			case *ast.Comprehension:
				v1.walk(x)

			case *ast.Attribute:
				// Nothing to do.
			}
		}
		if v.ctx().inDefinition > 0 && !obj.optionals.isFull() {
			// For embeddings this is handled in binOp, in which case the
			// isClosed bit is cleared if a template is introduced.
			obj.closeStatus = toClose
		}
		if passDoc {
			v.doc = v1.doc // signal usage of document back to parent.
		}

	case *ast.ListLit:
		v1 := &astVisitor{
			astState: v.astState,
			object:   v.object,
			parent:   v,
		}

		if len(n.Elts) == 1 {
			if c, ok := n.Elts[0].(*ast.Comprehension); ok {
				yielder := &yield{baseValue: newExpr(c.Value)}
				lc := &listComprehension{
					newExpr(c),
					wrapClauses(v, yielder, c.Clauses),
				}
				// we don't support key for lists (yet?)

				// TODO(hack): unwrap struct lit if embedding of one element.
				// We do this as we do not yet support embedding of scalar
				// values in general. This prohibits:
				// - having fields alongside embedded values
				// - having more than one embedded value.
				// The latter would not be too hard to circumvent.
				expr := c.Value
				if s, ok := expr.(*ast.StructLit); ok && len(s.Elts) == 1 {
					if e, ok := s.Elts[0].(*ast.EmbedDecl); ok {
						expr = e.Expr
					}
				}
				yielder.value = v.walk(expr)
				return lc
			}
		}

		elts, ellipsis := internal.ListEllipsis(n)

		arcs := []arc{}
		for i, e := range elts {
			if _, ok := e.(*ast.Comprehension); ok {
				return v.errf(e, "comprehensions must be a single element within list (for now)")
			}
			elem := v1.walk(e)
			if elem == nil {
				// TODO: it would be consistent to allow aliasing in lists
				// as well, with a similar meaning as alias declarations in
				// structs.
				return v.errf(n, "alias not allowed in list")
			}
			v1.sel = strconv.Itoa(i)
			arcs = append(arcs, arc{Label: label(i), v: elem})
		}
		s := &structLit{baseValue: newExpr(n), Arcs: arcs}
		list := &list{baseValue: newExpr(n), elem: s}
		list.initLit()
		if ellipsis != nil {
			list.len = newBound(v.ctx(), list.baseValue, opGeq, intKind, list.len)
			if ellipsis.Type != nil {
				list.typ = v1.walk(ellipsis.Type)
			}
		}
		ret = list

	case *ast.Ellipsis:
		return v.errf(n, "ellipsis (...) only allowed at end of list or struct")

	case *ast.Comprehension:
		yielder := &yield{baseValue: newExpr(n.Value)}
		sc := &structComprehension{
			newNode(n),
			wrapClauses(v, yielder, n.Clauses),
		}
		// we don't support key for lists (yet?)
		switch n.Value.(type) {
		case *ast.StructLit:
		default:
			// Caught by parser, usually.
			v.errf(n, "comprehension must be struct")
		}
		yielder.value = v.walk(n.Value)
		v.object.comprehensions = append(v.object.comprehensions, compValue{comp: sc})

	case *ast.Field:
		opt := n.Optional != token.NoPos
		isDef := internal.IsDefinition(n.Label) || n.Token == token.ISA
		if isDef {
			ctx := v.ctx()
			ctx.inDefinition++
			defer func() { ctx.inDefinition-- }()
		}
		attrs, err := createAttrs(v.ctx(), newNode(n), n.Attrs)
		if err != nil {
			return v.errf(n, err.format, err.args)
		}
		var leftOverDoc *docNode
		for _, c := range n.Comments() {
			if c.Position == 0 {
				leftOverDoc = v.doc
				v.doc = &docNode{n: n}
				break
			}
		}

		lab := n.Label
		if a, ok := lab.(*ast.Alias); ok {
			if lab, ok = a.Expr.(ast.Label); !ok {
				return v.errf(n, "alias expression is not a valid label")
			}
		}

		switch x := lab.(type) {
		case *ast.Interpolation:
			v.sel = "?"
			// Must be struct comprehension.
			fc := &fieldComprehension{
				baseValue: newDecl(n),
				key:       v.walk(x),
				val:       v.walk(n.Value),
				opt:       opt,
				def:       isDef,
				doc:       leftOverDoc,
				attrs:     attrs,
			}
			v.object.comprehensions = append(v.object.comprehensions, compValue{comp: fc})

		case *ast.ListLit:
			if len(x.Elts) != 1 {
				return v.errf(x, "optional label expression must have exactly one element; found %d", len(x.Elts))
			}
			var f label
			expr := x.Elts[0]
			a, ok := expr.(*ast.Alias)
			if ok {
				expr = a.Expr
				f = v.Label(v.ident(a.Ident), true)
			} else {
				f = v.Label("_", true)
			}

			// Parse the key filter or a bulk-optional field. The special value
			// of nil to mean "all fields".
			var key value
			if i, ok := expr.(*ast.Ident); !ok || (i.Name != "string" && i.Name != "_") {
				key = v.walk(expr)
			}
			v.sel = "*"

			sig := &params{}
			sig.add(f, &basicType{newNode(lab), stringKind})
			template := &lambdaExpr{newNode(n), sig, nil}

			v.setScope(n, template)
			template.value = v.walk(n.Value)

			v.object.addTemplate(v.ctx(), token.NoPos, key, template)

		case *ast.TemplateLabel:
			if isDef {
				v.errf(x, "map element type cannot be a definition")
			}
			v.sel = "*"
			f := v.Label(v.ident(x.Ident), true)

			sig := &params{}
			sig.add(f, &basicType{newNode(lab), stringKind})
			template := &lambdaExpr{newNode(n), sig, nil}

			v.setScope(n, template)
			template.value = v.walk(n.Value)

			v.object.addTemplate(v.ctx(), token.NoPos, nil, template)

		case *ast.BasicLit, *ast.Ident:
			v.sel, _, _ = ast.LabelName(x)
			if v.sel == "_" {
				if _, ok := x.(*ast.BasicLit); ok {
					v.sel = "*"
				}
			}
			f, ok := v.NodeLabel(x)
			if !ok {
				return v.errf(lab, "invalid field name: %v", lab)
			}
			val := v.walk(n.Value)
			if val == nil {
				return v.errf(lab, "invalid field value: %v",
					internal.DebugStr(n.Value))
			}
			v.object.insertValue(v.ctx(), f, opt, isDef, val, attrs, v.doc)
			v.doc = leftOverDoc

		default:
			panic("cue: unknown label type")
		}

	case *ast.Alias, *ast.LetClause:
		// parsed verbatim at reference.

	case *ast.ListComprehension:
		yielder := &yield{baseValue: newExpr(n.Expr)}
		lc := &listComprehension{
			newExpr(n),
			wrapClauses(v, yielder, n.Clauses),
		}
		// we don't support key for lists (yet?)
		yielder.value = v.walk(n.Expr)
		return lc

	// Expressions
	case *ast.Ident:
		name := v.ident(n)

		if name == "_" {
			ret = &top{newNode(n)}
			break
		}

		if n.Node == nil {
			if ret = v.resolve(n); ret != nil {
				break
			}

			// TODO: consider supporting GraphQL-style names:
			// String, Bytes, Boolean, Integer, Number.
			// These names will not conflict with idiomatic camel-case JSON.
			switch name {
			case "_":
				return &top{newExpr(n)}
			case "string", "__string":
				return &basicType{newExpr(n), stringKind}
			case "bytes", "__bytes":
				return &basicType{newExpr(n), bytesKind}
			case "bool", "__bool":
				return &basicType{newExpr(n), boolKind}
			case "int", "__int":
				return &basicType{newExpr(n), intKind}
			case "float", "__float":
				return &basicType{newExpr(n), floatKind}
			case "number", "__number":
				return &basicType{newExpr(n), numKind}

			case "len", "__len":
				return lenBuiltin
			case "close", "__close":
				return closeBuiltin
			case "and", "__and":
				return andBuiltin
			case "or", "__or":
				return orBuiltin
			}
			if r, ok := predefinedRanges[name]; ok {
				return r
			}

			ret = v.errf(n, "reference %q not found", name)
			break
		}

		// Type of reference      Scope          Node
		// Let Clause             File/Struct    LetClause
		// Alias declaration      File/Struct    Alias (deprecated)
		// Illegal Reference      File/Struct
		// Fields
		//    Label               File/Struct    ParenExpr, Ident, BasicLit
		//    Value               File/Struct    Field
		// Template               Field          Template
		// Fields inside lambda
		//    Label               Field          Expr
		//    Value               Field          Field
		// Pkg                    nil            ImportSpec
		var expr ast.Expr
		switch x := n.Node.(type) {
		case *ast.Alias:
			expr = x.Expr
		case *ast.LetClause:
			expr = x.Expr
		}

		if expr != nil {
			// TODO(lang): should we exempt definitions? The substitution
			// principle says we should not.
			if ret = v.aliasMap[expr]; ret != nil {
				break
			}
			old := v.ctx().inDefinition
			v.ctx().inDefinition = 0
			ret = v.walk(expr)
			v.aliasMap[expr] = ret
			v.ctx().inDefinition = old
			break
		}

		f := v.Label(name, true)
		if _, ok := n.Node.(*ast.ImportSpec); ok {
			n2 := v.mapScope(n.Node)
			ref := &nodeRef{baseValue: newExpr(n), node: n2, label: f}
			ret = ref
			break
		}

		// TODO: probably unused. Verify and remove.
		if n.Scope == nil {
			// Package or direct ancestor node.
			n2 := v.mapScope(n.Node)
			ref := &nodeRef{baseValue: newExpr(n), node: n2, label: f}
			ret = ref
			break
		}

		n2 := v.mapScope(n.Scope)
		ret = &nodeRef{baseValue: newExpr(n), node: n2}

		// Allow different names to refer to the same field in unification. We
		// do this by anonymizing the the reference. This then has to be
		// resolved again when refering to lambdas.
		l, lambda := n2.(*lambdaExpr)
		if lambda && len(l.params.arcs) == 1 {
			f = 0
		}

		if field, ok := n.Node.(*ast.Field); ok {
			if lambda {
				// inside bulk optional.
				ret = v.errf(n, "referencing field (%q) within lambda not yet unsupported", name)
				break
			}
			name, _, err := ast.LabelName(field.Label)
			switch {
			case xerrors.Is(err, ast.ErrIsExpression):
				a := field.Label.(*ast.Alias)
				ret = &indexExpr{newExpr(n), ret, v.walk(a.Expr)}

			case err != nil:
				ret = v.errf(n, "invalid label: %v", err)

			case name != "":
				f = v.Label(name, true)
				ret = &selectorExpr{newExpr(n), ret, f}

			default:
				// TODO: support dynamically computed label lookup.
				// Should that also support lookup of definitions?
				ret = v.errf(n, "unsupported field alias %q", name)
			}
			break
		}

		ret = &selectorExpr{newExpr(n), ret, f}

	case *ast.BottomLit:
		// TODO: record inline comment.
		ret = &bottom{baseValue: newExpr(n), Code: codeUser, format: "from source"}

	case *ast.BadDecl:
		// nothing to do

	case *ast.BadExpr:
		ret = v.errf(n, "invalid expression")

	case *ast.BasicLit:
		ret = v.litParser.parse(n)

	case *ast.Interpolation:
		if len(n.Elts) == 0 {
			return v.errf(n, "invalid interpolation")
		}
		first, ok1 := n.Elts[0].(*ast.BasicLit)
		last, ok2 := n.Elts[len(n.Elts)-1].(*ast.BasicLit)
		if !ok1 || !ok2 {
			return v.errf(n, "invalid interpolation")
		}
		if len(n.Elts) == 1 {
			ret = v.walk(n.Elts[0])
			break
		}
		lit := &interpolation{baseValue: newExpr(n), K: stringKind}
		ret = lit
		info, prefixLen, _, err := literal.ParseQuotes(first.Value, last.Value)
		if err != nil {
			return v.errf(n, "invalid interpolation: %v", err)
		}
		prefix := ""
		for i := 0; i < len(n.Elts); i += 2 {
			l, ok := n.Elts[i].(*ast.BasicLit)
			if !ok {
				return v.errf(n, "invalid interpolation")
			}
			s := l.Value
			if !strings.HasPrefix(s, prefix) {
				return v.errf(l, "invalid interpolation: unmatched ')'")
			}
			s = l.Value[prefixLen:]
			x := parseString(v.ctx(), l, info, s)
			lit.Parts = append(lit.Parts, x)
			if i+1 < len(n.Elts) {
				lit.Parts = append(lit.Parts, v.walk(n.Elts[i+1]))
			}
			prefix = ")"
			prefixLen = 1
		}

	case *ast.ParenExpr:
		ret = v.walk(n.X)

	case *ast.SelectorExpr:
		v.inSelector++
		ret = &selectorExpr{
			newExpr(n),
			v.walk(n.X),
			v.Label(v.ident(n.Sel), true),
		}
		v.inSelector--

	case *ast.IndexExpr:
		ret = &indexExpr{newExpr(n), v.walk(n.X), v.walk(n.Index)}

	case *ast.SliceExpr:
		slice := &sliceExpr{baseValue: newExpr(n), X: v.walk(n.X)}
		if n.Low != nil {
			slice.Lo = v.walk(n.Low)
		}
		if n.High != nil {
			slice.Hi = v.walk(n.High)
		}
		ret = slice

	case *ast.CallExpr:
		call := &callExpr{baseValue: newExpr(n), Fun: v.walk(n.Fun)}
		for _, a := range n.Args {
			call.Args = append(call.Args, v.walk(a))
		}
		ret = call

	case *ast.UnaryExpr:
		switch n.Op {
		case token.NOT, token.ADD, token.SUB:
			ret = &unaryExpr{
				newExpr(n),
				tokenMap[n.Op],
				v.walk(n.X),
			}
		case token.GEQ, token.GTR, token.LSS, token.LEQ,
			token.NEQ, token.MAT, token.NMAT:
			ret = newBound(
				v.ctx(),
				newExpr(n),
				tokenMap[n.Op],
				topKind|nonGround,
				v.walk(n.X),
			)

		case token.MUL:
			return v.errf(n, "preference mark not allowed at this position")
		default:
			return v.errf(n, "unsupported unary operator %q", n.Op)
		}

	case *ast.BinaryExpr:
		switch n.Op {
		case token.OR:
			d := &disjunction{baseValue: newExpr(n)}
			v.addDisjunctionElem(d, n.X, false)
			v.addDisjunctionElem(d, n.Y, false)
			ret = d

		default:
			ret = updateBin(v.ctx(), &binaryExpr{
				newExpr(n),
				tokenMap[n.Op], // op
				v.walk(n.X),    // left
				v.walk(n.Y),    // right
			})
		}

	case *ast.CommentGroup:
		// Nothing to do for a free-floating comment group.

	case *ast.Attribute:
		// Nothing to do for now.

	// nothing to do
	// case *syntax.EmbedDecl:
	default:
		// TODO: unhandled node.
		// value = ctx.mkErr(n, "unknown node type %T", n)
		panic(fmt.Sprintf("unimplemented %T", n))

	}
	return ret
}

func (v *astVisitor) addDisjunctionElem(d *disjunction, n ast.Node, mark bool) {
	switch x := n.(type) {
	case *ast.BinaryExpr:
		if x.Op == token.OR {
			v.addDisjunctionElem(d, x.X, mark)
			v.addDisjunctionElem(d, x.Y, mark)
			return
		}
	case *ast.UnaryExpr:
		if x.Op == token.MUL {
			mark = true
			n = x.X
		}
		d.HasDefaults = true
	}
	d.Values = append(d.Values, dValue{v.walk(n), mark})
}

func wrapClauses(v *astVisitor, y yielder, clauses []ast.Clause) yielder {
	for _, c := range clauses {
		if n, ok := c.(*ast.ForClause); ok {
			params := &params{}
			fn := &lambdaExpr{newExpr(n.Source), params, nil}
			v.setScope(n, fn)
		}
	}
	for i := len(clauses) - 1; i >= 0; i-- {
		switch n := clauses[i].(type) {
		case *ast.ForClause:
			fn := v.mapScope(n).(*lambdaExpr)
			fn.value = y

			key := "_"
			if n.Key != nil {
				key = v.ident(n.Key)
			}
			f := v.Label(key, true)
			fn.add(f, &basicType{newExpr(n.Key), stringKind | intKind})

			f = v.Label(v.ident(n.Value), true)
			fn.add(f, &top{})

			y = &feed{newExpr(n.Source), v.walk(n.Source), fn}

		case *ast.IfClause:
			y = &guard{newExpr(n.Condition), v.walk(n.Condition), y}
		}
	}
	return y
}
