github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/go/types/call.go (about) 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 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 // 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.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 // a non-constant result implies a function call 50 if x.mode != invalid && x.mode != constant_ { 51 check.hasCallOrRecv = true 52 } 53 return predeclaredFuncs[id].kind 54 55 default: 56 // function/method call 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 // determine result 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 // unpack tuple 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 // use type-checks each argument. 92 // Useful to make sure expressions are evaluated 93 // (and variables are "used") in the presence of other errors. 94 // The arguments may be nil. 95 func (check *Checker) use(arg ...ast.Expr) { 96 var x operand 97 for _, e := range arg { 98 // The nil check below is necessary since certain AST fields 99 // may legally be nil (e.g., the ast.SliceExpr.High field). 100 if e != nil { 101 check.rawExpr(&x, e, nil) 102 } 103 } 104 } 105 106 // useLHS is like use, but doesn't "use" top-level identifiers. 107 // It should be called instead of use if the arguments are 108 // expressions on the lhs of an assignment. 109 // The arguments must not be nil. 110 func (check *Checker) useLHS(arg ...ast.Expr) { 111 var x operand 112 for _, e := range arg { 113 // If the lhs is an identifier denoting a variable v, this assignment 114 // is not a 'use' of v. Remember current value of v.used and restore 115 // after evaluating the lhs via check.rawExpr. 116 var v *Var 117 var v_used bool 118 if ident, _ := unparen(e).(*ast.Ident); ident != nil { 119 // never type-check the blank name on the lhs 120 if ident.Name == "_" { 121 continue 122 } 123 if _, obj := check.scope.LookupParent(ident.Name, token.NoPos); obj != nil { 124 // It's ok to mark non-local variables, but ignore variables 125 // from other packages to avoid potential race conditions with 126 // dot-imported variables. 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 // restore v.used 136 } 137 } 138 } 139 140 // useGetter is like use, but takes a getter instead of a list of expressions. 141 // It should be called instead of use if a getter is present to avoid repeated 142 // evaluation of the first argument (since the getter was likely obtained via 143 // unpack, which may have evaluated the first argument already). 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 // A getter sets x as the i'th operand, where 0 <= i < n and n is the total 152 // number of operands (context-specific, and maintained elsewhere). A getter 153 // type-checks the i'th operand; the details of the actual check are getter- 154 // specific. 155 type getter func(x *operand, i int) 156 157 // unpack takes a getter get and a number of operands n. If n == 1, unpack 158 // calls the incoming getter for the first operand. If that operand is 159 // invalid, unpack returns (nil, 0, false). Otherwise, if that operand is a 160 // function call, or a comma-ok expression and allowCommaOk is set, the result 161 // is a new getter and operand count providing access to the function results, 162 // or comma-ok values, respectively. The third result value reports if it 163 // is indeed the comma-ok case. In all other cases, the incoming getter and 164 // operand count are returned unchanged, and the third result value is false. 165 // 166 // In other words, if there's exactly one operand that - after type-checking 167 // by calling get - stands for multiple operands, the resulting getter provides 168 // access to those operands instead. 169 // 170 // If the returned getter is called at most once for a given operand index i 171 // (including i == 0), that operand is guaranteed to cause only one call of 172 // the incoming getter with that i. 173 // 174 func unpack(get getter, n int, allowCommaOk bool) (getter, int, bool) { 175 if n != 1 { 176 // zero or multiple values 177 return get, n, false 178 } 179 // possibly result of an n-valued function call or comma,ok value 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 // result of an n-valued function call 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 // comma-ok value 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 // single value 209 return func(x *operand, i int) { 210 if i != 0 { 211 unreachable() 212 } 213 *x = x0 214 }, 1, false 215 } 216 217 // arguments checks argument passing for the call with the given signature. 218 // The arg function provides the operand for the i'th argument. 219 func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature, arg getter, n int) { 220 if call.Ellipsis.IsValid() { 221 // last argument is of the form x... 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 // f()... is not permitted if f() is multi-valued 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 // evaluate arguments 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(call.Fun, sig, i, x, ellipsis, context) 245 } 246 } 247 248 // check argument count 249 if sig.variadic { 250 // a variadic function accepts an "empty" 251 // last argument: count one extra 252 n++ 253 } 254 if n < sig.params.Len() { 255 check.errorf(call.Rparen, "too few arguments in call to %s", call.Fun) 256 // ok to continue 257 } 258 } 259 260 // argument checks passing of argument x to the i'th parameter of the given signature. 261 // If ellipsis is valid, the argument is followed by ... at that position in the call. 262 func (check *Checker) argument(fun ast.Expr, 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 // determine parameter type 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 // argument is of the form x... and x is single-valued 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] { // see issue #18268 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 // use the variadic parameter slice's element type 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 // these must be declared before the "goto Error" statements 307 var ( 308 obj Object 309 index []int 310 indirect bool 311 ) 312 313 sel := e.Sel.Name 314 // If the identifier refers to a package, handle everything here 315 // so we don't need a "package" mode for operands: package names 316 // can only appear in qualified identifiers which are mapped to 317 // selector expressions. 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 // ok to continue 335 } 336 check.recordUse(e.Sel, exp) 337 338 // Simplified version of the code for *ast.Idents: 339 // - imported objects are always fully initialized 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 // TODO(gri) should provide actual type where the conflict happens 378 check.errorf(e.Sel.Pos(), "ambiguous selector %s", sel) 379 case indirect: 380 // TODO(gri) be more specific with this error message 381 check.errorf(e.Sel.Pos(), "%s is not in method set of %s", sel, x.typ) 382 default: 383 // TODO(gri) should check if capitalization of sel matters and provide better error message in that case 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 // methods may not have a fully set up signature yet 390 if m, _ := obj.(*Func); m != nil { 391 check.objDecl(m, nil) 392 } 393 394 if x.mode == typexpr { 395 // method expression 396 m, _ := obj.(*Func) 397 if m == nil { 398 // TODO(gri) should check if capitalization of sel matters and provide better error message in that case 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 // the receiver type becomes the type of the first function 406 // argument of the method expression's function type 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 // regular selector 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 // TODO(gri) If we needed to take into account the receiver's 435 // addressability, should we report the type &(x.typ) instead? 436 check.recordSelection(e, MethodVal, x.typ, obj, index, indirect) 437 438 if debug { 439 // Verify that LookupFieldOrMethod and MethodSet.Lookup agree. 440 typ := x.typ 441 if x.mode == variable { 442 // If typ is not an (unnamed) pointer or an interface, 443 // use *typ instead, because the method set of *typ 444 // includes the methods of typ. 445 // Variables are addressable, so we can always take their 446 // address. 447 if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) { 448 typ = &Pointer{base: typ} 449 } 450 } 451 // If we created a synthetic pointer type above, we will throw 452 // away the method set computed here after use. 453 // TODO(gri) Method set computation should probably always compute 454 // both, the value and the pointer receiver method set and represent 455 // them in a single structure. 456 // TODO(gri) Consider also using a method set cache for the lifetime 457 // of checker once we rely on MethodSet lookup instead of individual 458 // lookup. 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 // remove receiver 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 // everything went well 482 x.expr = e 483 return 484 485 Error: 486 x.mode = invalid 487 x.expr = e 488 }