diff --git a/compiler/gengo/gengo.go b/compiler/gengo/gengo.go index 28e72e8..82025af 100644 --- a/compiler/gengo/gengo.go +++ b/compiler/gengo/gengo.go @@ -180,14 +180,29 @@ func doGenerate(file *ast.File, debug, library bool) string { } g.emitSymCache() - // Patch deferred imports: inline RTL may add "fmt"/"strings" after header was emitted. + // Patch deferred imports: emitDecl may add to g.imports after the + // header was written. The common cases are inline RTL pulling in + // "fmt"/"strings", but #pragma BEGINDUMP blocks can also hoist + // third-party / private modules (e.g. solmade's internal/dartapi). + // Dump every import not already in the header so external Go + // packages used inside BEGINDUMP actually link. result := g.buf.String() - var deferred string - if g.imports["fmt"] && !strings.Contains(result, "\"fmt\"") { - deferred += "\t\"fmt\"\n" + var deferredLines []string + for imp := range g.imports { + if strings.Contains(result, "\""+imp+"\"") { + continue // already emitted in the initial import block + } + if alias, ok := g.importAlias[imp]; ok && alias != "" { + deferredLines = append(deferredLines, fmt.Sprintf("\t%s %q", alias, imp)) + } else { + deferredLines = append(deferredLines, fmt.Sprintf("\t%q", imp)) + } } - if g.imports["strings"] && !strings.Contains(result, "\"strings\"") { - deferred += "\t\"strings\"\n" + // Sorted for deterministic diffs. + sort.Strings(deferredLines) + deferred := strings.Join(deferredLines, "\n") + if deferred != "" { + deferred += "\n" } result = strings.Replace(result, "\t/*DEFERRED_IMPORTS*/\n", deferred, 1) // Patch guards