loader

package
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Feb 12, 2024 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package loader defines helpers for loading packages from sources. It wraps go/packages, allow incremental loading of source code and manual control over which packages get type-checked. This allows for faster loading in cases where you don't actually care about certain imports.

Because it uses go/packages, it's modules-aware, and works in both modules- and non-modules environments.

Loading

The main entrypoint for loading is LoadRoots, which traverse the package graph starting at the given patterns (file, package, path, or ...-wildcard, as one might pass to go list). Packages beyond the roots can be accessed via the Imports() method. Packages are initially loaded with export data paths, filenames, and imports.

Packages are suitable for comparison, as each unique package only ever has one *Package object returned.

Syntax and TypeChecking

ASTs and type-checking information can be loaded with NeedSyntax and NeedTypesInfo, respectively. Both are idempotent -- repeated calls will simply re-use the cached contents. Note that NeedTypesInfo will *only* type check the current package -- if you want to type-check imports as well, you'll need to type-check them first.

Reference Pruning and Recursive Checking

In order to type-check using only the packages you care about, you can use a TypeChecker. TypeChecker will visit each top-level type declaration, collect (optionally filtered) references, and type-check references packages.

Errors

Errors can be added to each package. Use ErrFromNode to create an error from an AST node. Errors can then be printed (complete with file and position information) using PrintErrors, optionally filtered by error type. It's generally a good idea to filter out TypeErrors when doing incomplete type-checking with TypeChecker. You can use MaybeErrList to return multiple errors if you need to return an error instead of adding it to a package. AddError will later unroll it into individual errors.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EachType

func EachType(pkg *Package, cb TypeCallback)

EachType calls the given callback for each (gendecl, typespec) combo in the given package. Generally, using markers.EachType is better when working with marker data, and has a more convinient representation.

func ErrFromNode

func ErrFromNode(err error, node Node) error

ErrFromNode returns the given error, with additional information attaching it to the given AST node. It will automatically map over error lists.

func MaybeErrList

func MaybeErrList(errs []error) error

MaybeErrList constructs an ErrList if the given list of errors has any errors, otherwise returning nil.

func NonVendorPath

func NonVendorPath(rawPath string) string

NonVendorPath returns a package path that does not include anything before the last vendor directory. This is useful for when using vendor directories, and using go/types.Package.Path(), which returns the full path including vendor.

If you're using this, make sure you really need it -- it's better to index by the actual Package object when you can.

func ParseAstTag

func ParseAstTag(tag *ast.BasicLit) reflect.StructTag

ParseAstTag parses the given raw tag literal into a reflect.StructTag.

func PrintErrors

func PrintErrors(pkgs []*Package, filterKinds ...packages.ErrorKind) bool

PrintErrors print errors associated with all packages in the given package graph, starting at the given root packages and traversing through all imports. It will skip any errors of the kinds specified in filterKinds. It will return true if any errors were printed.

Types

type ErrList

type ErrList []error

ErrList is a list of errors aggregated together into a single error.

func (ErrList) Error

func (l ErrList) Error() string

type Node

type Node interface {
	Pos() token.Pos // position of first character belonging to the node
}

Node is the intersection of go/ast.Node and go/types.Var.

type NodeFilter

type NodeFilter func(ast.Node) bool

NodeFilter filters nodes, accepting them for reference collection when true is returned and rejecting them when false is returned.

type Package

type Package struct {
	*packages.Package

	sync.Mutex
	// contains filtered or unexported fields
}

Package is a single, unique Go package that can be lazily parsed and type-checked. Packages should not be constructed directly -- instead, use LoadRoots. For a given call to LoadRoots, only a single instance of each package exists, and thus they may be used as keys and for comparison.

func LoadRoots

func LoadRoots(roots ...string) ([]*Package, error)

LoadRoots loads the given "root" packages by path, transitively loading and all imports as well.

Loaded packages will have type size, imports, and exports file information populated. Additional information, like ASTs and type-checking information, can be accessed via methods on individual packages.

func LoadRootsWithConfig

func LoadRootsWithConfig(cfg *packages.Config, roots ...string) ([]*Package, error)

LoadRootsWithConfig functions like LoadRoots, except that it allows passing a custom loading config. The config will be modified to suit the needs of the loader.

This is generally only useful for use in testing when you need to modify loading settings to load from a fake location.

This function will traverse Go module boundaries for roots that are file- system paths and end with "...". Please note this feature currently only supports roots that are filesystem paths. For more information, please refer to the high-level outline of this function's logic:

  1. If no roots are provided then load the working directory and return early.

  2. Otherwise sort the provided roots into two, distinct buckets:

    a. package/module names b. filesystem paths

    A filesystem path is distinguished from a Go package/module name by the same rules as followed by the "go" command. At a high level, a root is a filesystem path IFF it meets ANY of the following criteria:

    * is absolute * begins with . * begins with ..

    For more information please refer to the output of the command "go help packages".

  3. Load the package/module roots as a single call to packages.Load. If there are no filesystem path roots then return early.

  4. For filesystem path roots ending with "...", check to see if its descendants include any nested, Go modules. If so, add the directory that contains the nested Go module to the filesystem path roots.

  5. Load the filesystem path roots and return the load packages for the package/module roots AND the filesystem path roots.

func (*Package) AddError

func (p *Package) AddError(err error)

AddError adds an error to the errors associated with the given package.

func (*Package) Imports

func (p *Package) Imports() map[string]*Package

Imports returns the imports for the given package, indexed by package path (*not* name in any particular file).

func (*Package) NeedSyntax

func (p *Package) NeedSyntax()

NeedSyntax indicates that a parsed AST is needed for this package. Actual ASTs can be accessed via the Syntax field.

func (*Package) NeedTypesInfo

func (p *Package) NeedTypesInfo()

NeedTypesInfo indicates that type-checking information is needed for this package. Actual type-checking information can be accessed via the Types and TypesInfo fields.

type PositionedError

type PositionedError struct {
	Pos token.Pos
	// contains filtered or unexported fields
}

PositionedError represents some error with an associated position. The position is tied to some external token.FileSet.

type TypeCallback

type TypeCallback func(file *ast.File, decl *ast.GenDecl, spec *ast.TypeSpec)

TypeCallback is a callback called for each raw AST (gendecl, typespec) combo.

type TypeChecker

type TypeChecker struct {
	// NodeFilters are used to filter the set of references that are followed
	// when typechecking.  If any of the filters returns true for a given node,
	// its package will be added to the set of packages to check.
	//
	// If no filters are specified, all references are followed (this may be slow).
	//
	// Modifying this after the first call to check may yield strange/invalid
	// results.
	NodeFilters []NodeFilter

	sync.Mutex
	// contains filtered or unexported fields
}

TypeChecker performs type-checking on a limitted subset of packages by checking each package's types' externally-referenced types, and only type-checking those packages.

func (*TypeChecker) Check

func (c *TypeChecker) Check(root *Package)

Check type-checks the given package and all packages referenced by types that pass through (have true returned by) any of the NodeFilters.

Directories

Path Synopsis
Package testutils defines utilities for using loader.Packages in tests.
Package testutils defines utilities for using loader.Packages in tests.

Jump to

Keyboard shortcuts

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