func (p *Package) NeedSyntax() {
	if p.Syntax != nil {
		return
	}
	out := make([]*ast.File, len(p.CompiledGoFiles))
	var wg sync.WaitGroup
	wg.Add(len(p.CompiledGoFiles))
	for i, filename := range p.CompiledGoFiles {
		go func(i int, filename string) {
			defer wg.Done()
			src, err := ioutil.ReadFile(filename)
			if err != nil {
				p.AddError(err)
				return
			}
			out[i], err = p.loader.parseFile(filename, src)
			if err != nil {
				p.AddError(err)
				return
			}
		}(i, filename)
	}
	wg.Wait()
	for _, file := range out {
		if file == nil {
			return
		}
	}
	p.Syntax = out
}
NeedSyntax indicates that a parsed AST is needed for this package.
Actual ASTs can be accessed via the Syntax field.
package loader
import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/scanner"
	"go/token"
	"go/types"
	"io/ioutil"
	"os"
	"sync"
	"golang.org/x/tools/go/packages"
)
func PrintErrors(pkgs []*Package, filterKinds ...packages.ErrorKind) bool {
	pkgsRaw := make([]*packages.Package, len(pkgs))
	for i, pkg := range pkgs {
		pkgsRaw[i] = pkg.Package
	}
	toSkip := make(map[packages.ErrorKind]struct{})
	for _, errKind := range filterKinds {
		toSkip[errKind] = struct{}{}
	}
	hadErrors := false
	packages.Visit(pkgsRaw, nil, func(pkgRaw *packages.Package) {
		for _, err := range pkgRaw.Errors {
			if _, skip := toSkip[err.Kind]; skip {
				continue
			}
			hadErrors = true
			fmt.Fprintln(os.Stderr, err)
		}
	})
	return hadErrors
}
type Package struct {
	*packages.Package
	imports map[string]*Package
	loader *loader
	sync.Mutex
}
func (p *Package) Imports() map[string]*Package {
	if p.imports == nil {
		p.imports = p.loader.packagesFor(p.Package.Imports)
	}
	return p.imports
}
func (p *Package) NeedTypesInfo() {
	if p.TypesInfo != nil {
		return
	}
	p.NeedSyntax()
	p.loader.typeCheck(p)
}