Source file src/go/types/recording.go

     1  // Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
     2  // Source: ../../cmd/compile/internal/types2/recording.go
     3  
     4  // Copyright 2024 The Go Authors. All rights reserved.
     5  // Use of this source code is governed by a BSD-style
     6  // license that can be found in the LICENSE file.
     7  
     8  // This file implements recording of type information
     9  // in the types2.Info maps.
    10  
    11  package types
    12  
    13  import (
    14  	"go/ast"
    15  	"go/constant"
    16  )
    17  
    18  func (check *Checker) record(x *operand) {
    19  	// convert x into a user-friendly set of values
    20  	// TODO(gri) this code can be simplified
    21  	var typ Type
    22  	var val constant.Value
    23  	switch x.mode {
    24  	case invalid:
    25  		typ = Typ[Invalid]
    26  	case novalue:
    27  		typ = (*Tuple)(nil)
    28  	case constant_:
    29  		typ = x.typ
    30  		val = x.val
    31  	default:
    32  		typ = x.typ
    33  	}
    34  	assert(x.expr != nil && typ != nil)
    35  
    36  	if isUntyped(typ) {
    37  		// delay type and value recording until we know the type
    38  		// or until the end of type checking
    39  		check.rememberUntyped(x.expr, false, x.mode, typ.(*Basic), val)
    40  	} else {
    41  		check.recordTypeAndValue(x.expr, x.mode, typ, val)
    42  	}
    43  }
    44  
    45  func (check *Checker) recordUntyped() {
    46  	if !debug && !check.recordTypes() {
    47  		return // nothing to do
    48  	}
    49  
    50  	for x, info := range check.untyped {
    51  		if debug && isTyped(info.typ) {
    52  			check.dump("%v: %s (type %s) is typed", x.Pos(), x, info.typ)
    53  			panic("unreachable")
    54  		}
    55  		check.recordTypeAndValue(x, info.mode, info.typ, info.val)
    56  	}
    57  }
    58  
    59  func (check *Checker) recordTypeAndValue(x ast.Expr, mode operandMode, typ Type, val constant.Value) {
    60  	assert(x != nil)
    61  	assert(typ != nil)
    62  	if mode == invalid {
    63  		return // omit
    64  	}
    65  	if mode == constant_ {
    66  		assert(val != nil)
    67  		// We check allBasic(typ, IsConstType) here as constant expressions may be
    68  		// recorded as type parameters.
    69  		assert(!isValid(typ) || allBasic(typ, IsConstType))
    70  	}
    71  	if m := check.Types; m != nil {
    72  		m[x] = TypeAndValue{mode, typ, val}
    73  	}
    74  	check.recordTypeAndValueInSyntax(x, mode, typ, val)
    75  }
    76  
    77  func (check *Checker) recordBuiltinType(f ast.Expr, sig *Signature) {
    78  	// f must be a (possibly parenthesized, possibly qualified)
    79  	// identifier denoting a built-in (including unsafe's non-constant
    80  	// functions Add and Slice): record the signature for f and possible
    81  	// children.
    82  	for {
    83  		check.recordTypeAndValue(f, builtin, sig, nil)
    84  		switch p := f.(type) {
    85  		case *ast.Ident, *ast.SelectorExpr:
    86  			return // we're done
    87  		case *ast.ParenExpr:
    88  			f = p.X
    89  		default:
    90  			panic("unreachable")
    91  		}
    92  	}
    93  }
    94  
    95  // recordCommaOkTypes updates recorded types to reflect that x is used in a commaOk context
    96  // (and therefore has tuple type).
    97  func (check *Checker) recordCommaOkTypes(x ast.Expr, a []*operand) {
    98  	assert(x != nil)
    99  	assert(len(a) == 2)
   100  	if a[0].mode == invalid {
   101  		return
   102  	}
   103  	t0, t1 := a[0].typ, a[1].typ
   104  	assert(isTyped(t0) && isTyped(t1) && (allBoolean(t1) || t1 == universeError))
   105  	if m := check.Types; m != nil {
   106  		for {
   107  			tv := m[x]
   108  			assert(tv.Type != nil) // should have been recorded already
   109  			pos := x.Pos()
   110  			tv.Type = NewTuple(
   111  				NewVar(pos, check.pkg, "", t0),
   112  				NewVar(pos, check.pkg, "", t1),
   113  			)
   114  			m[x] = tv
   115  			// if x is a parenthesized expression (p.X), update p.X
   116  			p, _ := x.(*ast.ParenExpr)
   117  			if p == nil {
   118  				break
   119  			}
   120  			x = p.X
   121  		}
   122  	}
   123  	check.recordCommaOkTypesInSyntax(x, t0, t1)
   124  }
   125  
   126  // recordInstance records instantiation information into check.Info, if the
   127  // Instances map is non-nil. The given expr must be an ident, selector, or
   128  // index (list) expr with ident or selector operand.
   129  //
   130  // TODO(rfindley): the expr parameter is fragile. See if we can access the
   131  // instantiated identifier in some other way.
   132  func (check *Checker) recordInstance(expr ast.Expr, targs []Type, typ Type) {
   133  	ident := instantiatedIdent(expr)
   134  	assert(ident != nil)
   135  	assert(typ != nil)
   136  	if m := check.Instances; m != nil {
   137  		m[ident] = Instance{newTypeList(targs), typ}
   138  	}
   139  }
   140  
   141  func (check *Checker) recordDef(id *ast.Ident, obj Object) {
   142  	assert(id != nil)
   143  	if m := check.Defs; m != nil {
   144  		m[id] = obj
   145  	}
   146  }
   147  
   148  func (check *Checker) recordUse(id *ast.Ident, obj Object) {
   149  	assert(id != nil)
   150  	assert(obj != nil)
   151  	if m := check.Uses; m != nil {
   152  		m[id] = obj
   153  	}
   154  }
   155  
   156  func (check *Checker) recordImplicit(node ast.Node, obj Object) {
   157  	assert(node != nil)
   158  	assert(obj != nil)
   159  	if m := check.Implicits; m != nil {
   160  		m[node] = obj
   161  	}
   162  }
   163  
   164  func (check *Checker) recordSelection(x *ast.SelectorExpr, kind SelectionKind, recv Type, obj Object, index []int, indirect bool) {
   165  	assert(obj != nil && (recv == nil || len(index) > 0))
   166  	check.recordUse(x.Sel, obj)
   167  	if m := check.Selections; m != nil {
   168  		m[x] = &Selection{kind, recv, obj, index, indirect}
   169  	}
   170  }
   171  
   172  func (check *Checker) recordScope(node ast.Node, scope *Scope) {
   173  	assert(node != nil)
   174  	assert(scope != nil)
   175  	if m := check.Scopes; m != nil {
   176  		m[node] = scope
   177  	}
   178  }
   179  

View as plain text