mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-10 05:53:39 +00:00
loader: load packages using Go modules
This commit replaces the existing ad-hoc package loader with a package loader that uses the x/tools/go/packages package to find all to-be-loaded packages.
This commit is contained in:
committed by
Ron Evans
parent
35015a7918
commit
4ca2d3f0cf
@@ -63,73 +63,14 @@ const (
|
||||
)
|
||||
|
||||
// Create and initialize a new *Program from a *ssa.Program.
|
||||
func NewProgram(lprogram *loader.Program, mainPath string) *Program {
|
||||
func NewProgram(lprogram *loader.Program) *Program {
|
||||
program := lprogram.LoadSSA()
|
||||
program.Build()
|
||||
|
||||
// Find the main package, which is a bit difficult when running a .go file
|
||||
// directly.
|
||||
mainPkg := program.ImportedPackage(mainPath)
|
||||
if mainPkg == nil {
|
||||
for _, pkgInfo := range program.AllPackages() {
|
||||
if pkgInfo.Pkg.Name() == "main" {
|
||||
if mainPkg != nil {
|
||||
panic("more than one main package found")
|
||||
}
|
||||
mainPkg = pkgInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
mainPkg := program.ImportedPackage(lprogram.MainPkg.PkgPath)
|
||||
if mainPkg == nil {
|
||||
panic("could not find main package")
|
||||
}
|
||||
|
||||
// Make a list of packages in import order.
|
||||
packageList := []*ssa.Package{}
|
||||
packageSet := map[string]struct{}{}
|
||||
worklist := []string{"runtime", mainPath}
|
||||
for len(worklist) != 0 {
|
||||
pkgPath := worklist[0]
|
||||
var pkg *ssa.Package
|
||||
if pkgPath == mainPath {
|
||||
pkg = mainPkg // necessary for compiling individual .go files
|
||||
} else {
|
||||
pkg = program.ImportedPackage(pkgPath)
|
||||
}
|
||||
if pkg == nil {
|
||||
// Non-SSA package (e.g. cgo).
|
||||
packageSet[pkgPath] = struct{}{}
|
||||
worklist = worklist[1:]
|
||||
continue
|
||||
}
|
||||
if _, ok := packageSet[pkgPath]; ok {
|
||||
// Package already in the final package list.
|
||||
worklist = worklist[1:]
|
||||
continue
|
||||
}
|
||||
|
||||
unsatisfiedImports := make([]string, 0)
|
||||
imports := pkg.Pkg.Imports()
|
||||
for _, pkg := range imports {
|
||||
if _, ok := packageSet[pkg.Path()]; ok {
|
||||
continue
|
||||
}
|
||||
unsatisfiedImports = append(unsatisfiedImports, pkg.Path())
|
||||
}
|
||||
if len(unsatisfiedImports) == 0 {
|
||||
// All dependencies of this package are satisfied, so add this
|
||||
// package to the list.
|
||||
packageList = append(packageList, pkg)
|
||||
packageSet[pkgPath] = struct{}{}
|
||||
worklist = worklist[1:]
|
||||
} else {
|
||||
// Prepend all dependencies to the worklist and reconsider this
|
||||
// package (by not removing it from the worklist). At that point, it
|
||||
// must be possible to add it to packageList.
|
||||
worklist = append(unsatisfiedImports, worklist...)
|
||||
}
|
||||
}
|
||||
|
||||
p := &Program{
|
||||
Program: program,
|
||||
LoaderProgram: lprogram,
|
||||
@@ -137,8 +78,8 @@ func NewProgram(lprogram *loader.Program, mainPath string) *Program {
|
||||
functionMap: make(map[*ssa.Function]*Function),
|
||||
}
|
||||
|
||||
for _, pkg := range packageList {
|
||||
p.AddPackage(pkg)
|
||||
for _, pkg := range lprogram.Sorted() {
|
||||
p.AddPackage(program.ImportedPackage(pkg.PkgPath))
|
||||
}
|
||||
|
||||
return p
|
||||
|
||||
Reference in New Issue
Block a user