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