Skip to content

Commit 40c5663

Browse files
Fixing empty files problem
1 parent 1cf1f06 commit 40c5663

File tree

2 files changed

+59
-5
lines changed

2 files changed

+59
-5
lines changed

build/build.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,13 +411,32 @@ func augmentOriginalFile(file *ast.File, overrides map[string]overrideInfo) {
411411
finalizeRemovals(file)
412412
}
413413

414+
// isOnlyImports determines if this file is empty except for imports.
415+
func isOnlyImports(file *ast.File) bool {
416+
for _, decl := range file.Decls {
417+
if gen, ok := decl.(*ast.GenDecl); !ok || gen.Tok != token.IMPORT {
418+
return false
419+
}
420+
}
421+
return true
422+
}
423+
414424
// pruneImports will remove any unused imports from the file.
415425
//
416-
// This will not remove any dot (`.`) or blank (`_`) imports.
426+
// This will not remove any dot (`.`) or blank (`_`) imports, unless
427+
// there are no declarations or directives meaning that all the imports
428+
// should be cleared.
417429
// If the removal of code causes an import to be removed, the init's from that
418430
// import may not be run anymore. If we still need to run an init for an import
419431
// which is no longer used, add it to the overlay as a blank (`_`) import.
420432
func pruneImports(file *ast.File) {
433+
if isOnlyImports(file) && !astutil.HasDirectivePrefix(file, `//go:linkname `) {
434+
// The file is empty, remove all imports including any `.` or `_` imports.
435+
file.Imports = nil
436+
file.Decls = nil
437+
return
438+
}
439+
421440
unused := make(map[string]int, len(file.Imports))
422441
for i, in := range file.Imports {
423442
if name := astutil.ImportName(in); len(name) > 0 {

build/build_test.go

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,8 +375,10 @@ func TestOverlayAugmentation(t *testing.T) {
375375
desc: `remove unsafe and embed if not needed`,
376376
src: `import "unsafe"
377377
import "embed"
378+
378379
//gopherjs:purge
379380
var eFile embed.FS
381+
380382
//gopherjs:purge
381383
func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)`,
382384
want: ``,
@@ -388,8 +390,10 @@ func TestOverlayAugmentation(t *testing.T) {
388390
desc: `keep unsafe and embed for directives`,
389391
src: `import "unsafe"
390392
import "embed"
393+
391394
//go:embed hello.txt
392395
var eFile embed.FS
396+
393397
//go:linkname runtimeNano runtime.nanotime
394398
func runtimeNano() int64`,
395399
noCodeChange: true,
@@ -565,14 +569,18 @@ func TestOriginalAugmentation(t *testing.T) {
565569
`Equal`: {},
566570
},
567571
src: `import "cmp"
572+
573+
// keeps the isOnlyImports from skipping what is being tested.
574+
func foo() {}
568575
569576
type Pointer[T any] struct {}
570577
571578
func Sort[S ~[]E, E cmp.Ordered](x S) {}
572579
573580
// overlay had stub "func Equal() {}"
574581
func Equal[S ~[]E, E any](s1, s2 S) bool {}`,
575-
want: ``,
582+
want: `// keeps the isOnlyImports from skipping what is being tested.
583+
func foo() {}`,
576584
}, {
577585
desc: `purge generics`,
578586
info: map[string]overrideInfo{
@@ -582,6 +590,9 @@ func TestOriginalAugmentation(t *testing.T) {
582590
},
583591
src: `import "cmp"
584592
593+
// keeps the isOnlyImports from skipping what is being tested.
594+
func foo() {}
595+
585596
type Pointer[T any] struct {}
586597
func (x *Pointer[T]) Load() *T {}
587598
func (x *Pointer[T]) Store(val *T) {}
@@ -590,12 +601,17 @@ func TestOriginalAugmentation(t *testing.T) {
590601
591602
// overlay had stub "func Equal() {}"
592603
func Equal[S ~[]E, E any](s1, s2 S) bool {}`,
593-
want: ``,
604+
want: `// keeps the isOnlyImports from skipping what is being tested.
605+
func foo() {}`,
594606
}, {
595607
desc: `prune an unused import`,
596608
info: map[string]overrideInfo{},
597-
src: `import foo "some/other/bar"`,
598-
want: ``,
609+
src: `import foo "some/other/bar"
610+
611+
// keeps the isOnlyImports from skipping what is being tested.
612+
func foo() {}`,
613+
want: `// keeps the isOnlyImports from skipping what is being tested.
614+
func foo() {}`,
599615
}, {
600616
desc: `override signature of function`,
601617
info: map[string]overrideInfo{
@@ -638,6 +654,25 @@ func TestOriginalAugmentation(t *testing.T) {
638654
}
639655
return b, false
640656
}`,
657+
}, {
658+
desc: `empty file removes all imports`,
659+
info: map[string]overrideInfo{
660+
`foo`: {},
661+
},
662+
src: `import . "math/rand"
663+
func foo() int {
664+
return Int()
665+
}`,
666+
want: ``,
667+
}, {
668+
desc: `empty file with directive`,
669+
info: map[string]overrideInfo{
670+
`foo`: {},
671+
},
672+
src: `//go:linkname foo bar
673+
import _ "unsafe"`,
674+
want: `//go:linkname foo bar
675+
import _ "unsafe"`,
641676
},
642677
}
643678

0 commit comments

Comments
 (0)