// Copyright 2017 The Bazel Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package resolve defines a name-resolution pass for Starlark abstract
// syntax trees.
//
// The resolver sets the Locals and FreeVars arrays of each DefStmt and
// the LocalIndex field of each syntax.Ident that refers to a local or
// free variable.  It also sets the Locals array of a File for locals
// bound by top-level comprehensions and load statements.
// Identifiers for global variables do not get an index.
package resolve // import "go.starlark.net/resolve"

// All references to names are statically resolved.  Names may be
// predeclared, global, or local to a function or file.
// File-local variables include those bound by top-level comprehensions
// and by load statements. ("Top-level" means "outside of any function".)
// The resolver maps each global name to a small integer and each local
// name to a small integer; these integers enable a fast and compact
// representation of globals and locals in the evaluator.
//
// As an optimization, the resolver classifies each predeclared name as
// either universal (e.g. None, len) or per-module (e.g. glob in Bazel's
// build language), enabling the evaluator to share the representation
// of the universal environment across all modules.
//
// The lexical environment is a tree of blocks with the file block at
// its root. The file's child blocks may be of two kinds: functions
// and comprehensions, and these may have further children of either
// kind.
//
// Python-style resolution requires multiple passes because a name is
// determined to be local to a function only if the function contains a
// "binding" use of it; similarly, a name is determined to be global (as
// opposed to predeclared) if the module contains a top-level binding use.
// Unlike ordinary top-level assignments, the bindings created by load
// statements are local to the file block.
// A non-binding use may lexically precede the binding to which it is resolved.
// In the first pass, we inspect each function, recording in
// 'uses' each identifier and the environment block in which it occurs.
// If a use of a name is binding, such as a function parameter or
// assignment, we add the name to the block's bindings mapping and add a
// local variable to the enclosing function.
//
// As we finish resolving each function, we inspect all the uses within
// that function and discard ones that were found to be function-local. The
// remaining ones must be either free (local to some lexically enclosing
// function), or top-level (global, predeclared, or file-local), but we cannot tell
// which until we have finished inspecting the outermost enclosing
// function. At that point, we can distinguish local from top-level names
// (and this is when Python would compute free variables).
//
// However, Starlark additionally requires that all references to global
// names are satisfied by some declaration in the current module;
// Starlark permits a function to forward-reference a global or file-local
// that has not
// been declared yet so long as it is declared before the end of the
// module.  So, instead of re-resolving the unresolved references after
// each top-level function, we defer this until the end of the module
// and ensure that all such references are satisfied by some definition.
//
// At the end of the module, we visit each of the nested function blocks
// in bottom-up order, doing a recursive lexical lookup for each
// unresolved name.  If the name is found to be local to some enclosing
// function, we must create a DefStmt.FreeVar (capture) parameter for
// each intervening function.  We enter these synthetic bindings into
// the bindings map so that we create at most one freevar per name.  If
// the name was not local, we check that it was defined at module level.
//
// We resolve all uses of locals in the module (due to load statements
// and comprehensions) in a similar way and compute the file's set of
// local variables.
//
// Starlark enforces that all global names are assigned at most once on
// all control flow paths by forbidding if/else statements and loops at
// top level. A global may be used before it is defined, leading to a
// dynamic error. However, the AllowGlobalReassign flag (really: allow
// top-level reassign) makes the resolver allow multiple to a variable
// at top-level. It also allows if-, for-, and while-loops at top-level,
// which in turn may make the evaluator dynamically assign multiple
// values to a variable at top-level. (These two roles should be separated.)

import (
	"fmt"
	"log"
	"sort"
	"strings"

	"go.starlark.net/internal/spell"
	"go.starlark.net/syntax"
)

const debug = false
const doesnt = "this Starlark dialect does not "

// global options
// These features are either not standard Starlark (yet), or deprecated
// features of the BUILD language, so we put them behind flags.
//
// Deprecated: use an explicit [syntax.FileOptions] argument instead,
// as it avoids all the usual problems of global variables.
var (
	AllowSet            = false // allow the 'set' built-in
	AllowGlobalReassign = false // allow reassignment to top-level names; also, allow if/for/while at top-level
	AllowRecursion      = false // allow while statements and recursive functions
	LoadBindsGlobally   = false // load creates global not file-local bindings (deprecated)

	// obsolete flags for features that are now standard. No effect.
	AllowNestedDef = true
	AllowLambda    = true
	AllowFloat     = true
	AllowBitwise   = true
)

// File resolves the specified file and records information about the
// module in file.Module.
//
// The isPredeclared and isUniversal predicates report whether a name is
// a pre-declared identifier (visible in the current module) or a
// universal identifier (visible in every module).
// Clients should typically pass predeclared.Has for the first and
// starlark.Universe.Has for the second, where predeclared is the
// module's StringDict of predeclared names and starlark.Universe is the
// standard set of built-ins.
// The isUniverse predicate is supplied a parameter to avoid a cyclic
// dependency upon starlark.Universe, not because users should ever need
// to redefine it.
func File(file *syntax.File, isPredeclared, isUniversal func(name string) bool) error {
	return REPLChunk(file, nil, isPredeclared, isUniversal)
}

// REPLChunk is a generalization of the File function that supports a
// non-empty initial global block, as occurs in a REPL.
func REPLChunk(file *syntax.File, isGlobal, isPredeclared, isUniversal func(name string) bool) error {
	r := newResolver(file.Options, isGlobal, isPredeclared, isUniversal)
	r.stmts(file.Stmts)

	r.env.resolveLocalUses()

	// At the end of the module, resolve all non-local variable references,
	// computing closures.
	// Function bodies may contain forward references to later global declarations.
	r.resolveNonLocalUses(r.env)

	file.Module = &Module{
		Locals:  r.moduleLocals,
		Globals: r.moduleGlobals,
	}

	if len(r.errors) > 0 {
		return r.errors
	}
	return nil
}

// Expr calls [ExprOptions] using [syntax.LegacyFileOptions].
// Deprecated: relies on legacy global variables.
func Expr(expr syntax.Expr, isPredeclared, isUniversal func(name string) bool) ([]*Binding, error) {
	return ExprOptions(syntax.LegacyFileOptions(), expr, isPredeclared, isUniversal)
}

// ExprOptions resolves the specified expression.
// It returns the local variables bound within the expression.
//
// The isPredeclared and isUniversal predicates behave as for the File function
func ExprOptions(opts *syntax.FileOptions, expr syntax.Expr, isPredeclared, isUniversal func(name string) bool) ([]*Binding, error) {
	r := newResolver(opts, nil, isPredeclared, isUniversal)
	r.expr(expr)
	r.env.resolveLocalUses()
	r.resolveNonLocalUses(r.env) // globals & universals
	if len(r.errors) > 0 {
		return nil, r.errors
	}
	return r.moduleLocals, nil
}

// An ErrorList is a non-empty list of resolver error messages.
type ErrorList []Error // len > 0

func (e ErrorList) Error() string { return e[0].Error() }

// An Error describes the nature and position of a resolver error.
type Error struct {
	Pos syntax.Position
	Msg string
}

func (e Error) Error() string { return e.Pos.String() + ": " + e.Msg }

func newResolver(options *syntax.FileOptions, isGlobal, isPredeclared, isUniversal func(name string) bool) *resolver {
	file := new(block)
	return &resolver{
		options:       options,
		file:          file,
		env:           file,
		isGlobal:      isGlobal,
		isPredeclared: isPredeclared,
		isUniversal:   isUniversal,
		globals:       make(map[string]*Binding),
		predeclared:   make(map[string]*Binding),
	}
}

type resolver struct {
	options *syntax.FileOptions

	// env is the current local environment:
	// a linked list of blocks, innermost first.
	// The tail of the list is the file block.
	env  *block
	file *block // file block (contains load bindings)

	// moduleLocals contains the local variables of the module
	// (due to load statements and comprehensions outside any function).
	// moduleGlobals contains the global variables of the module.
	moduleLocals  []*Binding
	moduleGlobals []*Binding

	// globals maps each global name in the module to its binding.
	// predeclared does the same for predeclared and universal names.
	globals     map[string]*Binding
	predeclared map[string]*Binding

	// These predicates report whether a name is
	// pre-declared, either in this module or universally,
	// or already declared in the module globals (as in a REPL).
	// isGlobal may be nil.
	isGlobal, isPredeclared, isUniversal func(name string) bool

	loops   int // number of enclosing for/while loops
	ifstmts int // number of enclosing if statements loops

	errors ErrorList
}

// container returns the innermost enclosing "container" block:
// a function (function != nil) or file (function == nil).
// Container blocks accumulate local variable bindings.
func (r *resolver) container() *block {
	for b := r.env; ; b = b.parent {
		if b.function != nil || b == r.file {
			return b
		}
	}
}

func (r *resolver) push(b *block) {
	r.env.children = append(r.env.children, b)
	b.parent = r.env
	r.env = b
}

func (r *resolver) pop() { r.env = r.env.parent }

type block struct {
	parent *block // nil for file block

	// In the file (root) block, both these fields are nil.
	function *Function             // only for function blocks
	comp     *syntax.Comprehension // only for comprehension blocks

	// bindings maps a name to its binding.
	// A local binding has an index into its innermost enclosing container's locals array.
	// A free binding has an index into its innermost enclosing function's freevars array.
	bindings map[string]*Binding

	// children records the child blocks of the current one.
	children []*block

	// uses records all identifiers seen in this container (function or file),
	// and a reference to the environment in which they appear.
	// As we leave each container block, we resolve them,
	// so that only free and global ones remain.
	// At the end of each top-level function we compute closures.
	uses []use
}

func (b *block) bind(name string, bind *Binding) {
	if b.bindings == nil {
		b.bindings = make(map[string]*Binding)
	}
	b.bindings[name] = bind
}

func (b *block) String() string {
	if b.function != nil {
		return "function block at " + fmt.Sprint(b.function.Pos)
	}
	if b.comp != nil {
		return "comprehension block at " + fmt.Sprint(b.comp.Span())
	}
	return "file block"
}

func (r *resolver) errorf(posn syntax.Position, format string, args ...interface{}) {
	r.errors = append(r.errors, Error{posn, fmt.Sprintf(format, args...)})
}

// A use records an identifier and the environment in which it appears.
type use struct {
	id  *syntax.Ident
	env *block
}

// bind creates a binding for id: a global (not file-local)
// binding at top-level, a local binding otherwise.
// At top-level, it reports an error if a global or file-local
// binding already exists, unless AllowGlobalReassign.
// It sets id.Binding to the binding (whether old or new),
// and returns whether a binding already existed.
func (r *resolver) bind(id *syntax.Ident) bool {
	// Binding outside any local (comprehension/function) block?
	if r.env == r.file {
		bind, ok := r.file.bindings[id.Name]
		if !ok {
			bind, ok = r.globals[id.Name]
			if !ok {
				// first global binding of this name
				bind = &Binding{
					First: id,
					Scope: Global,
					Index: len(r.moduleGlobals),
				}
				r.globals[id.Name] = bind
				r.moduleGlobals = append(r.moduleGlobals, bind)
			}
		}
		if ok && !r.options.GlobalReassign {
			r.errorf(id.NamePos, "cannot reassign %s %s declared at %s",
				bind.Scope, id.Name, bind.First.NamePos)
		}
		id.Binding = bind
		return ok
	}

	return r.bindLocal(id)
}

func (r *resolver) bindLocal(id *syntax.Ident) bool {
	// Mark this name as local to current block.
	// Assign it a new local (positive) index in the current container.
	_, ok := r.env.bindings[id.Name]
	if !ok {
		var locals *[]*Binding
		if fn := r.container().function; fn != nil {
			locals = &fn.Locals
		} else {
			locals = &r.moduleLocals
		}
		bind := &Binding{
			First: id,
			Scope: Local,
			Index: len(*locals),
		}
		r.env.bind(id.Name, bind)
		*locals = append(*locals, bind)
	}

	r.use(id)
	return ok
}

func (r *resolver) use(id *syntax.Ident) {
	use := use{id, r.env}

	// The spec says that if there is a global binding of a name
	// then all references to that name in that block refer to the
	// global, even if the use precedes the def---just as for locals.
	// For example, in this code,
	//
	//   print(len); len=1; print(len)
	//
	// both occurrences of len refer to the len=1 binding, which
	// completely shadows the predeclared len function.
	//
	// The rationale for these semantics, which differ from Python,
	// is that the static meaning of len (a reference to a global)
	// does not change depending on where it appears in the file.
	// Of course, its dynamic meaning does change, from an error
	// into a valid reference, so it's not clear these semantics
	// have any practical advantage.
	//
	// In any case, the Bazel implementation lags behind the spec
	// and follows Python behavior, so the first use of len refers
	// to the predeclared function.  This typically used in a BUILD
	// file that redefines a predeclared name half way through,
	// for example:
	//
	//	proto_library(...) 			# built-in rule
	//      load("myproto.bzl", "proto_library")
	//	proto_library(...) 			# user-defined rule
	//
	// We will piggyback support for the legacy semantics on the
	// AllowGlobalReassign flag, which is loosely related and also
	// required for Bazel.
	if r.options.GlobalReassign && r.env == r.file {
		r.useToplevel(use)
		return
	}

	b := r.container()
	b.uses = append(b.uses, use)
}

// useToplevel resolves use.id as a reference to a name visible at top-level.
// The use.env field captures the original environment for error reporting.
func (r *resolver) useToplevel(use use) (bind *Binding) {
	id := use.id

	if prev, ok := r.file.bindings[id.Name]; ok {
		// use of load-defined name in file block
		bind = prev
	} else if prev, ok := r.globals[id.Name]; ok {
		// use of global declared by module
		bind = prev
	} else if r.isGlobal != nil && r.isGlobal(id.Name) {
		// use of global defined in a previous REPL chunk
		bind = &Binding{
			First: id, // wrong: this is not even a binding use
			Scope: Global,
			Index: len(r.moduleGlobals),
		}
		r.globals[id.Name] = bind
		r.moduleGlobals = append(r.moduleGlobals, bind)
	} else if prev, ok := r.predeclared[id.Name]; ok {
		// repeated use of predeclared or universal
		bind = prev
	} else if r.isPredeclared(id.Name) {
		// use of pre-declared name
		bind = &Binding{Scope: Predeclared}
		r.predeclared[id.Name] = bind // save it
	} else if r.isUniversal(id.Name) {
		// use of universal name
		if !r.options.Set && id.Name == "set" {
			r.errorf(id.NamePos, doesnt+"support sets")
		}
		bind = &Binding{Scope: Universal}
		r.predeclared[id.Name] = bind // save it
	} else {
		bind = &Binding{Scope: Undefined}
		var hint string
		if n := r.spellcheck(use); n != "" {
			hint = fmt.Sprintf(" (did you mean %s?)", n)
		}
		r.errorf(id.NamePos, "undefined: %s%s", id.Name, hint)
	}
	id.Binding = bind
	return bind
}

// spellcheck returns the most likely misspelling of
// the name use.id in the environment use.env.
func (r *resolver) spellcheck(use use) string {
	var names []string

	// locals
	for b := use.env; b != nil; b = b.parent {
		for name := range b.bindings {
			names = append(names, name)
		}
	}

	// globals
	//
	// We have no way to enumerate the sets whose membership
	// tests are isPredeclared, isUniverse, and isGlobal,
	// which includes prior names in the REPL session.
	for _, bind := range r.moduleGlobals {
		names = append(names, bind.First.Name)
	}

	sort.Strings(names)
	return spell.Nearest(use.id.Name, names)
}

// resolveLocalUses is called when leaving a container (function/module)
// block.  It resolves all uses of locals/cells within that block.
func (b *block) resolveLocalUses() {
	unresolved := b.uses[:0]
	for _, use := range b.uses {
		if bind := lookupLocal(use); bind != nil && (bind.Scope == Local || bind.Scope == Cell) {
			use.id.Binding = bind
		} else {
			unresolved = append(unresolved, use)
		}
	}
	b.uses = unresolved
}

func (r *resolver) stmts(stmts []syntax.Stmt) {
	for _, stmt := range stmts {
		r.stmt(stmt)
	}
}

func (r *resolver) stmt(stmt syntax.Stmt) {
	switch stmt := stmt.(type) {
	case *syntax.ExprStmt:
		r.expr(stmt.X)

	case *syntax.BranchStmt:
		if r.loops == 0 && (stmt.Token == syntax.BREAK || stmt.Token == syntax.CONTINUE) {
			r.errorf(stmt.TokenPos, "%s not in a loop", stmt.Token)
		}

	case *syntax.IfStmt:
		if !r.options.TopLevelControl && r.container().function == nil {
			r.errorf(stmt.If, "if statement not within a function")
		}
		r.expr(stmt.Cond)
		r.ifstmts++
		r.stmts(stmt.True)
		r.stmts(stmt.False)
		r.ifstmts--

	case *syntax.AssignStmt:
		r.expr(stmt.RHS)
		isAugmented := stmt.Op != syntax.EQ
		r.assign(stmt.LHS, isAugmented)

	case *syntax.DefStmt:
		r.bind(stmt.Name)
		fn := &Function{
			Name:   stmt.Name.Name,
			Pos:    stmt.Def,
			Params: stmt.Params,
			Body:   stmt.Body,
		}
		stmt.Function = fn
		r.function(fn, stmt.Def)

	case *syntax.ForStmt:
		if !r.options.TopLevelControl && r.container().function == nil {
			r.errorf(stmt.For, "for loop not within a function")
		}
		r.expr(stmt.X)
		const isAugmented = false
		r.assign(stmt.Vars, isAugmented)
		r.loops++
		r.stmts(stmt.Body)
		r.loops--

	case *syntax.WhileStmt:
		if !r.options.While {
			r.errorf(stmt.While, doesnt+"support while loops")
		}
		if !r.options.TopLevelControl && r.container().function == nil {
			r.errorf(stmt.While, "while loop not within a function")
		}
		r.expr(stmt.Cond)
		r.loops++
		r.stmts(stmt.Body)
		r.loops--

	case *syntax.ReturnStmt:
		if r.container().function == nil {
			r.errorf(stmt.Return, "return statement not within a function")
		}
		if stmt.Result != nil {
			r.expr(stmt.Result)
		}

	case *syntax.LoadStmt:
		// A load statement may not be nested in any other statement.
		if r.container().function != nil {
			r.errorf(stmt.Load, "load statement within a function")
		} else if r.loops > 0 {
			r.errorf(stmt.Load, "load statement within a loop")
		} else if r.ifstmts > 0 {
			r.errorf(stmt.Load, "load statement within a conditional")
		}

		for i, from := range stmt.From {
			if from.Name == "" {
				r.errorf(from.NamePos, "load: empty identifier")
				continue
			}
			if from.Name[0] == '_' {
				r.errorf(from.NamePos, "load: names with leading underscores are not exported: %s", from.Name)
			}

			id := stmt.To[i]
			if r.options.LoadBindsGlobally {
				r.bind(id)
			} else if r.bindLocal(id) && !r.options.GlobalReassign {
				// "Global" in AllowGlobalReassign is a misnomer for "toplevel".
				// Sadly we can't report the previous declaration
				// as id.Binding may not be set yet.
				r.errorf(id.NamePos, "cannot reassign top-level %s", id.Name)
			}
		}

	default:
		log.Panicf("unexpected stmt %T", stmt)
	}
}

func (r *resolver) assign(lhs syntax.Expr, isAugmented bool) {
	switch lhs := lhs.(type) {
	case *syntax.Ident:
		// x = ...
		r.bind(lhs)

	case *syntax.IndexExpr:
		// x[i] = ...
		r.expr(lhs.X)
		r.expr(lhs.Y)

	case *syntax.DotExpr:
		// x.f = ...
		r.expr(lhs.X)

	case *syntax.TupleExpr:
		// (x, y) = ...
		if isAugmented {
			r.errorf(syntax.Start(lhs), "can't use tuple expression in augmented assignment")
		}
		for _, elem := range lhs.List {
			r.assign(elem, isAugmented)
		}

	case *syntax.ListExpr:
		// [x, y, z] = ...
		if isAugmented {
			r.errorf(syntax.Start(lhs), "can't use list expression in augmented assignment")
		}
		for _, elem := range lhs.List {
			r.assign(elem, isAugmented)
		}

	case *syntax.ParenExpr:
		r.assign(lhs.X, isAugmented)

	default:
		name := strings.ToLower(strings.TrimPrefix(fmt.Sprintf("%T", lhs), "*syntax."))
		r.errorf(syntax.Start(lhs), "can't assign to %s", name)
	}
}

func (r *resolver) expr(e syntax.Expr) {
	switch e := e.(type) {
	case *syntax.Ident:
		r.use(e)

	case *syntax.Literal:

	case *syntax.ListExpr:
		for _, x := range e.List {
			r.expr(x)
		}

	case *syntax.CondExpr:
		r.expr(e.Cond)
		r.expr(e.True)
		r.expr(e.False)

	case *syntax.IndexExpr:
		r.expr(e.X)
		r.expr(e.Y)

	case *syntax.DictEntry:
		r.expr(e.Key)
		r.expr(e.Value)

	case *syntax.SliceExpr:
		r.expr(e.X)
		if e.Lo != nil {
			r.expr(e.Lo)
		}
		if e.Hi != nil {
			r.expr(e.Hi)
		}
		if e.Step != nil {
			r.expr(e.Step)
		}

	case *syntax.Comprehension:
		// The 'in' operand of the first clause (always a ForClause)
		// is resolved in the outer block; consider: [x for x in x].
		clause := e.Clauses[0].(*syntax.ForClause)
		r.expr(clause.X)

		// A list/dict comprehension defines a new lexical block.
		// Locals defined within the block will be allotted
		// distinct slots in the locals array of the innermost
		// enclosing container (function/module) block.
		r.push(&block{comp: e})

		const isAugmented = false
		r.assign(clause.Vars, isAugmented)

		for _, clause := range e.Clauses[1:] {
			switch clause := clause.(type) {
			case *syntax.IfClause:
				r.expr(clause.Cond)
			case *syntax.ForClause:
				r.assign(clause.Vars, isAugmented)
				r.expr(clause.X)
			}
		}
		r.expr(e.Body) // body may be *DictEntry
		r.pop()

	case *syntax.TupleExpr:
		for _, x := range e.List {
			r.expr(x)
		}

	case *syntax.DictExpr:
		for _, entry := range e.List {
			entry := entry.(*syntax.DictEntry)
			r.expr(entry.Key)
			r.expr(entry.Value)
		}

	case *syntax.UnaryExpr:
		r.expr(e.X)

	case *syntax.BinaryExpr:
		r.expr(e.X)
		r.expr(e.Y)

	case *syntax.DotExpr:
		r.expr(e.X)
		// ignore e.Name

	case *syntax.CallExpr:
		r.expr(e.Fn)
		var seenVarargs, seenKwargs bool
		var seenName map[string]bool
		var n, p int
		for _, arg := range e.Args {
			pos, _ := arg.Span()
			if unop, ok := arg.(*syntax.UnaryExpr); ok && unop.Op == syntax.STARSTAR {
				// **kwargs
				if seenKwargs {
					r.errorf(pos, "multiple **kwargs not allowed")
				}
				seenKwargs = true
				r.expr(arg)
			} else if ok && unop.Op == syntax.STAR {
				// *args
				if seenKwargs {
					r.errorf(pos, "*args may not follow **kwargs")
				} else if seenVarargs {
					r.errorf(pos, "multiple *args not allowed")
				}
				seenVarargs = true
				r.expr(arg)
			} else if binop, ok := arg.(*syntax.BinaryExpr); ok && binop.Op == syntax.EQ {
				// k=v
				n++
				if seenKwargs {
					r.errorf(pos, "keyword argument may not follow **kwargs")
				} else if seenVarargs {
					r.errorf(pos, "keyword argument may not follow *args")
				}
				x := binop.X.(*syntax.Ident)
				if seenName[x.Name] {
					r.errorf(x.NamePos, "keyword argument %q is repeated", x.Name)
				} else {
					if seenName == nil {
						seenName = make(map[string]bool)
					}
					seenName[x.Name] = true
				}
				r.expr(binop.Y)
			} else {
				// positional argument
				p++
				if seenVarargs {
					r.errorf(pos, "positional argument may not follow *args")
				} else if seenKwargs {
					r.errorf(pos, "positional argument may not follow **kwargs")
				} else if len(seenName) > 0 {
					r.errorf(pos, "positional argument may not follow named")
				}
				r.expr(arg)
			}
		}

		// Fail gracefully if compiler-imposed limit is exceeded.
		if p >= 256 {
			pos, _ := e.Span()
			r.errorf(pos, "%v positional arguments in call, limit is 255", p)
		}
		if n >= 256 {
			pos, _ := e.Span()
			r.errorf(pos, "%v keyword arguments in call, limit is 255", n)
		}

	case *syntax.LambdaExpr:
		fn := &Function{
			Name:   "lambda",
			Pos:    e.Lambda,
			Params: e.Params,
			Body:   []syntax.Stmt{&syntax.ReturnStmt{Result: e.Body}},
		}
		e.Function = fn
		r.function(fn, e.Lambda)

	case *syntax.ParenExpr:
		r.expr(e.X)

	default:
		log.Panicf("unexpected expr %T", e)
	}
}

func (r *resolver) function(function *Function, pos syntax.Position) {
	// Resolve defaults in enclosing environment.
	for _, param := range function.Params {
		if binary, ok := param.(*syntax.BinaryExpr); ok {
			r.expr(binary.Y)
		}
	}

	// Enter function block.
	b := &block{function: function}
	r.push(b)

	var seenOptional bool
	var star *syntax.UnaryExpr // * or *args param
	var starStar *syntax.Ident // **kwargs ident
	var numKwonlyParams int
	for _, param := range function.Params {
		switch param := param.(type) {
		case *syntax.Ident:
			// e.g. x
			if starStar != nil {
				r.errorf(param.NamePos, "required parameter may not follow **%s", starStar.Name)
			} else if star != nil {
				numKwonlyParams++
			} else if seenOptional {
				r.errorf(param.NamePos, "required parameter may not follow optional")
			}
			if r.bind(param) {
				r.errorf(param.NamePos, "duplicate parameter: %s", param.Name)
			}

		case *syntax.BinaryExpr:
			// e.g. y=dflt
			if starStar != nil {
				r.errorf(param.OpPos, "optional parameter may not follow **%s", starStar.Name)
			} else if star != nil {
				numKwonlyParams++
			}
			if id := param.X.(*syntax.Ident); r.bind(id) {
				r.errorf(param.OpPos, "duplicate parameter: %s", id.Name)
			}
			seenOptional = true

		case *syntax.UnaryExpr:
			// * or *args or **kwargs
			if param.Op == syntax.STAR {
				if starStar != nil {
					r.errorf(param.OpPos, "* parameter may not follow **%s", starStar.Name)
				} else if star != nil {
					r.errorf(param.OpPos, "multiple * parameters not allowed")
				} else {
					star = param
				}
			} else {
				if starStar != nil {
					r.errorf(param.OpPos, "multiple ** parameters not allowed")
				}
				starStar = param.X.(*syntax.Ident)
			}
		}
	}

	// Bind the *args and **kwargs parameters at the end,
	// so that regular parameters a/b/c are contiguous and
	// there is no hole for the "*":
	//   def f(a, b, *args, c=0, **kwargs)
	//   def f(a, b, *,     c=0, **kwargs)
	if star != nil {
		if id, _ := star.X.(*syntax.Ident); id != nil {
			// *args
			if r.bind(id) {
				r.errorf(id.NamePos, "duplicate parameter: %s", id.Name)
			}
			function.HasVarargs = true
		} else if numKwonlyParams == 0 {
			r.errorf(star.OpPos, "bare * must be followed by keyword-only parameters")
		}
	}
	if starStar != nil {
		if r.bind(starStar) {
			r.errorf(starStar.NamePos, "duplicate parameter: %s", starStar.Name)
		}
		function.HasKwargs = true
	}

	function.NumKwonlyParams = numKwonlyParams
	r.stmts(function.Body)

	// Resolve all uses of this function's local vars,
	// and keep just the remaining uses of free/global vars.
	b.resolveLocalUses()

	// Leave function block.
	r.pop()

	// References within the function body to globals are not
	// resolved until the end of the module.
}

func (r *resolver) resolveNonLocalUses(b *block) {
	// First resolve inner blocks.
	for _, child := range b.children {
		r.resolveNonLocalUses(child)
	}
	for _, use := range b.uses {
		use.id.Binding = r.lookupLexical(use, use.env)
	}
}

// lookupLocal looks up an identifier within its immediately enclosing function.
func lookupLocal(use use) *Binding {
	for env := use.env; env != nil; env = env.parent {
		if bind, ok := env.bindings[use.id.Name]; ok {
			if bind.Scope == Free {
				// shouldn't exist till later
				log.Panicf("%s: internal error: %s, %v", use.id.NamePos, use.id.Name, bind)
			}
			return bind // found
		}
		if env.function != nil {
			break
		}
	}
	return nil // not found in this function
}

// lookupLexical looks up an identifier use.id within its lexically enclosing environment.
// The use.env field captures the original environment for error reporting.
func (r *resolver) lookupLexical(use use, env *block) (bind *Binding) {
	if debug {
		fmt.Printf("lookupLexical %s in %s = ...\n", use.id.Name, env)
		defer func() { fmt.Printf("= %v\n", bind) }()
	}

	// Is this the file block?
	if env == r.file {
		return r.useToplevel(use) // file-local, global, predeclared, or not found
	}

	// Defined in this block?
	bind, ok := env.bindings[use.id.Name]
	if !ok {
		// Defined in parent block?
		bind = r.lookupLexical(use, env.parent)
		if env.function != nil && (bind.Scope == Local || bind.Scope == Free || bind.Scope == Cell) {
			// Found in parent block, which belongs to enclosing function.
			// Add the parent's binding to the function's freevars,
			// and add a new 'free' binding to the inner function's block,
			// and turn the parent's local into cell.
			if bind.Scope == Local {
				bind.Scope = Cell
			}
			index := len(env.function.FreeVars)
			env.function.FreeVars = append(env.function.FreeVars, bind)
			bind = &Binding{
				First: bind.First,
				Scope: Free,
				Index: index,
			}
			if debug {
				fmt.Printf("creating freevar %v in function at %s: %s\n",
					len(env.function.FreeVars), env.function.Pos, use.id.Name)
			}
		}

		// Memoize, to avoid duplicate free vars
		// and redundant global (failing) lookups.
		env.bind(use.id.Name, bind)
	}
	return bind
}
