github.com/lovishpuri/go-40569/src@v0.0.0-20230519171745-f8623e7c56cf/go/types/selection.go (about)

     1  // Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
     2  
     3  // Copyright 2013 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // This file implements Selections.
     8  
     9  package types
    10  
    11  import (
    12  	"bytes"
    13  	"fmt"
    14  )
    15  
    16  // SelectionKind describes the kind of a selector expression x.f
    17  // (excluding qualified identifiers).
    18  type SelectionKind int
    19  
    20  const (
    21  	FieldVal   SelectionKind = iota // x.f is a struct field selector
    22  	MethodVal                       // x.f is a method selector
    23  	MethodExpr                      // x.f is a method expression
    24  )
    25  
    26  // A Selection describes a selector expression x.f.
    27  // For the declarations:
    28  //
    29  //	type T struct{ x int; E }
    30  //	type E struct{}
    31  //	func (e E) m() {}
    32  //	var p *T
    33  //
    34  // the following relations exist:
    35  //
    36  //	Selector    Kind          Recv    Obj    Type       Index     Indirect
    37  //
    38  //	p.x         FieldVal      T       x      int        {0}       true
    39  //	p.m         MethodVal     *T      m      func()     {1, 0}    true
    40  //	T.m         MethodExpr    T       m      func(T)    {1, 0}    false
    41  type Selection struct {
    42  	kind     SelectionKind
    43  	recv     Type   // type of x
    44  	obj      Object // object denoted by x.f
    45  	index    []int  // path from x to x.f
    46  	indirect bool   // set if there was any pointer indirection on the path
    47  }
    48  
    49  // Kind returns the selection kind.
    50  func (s *Selection) Kind() SelectionKind { return s.kind }
    51  
    52  // Recv returns the type of x in x.f.
    53  func (s *Selection) Recv() Type { return s.recv }
    54  
    55  // Obj returns the object denoted by x.f; a *Var for
    56  // a field selection, and a *Func in all other cases.
    57  func (s *Selection) Obj() Object { return s.obj }
    58  
    59  // Type returns the type of x.f, which may be different from the type of f.
    60  // See Selection for more information.
    61  func (s *Selection) Type() Type {
    62  	switch s.kind {
    63  	case MethodVal:
    64  		// The type of x.f is a method with its receiver type set
    65  		// to the type of x.
    66  		sig := *s.obj.(*Func).typ.(*Signature)
    67  		recv := *sig.recv
    68  		recv.typ = s.recv
    69  		sig.recv = &recv
    70  		return &sig
    71  
    72  	case MethodExpr:
    73  		// The type of x.f is a function (without receiver)
    74  		// and an additional first argument with the same type as x.
    75  		// TODO(gri) Similar code is already in call.go - factor!
    76  		// TODO(gri) Compute this eagerly to avoid allocations.
    77  		sig := *s.obj.(*Func).typ.(*Signature)
    78  		arg0 := *sig.recv
    79  		sig.recv = nil
    80  		arg0.typ = s.recv
    81  		var params []*Var
    82  		if sig.params != nil {
    83  			params = sig.params.vars
    84  		}
    85  		sig.params = NewTuple(append([]*Var{&arg0}, params...)...)
    86  		return &sig
    87  	}
    88  
    89  	// In all other cases, the type of x.f is the type of x.
    90  	return s.obj.Type()
    91  }
    92  
    93  // Index describes the path from x to f in x.f.
    94  // The last index entry is the field or method index of the type declaring f;
    95  // either:
    96  //
    97  //  1. the list of declared methods of a named type; or
    98  //  2. the list of methods of an interface type; or
    99  //  3. the list of fields of a struct type.
   100  //
   101  // The earlier index entries are the indices of the embedded fields implicitly
   102  // traversed to get from (the type of) x to f, starting at embedding depth 0.
   103  func (s *Selection) Index() []int { return s.index }
   104  
   105  // Indirect reports whether any pointer indirection was required to get from
   106  // x to f in x.f.
   107  func (s *Selection) Indirect() bool { return s.indirect }
   108  
   109  func (s *Selection) String() string { return SelectionString(s, nil) }
   110  
   111  // SelectionString returns the string form of s.
   112  // The Qualifier controls the printing of
   113  // package-level objects, and may be nil.
   114  //
   115  // Examples:
   116  //
   117  //	"field (T) f int"
   118  //	"method (T) f(X) Y"
   119  //	"method expr (T) f(X) Y"
   120  func SelectionString(s *Selection, qf Qualifier) string {
   121  	var k string
   122  	switch s.kind {
   123  	case FieldVal:
   124  		k = "field "
   125  	case MethodVal:
   126  		k = "method "
   127  	case MethodExpr:
   128  		k = "method expr "
   129  	default:
   130  		unreachable()
   131  	}
   132  	var buf bytes.Buffer
   133  	buf.WriteString(k)
   134  	buf.WriteByte('(')
   135  	WriteType(&buf, s.Recv(), qf)
   136  	fmt.Fprintf(&buf, ") %s", s.obj.Name())
   137  	if T := s.Type(); s.kind == FieldVal {
   138  		buf.WriteByte(' ')
   139  		WriteType(&buf, T, qf)
   140  	} else {
   141  		WriteSignature(&buf, T.(*Signature), qf)
   142  	}
   143  	return buf.String()
   144  }