Skip to content

Commit 3c4cc5d

Browse files
Updating to match some future changes
1 parent 3b94762 commit 3c4cc5d

File tree

5 files changed

+131
-85
lines changed

5 files changed

+131
-85
lines changed

compiler/internal/dce/collector.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,33 @@ type Decl interface {
1414
// Collector is a tool to collect dependencies for a declaration
1515
// that'll be used in dead-code elimination (DCE).
1616
type Collector struct {
17-
dependencies map[types.Object]struct{}
17+
dce *Info
1818
}
1919

2020
// CollectDCEDeps captures a list of Go objects (types, functions, etc.)
2121
// the code translated inside f() depends on. Then sets those objects
2222
// as dependencies of the given dead-code elimination info.
2323
//
2424
// Only one CollectDCEDeps call can be active at a time.
25-
// This will overwrite any previous dependencies collected for the given DCE.
2625
func (c *Collector) CollectDCEDeps(decl Decl, f func()) {
27-
if c.dependencies != nil {
26+
if c.dce != nil {
2827
panic(errors.New(`called CollectDCEDeps inside another CollectDCEDeps call`))
2928
}
3029

31-
c.dependencies = make(map[types.Object]struct{})
32-
defer func() { c.dependencies = nil }()
30+
c.dce = decl.Dce()
31+
defer func() { c.dce = nil }()
3332

3433
f()
35-
36-
decl.Dce().setDeps(c.dependencies)
3734
}
3835

3936
// DeclareDCEDep records that the code that is currently being transpiled
40-
// depends on a given Go object.
37+
// depends on a given Go object with optional type arguments.
38+
//
39+
// The given optional type arguments are used to when the object is a
40+
// function with type parameters or anytime the object doesn't carry them.
41+
// If not given, this attempts to get the type arguments from the object.
4142
func (c *Collector) DeclareDCEDep(o types.Object) {
42-
if c.dependencies == nil {
43-
return // Dependencies are not being collected.
43+
if c.dce != nil {
44+
c.dce.addDep(o)
4445
}
45-
c.dependencies[o] = struct{}{}
4646
}

compiler/internal/dce/dce_test.go

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,13 @@ func Test_Collector_Collecting(t *testing.T) {
6565
depCount(t, decl1, 2)
6666
depCount(t, decl2, 3)
6767

68-
// The second collection overwrites the first collection.
68+
// The second collection adds to existing dependencies.
6969
c.CollectDCEDeps(decl2, func() {
70+
c.DeclareDCEDep(obj4)
7071
c.DeclareDCEDep(obj5)
7172
})
7273
depCount(t, decl1, 2)
73-
depCount(t, decl2, 1)
74+
depCount(t, decl2, 4)
7475
}
7576

7677
func Test_Info_SetNameAndDep(t *testing.T) {
@@ -86,8 +87,7 @@ func Test_Info_SetNameAndDep(t *testing.T) {
8687
`package jim
8788
import Sarah "fmt"`),
8889
want: Info{
89-
importPath: `jim`,
90-
objectFilter: `Sarah`,
90+
objectFilter: `jim.Sarah`,
9191
},
9292
wantDep: `jim.Sarah`,
9393
},
@@ -97,8 +97,7 @@ func Test_Info_SetNameAndDep(t *testing.T) {
9797
`package jim
9898
var Toby float64`),
9999
want: Info{
100-
importPath: `jim`,
101-
objectFilter: `Toby`,
100+
objectFilter: `jim.Toby`,
102101
},
103102
wantDep: `jim.Toby`,
104103
},
@@ -108,8 +107,7 @@ func Test_Info_SetNameAndDep(t *testing.T) {
108107
`package jim
109108
const Ludo int = 42`),
110109
want: Info{
111-
importPath: `jim`,
112-
objectFilter: `Ludo`,
110+
objectFilter: `jim.Ludo`,
113111
},
114112
wantDep: `jim.Ludo`,
115113
},
@@ -126,8 +124,7 @@ func Test_Info_SetNameAndDep(t *testing.T) {
126124
}
127125
}`),
128126
want: Info{
129-
importPath: `jim`,
130-
objectFilter: `Gobo`,
127+
objectFilter: `jim.Gobo`,
131128
},
132129
wantDep: `jim.Gobo`,
133130
},
@@ -137,8 +134,7 @@ func Test_Info_SetNameAndDep(t *testing.T) {
137134
`package jim
138135
type Jen struct{}`),
139136
want: Info{
140-
importPath: `jim`,
141-
objectFilter: `Jen`,
137+
objectFilter: `jim.Jen`,
142138
},
143139
wantDep: `jim.Jen`,
144140
},
@@ -148,8 +144,7 @@ func Test_Info_SetNameAndDep(t *testing.T) {
148144
`package jim
149145
type Henson[T comparable] struct{}`),
150146
want: Info{
151-
importPath: `jim`,
152-
objectFilter: `Henson`,
147+
objectFilter: `jim.Henson`,
153148
},
154149
wantDep: `jim.Henson`,
155150
},
@@ -159,8 +154,7 @@ func Test_Info_SetNameAndDep(t *testing.T) {
159154
`package jim
160155
func Jareth() {}`),
161156
want: Info{
162-
importPath: `jim`,
163-
objectFilter: `Jareth`,
157+
objectFilter: `jim.Jareth`,
164158
},
165159
wantDep: `jim.Jareth`,
166160
},
@@ -170,8 +164,7 @@ func Test_Info_SetNameAndDep(t *testing.T) {
170164
`package jim
171165
func Didymus[T comparable]() {}`),
172166
want: Info{
173-
importPath: `jim`,
174-
objectFilter: `Didymus`,
167+
objectFilter: `jim.Didymus`,
175168
},
176169
wantDep: `jim.Didymus`,
177170
},
@@ -182,8 +175,7 @@ func Test_Info_SetNameAndDep(t *testing.T) {
182175
type Fizzgig string
183176
func (f Fizzgig) Kira() {}`),
184177
want: Info{
185-
importPath: `jim`,
186-
objectFilter: `Fizzgig`,
178+
objectFilter: `jim.Fizzgig`,
187179
},
188180
wantDep: `jim.Kira~`,
189181
},
@@ -194,9 +186,8 @@ func Test_Info_SetNameAndDep(t *testing.T) {
194186
type Aughra int
195187
func (a Aughra) frank() {}`),
196188
want: Info{
197-
importPath: `jim`,
198-
objectFilter: `Aughra`,
199-
methodFilter: `frank~`,
189+
objectFilter: `jim.Aughra`,
190+
methodFilter: `jim.frank~`,
200191
},
201192
wantDep: `jim.frank~`,
202193
},
@@ -207,8 +198,7 @@ func Test_Info_SetNameAndDep(t *testing.T) {
207198
type wembley struct{}
208199
func (w wembley) Red() {}`),
209200
want: Info{
210-
importPath: `jim`,
211-
objectFilter: `wembley`,
201+
objectFilter: `jim.wembley`,
212202
},
213203
wantDep: `jim.Red~`,
214204
},
@@ -219,12 +209,11 @@ func Test_Info_SetNameAndDep(t *testing.T) {
219209
t.Run(tt.name, func(t *testing.T) {
220210
d := &testDecl{}
221211
equal(t, d.Dce().unnamed(), true)
222-
equal(t, d.Dce().String(), `[unnamed] . -> []`)
212+
equal(t, d.Dce().String(), `[unnamed] -> []`)
223213
t.Log(`object:`, types.ObjectString(tt.obj, nil))
224214

225215
d.Dce().SetName(tt.obj)
226216
equal(t, d.Dce().unnamed(), tt.want.unnamed())
227-
equal(t, d.Dce().importPath, tt.want.importPath)
228217
equal(t, d.Dce().objectFilter, tt.want.objectFilter)
229218
equal(t, d.Dce().methodFilter, tt.want.methodFilter)
230219
equal(t, d.Dce().String(), tt.want.String())
@@ -238,11 +227,17 @@ func Test_Info_SetNameAndDep(t *testing.T) {
238227
d := &testDecl{}
239228
t.Log(`object:`, types.ObjectString(tt.obj, nil))
240229

241-
d.Dce().setDeps(map[types.Object]struct{}{
242-
tt.obj: {},
230+
wantDeps := []string{}
231+
if len(tt.wantDep) > 0 {
232+
wantDeps = append(wantDeps, tt.wantDep)
233+
}
234+
sort.Strings(wantDeps)
235+
236+
c := Collector{}
237+
c.CollectDCEDeps(d, func() {
238+
c.DeclareDCEDep(tt.obj)
243239
})
244-
equal(t, len(d.Dce().deps), 1)
245-
equal(t, d.Dce().deps[0], tt.wantDep)
240+
equalSlices(t, d.Dce().getDeps(), wantDeps)
246241
})
247242
}
248243
})
@@ -269,11 +264,11 @@ func Test_Info_SetAsAlive(t *testing.T) {
269264
obj := quickVar(pkg, `Falkor`)
270265
decl := &testDecl{}
271266
equal(t, decl.Dce().isAlive(), true) // unnamed is automatically alive
272-
equal(t, decl.Dce().String(), `[unnamed] . -> []`)
267+
equal(t, decl.Dce().String(), `[unnamed] -> []`)
273268

274269
decl.Dce().SetAsAlive()
275270
equal(t, decl.Dce().isAlive(), true) // still alive but now explicitly alive
276-
equal(t, decl.Dce().String(), `[alive] [unnamed] . -> []`)
271+
equal(t, decl.Dce().String(), `[alive] [unnamed] -> []`)
277272

278273
decl.Dce().SetName(obj)
279274
equal(t, decl.Dce().isAlive(), true) // alive because SetAsAlive was called
@@ -284,7 +279,7 @@ func Test_Info_SetAsAlive(t *testing.T) {
284279
obj := quickVar(pkg, `Artax`)
285280
decl := &testDecl{}
286281
equal(t, decl.Dce().isAlive(), true) // unnamed is automatically alive
287-
equal(t, decl.Dce().String(), `[unnamed] . -> []`)
282+
equal(t, decl.Dce().String(), `[unnamed] -> []`)
288283

289284
decl.Dce().SetName(obj)
290285
equal(t, decl.Dce().isAlive(), false) // named so no longer automatically alive
@@ -493,6 +488,7 @@ func Test_Selector_SpecificMethods(t *testing.T) {
493488

494489
for _, tt := range tests {
495490
t.Run(tt.name, func(t *testing.T) {
491+
vetinari.Dce().deps = nil // reset deps
496492
c.CollectDCEDeps(vetinari, func() {
497493
for _, decl := range tt.deps {
498494
c.DeclareDCEDep(decl.obj)
@@ -626,6 +622,17 @@ func depCount(t *testing.T, decl *testDecl, want int) {
626622
func equal[T comparable](t *testing.T, got, want T) {
627623
t.Helper()
628624
if got != want {
629-
t.Errorf(`expected %#v but got %#v`, want, got)
625+
t.Errorf("Unexpected value was gotten:\n\texp: %#v\n\tgot: %#v", want, got)
626+
}
627+
}
628+
629+
func equalSlices[T comparable](t *testing.T, got, want []T) {
630+
t.Helper()
631+
if len(got) != len(want) {
632+
t.Errorf("expected %d but got %d\n\texp: %#v\n\tgot: %#v", len(want), len(got), want, got)
633+
return
634+
}
635+
for i, wantElem := range want {
636+
equal(t, got[i], wantElem)
630637
}
631638
}

compiler/internal/dce/filters.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package dce
2+
3+
import (
4+
"go/types"
5+
6+
"github.com/gopherjs/gopherjs/compiler/typesutil"
7+
)
8+
9+
// getFilters determines the DCE filters for the given object.
10+
// This will return an object filter and optionally return a method filter.
11+
func getFilters(o types.Object) (objectFilter, methodFilter string) {
12+
importPath := o.Pkg().Path()
13+
if typesutil.IsMethod(o) {
14+
recv := typesutil.RecvType(o.Type().(*types.Signature)).Obj()
15+
objectFilter = importPath + `.` + recv.Name()
16+
if !o.Exported() {
17+
methodFilter = importPath + `.` + o.Name() + `~`
18+
}
19+
} else {
20+
objectFilter = importPath + `.` + o.Name()
21+
}
22+
return
23+
}
24+
25+
// getDepFilter returns the filter for the given object to be used as a dependency.
26+
func getDepFilter(o types.Object) string {
27+
qualifiedName := o.Pkg().Path() + "." + o.Name()
28+
if typesutil.IsMethod(o) {
29+
qualifiedName += "~"
30+
}
31+
return qualifiedName
32+
}

0 commit comments

Comments
 (0)