Source file src/pkg/go/types/call.go
1
2
3
4
5
6
7 package types
8
9 import (
10 "go/ast"
11 "go/token"
12 )
13
14 func (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
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.use(e.Args...)
38 check.errorf(e.Args[n-1].Pos(), "too many arguments in conversion to %s", T)
39 }
40 x.expr = e
41 return conversion
42
43 case builtin:
44 id := x.id
45 if !check.builtin(x, e, id) {
46 x.mode = invalid
47 }
48 x.expr = e
49
50 if x.mode != invalid && x.mode != constant_ {
51 check.hasCallOrRecv = true
52 }
53 return predeclaredFuncs[id].kind
54
55 default:
56
57 sig, _ := x.typ.Underlying().(*Signature)
58 if sig == nil {
59 check.invalidOp(x.pos(), "cannot call non-function %s", x)
60 x.mode = invalid
61 x.expr = e
62 return statement
63 }
64
65 arg, n, _ := unpack(func(x *operand, i int) { check.multiExpr(x, e.Args[i]) }, len(e.Args), false)
66 if arg != nil {
67 check.arguments(x, e, sig, arg, n)
68 } else {
69 x.mode = invalid
70 }
71
72
73 switch sig.results.Len() {
74 case 0:
75 x.mode = novalue
76 case 1:
77 x.mode = value
78 x.typ = sig.results.vars[0].typ
79 default:
80 x.mode = value
81 x.typ = sig.results
82 }
83
84 x.expr = e
85 check.hasCallOrRecv = true
86
87 return statement
88 }
89 }
90
91
92
93
94
95 func (check *Checker) use(arg ...ast.Expr) {
96 var x operand
97 for _, e := range arg {
98
99
100 if e != nil {
101 check.rawExpr(&x, e, nil)
102 }
103 }
104 }
105
106
107
108
109
110 func (check *Checker) useLHS(arg ...ast.Expr) {
111 var x operand
112 for _, e := range arg {
113
114
115
116 var v *Var
117 var v_used bool
118 if ident, _ := unparen(e).(*ast.Ident); ident != nil {
119
120 if ident.Name == "_" {
121 continue
122 }
123 if _, obj := check.scope.LookupParent(ident.Name, token.NoPos); obj != nil {
124
125
126
127 if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
128 v = w
129 v_used = v.used
130 }
131 }
132 }
133 check.rawExpr(&x, e, nil)
134 if v != nil {
135 v.used = v_used
136 }
137 }
138 }
139
140
141
142
143
144 func (check *Checker) useGetter(get getter, n int) {
145 var x operand
146 for i := 0; i < n; i++ {
147 get(&x, i)
148 }
149 }
150
151
152
153
154
155 type getter func(x *operand, i int)
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174 func unpack(get getter, n int, allowCommaOk bool) (getter, int, bool) {
175 if n != 1 {
176
177 return get, n, false
178 }
179
180 var x0 operand
181 get(&x0, 0)
182 if x0.mode == invalid {
183 return nil, 0, false
184 }
185
186 if t, ok := x0.typ.(*Tuple); ok {
187
188 return func(x *operand, i int) {
189 x.mode = value
190 x.expr = x0.expr
191 x.typ = t.At(i).typ
192 }, t.Len(), false
193 }
194
195 if x0.mode == mapindex || x0.mode == commaok {
196
197 if allowCommaOk {
198 a := [2]Type{x0.typ, Typ[UntypedBool]}
199 return func(x *operand, i int) {
200 x.mode = value
201 x.expr = x0.expr
202 x.typ = a[i]
203 }, 2, true
204 }
205 x0.mode = value
206 }
207
208
209 return func(x *operand, i int) {
210 if i != 0 {
211 unreachable()
212 }
213 *x = x0
214 }, 1, false
215 }
216
217
218
219 func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature, arg getter, n int) {
220 if call.Ellipsis.IsValid() {
221
222 if !sig.variadic {
223 check.errorf(call.Ellipsis, "cannot use ... in call to non-variadic %s", call.Fun)
224 check.useGetter(arg, n)
225 return
226 }
227 if len(call.Args) == 1 && n > 1 {
228
229 check.errorf(call.Ellipsis, "cannot use ... with %d-valued %s", n, call.Args[0])
230 check.useGetter(arg, n)
231 return
232 }
233 }
234
235
236 context := check.sprintf("argument to %s", call.Fun)
237 for i := 0; i < n; i++ {
238 arg(x, i)
239 if x.mode != invalid {
240 var ellipsis token.Pos
241 if i == n-1 && call.Ellipsis.IsValid() {
242 ellipsis = call.Ellipsis
243 }
244 check.argument(sig, i, x, ellipsis, context)
245 }
246 }
247
248
249 if sig.variadic {
250
251
252 n++
253 }
254 if n < sig.params.Len() {
255 check.errorf(call.Rparen, "too few arguments in call to %s", call.Fun)
256
257 }
258 }
259
260
261
262 func (check *Checker) argument(sig *Signature, i int, x *operand, ellipsis token.Pos, context string) {
263 check.singleValue(x)
264 if x.mode == invalid {
265 return
266 }
267
268 n := sig.params.Len()
269
270
271 var typ Type
272 switch {
273 case i < n:
274 typ = sig.params.vars[i].typ
275 case sig.variadic:
276 typ = sig.params.vars[n-1].typ
277 if debug {
278 if _, ok := typ.(*Slice); !ok {
279 check.dump("%v: expected unnamed slice type, got %s", sig.params.vars[n-1].Pos(), typ)
280 }
281 }
282 default:
283 check.errorf(x.pos(), "too many arguments")
284 return
285 }
286
287 if ellipsis.IsValid() {
288
289 if i != n-1 {
290 check.errorf(ellipsis, "can only use ... with matching parameter")
291 return
292 }
293 if _, ok := x.typ.Underlying().(*Slice); !ok && x.typ != Typ[UntypedNil] {
294 check.errorf(x.pos(), "cannot use %s as parameter of type %s", x, typ)
295 return
296 }
297 } else if sig.variadic && i >= n-1 {
298
299 typ = typ.(*Slice).elem
300 }
301
302 check.assignment(x, typ, context)
303 }
304
305 func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
306
307 var (
308 obj Object
309 index []int
310 indirect bool
311 )
312
313 sel := e.Sel.Name
314
315
316
317
318 if ident, ok := e.X.(*ast.Ident); ok {
319 obj := check.lookup(ident.Name)
320 if pname, _ := obj.(*PkgName); pname != nil {
321 assert(pname.pkg == check.pkg)
322 check.recordUse(ident, pname)
323 pname.used = true
324 pkg := pname.imported
325 exp := pkg.scope.Lookup(sel)
326 if exp == nil {
327 if !pkg.fake {
328 check.errorf(e.Sel.Pos(), "%s not declared by package %s", sel, pkg.name)
329 }
330 goto Error
331 }
332 if !exp.Exported() {
333 check.errorf(e.Sel.Pos(), "%s not exported by package %s", sel, pkg.name)
334
335 }
336 check.recordUse(e.Sel, exp)
337
338
339
340 switch exp := exp.(type) {
341 case *Const:
342 assert(exp.Val() != nil)
343 x.mode = constant_
344 x.typ = exp.typ
345 x.val = exp.val
346 case *TypeName:
347 x.mode = typexpr
348 x.typ = exp.typ
349 case *Var:
350 x.mode = variable
351 x.typ = exp.typ
352 case *Func:
353 x.mode = value
354 x.typ = exp.typ
355 case *Builtin:
356 x.mode = builtin
357 x.typ = exp.typ
358 x.id = exp.id
359 default:
360 check.dump("unexpected object %v", exp)
361 unreachable()
362 }
363 x.expr = e
364 return
365 }
366 }
367
368 check.exprOrType(x, e.X)
369 if x.mode == invalid {
370 goto Error
371 }
372
373 obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
374 if obj == nil {
375 switch {
376 case index != nil:
377
378 check.errorf(e.Sel.Pos(), "ambiguous selector %s", sel)
379 case indirect:
380
381 check.errorf(e.Sel.Pos(), "%s is not in method set of %s", sel, x.typ)
382 default:
383
384 check.errorf(e.Sel.Pos(), "%s.%s undefined (type %s has no field or method %s)", x.expr, sel, x.typ, sel)
385 }
386 goto Error
387 }
388
389
390 if m, _ := obj.(*Func); m != nil {
391 check.objDecl(m, nil)
392 }
393
394 if x.mode == typexpr {
395
396 m, _ := obj.(*Func)
397 if m == nil {
398
399 check.errorf(e.Sel.Pos(), "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
400 goto Error
401 }
402
403 check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
404
405
406
407 var params []*Var
408 sig := m.typ.(*Signature)
409 if sig.params != nil {
410 params = sig.params.vars
411 }
412 x.mode = value
413 x.typ = &Signature{
414 params: NewTuple(append([]*Var{NewVar(token.NoPos, check.pkg, "", x.typ)}, params...)...),
415 results: sig.results,
416 variadic: sig.variadic,
417 }
418
419 check.addDeclDep(m)
420
421 } else {
422
423 switch obj := obj.(type) {
424 case *Var:
425 check.recordSelection(e, FieldVal, x.typ, obj, index, indirect)
426 if x.mode == variable || indirect {
427 x.mode = variable
428 } else {
429 x.mode = value
430 }
431 x.typ = obj.typ
432
433 case *Func:
434
435
436 check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
437
438 if debug {
439
440 typ := x.typ
441 if x.mode == variable {
442
443
444
445
446
447 if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) {
448 typ = &Pointer{base: typ}
449 }
450 }
451
452
453
454
455
456
457
458
459 mset := NewMethodSet(typ)
460 if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj {
461 check.dump("%v: (%s).%v -> %s", e.Pos(), typ, obj.name, m)
462 check.dump("%s\n", mset)
463 panic("method sets and lookup don't agree")
464 }
465 }
466
467 x.mode = value
468
469
470 sig := *obj.typ.(*Signature)
471 sig.recv = nil
472 x.typ = &sig
473
474 check.addDeclDep(obj)
475
476 default:
477 unreachable()
478 }
479 }
480
481
482 x.expr = e
483 return
484
485 Error:
486 x.mode = invalid
487 x.expr = e
488 }
489
View as plain text