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
16func unsupported() {
17	panic("type parameters are unsupported at this go version")
18}
19
20// GetIndexExprData extracts data from *ast.IndexExpr nodes.
21// For other nodes, GetIndexExprData returns nil.
22func GetIndexExprData(n ast.Node) *IndexExprData {
23	if e, _ := n.(*ast.IndexExpr); e != nil {
24		return &IndexExprData{
25			X:       e.X,
26			Lbrack:  e.Lbrack,
27			Indices: []ast.Expr{e.Index},
28			Rbrack:  e.Rbrack,
29		}
30	}
31	return nil
32}
33
34// PackIndexExpr returns an *ast.IndexExpr with the given index.
35// Calling PackIndexExpr with len(indices) != 1 will panic.
36func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) ast.Expr {
37	switch len(indices) {
38	case 0:
39		panic("empty indices")
40	case 1:
41		return &ast.IndexExpr{
42			X:      x,
43			Lbrack: lbrack,
44			Index:  indices[0],
45			Rbrack: rbrack,
46		}
47	default:
48		panic("cannot pack multiple indices at this go version")
49	}
50}
51
52// IndexListExpr is a placeholder type, as type parameters are not supported at
53// this Go version. Its methods panic on use.
54type IndexListExpr struct {
55	ast.Expr
56	X       ast.Expr   // expression
57	Lbrack  token.Pos  // position of "["
58	Indices []ast.Expr // index expressions
59	Rbrack  token.Pos  // position of "]"
60}
61
62// ForTypeSpec returns an empty field list, as type parameters on not supported
63// at this Go version.
64func ForTypeSpec(*ast.TypeSpec) *ast.FieldList {
65	return nil
66}
67
68// ForFuncType returns an empty field list, as type parameters are not
69// supported at this Go version.
70func ForFuncType(*ast.FuncType) *ast.FieldList {
71	return nil
72}
73
74// TypeParam is a placeholder type, as type parameters are not supported at
75// this Go version. Its methods panic on use.
76type TypeParam struct{ types.Type }
77
78func (*TypeParam) Index() int             { unsupported(); return 0 }
79func (*TypeParam) Constraint() types.Type { unsupported(); return nil }
80func (*TypeParam) Obj() *types.TypeName   { unsupported(); return nil }
81
82// TypeParamList is a placeholder for an empty type parameter list.
83type TypeParamList struct{}
84
85func (*TypeParamList) Len() int          { return 0 }
86func (*TypeParamList) At(int) *TypeParam { unsupported(); return nil }
87
88// TypeList is a placeholder for an empty type list.
89type TypeList struct{}
90
91func (*TypeList) Len() int          { return 0 }
92func (*TypeList) At(int) types.Type { unsupported(); return nil }
93
94// NewTypeParam is unsupported at this Go version, and panics.
95func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam {
96	unsupported()
97	return nil
98}
99
100// SetTypeParamConstraint is unsupported at this Go version, and panics.
101func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) {
102	unsupported()
103}
104
105// NewSignatureType calls types.NewSignature, panicking if recvTypeParams or
106// typeParams is non-empty.
107func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature {
108	if len(recvTypeParams) != 0 || len(typeParams) != 0 {
109		panic("signatures cannot have type parameters at this Go version")
110	}
111	return types.NewSignature(recv, params, results, variadic)
112}
113
114// ForSignature returns an empty slice.
115func ForSignature(*types.Signature) *TypeParamList {
116	return nil
117}
118
119// RecvTypeParams returns a nil slice.
120func RecvTypeParams(sig *types.Signature) *TypeParamList {
121	return nil
122}
123
124// IsComparable returns false, as no interfaces are type-restricted at this Go
125// version.
126func IsComparable(*types.Interface) bool {
127	return false
128}
129
130// IsMethodSet returns true, as no interfaces are type-restricted at this Go
131// version.
132func IsMethodSet(*types.Interface) bool {
133	return true
134}
135
136// IsImplicit returns false, as no interfaces are implicit at this Go version.
137func IsImplicit(*types.Interface) bool {
138	return false
139}
140
141// MarkImplicit does nothing, because this Go version does not have implicit
142// interfaces.
143func MarkImplicit(*types.Interface) {}
144
145// ForNamed returns an empty type parameter list, as type parameters are not
146// supported at this Go version.
147func ForNamed(*types.Named) *TypeParamList {
148	return nil
149}
150
151// SetForNamed panics if tparams is non-empty.
152func SetForNamed(_ *types.Named, tparams []*TypeParam) {
153	if len(tparams) > 0 {
154		unsupported()
155	}
156}
157
158// NamedTypeArgs returns nil.
159func NamedTypeArgs(*types.Named) *TypeList {
160	return nil
161}
162
163// NamedTypeOrigin is the identity method at this Go version.
164func NamedTypeOrigin(named *types.Named) types.Type {
165	return named
166}
167
168// Term holds information about a structural type restriction.
169type Term struct {
170	tilde bool
171	typ   types.Type
172}
173
174func (m *Term) Tilde() bool      { return m.tilde }
175func (m *Term) Type() types.Type { return m.typ }
176func (m *Term) String() string {
177	pre := ""
178	if m.tilde {
179		pre = "~"
180	}
181	return pre + m.typ.String()
182}
183
184// NewTerm is unsupported at this Go version, and panics.
185func NewTerm(tilde bool, typ types.Type) *Term {
186	return &Term{tilde, typ}
187}
188
189// Union is a placeholder type, as type parameters are not supported at this Go
190// version. Its methods panic on use.
191type Union struct{ types.Type }
192
193func (*Union) Len() int         { return 0 }
194func (*Union) Term(i int) *Term { unsupported(); return nil }
195
196// NewUnion is unsupported at this Go version, and panics.
197func NewUnion(terms []*Term) *Union {
198	unsupported()
199	return nil
200}
201
202// InitInstanceInfo is a noop at this Go version.
203func InitInstanceInfo(*types.Info) {}
204
205// Instance is a placeholder type, as type parameters are not supported at this
206// Go version.
207type Instance struct {
208	TypeArgs *TypeList
209	Type     types.Type
210}
211
212// GetInstances returns a nil map, as type parameters are not supported at this
213// Go version.
214func GetInstances(info *types.Info) map[*ast.Ident]Instance { return nil }
215
216// Context is a placeholder type, as type parameters are not supported at
217// this Go version.
218type Context struct{}
219
220// Instantiate is unsupported on this Go version, and panics.
221func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) {
222	unsupported()
223	return nil, nil
224}
225