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

loader: 重构 vfs 加载

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