Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

Commit afba47f

Browse files
committed
Fix bug in preparation of workmaps
The old logic was a holdover from before a proper depth-first search algorithm was implemented in wmToReach(). It was trying to do a "bit" of the search work before the real algorithm; however, the final else statement was causing some internal imports to be dropped if the referent had already been visited. The bug was intermittent, as it depended on map iteration order. This also solves the secondary problem of inaccurate backpropagation/poisoning in wmToReach itself, as the internal linkage data it's operating on is now reliable.
1 parent 6816de4 commit afba47f

File tree

2 files changed

+109
-13
lines changed

2 files changed

+109
-13
lines changed

analysis.go

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -462,35 +462,28 @@ func (t PackageTree) ToReachMaps(main, tests bool, ignore map[string]bool) (ex R
462462
}
463463

464464
imps = imps[:0]
465-
imps = p.Imports
466465
if tests {
467-
imps = dedupeStrings(imps, p.TestImports)
466+
imps = dedupeStrings(p.Imports, p.TestImports)
467+
} else {
468+
imps = p.Imports
468469
}
469470

470471
w := wm{
471472
ex: make(map[string]bool),
472473
in: make(map[string]bool),
473474
}
474475

476+
// For each import, decide whether it should be ignored, or if it
477+
// belongs in the external or internal imports list.
475478
for _, imp := range imps {
476-
// Skip ignored imports
477479
if ignore[imp] {
478480
continue
479481
}
480482

481483
if !eqOrSlashedPrefix(imp, t.ImportRoot) {
482484
w.ex[imp] = true
483485
} else {
484-
if w2, seen := workmap[imp]; seen {
485-
for i := range w2.ex {
486-
w.ex[i] = true
487-
}
488-
for i := range w2.in {
489-
w.in[i] = true
490-
}
491-
} else {
492-
w.in[imp] = true
493-
}
486+
w.in[imp] = true
494487
}
495488
}
496489

analysis_test.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,109 @@ func TestWorkmapToReach(t *testing.T) {
243243
"A/quux": nil,
244244
},
245245
},
246+
// The following tests are mostly about regressions and weeding out
247+
// weird assumptions
248+
"internal diamond": {
249+
workmap: map[string]wm{
250+
"A": {
251+
ex: map[string]bool{
252+
"B/foo": true,
253+
},
254+
in: map[string]bool{
255+
"A/foo": true,
256+
"A/bar": true,
257+
},
258+
},
259+
"A/foo": {
260+
ex: map[string]bool{
261+
"C": true,
262+
},
263+
in: map[string]bool{
264+
"A/quux": true,
265+
},
266+
},
267+
"A/bar": {
268+
ex: map[string]bool{
269+
"D": true,
270+
},
271+
in: map[string]bool{
272+
"A/quux": true,
273+
},
274+
},
275+
"A/quux": {
276+
ex: map[string]bool{
277+
"B/baz": true,
278+
},
279+
in: empty(),
280+
},
281+
},
282+
exrm: ReachMap{
283+
"A": {
284+
"B/baz",
285+
"B/foo",
286+
"C",
287+
"D",
288+
},
289+
"A/foo": {
290+
"B/baz",
291+
"C",
292+
},
293+
"A/bar": {
294+
"B/baz",
295+
"D",
296+
},
297+
"A/quux": {
298+
"B/baz",
299+
},
300+
},
301+
inrm: ReachMap{
302+
"A": {
303+
"A/bar",
304+
"A/foo",
305+
"A/quux",
306+
},
307+
"A/foo": {
308+
"A/quux",
309+
},
310+
"A/bar": {
311+
"A/quux",
312+
},
313+
"A/quux": nil,
314+
},
315+
},
316+
"rootmost gets imported": {
317+
workmap: map[string]wm{
318+
"A": {
319+
ex: map[string]bool{
320+
"B": true,
321+
},
322+
in: empty(),
323+
},
324+
"A/foo": {
325+
ex: map[string]bool{
326+
"C": true,
327+
},
328+
in: map[string]bool{
329+
"A": true,
330+
},
331+
},
332+
},
333+
exrm: ReachMap{
334+
"A": {
335+
"B",
336+
},
337+
"A/foo": {
338+
"B",
339+
"C",
340+
},
341+
},
342+
inrm: ReachMap{
343+
"A": nil,
344+
"A/foo": {
345+
"A",
346+
},
347+
},
348+
},
246349
}
247350

248351
for name, fix := range table {

0 commit comments

Comments
 (0)