1// Copyright 2013 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// This file implements typechecking of call and selector expressions.
6
7package types
8
9import (
10	"go/ast"
11	"go/token"
12)
13
14func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind {
15	check.exprOrType(x, e.Fun)
16
17	switch x.mode {
18	case invalid:
19		check.use(e.Args...)
20		x.mode = invalid
21		x.expr = e
22		return statement
23
24	case typexpr:
25		// conversion
26		T := x.typ
27		x.mode = invalid
28		switch n := len(e.Args); n {
29		case 0:
30			check.errorf(e.Rparen, "missing argument in conversion to %s", T)
31		case 1:
32			check.expr(x, e.Args[0])
33			if x.mode != invalid {
34				check.conversion(x, T)
35			}
36		default:
37			check.errorf(e.Args[n-1].Pos(), "too many arguments in conversion to %s", T)
38		}
39		x.expr = e
40		return conversion
41
42	case builtin:
43		id := x.id
44		if !check.builtin(x, e, id) {
45			x.mode = invalid
46		}
47		x.expr = e
48		// a non-constant result implies a function call
49		if x.mode != invalid && x.mode != constant_ {
50			check.hasCallOrRecv = true
51		}
52		return predeclaredFuncs[id].kind
53
54	default:
55		// function/method call
56		sig, _ := x.typ.Underlying().(*Signature)
57		if sig == nil {
58			check.invalidOp(x.pos(), "cannot call non-function %s", x)
59			x.mode = invalid
60			x.expr = e
61			return statement
62		}
63
64		arg, n, _ := unpack(func(x *operand, i int) { check.multiExpr(x, e.Args[i]) }, len(e.Args), false)
65		if arg == nil {
66			x.mode = invalid
67			x.expr = e
68			return statement
69		}
70
71		check.arguments(x, e, sig, arg, n)
72
73		// determine result
74		switch sig.results.Len() {
75		case 0:
76			x.mode = novalue
77		case 1:
78			x.mode = value
79			x.typ = sig.results.vars[0].typ // unpack tuple
80		default:
81			x.mode = value
82			x.typ = sig.results
83		}
84		x.expr = e
85		check.hasCallOrRecv = true
86
87		return statement
88	}
89}
90
91// use type-checks each argument.
92// Useful to make sure expressions are evaluated
93// (and variables are "used") in the presence of other errors.
94func (check *Checker) use(arg ...ast.Expr) {
95	var x operand
96	for _, e := range arg {
97		check.rawExpr(&x, e, nil)
98	}
99}
100
101// useGetter is like use, but takes a getter instead of a list of expressions.
102// It should be called instead of use if a getter is present to avoid repeated
103// evaluation of the first argument (since the getter was likely obtained via
104// unpack, which may have evaluated the first argument already).
105func (check *Checker) useGetter(get getter, n int) {
106	var x operand
107	for i := 0; i < n; i++ {
108		get(&x, i)
109	}
110}
111
112// A getter sets x as the i'th operand, where 0 <= i < n and n is the total
113// number of operands (context-specific, and maintained elsewhere). A getter
114// type-checks the i'th operand; the details of the actual check are getter-
115// specific.
116type getter func(x *operand, i int)
117
118// unpack takes a getter get and a number of operands n. If n == 1, unpack
119// calls the incoming getter for the first operand. If that operand is
120// invalid, unpack returns (nil, 0, false). Otherwise, if that operand is a
121// function call, or a comma-ok expression and allowCommaOk is set, the result
122// is a new getter and operand count providing access to the function results,
123// or comma-ok values, respectively. The third result value reports if it
124// is indeed the comma-ok case. In all other cases, the incoming getter and
125// operand count are returned unchanged, and the third result value is false.
126//
127// In other words, if there's exactly one operand that - after type-checking
128// by calling get - stands for multiple operands, the resulting getter provides
129// access to those operands instead.
130//
131// If the returned getter is called at most once for a given operand index i
132// (including i == 0), that operand is guaranteed to cause only one call of
133// the incoming getter with that i.
134//
135func unpack(get getter, n int, allowCommaOk bool) (getter, int, bool) {
136	if n == 1 {
137		// possibly result of an n-valued function call or comma,ok value
138		var x0 operand
139		get(&x0, 0)
140		if x0.mode == invalid {
141			return nil, 0, false
142		}
143
144		if t, ok := x0.typ.(*Tuple); ok {
145			// result of an n-valued function call
146			return func(x *operand, i int) {
147				x.mode = value
148				x.expr = x0.expr
149				x.typ = t.At(i).typ
150			}, t.Len(), false
151		}
152
153		if x0.mode == mapindex || x0.mode == commaok {
154			// comma-ok value
155			if allowCommaOk {
156				a := [2]Type{x0.typ, Typ[UntypedBool]}
157				return func(x *operand, i int) {
158					x.mode = value
159					x.expr = x0.expr
160					x.typ = a[i]
161				}, 2, true
162			}
163			x0.mode = value
164		}
165
166		// single value
167		return func(x *operand, i int) {
168			if i != 0 {
169				unreachable()
170			}
171			*x = x0
172		}, 1, false
173	}
174
175	// zero or multiple values
176	return get, n, false
177}
178
179// arguments checks argument passing for the call with the given signature.
180// The arg function provides the operand for the i'th argument.
181func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature, arg getter, n int) {
182	if call.Ellipsis.IsValid() {
183		// last argument is of the form x...
184		if !sig.variadic {
185			check.errorf(call.Ellipsis, "cannot use ... in call to non-variadic %s", call.Fun)
186			check.useGetter(arg, n)
187			return
188		}
189		if len(call.Args) == 1 && n > 1 {
190			// f()... is not permitted if f() is multi-valued
191			check.errorf(call.Ellipsis, "cannot use ... with %d-valued %s", n, call.Args[0])
192			check.useGetter(arg, n)
193			return
194		}
195	}
196
197	// evaluate arguments
198	for i := 0; i < n; i++ {
199		arg(x, i)
200		if x.mode != invalid {
201			var ellipsis token.Pos
202			if i == n-1 && call.Ellipsis.IsValid() {
203				ellipsis = call.Ellipsis
204			}
205			check.argument(call.Fun, sig, i, x, ellipsis)
206		}
207	}
208
209	// check argument count
210	if sig.variadic {
211		// a variadic function accepts an "empty"
212		// last argument: count one extra
213		n++
214	}
215	if n < sig.params.Len() {
216		check.errorf(call.Rparen, "too few arguments in call to %s", call.Fun)
217		// ok to continue
218	}
219}
220
221// argument checks passing of argument x to the i'th parameter of the given signature.
222// If ellipsis is valid, the argument is followed by ... at that position in the call.
223func (check *Checker) argument(fun ast.Expr, sig *Signature, i int, x *operand, ellipsis token.Pos) {
224	check.singleValue(x)
225	if x.mode == invalid {
226		return
227	}
228
229	n := sig.params.Len()
230
231	// determine parameter type
232	var typ Type
233	switch {
234	case i < n:
235		typ = sig.params.vars[i].typ
236	case sig.variadic:
237		typ = sig.params.vars[n-1].typ
238		if debug {
239			if _, ok := typ.(*Slice); !ok {
240				check.dump("%s: expected unnamed slice type, got %s", sig.params.vars[n-1].Pos(), typ)
241			}
242		}
243	default:
244		check.errorf(x.pos(), "too many arguments")
245		return
246	}
247
248	if ellipsis.IsValid() {
249		// argument is of the form x... and x is single-valued
250		if i != n-1 {
251			check.errorf(ellipsis, "can only use ... with matching parameter")
252			return
253		}
254		if _, ok := x.typ.Underlying().(*Slice); !ok {
255			check.errorf(x.pos(), "cannot use %s as parameter of type %s", x, typ)
256			return
257		}
258	} else if sig.variadic && i >= n-1 {
259		// use the variadic parameter slice's element type
260		typ = typ.(*Slice).elem
261	}
262
263	check.assignment(x, typ, check.sprintf("argument to %s", fun))
264}
265
266func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
267	// these must be declared before the "goto Error" statements
268	var (
269		obj      Object
270		index    []int
271		indirect bool
272	)
273
274	sel := e.Sel.Name
275	// If the identifier refers to a package, handle everything here
276	// so we don't need a "package" mode for operands: package names
277	// can only appear in qualified identifiers which are mapped to
278	// selector expressions.
279	if ident, ok := e.X.(*ast.Ident); ok {
280		_, obj := check.scope.LookupParent(ident.Name, check.pos)
281		if pkg, _ := obj.(*PkgName); pkg != nil {
282			assert(pkg.pkg == check.pkg)
283			check.recordUse(ident, pkg)
284			pkg.used = true
285			exp := pkg.imported.scope.Lookup(sel)
286			if exp == nil {
287				if !pkg.imported.fake {
288					check.errorf(e.Pos(), "%s not declared by package %s", sel, ident)
289				}
290				goto Error
291			}
292			if !exp.Exported() {
293				check.errorf(e.Pos(), "%s not exported by package %s", sel, ident)
294				// ok to continue
295			}
296			check.recordUse(e.Sel, exp)
297			// Simplified version of the code for *ast.Idents:
298			// - imported objects are always fully initialized
299			switch exp := exp.(type) {
300			case *Const:
301				assert(exp.Val() != nil)
302				x.mode = constant_
303				x.typ = exp.typ
304				x.val = exp.val
305			case *TypeName:
306				x.mode = typexpr
307				x.typ = exp.typ
308			case *Var:
309				x.mode = variable
310				x.typ = exp.typ
311			case *Func:
312				x.mode = value
313				x.typ = exp.typ
314			case *Builtin:
315				x.mode = builtin
316				x.typ = exp.typ
317				x.id = exp.id
318			default:
319				unreachable()
320			}
321			x.expr = e
322			return
323		}
324	}
325
326	check.exprOrType(x, e.X)
327	if x.mode == invalid {
328		goto Error
329	}
330
331	obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
332	if obj == nil {
333		switch {
334		case index != nil:
335			// TODO(gri) should provide actual type where the conflict happens
336			check.invalidOp(e.Pos(), "ambiguous selector %s", sel)
337		case indirect:
338			check.invalidOp(e.Pos(), "%s is not in method set of %s", sel, x.typ)
339		default:
340			check.invalidOp(e.Pos(), "%s has no field or method %s", x, sel)
341		}
342		goto Error
343	}
344
345	if x.mode == typexpr {
346		// method expression
347		m, _ := obj.(*Func)
348		if m == nil {
349			check.invalidOp(e.Pos(), "%s has no method %s", x, sel)
350			goto Error
351		}
352
353		check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
354
355		// the receiver type becomes the type of the first function
356		// argument of the method expression's function type
357		var params []*Var
358		sig := m.typ.(*Signature)
359		if sig.params != nil {
360			params = sig.params.vars
361		}
362		x.mode = value
363		x.typ = &Signature{
364			params:   NewTuple(append([]*Var{NewVar(token.NoPos, check.pkg, "", x.typ)}, params...)...),
365			results:  sig.results,
366			variadic: sig.variadic,
367		}
368
369		check.addDeclDep(m)
370
371	} else {
372		// regular selector
373		switch obj := obj.(type) {
374		case *Var:
375			check.recordSelection(e, FieldVal, x.typ, obj, index, indirect)
376			if x.mode == variable || indirect {
377				x.mode = variable
378			} else {
379				x.mode = value
380			}
381			x.typ = obj.typ
382
383		case *Func:
384			// TODO(gri) If we needed to take into account the receiver's
385			// addressability, should we report the type &(x.typ) instead?
386			check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
387
388			if debug {
389				// Verify that LookupFieldOrMethod and MethodSet.Lookup agree.
390				typ := x.typ
391				if x.mode == variable {
392					// If typ is not an (unnamed) pointer or an interface,
393					// use *typ instead, because the method set of *typ
394					// includes the methods of typ.
395					// Variables are addressable, so we can always take their
396					// address.
397					if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) {
398						typ = &Pointer{base: typ}
399					}
400				}
401				// If we created a synthetic pointer type above, we will throw
402				// away the method set computed here after use.
403				// TODO(gri) Method set computation should probably always compute
404				// both, the value and the pointer receiver method set and represent
405				// them in a single structure.
406				// TODO(gri) Consider also using a method set cache for the lifetime
407				// of checker once we rely on MethodSet lookup instead of individual
408				// lookup.
409				mset := NewMethodSet(typ)
410				if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj {
411					check.dump("%s: (%s).%v -> %s", e.Pos(), typ, obj.name, m)
412					check.dump("%s\n", mset)
413					panic("method sets and lookup don't agree")
414				}
415			}
416
417			x.mode = value
418
419			// remove receiver
420			sig := *obj.typ.(*Signature)
421			sig.recv = nil
422			x.typ = &sig
423
424			check.addDeclDep(obj)
425
426		default:
427			unreachable()
428		}
429	}
430
431	// everything went well
432	x.expr = e
433	return
434
435Error:
436	x.mode = invalid
437	x.expr = e
438}
439