Documentation
¶
Overview ¶
Package loader: convert.go contains helpers that convert parsed Go AST expressions and function types into the model's intermediate Node and Func representations, including generic type parameters and alias resolution using import alias maps.
Package loader: deep.go provides recursive package loading on top of fs.FS without relying on GOPATH semantics. It walks non-stdlib imports that are within the same module and attaches loaded packages to Dependencies.
Package loader provides utilities to parse Go packages and modules into an intermediate model suitable for code generation. It discovers modules, loads package files, extracts types, globals, methods, free functions, and embedded resources, and converts Go AST into the model's Node graph. Methods are captured both as AST (for stub rendering) and as model-level signatures under Type.Methods (value/pointer receivers) for programmatic use.
Primary entrypoints
- LoadPackageDeepFS: recursively loads in-module dependencies from any fs.FS and optionally resolves external imports via DeepOptions.ResolveExternal.
- LoadExternalModule: start from an import path and a resolver that maps import paths to (fs.FS, dir); use this to deep-load external modules.
Thin helpers
- LoadPackageDeepOS: convenience wrapper around the OS filesystem.
- LoadPackageDeepGOPATH: GOPATH-based deep loader (directory-based; deprecated in favour of LoadExternalModuleGOPATH when starting from an import path).
- LoadPackageDeepAFS (viant_afs build): deep loader backed by an AFS service.
- LoadExternalModuleGOPATH: start from import path using GOPATHResolver.
- LoadExternalModuleAFSGOPATH (viant_afs build): start from import path using AFSGOPATHResolver.
Resolver helpers
- GOPATHResolver(gopath): maps import paths to os.DirFS("/") + $GOPATH/src/<import>.
- AFSGOPATHResolver (viant_afs build): maps import paths under an AFS baseURL (e.g., mem://localhost/gopath/src/<import>).
Examples demonstrate both shallow (LoadPackageFS) and deep loading. In most cases, prefer LoadPackageDeepFS with a ResolveExternal function (via DeepOptions) or use LoadExternalModule to start from an import path: this keeps the API minimal and backend-agnostic. GOPATH and AFS wrappers are provided as convenience.
Package loader: methods.go binds method declarations to their owning types and updates both AST and model-level method representations, including conversion of signatures to model.Func for downstream code generation.
Package loader: module.go contains module-level discovery and walking logic. It locates the module root (go.mod), parses the module path, and walks the directory tree to find packages, delegating to LoadPackageFS.
Package loader: package_load.go contains the high-level package loading workflow. It enumerates Go files, derives the package import path, and orchestrates per-file parsing and model population via loadPackageFile.
Index ¶
- func GOPATHResolver(gopath string) func(ctx context.Context, importPath string) (fs.FS, string, error)
- func LoadExternalModule(ctx context.Context, importPath string, ...) (*model.Package, error)
- func LoadExternalModuleGOPATH(ctx context.Context, importPath, gopath string) (*model.Package, error)
- func LoadModuleFS(ctx context.Context, fsys fs.FS, root string) (*model.Module, error)
- func LoadPackageDeepFS(ctx context.Context, fsys fs.FS, dir string, opts ...DeepOptions) (*model.Package, error)
- func LoadPackageDeepGOPATH(ctx context.Context, startDir string, gopath string) (*model.Package, error)deprecated
- func LoadPackageDeepOS(ctx context.Context, dir string, opts ...DeepOptions) (*model.Package, error)
- func LoadPackageFS(ctx context.Context, fsys fs.FS, dir string) (*model.Package, error)
- func MkFS(t *testing.T, files map[string]string) fstest.MapFS
- type DeepOptions
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GOPATHResolver ¶
func GOPATHResolver(gopath string) func(ctx context.Context, importPath string) (fs.FS, string, error)
GOPATHResolver returns a DeepOptions.ResolveExternal-compatible function which resolves an import path to (os.DirFS("/"), GOPATH/src/<importPath>). If gopath is empty, it falls back to $GOPATH.
func LoadExternalModule ¶
func LoadExternalModule(ctx context.Context, importPath string, resolver func(ctx context.Context, importPath string) (fs.FS, string, error)) (*model.Package, error)
LoadExternalModule resolves importPath via resolver and deep-loads that module. The same resolver is used to resolve any external dependencies discovered while traversing the module graph.
func LoadExternalModuleGOPATH ¶
func LoadExternalModuleGOPATH(ctx context.Context, importPath, gopath string) (*model.Package, error)
LoadExternalModuleGOPATH deep-loads a module identified by importPath using a GOPATH-style resolver (mapping to $GOPATH/src/<importPath>). It is a thin convenience wrapper around LoadExternalModule and GOPATHResolver.
Prefer this helper when you have an import path and want resolution based on a traditional GOPATH layout. For custom resolution, pass your own resolver to LoadExternalModule.
func LoadModuleFS ¶
LoadModuleFS walks a module rooted at root within fsys, discovers the module path from go.mod, and loads all packages recursively.
func LoadPackageDeepFS ¶
func LoadPackageDeepFS(ctx context.Context, fsys fs.FS, dir string, opts ...DeepOptions) (*model.Package, error)
LoadPackageDeepFS loads a package from dir and recursively loads its non-stdlib dependencies using fsys. It automatically follows in-module imports. External imports can be resolved using opts.ResolveExternal.
Example ¶
ExampleLoadPackageDeepFS shows deep loading in-memory via fs.FS.
fsys := fstest.MapFS{
"root/go.mod": &fstest.MapFile{Data: []byte("module example.com/deep\n\n")},
"root/a/a.go": &fstest.MapFile{Data: []byte("package a\n\nimport \"example.com/deep/b\"\n type A struct{ B *b.B }\n")},
"root/b/b.go": &fstest.MapFile{Data: []byte("package b\n\nimport \"example.com/deep/c\"\n type B struct{ C *c.C }\n")},
"root/c/c.go": &fstest.MapFile{Data: []byte("package c\n\nimport \"example.com/deep/a\"\n type C struct{ A *a.A }\n")},
}
ctx := context.Background()
pkg, _ := LoadPackageDeepFS(ctx, fsys, "root/a")
fmt.Println(len(pkg.Dependencies) > 0)
Output: true
func LoadPackageDeepGOPATH
deprecated
func LoadPackageDeepGOPATH(ctx context.Context, startDir string, gopath string) (*model.Package, error)
LoadPackageDeepGOPATH resolves non-stdlib imports by mapping to directories under GOPATH/src and recursively loading their packages using the host filesystem. It starts at startDir (an absolute directory).
Deprecated: prefer starting from an import path using LoadExternalModule in combination with GOPATHResolver or the convenience wrapper LoadExternalModuleGOPATH when possible. This function remains for cases where discovery starts at a physical directory.
Example ¶
ExampleLoadPackageDeepGOPATH shows resolving external imports via GOPATH. This example falls back to shallow loading when GOPATH is empty.
// Provide an absolute directory for a module and package as needed in real usage.
// For brevity, this example demonstrates the call shape and prints true.
_ = os.Setenv("GOPATH", "")
ctx := context.Background()
// startDir would be an absolute path in a real scenario.
_, _ = LoadPackageDeepGOPATH(ctx, "/tmp/nonexistent", "")
fmt.Println(true)
Output: true
func LoadPackageDeepOS ¶
func LoadPackageDeepOS(ctx context.Context, dir string, opts ...DeepOptions) (*model.Package, error)
LoadPackageDeepOS is a convenience wrapper that uses the host filesystem to recursively load in-module dependencies starting at an absolute dir.
Example ¶
ExampleLoadPackageDeepOS shows deep loading on the OS filesystem.
tmp := os.TempDir()
root := filepath.Join(tmp, "example_deep_mod")
_ = os.RemoveAll(root)
_ = os.MkdirAll(filepath.Join(root, "a"), 0o755)
_ = os.MkdirAll(filepath.Join(root, "b"), 0o755)
_ = os.MkdirAll(filepath.Join(root, "c"), 0o755)
_ = os.WriteFile(filepath.Join(root, "go.mod"), []byte("module example.com/deep\n\n"), 0o644)
_ = os.WriteFile(filepath.Join(root, "a", "a.go"), []byte("package a\n\nimport \"example.com/deep/b\"\n type A struct{ B *b.B }\n"), 0o644)
_ = os.WriteFile(filepath.Join(root, "b", "b.go"), []byte("package b\n\nimport \"example.com/deep/c\"\n type B struct{ C *c.C }\n"), 0o644)
_ = os.WriteFile(filepath.Join(root, "c", "c.go"), []byte("package c\n\nimport \"example.com/deep/a\"\n type C struct{ A *a.A }\n"), 0o644)
ctx := context.Background()
// Use an OS-backed fs.FS rooted at the module directory.
pkg, _ := LoadPackageDeepFS(ctx, os.DirFS(root), "a")
// print package path includes module path
fmt.Println(strings.Contains(pkg.PkgPath, "example.com/deep"))
Output: true
func LoadPackageFS ¶
LoadPackageFS parses all non-test .go files under dir within fsys and produces a model.Package with files, types, functions, and imports.
Example ¶
ExampleLoadPackageFS demonstrates loading a package from an in-memory fs.FS and rendering its files.
fsys := fstest.MapFS{
"root/go.mod": &fstest.MapFile{Data: []byte("module example.com/demo\n\n")},
"root/p/types.go": &fstest.MapFile{Data: []byte("package p\n\n type T struct{ ID int }\n")},
}
ctx := context.Background()
pkg, _ := LoadPackageFS(ctx, fsys, "root/p")
files, _ := pkg.RenderFiles()
fmt.Println(strings.Contains(files["types.go"], "type T struct"))
Output: true
Types ¶
type DeepOptions ¶
type DeepOptions struct {
ResolveExternal func(ctx context.Context, importPath string) (fs.FS, string, error)
}
DeepOptions controls deep loading resolution for imports outside the current module. When ResolveExternal is provided, it is invoked for non-stdlib imports that are not within the current module to return an fs.FS and a directory that roots that import path. Returning a nil fs.FS disables resolution for that import (it will be skipped).