github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/cmd/compile/internal/types2/selection.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 Selections.
     6  
     7  package types2
     8  
     9  // SelectionKind describes the kind of a selector expression x.f
    10  // (excluding qualified identifiers).
    11  //
    12  // If x is a struct or *struct, a selector expression x.f may denote a
    13  // sequence of selection operations x.a.b.c.f. The SelectionKind
    14  // describes the kind of the final (explicit) operation; all the
    15  // previous (implicit) operations are always field selections.
    16  // Each element of Indices specifies an implicit field (a, b, c)
    17  // by its index in the struct type of the field selection operand.
    18  //
    19  // For a FieldVal operation, the final selection refers to the field
    20  // specified by Selection.Obj.
    21  //
    22  // For a MethodVal operation, the final selection refers to a method.
    23  // If the "pointerness" of the method's declared receiver does not
    24  // match that of the effective receiver after implicit field
    25  // selection, then an & or * operation is implicitly applied to the
    26  // receiver variable or value.
    27  // So, x.f denotes (&x.a.b.c).f when f requires a pointer receiver but
    28  // x.a.b.c is a non-pointer variable; and it denotes (*x.a.b.c).f when
    29  // f requires a non-pointer receiver but x.a.b.c is a pointer value.
    30  //
    31  // All pointer indirections, whether due to implicit or explicit field
    32  // selections or * operations inserted for "pointerness", panic if
    33  // applied to a nil pointer, so a method call x.f() may panic even
    34  // before the function call.
    35  //
    36  // By contrast, a MethodExpr operation T.f is essentially equivalent
    37  // to a function literal of the form:
    38  //
    39  //	func(x T, args) (results) { return x.f(args) }
    40  //
    41  // Consequently, any implicit field selections and * operations
    42  // inserted for "pointerness" are not evaluated until the function is
    43  // called, so a T.f or (*T).f expression never panics.
    44  type SelectionKind int
    45  
    46  const (
    47  	FieldVal   SelectionKind = iota
    48  	MethodVal
    49  	MethodExpr
    50  )
    51  
    52  // A Selection describes a selector expression x.f.
    53  // For the declarations:
    54  //
    55  //	type T struct{ x int; E }
    56  //	type E struct{}
    57  //	func (e E) m() {}
    58  //	var p *T
    59  //
    60  // the following relations exist:
    61  //
    62  //	Selector    Kind          Recv    Obj    Type       Index     Indirect
    63  //
    64  //	p.x         FieldVal      T       x      int        {0}       true
    65  //	p.m         MethodVal     *T      m      func()     {1, 0}    true
    66  //	T.m         MethodExpr    T       m      func(T)    {1, 0}    false
    67  type Selection struct {
    68  	kind     SelectionKind
    69  	recv     Type
    70  	obj      Object
    71  	index    []int
    72  	indirect bool
    73  }
    74  
    75  // Kind returns the selection kind.
    76  func (s *Selection) Kind() SelectionKind
    77  
    78  // Recv returns the type of x in x.f.
    79  func (s *Selection) Recv() Type
    80  
    81  // Obj returns the object denoted by x.f; a *Var for
    82  // a field selection, and a *Func in all other cases.
    83  func (s *Selection) Obj() Object
    84  
    85  // Type returns the type of x.f, which may be different from the type of f.
    86  // See Selection for more information.
    87  func (s *Selection) Type() Type
    88  
    89  // Index describes the path from x to f in x.f.
    90  // The last index entry is the field or method index of the type declaring f;
    91  // either:
    92  //
    93  //  1. the list of declared methods of a named type; or
    94  //  2. the list of methods of an interface type; or
    95  //  3. the list of fields of a struct type.
    96  //
    97  // The earlier index entries are the indices of the embedded fields implicitly
    98  // traversed to get from (the type of) x to f, starting at embedding depth 0.
    99  func (s *Selection) Index() []int
   100  
   101  // Indirect reports whether any pointer indirection was required to get from
   102  // x to f in x.f.
   103  //
   104  // Beware: Indirect spuriously returns true (Go issue #8353) for a
   105  // MethodVal selection in which the receiver argument and parameter
   106  // both have type *T so there is no indirection.
   107  // Unfortunately, a fix is too risky.
   108  func (s *Selection) Indirect() bool
   109  
   110  func (s *Selection) String() string
   111  
   112  // SelectionString returns the string form of s.
   113  // The Qualifier controls the printing of
   114  // package-level objects, and may be nil.
   115  //
   116  // Examples:
   117  //
   118  //	"field (T) f int"
   119  //	"method (T) f(X) Y"
   120  //	"method expr (T) f(X) Y"
   121  func SelectionString(s *Selection, qf Qualifier) string