@@ -4,143 +4,8 @@ import (
4
4
"fmt"
5
5
"go/ast"
6
6
"go/types"
7
- "strings"
8
-
9
- "github.com/gopherjs/gopherjs/compiler/typesutil"
10
- "github.com/gopherjs/gopherjs/internal/govendor/subst"
11
7
)
12
8
13
- // Resolver translates types defined in terms of type parameters into concrete
14
- // types, given a mapping from type params to type arguments.
15
- type Resolver struct {
16
- tParams * types.TypeParamList
17
- tArgs []types.Type
18
- parent * Resolver
19
-
20
- // subster is the substitution helper that will perform the actual
21
- // substitutions. This maybe nil when there are no substitutions but
22
- // will still usable when nil.
23
- subster * subst.Subster
24
- selMemo map [typesutil.Selection ]typesutil.Selection
25
- }
26
-
27
- // NewResolver creates a new Resolver with tParams entries mapping to tArgs
28
- // entries with the same index.
29
- func NewResolver (tc * types.Context , tParams * types.TypeParamList , tArgs []types.Type , parent * Resolver ) * Resolver {
30
- r := & Resolver {
31
- tParams : tParams ,
32
- tArgs : tArgs ,
33
- parent : parent ,
34
- subster : subst .New (tc , tParams , tArgs ),
35
- selMemo : map [typesutil.Selection ]typesutil.Selection {},
36
- }
37
- return r
38
- }
39
-
40
- // TypeParams is the list of type parameters that this resolver
41
- // (not any parent) will substitute.
42
- func (r * Resolver ) TypeParams () * types.TypeParamList {
43
- if r == nil {
44
- return nil
45
- }
46
- return r .tParams
47
- }
48
-
49
- // TypeArgs is the list of type arguments that this resolver
50
- // (not any parent) will resolve to.
51
- func (r * Resolver ) TypeArgs () []types.Type {
52
- if r == nil {
53
- return nil
54
- }
55
- return r .tArgs
56
- }
57
-
58
- // Parent is the resolver for the function or method that this resolver
59
- // is nested in. This may be nil if the context for this resolver is not
60
- // nested in another generic function or method.
61
- func (r * Resolver ) Parent () * Resolver {
62
- if r == nil {
63
- return nil
64
- }
65
- return r .parent
66
- }
67
-
68
- // Substitute replaces references to type params in the provided type definition
69
- // with the corresponding concrete types.
70
- func (r * Resolver ) Substitute (typ types.Type ) types.Type {
71
- if r == nil || typ == nil {
72
- return typ // No substitutions to be made.
73
- }
74
- typ = r .subster .Type (typ )
75
- typ = r .parent .Substitute (typ )
76
- return typ
77
- }
78
-
79
- // SubstituteAll same as Substitute, but accepts a TypeList are returns
80
- // substitution results as a slice in the same order.
81
- func (r * Resolver ) SubstituteAll (list * types.TypeList ) []types.Type {
82
- result := make ([]types.Type , list .Len ())
83
- for i := range result {
84
- result [i ] = r .Substitute (list .At (i ))
85
- }
86
- return result
87
- }
88
-
89
- // SubstituteSelection replaces a method of field selection on a generic type
90
- // defined in terms of type parameters with a method selection on a concrete
91
- // instantiation of the type.
92
- func (r * Resolver ) SubstituteSelection (sel typesutil.Selection ) typesutil.Selection {
93
- if r == nil || sel == nil {
94
- return sel // No substitutions to be made.
95
- }
96
- if concrete , ok := r .selMemo [sel ]; ok {
97
- return concrete
98
- }
99
-
100
- switch sel .Kind () {
101
- case types .MethodExpr , types .MethodVal , types .FieldVal :
102
- recv := r .Substitute (sel .Recv ())
103
- if types .Identical (recv , sel .Recv ()) {
104
- return sel // Non-generic receiver, no substitution necessary.
105
- }
106
-
107
- // Look up the method on the instantiated receiver.
108
- pkg := sel .Obj ().Pkg ()
109
- obj , index , _ := types .LookupFieldOrMethod (recv , true , pkg , sel .Obj ().Name ())
110
- if obj == nil {
111
- panic (fmt .Errorf ("failed to lookup field %q in type %v" , sel .Obj ().Name (), recv ))
112
- }
113
- typ := obj .Type ()
114
-
115
- if sel .Kind () == types .MethodExpr {
116
- typ = typesutil .RecvAsFirstArg (typ .(* types.Signature ))
117
- }
118
- concrete := typesutil .NewSelection (sel .Kind (), recv , index , obj , typ )
119
- r .selMemo [sel ] = concrete
120
- return concrete
121
- default :
122
- panic (fmt .Errorf ("unexpected selection kind %v: %v" , sel .Kind (), sel ))
123
- }
124
- }
125
-
126
- // String gets a strings representation of the resolver for debugging.
127
- func (r * Resolver ) String () string {
128
- if r == nil {
129
- return `{}`
130
- }
131
-
132
- parts := make ([]string , 0 , len (r .tArgs ))
133
- for i , ta := range r .tArgs {
134
- parts = append (parts , fmt .Sprintf ("%s->%s" , r .tParams .At (i ), ta ))
135
- }
136
-
137
- nestStr := ``
138
- if r .parent != nil {
139
- nestStr = r .parent .String () + `:`
140
- }
141
- return nestStr + `{` + strings .Join (parts , `, ` ) + `}`
142
- }
143
-
144
9
// visitor implements ast.Visitor and collects instances of generic types and
145
10
// functions into an InstanceSet.
146
11
//
@@ -151,7 +16,9 @@ type visitor struct {
151
16
instances * PackageInstanceSets
152
17
resolver * Resolver
153
18
info * types.Info
154
- tNest []types.Type // The type arguments for a nested context.
19
+
20
+ nestTParams * types.TypeParamList // The type parameters for a nested context.
21
+ nestTArgs []types.Type // The type arguments for a nested context.
155
22
}
156
23
157
24
var _ ast.Visitor = & visitor {}
@@ -195,12 +62,14 @@ func (c *visitor) visitInstance(ident *ast.Ident, inst types.Instance) {
195
62
196
63
// If the object is defined in the same scope as the instance,
197
64
// then we apply the current nested type arguments.
198
- var tNest []types.Type
65
+ var nestTParams * types.TypeParamList
66
+ var nestTArgs []types.Type
199
67
if obj .Parent ().Contains (ident .Pos ()) {
200
- tNest = c .tNest
68
+ nestTParams = c .nestTParams
69
+ nestTArgs = c .nestTArgs
201
70
}
202
71
203
- c .addInstance (obj , tArgs , tNest )
72
+ c .addInstance (obj , tArgs , nestTParams , nestTArgs )
204
73
}
205
74
206
75
func (c * visitor ) visitNestedType (obj types.Object ) {
@@ -222,12 +91,12 @@ func (c *visitor) visitNestedType(obj types.Object) {
222
91
return
223
92
}
224
93
225
- c .addInstance (obj , nil , c .resolver .TypeArgs ())
94
+ c .addInstance (obj , nil , c .resolver .TypeParams (), c . resolver . TypeArgs ())
226
95
}
227
96
228
- func (c * visitor ) addInstance (obj types.Object , tArgList * types.TypeList , tNest []types.Type ) {
97
+ func (c * visitor ) addInstance (obj types.Object , tArgList * types.TypeList , nestTParams * types. TypeParamList , nestTArgs []types.Type ) {
229
98
tArgs := c .resolver .SubstituteAll (tArgList )
230
- if isGeneric (tArgs ... ) {
99
+ if isGeneric (nestTParams , tArgs ) {
231
100
// Skip any instances that still have type parameters in them after
232
101
// substitution. This occurs when a type is defined while nested
233
102
// in a generic context and is not fully instantiated yet.
@@ -238,7 +107,7 @@ func (c *visitor) addInstance(obj types.Object, tArgList *types.TypeList, tNest
238
107
c .instances .Add (Instance {
239
108
Object : obj ,
240
109
TArgs : tArgs ,
241
- TNest : tNest ,
110
+ TNest : nestTArgs ,
242
111
})
243
112
244
113
if t , ok := obj .Type ().(* types.Named ); ok {
@@ -247,7 +116,7 @@ func (c *visitor) addInstance(obj types.Object, tArgList *types.TypeList, tNest
247
116
c .instances .Add (Instance {
248
117
Object : method .Origin (),
249
118
TArgs : tArgs ,
250
- TNest : tNest ,
119
+ TNest : nestTArgs ,
251
120
})
252
121
}
253
122
}
@@ -358,12 +227,13 @@ func (c *Collector) Scan(pkg *types.Package, files ...*ast.File) {
358
227
}
359
228
360
229
func (c * Collector ) scanSignature (inst Instance , typ * types.Signature , objMap map [types.Object ]ast.Node ) {
361
- tParams := SignatureTypeParams (typ )
362
230
v := visitor {
363
231
instances : c .Instances ,
364
- resolver : NewResolver (c .TContext , tParams , inst . TArgs , nil ),
232
+ resolver : NewResolver (c .TContext , inst ),
365
233
info : c .Info ,
366
- tNest : inst .TArgs ,
234
+
235
+ nestTParams : SignatureTypeParams (typ ),
236
+ nestTArgs : inst .TArgs ,
367
237
}
368
238
ast .Walk (& v , objMap [inst .Object ])
369
239
}
@@ -377,18 +247,19 @@ func (c *Collector) scanNamed(inst Instance, typ *types.Named, objMap map[types.
377
247
return
378
248
}
379
249
380
- var nestResolver * Resolver
381
- if len (inst .TNest ) > 0 {
382
- fn := FindNestingFunc (inst .Object )
383
- tp := SignatureTypeParams (fn .Type ().(* types.Signature ))
384
- nestResolver = NewResolver (c .TContext , tp , inst .TNest , nil )
250
+ var nestTParams * types.TypeParamList
251
+ nest := FindNestingFunc (obj )
252
+ if nest != nil {
253
+ nestTParams = SignatureTypeParams (nest .Type ().(* types.Signature ))
385
254
}
386
255
387
256
v := visitor {
388
257
instances : c .Instances ,
389
- resolver : NewResolver (c .TContext , typ . TypeParams (), inst . TArgs , nestResolver ),
258
+ resolver : NewResolver (c .TContext , inst ),
390
259
info : c .Info ,
391
- tNest : inst .TNest ,
260
+
261
+ nestTParams : nestTParams ,
262
+ nestTArgs : inst .TNest ,
392
263
}
393
264
ast .Walk (& v , node )
394
265
}
0 commit comments