...
1
2
3
4
5 package ssa
6
7 import (
8 "go/types"
9
10 "golang.org/x/tools/internal/typeparams"
11 )
12
13
14
15
16 type tpWalker struct {
17 seen map[types.Type]bool
18 }
19
20
21 func (w *tpWalker) isParameterized(typ types.Type) (res bool) {
22
23
24
25 if x, ok := w.seen[typ]; ok {
26 return x
27 }
28 w.seen[typ] = false
29 defer func() {
30 w.seen[typ] = res
31 }()
32
33 switch t := typ.(type) {
34 case nil, *types.Basic:
35 break
36
37 case *types.Array:
38 return w.isParameterized(t.Elem())
39
40 case *types.Slice:
41 return w.isParameterized(t.Elem())
42
43 case *types.Struct:
44 for i, n := 0, t.NumFields(); i < n; i++ {
45 if w.isParameterized(t.Field(i).Type()) {
46 return true
47 }
48 }
49
50 case *types.Pointer:
51 return w.isParameterized(t.Elem())
52
53 case *types.Tuple:
54 n := t.Len()
55 for i := 0; i < n; i++ {
56 if w.isParameterized(t.At(i).Type()) {
57 return true
58 }
59 }
60
61 case *types.Signature:
62
63
64
65
66
67
68
69 return w.isParameterized(t.Params()) || w.isParameterized(t.Results())
70
71 case *types.Interface:
72 for i, n := 0, t.NumMethods(); i < n; i++ {
73 if w.isParameterized(t.Method(i).Type()) {
74 return true
75 }
76 }
77 terms, err := typeparams.InterfaceTermSet(t)
78 if err != nil {
79 panic(err)
80 }
81 for _, term := range terms {
82 if w.isParameterized(term.Type()) {
83 return true
84 }
85 }
86
87 case *types.Map:
88 return w.isParameterized(t.Key()) || w.isParameterized(t.Elem())
89
90 case *types.Chan:
91 return w.isParameterized(t.Elem())
92
93 case *types.Named:
94 args := typeparams.NamedTypeArgs(t)
95
96 if params := typeparams.ForNamed(t); params.Len() > args.Len() {
97 return true
98 }
99 for i, n := 0, args.Len(); i < n; i++ {
100 if w.isParameterized(args.At(i)) {
101 return true
102 }
103 }
104
105 case *typeparams.TypeParam:
106 return true
107
108 default:
109 panic(t)
110 }
111
112 return false
113 }
114
115 func (w *tpWalker) anyParameterized(ts []types.Type) bool {
116 for _, t := range ts {
117 if w.isParameterized(t) {
118 return true
119 }
120 }
121 return false
122 }
123
View as plain text