1// Copyright 2021 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//go:build go1.18 6// +build go1.18 7 8package typeparams 9 10import ( 11 "go/ast" 12 "go/token" 13 "go/types" 14) 15 16// GetIndexExprData extracts data from AST nodes that represent index 17// expressions. 18// 19// For an ast.IndexExpr, the resulting IndexExprData will have exactly one 20// index expression. For an ast.IndexListExpr (go1.18+), it may have a 21// variable number of index expressions. 22// 23// For nodes that don't represent index expressions, GetIndexExprData returns 24// nil. 25// TODO(rfindley): remove this function in favor of using the alias below. 26func GetIndexExprData(n ast.Node) *IndexExprData { 27 switch e := n.(type) { 28 case *ast.IndexExpr: 29 return &IndexExprData{ 30 X: e.X, 31 Lbrack: e.Lbrack, 32 Indices: []ast.Expr{e.Index}, 33 Rbrack: e.Rbrack, 34 } 35 case *ast.IndexListExpr: 36 return (*IndexExprData)(e) 37 } 38 return nil 39} 40 41// PackIndexExpr returns an *ast.IndexExpr or *ast.IndexListExpr, depending on 42// the cardinality of indices. Calling PackIndexExpr with len(indices) == 0 43// will panic. 44func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) ast.Expr { 45 switch len(indices) { 46 case 0: 47 panic("empty indices") 48 case 1: 49 return &ast.IndexExpr{ 50 X: x, 51 Lbrack: lbrack, 52 Index: indices[0], 53 Rbrack: rbrack, 54 } 55 default: 56 return &ast.IndexListExpr{ 57 X: x, 58 Lbrack: lbrack, 59 Indices: indices, 60 Rbrack: rbrack, 61 } 62 } 63} 64 65// IndexListExpr is an alias for ast.IndexListExpr. 66type IndexListExpr = ast.IndexListExpr 67 68// ForTypeSpec returns n.TypeParams. 69func ForTypeSpec(n *ast.TypeSpec) *ast.FieldList { 70 if n == nil { 71 return nil 72 } 73 return n.TypeParams 74} 75 76// ForFuncType returns n.TypeParams. 77func ForFuncType(n *ast.FuncType) *ast.FieldList { 78 if n == nil { 79 return nil 80 } 81 return n.TypeParams 82} 83 84// TypeParam is an alias for types.TypeParam 85type TypeParam = types.TypeParam 86 87// TypeParamList is an alias for types.TypeParamList 88type TypeParamList = types.TypeParamList 89 90// TypeList is an alias for types.TypeList 91type TypeList = types.TypeList 92 93// NewTypeParam calls types.NewTypeParam. 94func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam { 95 return types.NewTypeParam(name, constraint) 96} 97 98// SetTypeParamConstraint calls tparam.SetConstraint(constraint). 99func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) { 100 tparam.SetConstraint(constraint) 101} 102 103// NewSignatureType calls types.NewSignatureType. 104func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature { 105 return types.NewSignatureType(recv, recvTypeParams, typeParams, params, results, variadic) 106} 107 108// ForSignature returns sig.TypeParams() 109func ForSignature(sig *types.Signature) *TypeParamList { 110 return sig.TypeParams() 111} 112 113// RecvTypeParams returns sig.RecvTypeParams(). 114func RecvTypeParams(sig *types.Signature) *TypeParamList { 115 return sig.RecvTypeParams() 116} 117 118// IsComparable calls iface.IsComparable(). 119func IsComparable(iface *types.Interface) bool { 120 return iface.IsComparable() 121} 122 123// IsMethodSet calls iface.IsMethodSet(). 124func IsMethodSet(iface *types.Interface) bool { 125 return iface.IsMethodSet() 126} 127 128// IsImplicit calls iface.IsImplicit(). 129func IsImplicit(iface *types.Interface) bool { 130 return iface.IsImplicit() 131} 132 133// MarkImplicit calls iface.MarkImplicit(). 134func MarkImplicit(iface *types.Interface) { 135 iface.MarkImplicit() 136} 137 138// ForNamed extracts the (possibly empty) type parameter object list from 139// named. 140func ForNamed(named *types.Named) *TypeParamList { 141 return named.TypeParams() 142} 143 144// SetForNamed sets the type params tparams on n. Each tparam must be of 145// dynamic type *types.TypeParam. 146func SetForNamed(n *types.Named, tparams []*TypeParam) { 147 n.SetTypeParams(tparams) 148} 149 150// NamedTypeArgs returns named.TypeArgs(). 151func NamedTypeArgs(named *types.Named) *TypeList { 152 return named.TypeArgs() 153} 154 155// NamedTypeOrigin returns named.Orig(). 156func NamedTypeOrigin(named *types.Named) types.Type { 157 return named.Origin() 158} 159 160// Term is an alias for types.Term. 161type Term = types.Term 162 163// NewTerm calls types.NewTerm. 164func NewTerm(tilde bool, typ types.Type) *Term { 165 return types.NewTerm(tilde, typ) 166} 167 168// Union is an alias for types.Union 169type Union = types.Union 170 171// NewUnion calls types.NewUnion. 172func NewUnion(terms []*Term) *Union { 173 return types.NewUnion(terms) 174} 175 176// InitInstanceInfo initializes info to record information about type and 177// function instances. 178func InitInstanceInfo(info *types.Info) { 179 info.Instances = make(map[*ast.Ident]types.Instance) 180} 181 182// Instance is an alias for types.Instance. 183type Instance = types.Instance 184 185// GetInstances returns info.Instances. 186func GetInstances(info *types.Info) map[*ast.Ident]Instance { 187 return info.Instances 188} 189 190// Context is an alias for types.Context. 191type Context = types.Context 192 193// Instantiate calls types.Instantiate. 194func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) { 195 return types.Instantiate(ctxt, typ, targs, validate) 196} 197