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