提交 27e5ab0a 编写于 作者: chai2010's avatar chai2010

loader: 重构 vfs 加载

上级 e99ab37e
......@@ -42,9 +42,9 @@ func LoadProgram(cfg *config.Config, appPath string) (*Program, error) {
// 基于 VFS 加载程序
// 入口 pkgPath 是包路径, 必须是 vfs.App 子包
func LoadProgramVFS(vfs config.PkgVFS, cfg *config.Config, pkgPath string) (*Program, error) {
panic("TODO")
func LoadProgramVFS(vfs *config.PkgVFS, cfg *config.Config, pkgPath string) (*Program, error) {
return loader.LoadProgramVFS(vfs, cfg, pkgPath)
}
// TODO: 解析 ast/语义/SSA 分阶段解析
// TODO: 解析 ast/语义/SSA 分阶段解析, 放到 Program 中
// TODO: Program 编译到不同后端的函数
......@@ -54,6 +54,18 @@ func (p *Manifest) Clone() *Manifest {
return &v
}
// 简版 Manifest
func SimpleManifest(mainPkg, appName string) *Manifest {
p := &Manifest{
MainPkg: mainPkg,
Pkg: Manifest_package{
Name: appName,
Pkgpath: mainPkg,
},
}
return p
}
// 加载 WaModFile 文件
// 如果 vfs 为空则从本地文件系统读取
func LoadManifest(vfs fs.FS, appPath string) (p *Manifest, err error) {
......
......@@ -37,3 +37,9 @@ type Package struct {
func LoadProgram(cfg *config.Config, appPath string) (*Program, error) {
return newLoader(cfg).LoadProgram(appPath)
}
// 基于 VFS 加载程序
// 入口 pkgPath 是包路径, 必须是 vfs.App 子包
func LoadProgramVFS(vfs *config.PkgVFS, cfg *config.Config, pkgPath string) (*Program, error) {
return newLoader(cfg).LoadProgramVFS(vfs, pkgPath)
}
// 版权 @2021 凹语言 作者。保留所有权利。
// TODO: 解析 ast/语义/SSA 分阶段解析
package loader
import (
"io/fs"
"os"
"path/filepath"
"sort"
"strings"
"testing/fstest"
"github.com/wa-lang/wa/internal/ast"
"github.com/wa-lang/wa/internal/config"
......@@ -29,53 +25,47 @@ type _Loader struct {
}
func newLoader(cfg *config.Config) *_Loader {
p := &_Loader{
return &_Loader{
cfg: *cfg.Clone(),
prog: &Program{
Pkgs: make(map[string]*Package),
},
}
return p
}
// 加载程序
func (p *_Loader) LoadProgram(appPath string) (*Program, error) {
logger.Tracef(&config.EnableTrace_loader, "cfg: %+v", p.cfg)
logger.Tracef(&config.EnableTrace_loader, "appPath: %s", appPath)
vfs, manifest, err := loadProgramMeta(&p.cfg, appPath)
if err != nil {
logger.Tracef(&config.EnableTrace_loader, "err: %v", err)
return nil, err
}
return p.loadProgram(vfs, manifest)
}
func (p *_Loader) LoadProgramVFS(vfs *config.PkgVFS, appPath string) (*Program, error) {
manifest, err := config.LoadManifest(nil, appPath)
if err != nil {
logger.Tracef(&config.EnableTrace_loader, "err: %v", err)
return nil, err
}
return p.loadProgram(vfs, manifest)
}
// 加载程序
func (p *_Loader) loadProgram(vfs *config.PkgVFS, manifest *config.Manifest) (*Program, error) {
logger.DumpFS(&config.EnableTrace_loader, "vfs.app", vfs.App, ".")
logger.Tracef(&config.EnableTrace_loader, "manifest: %s", manifest.JSONString())
p.vfs = *vfs
p.prog.Cfg = &p.cfg
p.prog.Manifest = manifest
p.prog.Fset = token.NewFileSet()
if p.vfs.App == nil {
p.vfs.App = os.DirFS(filepath.Join(p.prog.Manifest.Root, "src"))
}
logger.DumpFS(&config.EnableTrace_loader, "p.vfs.App", p.vfs.App, ".")
if p.vfs.Std == nil {
if p.cfg.WaRoot != "" {
p.vfs.Std = os.DirFS(filepath.Join(p.cfg.WaRoot, "src"))
} else {
p.vfs.Std = waroot.GetFS()
}
}
if p.vfs.Vendor == nil {
p.vfs.Vendor = os.DirFS(filepath.Join(p.prog.Manifest.Root, "vendor"))
if p.vfs.Vendor == nil {
p.vfs.Vendor = make(fstest.MapFS) // empty fs
}
}
// import "runtime"
logger.Trace(&config.EnableTrace_loader, "import runtime")
if _, err := p.Import("runtime"); err != nil {
......
// 版权 @2021 凹语言 作者。保留所有权利。
package loader
import (
"os"
"path/filepath"
"testing/fstest"
"github.com/wa-lang/wa/internal/config"
"github.com/wa-lang/wa/internal/logger"
"github.com/wa-lang/wa/internal/waroot"
)
// 根据路径加载需要的 vfs 和 manifest
func loadProgramMeta(cfg *config.Config, appPath string) (
vfs *config.PkgVFS,
manifest *config.Manifest,
err error,
) {
logger.Tracef(&config.EnableTrace_loader, "cfg: %+v", cfg)
logger.Tracef(&config.EnableTrace_loader, "appPath: %s", appPath)
manifest, err = config.LoadManifest(nil, appPath)
if err != nil {
logger.Tracef(&config.EnableTrace_loader, "err: %v", err)
return nil, nil, err
}
logger.Tracef(&config.EnableTrace_loader, "manifest: %s", manifest.JSONString())
vfs = new(config.PkgVFS)
if vfs.App == nil {
vfs.App = os.DirFS(filepath.Join(manifest.Root, "src"))
}
if vfs.Std == nil {
if cfg.WaRoot != "" {
vfs.Std = os.DirFS(filepath.Join(cfg.WaRoot, "src"))
} else {
vfs.Std = waroot.GetFS()
}
}
if vfs.Vendor == nil {
vfs.Vendor = os.DirFS(filepath.Join(manifest.Root, "vendor"))
if vfs.Vendor == nil {
vfs.Vendor = make(fstest.MapFS) // empty fs
}
}
return
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册