ast

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

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

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

func LoadModuleFS(ctx context.Context, fsys fs.FS, root string) (*model.Module, error)

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

func LoadPackageFS(ctx context.Context, fsys fs.FS, dir string) (*model.Package, error)

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

func MkFS

func MkFS(t *testing.T, files map[string]string) fstest.MapFS

mkFS builds an in-memory fs.FS using fstest.MapFS from a map of path->content. Paths must use forward slashes and include a module root path prefix, e.g.:

root/go.mod, root/pkg/types.go

MkFS is exported for reuse by testutil.

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).

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL