github.com/jhump/golang-x-tools@v0.0.0-20220218190644-4958d6d39439/go/packages/packages.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package packages 6 7 // See doc.go for package documentation and implementation notes. 8 9 import ( 10 "context" 11 "encoding/json" 12 "fmt" 13 "go/ast" 14 "go/parser" 15 "go/scanner" 16 "go/token" 17 "go/types" 18 "io/ioutil" 19 "log" 20 "os" 21 "path/filepath" 22 "strings" 23 "sync" 24 "time" 25 26 "github.com/jhump/golang-x-tools/go/gcexportdata" 27 "github.com/jhump/golang-x-tools/internal/gocommand" 28 "github.com/jhump/golang-x-tools/internal/packagesinternal" 29 "github.com/jhump/golang-x-tools/internal/typeparams" 30 "github.com/jhump/golang-x-tools/internal/typesinternal" 31 ) 32 33 // A LoadMode controls the amount of detail to return when loading. 34 // The bits below can be combined to specify which fields should be 35 // filled in the result packages. 36 // The zero value is a special case, equivalent to combining 37 // the NeedName, NeedFiles, and NeedCompiledGoFiles bits. 38 // ID and Errors (if present) will always be filled. 39 // Load may return more information than requested. 40 type LoadMode int 41 42 // TODO(matloob): When a V2 of go/packages is released, rename NeedExportsFile to 43 // NeedExportFile to make it consistent with the Package field it's adding. 44 45 const ( 46 // NeedName adds Name and PkgPath. 47 NeedName LoadMode = 1 << iota 48 49 // NeedFiles adds GoFiles and OtherFiles. 50 NeedFiles 51 52 // NeedCompiledGoFiles adds CompiledGoFiles. 53 NeedCompiledGoFiles 54 55 // NeedImports adds Imports. If NeedDeps is not set, the Imports field will contain 56 // "placeholder" Packages with only the ID set. 57 NeedImports 58 59 // NeedDeps adds the fields requested by the LoadMode in the packages in Imports. 60 NeedDeps 61 62 // NeedExportsFile adds ExportFile. 63 NeedExportsFile 64 65 // NeedTypes adds Types, Fset, and IllTyped. 66 NeedTypes 67 68 // NeedSyntax adds Syntax. 69 NeedSyntax 70 71 // NeedTypesInfo adds TypesInfo. 72 NeedTypesInfo 73 74 // NeedTypesSizes adds TypesSizes. 75 NeedTypesSizes 76 77 // typecheckCgo enables full support for type checking cgo. Requires Go 1.15+. 78 // Modifies CompiledGoFiles and Types, and has no effect on its own. 79 typecheckCgo 80 81 // NeedModule adds Module. 82 NeedModule 83 ) 84 85 const ( 86 // Deprecated: LoadFiles exists for historical compatibility 87 // and should not be used. Please directly specify the needed fields using the Need values. 88 LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles 89 90 // Deprecated: LoadImports exists for historical compatibility 91 // and should not be used. Please directly specify the needed fields using the Need values. 92 LoadImports = LoadFiles | NeedImports 93 94 // Deprecated: LoadTypes exists for historical compatibility 95 // and should not be used. Please directly specify the needed fields using the Need values. 96 LoadTypes = LoadImports | NeedTypes | NeedTypesSizes 97 98 // Deprecated: LoadSyntax exists for historical compatibility 99 // and should not be used. Please directly specify the needed fields using the Need values. 100 LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo 101 102 // Deprecated: LoadAllSyntax exists for historical compatibility 103 // and should not be used. Please directly specify the needed fields using the Need values. 104 LoadAllSyntax = LoadSyntax | NeedDeps 105 ) 106 107 // A Config specifies details about how packages should be loaded. 108 // The zero value is a valid configuration. 109 // Calls to Load do not modify this struct. 110 type Config struct { 111 // Mode controls the level of information returned for each package. 112 Mode LoadMode 113 114 // Context specifies the context for the load operation. 115 // If the context is cancelled, the loader may stop early 116 // and return an ErrCancelled error. 117 // If Context is nil, the load cannot be cancelled. 118 Context context.Context 119 120 // Logf is the logger for the config. 121 // If the user provides a logger, debug logging is enabled. 122 // If the GOPACKAGESDEBUG environment variable is set to true, 123 // but the logger is nil, default to log.Printf. 124 Logf func(format string, args ...interface{}) 125 126 // Dir is the directory in which to run the build system's query tool 127 // that provides information about the packages. 128 // If Dir is empty, the tool is run in the current directory. 129 Dir string 130 131 // Env is the environment to use when invoking the build system's query tool. 132 // If Env is nil, the current environment is used. 133 // As in os/exec's Cmd, only the last value in the slice for 134 // each environment key is used. To specify the setting of only 135 // a few variables, append to the current environment, as in: 136 // 137 // opt.Env = append(os.Environ(), "GOOS=plan9", "GOARCH=386") 138 // 139 Env []string 140 141 // gocmdRunner guards go command calls from concurrency errors. 142 gocmdRunner *gocommand.Runner 143 144 // BuildFlags is a list of command-line flags to be passed through to 145 // the build system's query tool. 146 BuildFlags []string 147 148 // modFile will be used for -modfile in go command invocations. 149 modFile string 150 151 // modFlag will be used for -modfile in go command invocations. 152 modFlag string 153 154 // Fset provides source position information for syntax trees and types. 155 // If Fset is nil, Load will use a new fileset, but preserve Fset's value. 156 Fset *token.FileSet 157 158 // ParseFile is called to read and parse each file 159 // when preparing a package's type-checked syntax tree. 160 // It must be safe to call ParseFile simultaneously from multiple goroutines. 161 // If ParseFile is nil, the loader will uses parser.ParseFile. 162 // 163 // ParseFile should parse the source from src and use filename only for 164 // recording position information. 165 // 166 // An application may supply a custom implementation of ParseFile 167 // to change the effective file contents or the behavior of the parser, 168 // or to modify the syntax tree. For example, selectively eliminating 169 // unwanted function bodies can significantly accelerate type checking. 170 ParseFile func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) 171 172 // If Tests is set, the loader includes not just the packages 173 // matching a particular pattern but also any related test packages, 174 // including test-only variants of the package and the test executable. 175 // 176 // For example, when using the go command, loading "fmt" with Tests=true 177 // returns four packages, with IDs "fmt" (the standard package), 178 // "fmt [fmt.test]" (the package as compiled for the test), 179 // "fmt_test" (the test functions from source files in package fmt_test), 180 // and "fmt.test" (the test binary). 181 // 182 // In build systems with explicit names for tests, 183 // setting Tests may have no effect. 184 Tests bool 185 186 // Overlay provides a mapping of absolute file paths to file contents. 187 // If the file with the given path already exists, the parser will use the 188 // alternative file contents provided by the map. 189 // 190 // Overlays provide incomplete support for when a given file doesn't 191 // already exist on disk. See the package doc above for more details. 192 Overlay map[string][]byte 193 } 194 195 // driver is the type for functions that query the build system for the 196 // packages named by the patterns. 197 type driver func(cfg *Config, patterns ...string) (*driverResponse, error) 198 199 // driverResponse contains the results for a driver query. 200 type driverResponse struct { 201 // NotHandled is returned if the request can't be handled by the current 202 // driver. If an external driver returns a response with NotHandled, the 203 // rest of the driverResponse is ignored, and go/packages will fallback 204 // to the next driver. If go/packages is extended in the future to support 205 // lists of multiple drivers, go/packages will fall back to the next driver. 206 NotHandled bool 207 208 // Sizes, if not nil, is the types.Sizes to use when type checking. 209 Sizes *types.StdSizes 210 211 // Roots is the set of package IDs that make up the root packages. 212 // We have to encode this separately because when we encode a single package 213 // we cannot know if it is one of the roots as that requires knowledge of the 214 // graph it is part of. 215 Roots []string `json:",omitempty"` 216 217 // Packages is the full set of packages in the graph. 218 // The packages are not connected into a graph. 219 // The Imports if populated will be stubs that only have their ID set. 220 // Imports will be connected and then type and syntax information added in a 221 // later pass (see refine). 222 Packages []*Package 223 } 224 225 // Load loads and returns the Go packages named by the given patterns. 226 // 227 // Config specifies loading options; 228 // nil behaves the same as an empty Config. 229 // 230 // Load returns an error if any of the patterns was invalid 231 // as defined by the underlying build system. 232 // It may return an empty list of packages without an error, 233 // for instance for an empty expansion of a valid wildcard. 234 // Errors associated with a particular package are recorded in the 235 // corresponding Package's Errors list, and do not cause Load to 236 // return an error. Clients may need to handle such errors before 237 // proceeding with further analysis. The PrintErrors function is 238 // provided for convenient display of all errors. 239 func Load(cfg *Config, patterns ...string) ([]*Package, error) { 240 l := newLoader(cfg) 241 response, err := defaultDriver(&l.Config, patterns...) 242 if err != nil { 243 return nil, err 244 } 245 l.sizes = response.Sizes 246 return l.refine(response.Roots, response.Packages...) 247 } 248 249 // defaultDriver is a driver that implements go/packages' fallback behavior. 250 // It will try to request to an external driver, if one exists. If there's 251 // no external driver, or the driver returns a response with NotHandled set, 252 // defaultDriver will fall back to the go list driver. 253 func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, error) { 254 driver := findExternalDriver(cfg) 255 if driver == nil { 256 driver = goListDriver 257 } 258 response, err := driver(cfg, patterns...) 259 if err != nil { 260 return response, err 261 } else if response.NotHandled { 262 return goListDriver(cfg, patterns...) 263 } 264 return response, nil 265 } 266 267 // A Package describes a loaded Go package. 268 type Package struct { 269 // ID is a unique identifier for a package, 270 // in a syntax provided by the underlying build system. 271 // 272 // Because the syntax varies based on the build system, 273 // clients should treat IDs as opaque and not attempt to 274 // interpret them. 275 ID string 276 277 // Name is the package name as it appears in the package source code. 278 Name string 279 280 // PkgPath is the package path as used by the go/types package. 281 PkgPath string 282 283 // Errors contains any errors encountered querying the metadata 284 // of the package, or while parsing or type-checking its files. 285 Errors []Error 286 287 // GoFiles lists the absolute file paths of the package's Go source files. 288 GoFiles []string 289 290 // CompiledGoFiles lists the absolute file paths of the package's source 291 // files that are suitable for type checking. 292 // This may differ from GoFiles if files are processed before compilation. 293 CompiledGoFiles []string 294 295 // OtherFiles lists the absolute file paths of the package's non-Go source files, 296 // including assembly, C, C++, Fortran, Objective-C, SWIG, and so on. 297 OtherFiles []string 298 299 // IgnoredFiles lists source files that are not part of the package 300 // using the current build configuration but that might be part of 301 // the package using other build configurations. 302 IgnoredFiles []string 303 304 // ExportFile is the absolute path to a file containing type 305 // information for the package as provided by the build system. 306 ExportFile string 307 308 // Imports maps import paths appearing in the package's Go source files 309 // to corresponding loaded Packages. 310 Imports map[string]*Package 311 312 // Types provides type information for the package. 313 // The NeedTypes LoadMode bit sets this field for packages matching the 314 // patterns; type information for dependencies may be missing or incomplete, 315 // unless NeedDeps and NeedImports are also set. 316 Types *types.Package 317 318 // Fset provides position information for Types, TypesInfo, and Syntax. 319 // It is set only when Types is set. 320 Fset *token.FileSet 321 322 // IllTyped indicates whether the package or any dependency contains errors. 323 // It is set only when Types is set. 324 IllTyped bool 325 326 // Syntax is the package's syntax trees, for the files listed in CompiledGoFiles. 327 // 328 // The NeedSyntax LoadMode bit populates this field for packages matching the patterns. 329 // If NeedDeps and NeedImports are also set, this field will also be populated 330 // for dependencies. 331 // 332 // Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are 333 // removed. If parsing returned nil, Syntax may be shorter than CompiledGoFiles. 334 Syntax []*ast.File 335 336 // TypesInfo provides type information about the package's syntax trees. 337 // It is set only when Syntax is set. 338 TypesInfo *types.Info 339 340 // TypesSizes provides the effective size function for types in TypesInfo. 341 TypesSizes types.Sizes 342 343 // forTest is the package under test, if any. 344 forTest string 345 346 // depsErrors is the DepsErrors field from the go list response, if any. 347 depsErrors []*packagesinternal.PackageError 348 349 // module is the module information for the package if it exists. 350 Module *Module 351 } 352 353 // Module provides module information for a package. 354 type Module struct { 355 Path string // module path 356 Version string // module version 357 Replace *Module // replaced by this module 358 Time *time.Time // time version was created 359 Main bool // is this the main module? 360 Indirect bool // is this module only an indirect dependency of main module? 361 Dir string // directory holding files for this module, if any 362 GoMod string // path to go.mod file used when loading this module, if any 363 GoVersion string // go version used in module 364 Error *ModuleError // error loading module 365 } 366 367 // ModuleError holds errors loading a module. 368 type ModuleError struct { 369 Err string // the error itself 370 } 371 372 func init() { 373 packagesinternal.GetForTest = func(p interface{}) string { 374 return p.(*Package).forTest 375 } 376 packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError { 377 return p.(*Package).depsErrors 378 } 379 packagesinternal.GetGoCmdRunner = func(config interface{}) *gocommand.Runner { 380 return config.(*Config).gocmdRunner 381 } 382 packagesinternal.SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) { 383 config.(*Config).gocmdRunner = runner 384 } 385 packagesinternal.SetModFile = func(config interface{}, value string) { 386 config.(*Config).modFile = value 387 } 388 packagesinternal.SetModFlag = func(config interface{}, value string) { 389 config.(*Config).modFlag = value 390 } 391 packagesinternal.TypecheckCgo = int(typecheckCgo) 392 } 393 394 // An Error describes a problem with a package's metadata, syntax, or types. 395 type Error struct { 396 Pos string // "file:line:col" or "file:line" or "" or "-" 397 Msg string 398 Kind ErrorKind 399 } 400 401 // ErrorKind describes the source of the error, allowing the user to 402 // differentiate between errors generated by the driver, the parser, or the 403 // type-checker. 404 type ErrorKind int 405 406 const ( 407 UnknownError ErrorKind = iota 408 ListError 409 ParseError 410 TypeError 411 ) 412 413 func (err Error) Error() string { 414 pos := err.Pos 415 if pos == "" { 416 pos = "-" // like token.Position{}.String() 417 } 418 return pos + ": " + err.Msg 419 } 420 421 // flatPackage is the JSON form of Package 422 // It drops all the type and syntax fields, and transforms the Imports 423 // 424 // TODO(adonovan): identify this struct with Package, effectively 425 // publishing the JSON protocol. 426 type flatPackage struct { 427 ID string 428 Name string `json:",omitempty"` 429 PkgPath string `json:",omitempty"` 430 Errors []Error `json:",omitempty"` 431 GoFiles []string `json:",omitempty"` 432 CompiledGoFiles []string `json:",omitempty"` 433 OtherFiles []string `json:",omitempty"` 434 IgnoredFiles []string `json:",omitempty"` 435 ExportFile string `json:",omitempty"` 436 Imports map[string]string `json:",omitempty"` 437 } 438 439 // MarshalJSON returns the Package in its JSON form. 440 // For the most part, the structure fields are written out unmodified, and 441 // the type and syntax fields are skipped. 442 // The imports are written out as just a map of path to package id. 443 // The errors are written using a custom type that tries to preserve the 444 // structure of error types we know about. 445 // 446 // This method exists to enable support for additional build systems. It is 447 // not intended for use by clients of the API and we may change the format. 448 func (p *Package) MarshalJSON() ([]byte, error) { 449 flat := &flatPackage{ 450 ID: p.ID, 451 Name: p.Name, 452 PkgPath: p.PkgPath, 453 Errors: p.Errors, 454 GoFiles: p.GoFiles, 455 CompiledGoFiles: p.CompiledGoFiles, 456 OtherFiles: p.OtherFiles, 457 IgnoredFiles: p.IgnoredFiles, 458 ExportFile: p.ExportFile, 459 } 460 if len(p.Imports) > 0 { 461 flat.Imports = make(map[string]string, len(p.Imports)) 462 for path, ipkg := range p.Imports { 463 flat.Imports[path] = ipkg.ID 464 } 465 } 466 return json.Marshal(flat) 467 } 468 469 // UnmarshalJSON reads in a Package from its JSON format. 470 // See MarshalJSON for details about the format accepted. 471 func (p *Package) UnmarshalJSON(b []byte) error { 472 flat := &flatPackage{} 473 if err := json.Unmarshal(b, &flat); err != nil { 474 return err 475 } 476 *p = Package{ 477 ID: flat.ID, 478 Name: flat.Name, 479 PkgPath: flat.PkgPath, 480 Errors: flat.Errors, 481 GoFiles: flat.GoFiles, 482 CompiledGoFiles: flat.CompiledGoFiles, 483 OtherFiles: flat.OtherFiles, 484 ExportFile: flat.ExportFile, 485 } 486 if len(flat.Imports) > 0 { 487 p.Imports = make(map[string]*Package, len(flat.Imports)) 488 for path, id := range flat.Imports { 489 p.Imports[path] = &Package{ID: id} 490 } 491 } 492 return nil 493 } 494 495 func (p *Package) String() string { return p.ID } 496 497 // loaderPackage augments Package with state used during the loading phase 498 type loaderPackage struct { 499 *Package 500 importErrors map[string]error // maps each bad import to its error 501 loadOnce sync.Once 502 color uint8 // for cycle detection 503 needsrc bool // load from source (Mode >= LoadTypes) 504 needtypes bool // type information is either requested or depended on 505 initial bool // package was matched by a pattern 506 } 507 508 // loader holds the working state of a single call to load. 509 type loader struct { 510 pkgs map[string]*loaderPackage 511 Config 512 sizes types.Sizes 513 parseCache map[string]*parseValue 514 parseCacheMu sync.Mutex 515 exportMu sync.Mutex // enforces mutual exclusion of exportdata operations 516 517 // Config.Mode contains the implied mode (see impliedLoadMode). 518 // Implied mode contains all the fields we need the data for. 519 // In requestedMode there are the actually requested fields. 520 // We'll zero them out before returning packages to the user. 521 // This makes it easier for us to get the conditions where 522 // we need certain modes right. 523 requestedMode LoadMode 524 } 525 526 type parseValue struct { 527 f *ast.File 528 err error 529 ready chan struct{} 530 } 531 532 func newLoader(cfg *Config) *loader { 533 ld := &loader{ 534 parseCache: map[string]*parseValue{}, 535 } 536 if cfg != nil { 537 ld.Config = *cfg 538 // If the user has provided a logger, use it. 539 ld.Config.Logf = cfg.Logf 540 } 541 if ld.Config.Logf == nil { 542 // If the GOPACKAGESDEBUG environment variable is set to true, 543 // but the user has not provided a logger, default to log.Printf. 544 if debug { 545 ld.Config.Logf = log.Printf 546 } else { 547 ld.Config.Logf = func(format string, args ...interface{}) {} 548 } 549 } 550 if ld.Config.Mode == 0 { 551 ld.Config.Mode = NeedName | NeedFiles | NeedCompiledGoFiles // Preserve zero behavior of Mode for backwards compatibility. 552 } 553 if ld.Config.Env == nil { 554 ld.Config.Env = os.Environ() 555 } 556 if ld.Config.gocmdRunner == nil { 557 ld.Config.gocmdRunner = &gocommand.Runner{} 558 } 559 if ld.Context == nil { 560 ld.Context = context.Background() 561 } 562 if ld.Dir == "" { 563 if dir, err := os.Getwd(); err == nil { 564 ld.Dir = dir 565 } 566 } 567 568 // Save the actually requested fields. We'll zero them out before returning packages to the user. 569 ld.requestedMode = ld.Mode 570 ld.Mode = impliedLoadMode(ld.Mode) 571 572 if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 { 573 if ld.Fset == nil { 574 ld.Fset = token.NewFileSet() 575 } 576 577 // ParseFile is required even in LoadTypes mode 578 // because we load source if export data is missing. 579 if ld.ParseFile == nil { 580 ld.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { 581 const mode = parser.AllErrors | parser.ParseComments 582 return parser.ParseFile(fset, filename, src, mode) 583 } 584 } 585 } 586 587 return ld 588 } 589 590 // refine connects the supplied packages into a graph and then adds type and 591 // and syntax information as requested by the LoadMode. 592 func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) { 593 rootMap := make(map[string]int, len(roots)) 594 for i, root := range roots { 595 rootMap[root] = i 596 } 597 ld.pkgs = make(map[string]*loaderPackage) 598 // first pass, fixup and build the map and roots 599 var initial = make([]*loaderPackage, len(roots)) 600 for _, pkg := range list { 601 rootIndex := -1 602 if i, found := rootMap[pkg.ID]; found { 603 rootIndex = i 604 } 605 606 // Overlays can invalidate export data. 607 // TODO(matloob): make this check fine-grained based on dependencies on overlaid files 608 exportDataInvalid := len(ld.Overlay) > 0 || pkg.ExportFile == "" && pkg.PkgPath != "unsafe" 609 // This package needs type information if the caller requested types and the package is 610 // either a root, or it's a non-root and the user requested dependencies ... 611 needtypes := (ld.Mode&NeedTypes|NeedTypesInfo != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) 612 // This package needs source if the call requested source (or types info, which implies source) 613 // and the package is either a root, or itas a non- root and the user requested dependencies... 614 needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) || 615 // ... or if we need types and the exportData is invalid. We fall back to (incompletely) 616 // typechecking packages from source if they fail to compile. 617 (ld.Mode&NeedTypes|NeedTypesInfo != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe" 618 lpkg := &loaderPackage{ 619 Package: pkg, 620 needtypes: needtypes, 621 needsrc: needsrc, 622 } 623 ld.pkgs[lpkg.ID] = lpkg 624 if rootIndex >= 0 { 625 initial[rootIndex] = lpkg 626 lpkg.initial = true 627 } 628 } 629 for i, root := range roots { 630 if initial[i] == nil { 631 return nil, fmt.Errorf("root package %v is missing", root) 632 } 633 } 634 635 // Materialize the import graph. 636 637 const ( 638 white = 0 // new 639 grey = 1 // in progress 640 black = 2 // complete 641 ) 642 643 // visit traverses the import graph, depth-first, 644 // and materializes the graph as Packages.Imports. 645 // 646 // Valid imports are saved in the Packages.Import map. 647 // Invalid imports (cycles and missing nodes) are saved in the importErrors map. 648 // Thus, even in the presence of both kinds of errors, the Import graph remains a DAG. 649 // 650 // visit returns whether the package needs src or has a transitive 651 // dependency on a package that does. These are the only packages 652 // for which we load source code. 653 var stack []*loaderPackage 654 var visit func(lpkg *loaderPackage) bool 655 var srcPkgs []*loaderPackage 656 visit = func(lpkg *loaderPackage) bool { 657 switch lpkg.color { 658 case black: 659 return lpkg.needsrc 660 case grey: 661 panic("internal error: grey node") 662 } 663 lpkg.color = grey 664 stack = append(stack, lpkg) // push 665 stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports 666 // If NeedImports isn't set, the imports fields will all be zeroed out. 667 if ld.Mode&NeedImports != 0 { 668 lpkg.Imports = make(map[string]*Package, len(stubs)) 669 for importPath, ipkg := range stubs { 670 var importErr error 671 imp := ld.pkgs[ipkg.ID] 672 if imp == nil { 673 // (includes package "C" when DisableCgo) 674 importErr = fmt.Errorf("missing package: %q", ipkg.ID) 675 } else if imp.color == grey { 676 importErr = fmt.Errorf("import cycle: %s", stack) 677 } 678 if importErr != nil { 679 if lpkg.importErrors == nil { 680 lpkg.importErrors = make(map[string]error) 681 } 682 lpkg.importErrors[importPath] = importErr 683 continue 684 } 685 686 if visit(imp) { 687 lpkg.needsrc = true 688 } 689 lpkg.Imports[importPath] = imp.Package 690 } 691 } 692 if lpkg.needsrc { 693 srcPkgs = append(srcPkgs, lpkg) 694 } 695 if ld.Mode&NeedTypesSizes != 0 { 696 lpkg.TypesSizes = ld.sizes 697 } 698 stack = stack[:len(stack)-1] // pop 699 lpkg.color = black 700 701 return lpkg.needsrc 702 } 703 704 if ld.Mode&NeedImports == 0 { 705 // We do this to drop the stub import packages that we are not even going to try to resolve. 706 for _, lpkg := range initial { 707 lpkg.Imports = nil 708 } 709 } else { 710 // For each initial package, create its import DAG. 711 for _, lpkg := range initial { 712 visit(lpkg) 713 } 714 } 715 if ld.Mode&NeedImports != 0 && ld.Mode&NeedTypes != 0 { 716 for _, lpkg := range srcPkgs { 717 // Complete type information is required for the 718 // immediate dependencies of each source package. 719 for _, ipkg := range lpkg.Imports { 720 imp := ld.pkgs[ipkg.ID] 721 imp.needtypes = true 722 } 723 } 724 } 725 // Load type data and syntax if needed, starting at 726 // the initial packages (roots of the import DAG). 727 if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 { 728 var wg sync.WaitGroup 729 for _, lpkg := range initial { 730 wg.Add(1) 731 go func(lpkg *loaderPackage) { 732 ld.loadRecursive(lpkg) 733 wg.Done() 734 }(lpkg) 735 } 736 wg.Wait() 737 } 738 739 result := make([]*Package, len(initial)) 740 for i, lpkg := range initial { 741 result[i] = lpkg.Package 742 } 743 for i := range ld.pkgs { 744 // Clear all unrequested fields, 745 // to catch programs that use more than they request. 746 if ld.requestedMode&NeedName == 0 { 747 ld.pkgs[i].Name = "" 748 ld.pkgs[i].PkgPath = "" 749 } 750 if ld.requestedMode&NeedFiles == 0 { 751 ld.pkgs[i].GoFiles = nil 752 ld.pkgs[i].OtherFiles = nil 753 ld.pkgs[i].IgnoredFiles = nil 754 } 755 if ld.requestedMode&NeedCompiledGoFiles == 0 { 756 ld.pkgs[i].CompiledGoFiles = nil 757 } 758 if ld.requestedMode&NeedImports == 0 { 759 ld.pkgs[i].Imports = nil 760 } 761 if ld.requestedMode&NeedExportsFile == 0 { 762 ld.pkgs[i].ExportFile = "" 763 } 764 if ld.requestedMode&NeedTypes == 0 { 765 ld.pkgs[i].Types = nil 766 ld.pkgs[i].Fset = nil 767 ld.pkgs[i].IllTyped = false 768 } 769 if ld.requestedMode&NeedSyntax == 0 { 770 ld.pkgs[i].Syntax = nil 771 } 772 if ld.requestedMode&NeedTypesInfo == 0 { 773 ld.pkgs[i].TypesInfo = nil 774 } 775 if ld.requestedMode&NeedTypesSizes == 0 { 776 ld.pkgs[i].TypesSizes = nil 777 } 778 if ld.requestedMode&NeedModule == 0 { 779 ld.pkgs[i].Module = nil 780 } 781 } 782 783 return result, nil 784 } 785 786 // loadRecursive loads the specified package and its dependencies, 787 // recursively, in parallel, in topological order. 788 // It is atomic and idempotent. 789 // Precondition: ld.Mode&NeedTypes. 790 func (ld *loader) loadRecursive(lpkg *loaderPackage) { 791 lpkg.loadOnce.Do(func() { 792 // Load the direct dependencies, in parallel. 793 var wg sync.WaitGroup 794 for _, ipkg := range lpkg.Imports { 795 imp := ld.pkgs[ipkg.ID] 796 wg.Add(1) 797 go func(imp *loaderPackage) { 798 ld.loadRecursive(imp) 799 wg.Done() 800 }(imp) 801 } 802 wg.Wait() 803 ld.loadPackage(lpkg) 804 }) 805 } 806 807 // loadPackage loads the specified package. 808 // It must be called only once per Package, 809 // after immediate dependencies are loaded. 810 // Precondition: ld.Mode & NeedTypes. 811 func (ld *loader) loadPackage(lpkg *loaderPackage) { 812 if lpkg.PkgPath == "unsafe" { 813 // Fill in the blanks to avoid surprises. 814 lpkg.Types = types.Unsafe 815 lpkg.Fset = ld.Fset 816 lpkg.Syntax = []*ast.File{} 817 lpkg.TypesInfo = new(types.Info) 818 lpkg.TypesSizes = ld.sizes 819 return 820 } 821 822 // Call NewPackage directly with explicit name. 823 // This avoids skew between golist and go/types when the files' 824 // package declarations are inconsistent. 825 lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name) 826 lpkg.Fset = ld.Fset 827 828 // Subtle: we populate all Types fields with an empty Package 829 // before loading export data so that export data processing 830 // never has to create a types.Package for an indirect dependency, 831 // which would then require that such created packages be explicitly 832 // inserted back into the Import graph as a final step after export data loading. 833 // The Diamond test exercises this case. 834 if !lpkg.needtypes && !lpkg.needsrc { 835 return 836 } 837 if !lpkg.needsrc { 838 ld.loadFromExportData(lpkg) 839 return // not a source package, don't get syntax trees 840 } 841 842 appendError := func(err error) { 843 // Convert various error types into the one true Error. 844 var errs []Error 845 switch err := err.(type) { 846 case Error: 847 // from driver 848 errs = append(errs, err) 849 850 case *os.PathError: 851 // from parser 852 errs = append(errs, Error{ 853 Pos: err.Path + ":1", 854 Msg: err.Err.Error(), 855 Kind: ParseError, 856 }) 857 858 case scanner.ErrorList: 859 // from parser 860 for _, err := range err { 861 errs = append(errs, Error{ 862 Pos: err.Pos.String(), 863 Msg: err.Msg, 864 Kind: ParseError, 865 }) 866 } 867 868 case types.Error: 869 // from type checker 870 errs = append(errs, Error{ 871 Pos: err.Fset.Position(err.Pos).String(), 872 Msg: err.Msg, 873 Kind: TypeError, 874 }) 875 876 default: 877 // unexpected impoverished error from parser? 878 errs = append(errs, Error{ 879 Pos: "-", 880 Msg: err.Error(), 881 Kind: UnknownError, 882 }) 883 884 // If you see this error message, please file a bug. 885 log.Printf("internal error: error %q (%T) without position", err, err) 886 } 887 888 lpkg.Errors = append(lpkg.Errors, errs...) 889 } 890 891 if ld.Config.Mode&NeedTypes != 0 && len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" { 892 // The config requested loading sources and types, but sources are missing. 893 // Add an error to the package and fall back to loading from export data. 894 appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError}) 895 ld.loadFromExportData(lpkg) 896 return // can't get syntax trees for this package 897 } 898 899 files, errs := ld.parseFiles(lpkg.CompiledGoFiles) 900 for _, err := range errs { 901 appendError(err) 902 } 903 904 lpkg.Syntax = files 905 if ld.Config.Mode&NeedTypes == 0 { 906 return 907 } 908 909 lpkg.TypesInfo = &types.Info{ 910 Types: make(map[ast.Expr]types.TypeAndValue), 911 Defs: make(map[*ast.Ident]types.Object), 912 Uses: make(map[*ast.Ident]types.Object), 913 Implicits: make(map[ast.Node]types.Object), 914 Scopes: make(map[ast.Node]*types.Scope), 915 Selections: make(map[*ast.SelectorExpr]*types.Selection), 916 } 917 typeparams.InitInstanceInfo(lpkg.TypesInfo) 918 lpkg.TypesSizes = ld.sizes 919 920 importer := importerFunc(func(path string) (*types.Package, error) { 921 if path == "unsafe" { 922 return types.Unsafe, nil 923 } 924 925 // The imports map is keyed by import path. 926 ipkg := lpkg.Imports[path] 927 if ipkg == nil { 928 if err := lpkg.importErrors[path]; err != nil { 929 return nil, err 930 } 931 // There was skew between the metadata and the 932 // import declarations, likely due to an edit 933 // race, or because the ParseFile feature was 934 // used to supply alternative file contents. 935 return nil, fmt.Errorf("no metadata for %s", path) 936 } 937 938 if ipkg.Types != nil && ipkg.Types.Complete() { 939 return ipkg.Types, nil 940 } 941 log.Fatalf("internal error: package %q without types was imported from %q", path, lpkg) 942 panic("unreachable") 943 }) 944 945 // type-check 946 tc := &types.Config{ 947 Importer: importer, 948 949 // Type-check bodies of functions only in non-initial packages. 950 // Example: for import graph A->B->C and initial packages {A,C}, 951 // we can ignore function bodies in B. 952 IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial, 953 954 Error: appendError, 955 Sizes: ld.sizes, 956 } 957 if (ld.Mode & typecheckCgo) != 0 { 958 if !typesinternal.SetUsesCgo(tc) { 959 appendError(Error{ 960 Msg: "typecheckCgo requires Go 1.15+", 961 Kind: ListError, 962 }) 963 return 964 } 965 } 966 types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax) 967 968 lpkg.importErrors = nil // no longer needed 969 970 // If !Cgo, the type-checker uses FakeImportC mode, so 971 // it doesn't invoke the importer for import "C", 972 // nor report an error for the import, 973 // or for any undefined C.f reference. 974 // We must detect this explicitly and correctly 975 // mark the package as IllTyped (by reporting an error). 976 // TODO(adonovan): if these errors are annoying, 977 // we could just set IllTyped quietly. 978 if tc.FakeImportC { 979 outer: 980 for _, f := range lpkg.Syntax { 981 for _, imp := range f.Imports { 982 if imp.Path.Value == `"C"` { 983 err := types.Error{Fset: ld.Fset, Pos: imp.Pos(), Msg: `import "C" ignored`} 984 appendError(err) 985 break outer 986 } 987 } 988 } 989 } 990 991 // Record accumulated errors. 992 illTyped := len(lpkg.Errors) > 0 993 if !illTyped { 994 for _, imp := range lpkg.Imports { 995 if imp.IllTyped { 996 illTyped = true 997 break 998 } 999 } 1000 } 1001 lpkg.IllTyped = illTyped 1002 } 1003 1004 // An importFunc is an implementation of the single-method 1005 // types.Importer interface based on a function value. 1006 type importerFunc func(path string) (*types.Package, error) 1007 1008 func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } 1009 1010 // We use a counting semaphore to limit 1011 // the number of parallel I/O calls per process. 1012 var ioLimit = make(chan bool, 20) 1013 1014 func (ld *loader) parseFile(filename string) (*ast.File, error) { 1015 ld.parseCacheMu.Lock() 1016 v, ok := ld.parseCache[filename] 1017 if ok { 1018 // cache hit 1019 ld.parseCacheMu.Unlock() 1020 <-v.ready 1021 } else { 1022 // cache miss 1023 v = &parseValue{ready: make(chan struct{})} 1024 ld.parseCache[filename] = v 1025 ld.parseCacheMu.Unlock() 1026 1027 var src []byte 1028 for f, contents := range ld.Config.Overlay { 1029 if sameFile(f, filename) { 1030 src = contents 1031 } 1032 } 1033 var err error 1034 if src == nil { 1035 ioLimit <- true // wait 1036 src, err = ioutil.ReadFile(filename) 1037 <-ioLimit // signal 1038 } 1039 if err != nil { 1040 v.err = err 1041 } else { 1042 v.f, v.err = ld.ParseFile(ld.Fset, filename, src) 1043 } 1044 1045 close(v.ready) 1046 } 1047 return v.f, v.err 1048 } 1049 1050 // parseFiles reads and parses the Go source files and returns the ASTs 1051 // of the ones that could be at least partially parsed, along with a 1052 // list of I/O and parse errors encountered. 1053 // 1054 // Because files are scanned in parallel, the token.Pos 1055 // positions of the resulting ast.Files are not ordered. 1056 // 1057 func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) { 1058 var wg sync.WaitGroup 1059 n := len(filenames) 1060 parsed := make([]*ast.File, n) 1061 errors := make([]error, n) 1062 for i, file := range filenames { 1063 if ld.Config.Context.Err() != nil { 1064 parsed[i] = nil 1065 errors[i] = ld.Config.Context.Err() 1066 continue 1067 } 1068 wg.Add(1) 1069 go func(i int, filename string) { 1070 parsed[i], errors[i] = ld.parseFile(filename) 1071 wg.Done() 1072 }(i, file) 1073 } 1074 wg.Wait() 1075 1076 // Eliminate nils, preserving order. 1077 var o int 1078 for _, f := range parsed { 1079 if f != nil { 1080 parsed[o] = f 1081 o++ 1082 } 1083 } 1084 parsed = parsed[:o] 1085 1086 o = 0 1087 for _, err := range errors { 1088 if err != nil { 1089 errors[o] = err 1090 o++ 1091 } 1092 } 1093 errors = errors[:o] 1094 1095 return parsed, errors 1096 } 1097 1098 // sameFile returns true if x and y have the same basename and denote 1099 // the same file. 1100 // 1101 func sameFile(x, y string) bool { 1102 if x == y { 1103 // It could be the case that y doesn't exist. 1104 // For instance, it may be an overlay file that 1105 // hasn't been written to disk. To handle that case 1106 // let x == y through. (We added the exact absolute path 1107 // string to the CompiledGoFiles list, so the unwritten 1108 // overlay case implies x==y.) 1109 return true 1110 } 1111 if strings.EqualFold(filepath.Base(x), filepath.Base(y)) { // (optimisation) 1112 if xi, err := os.Stat(x); err == nil { 1113 if yi, err := os.Stat(y); err == nil { 1114 return os.SameFile(xi, yi) 1115 } 1116 } 1117 } 1118 return false 1119 } 1120 1121 // loadFromExportData returns type information for the specified 1122 // package, loading it from an export data file on the first request. 1123 func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error) { 1124 if lpkg.PkgPath == "" { 1125 log.Fatalf("internal error: Package %s has no PkgPath", lpkg) 1126 } 1127 1128 // Because gcexportdata.Read has the potential to create or 1129 // modify the types.Package for each node in the transitive 1130 // closure of dependencies of lpkg, all exportdata operations 1131 // must be sequential. (Finer-grained locking would require 1132 // changes to the gcexportdata API.) 1133 // 1134 // The exportMu lock guards the Package.Pkg field and the 1135 // types.Package it points to, for each Package in the graph. 1136 // 1137 // Not all accesses to Package.Pkg need to be protected by exportMu: 1138 // graph ordering ensures that direct dependencies of source 1139 // packages are fully loaded before the importer reads their Pkg field. 1140 ld.exportMu.Lock() 1141 defer ld.exportMu.Unlock() 1142 1143 if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() { 1144 return tpkg, nil // cache hit 1145 } 1146 1147 lpkg.IllTyped = true // fail safe 1148 1149 if lpkg.ExportFile == "" { 1150 // Errors while building export data will have been printed to stderr. 1151 return nil, fmt.Errorf("no export data file") 1152 } 1153 f, err := os.Open(lpkg.ExportFile) 1154 if err != nil { 1155 return nil, err 1156 } 1157 defer f.Close() 1158 1159 // Read gc export data. 1160 // 1161 // We don't currently support gccgo export data because all 1162 // underlying workspaces use the gc toolchain. (Even build 1163 // systems that support gccgo don't use it for workspace 1164 // queries.) 1165 r, err := gcexportdata.NewReader(f) 1166 if err != nil { 1167 return nil, fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) 1168 } 1169 1170 // Build the view. 1171 // 1172 // The gcexportdata machinery has no concept of package ID. 1173 // It identifies packages by their PkgPath, which although not 1174 // globally unique is unique within the scope of one invocation 1175 // of the linker, type-checker, or gcexportdata. 1176 // 1177 // So, we must build a PkgPath-keyed view of the global 1178 // (conceptually ID-keyed) cache of packages and pass it to 1179 // gcexportdata. The view must contain every existing 1180 // package that might possibly be mentioned by the 1181 // current package---its transitive closure. 1182 // 1183 // In loadPackage, we unconditionally create a types.Package for 1184 // each dependency so that export data loading does not 1185 // create new ones. 1186 // 1187 // TODO(adonovan): it would be simpler and more efficient 1188 // if the export data machinery invoked a callback to 1189 // get-or-create a package instead of a map. 1190 // 1191 view := make(map[string]*types.Package) // view seen by gcexportdata 1192 seen := make(map[*loaderPackage]bool) // all visited packages 1193 var visit func(pkgs map[string]*Package) 1194 visit = func(pkgs map[string]*Package) { 1195 for _, p := range pkgs { 1196 lpkg := ld.pkgs[p.ID] 1197 if !seen[lpkg] { 1198 seen[lpkg] = true 1199 view[lpkg.PkgPath] = lpkg.Types 1200 visit(lpkg.Imports) 1201 } 1202 } 1203 } 1204 visit(lpkg.Imports) 1205 1206 viewLen := len(view) + 1 // adding the self package 1207 // Parse the export data. 1208 // (May modify incomplete packages in view but not create new ones.) 1209 tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath) 1210 if err != nil { 1211 return nil, fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) 1212 } 1213 if viewLen != len(view) { 1214 log.Fatalf("Unexpected package creation during export data loading") 1215 } 1216 1217 lpkg.Types = tpkg 1218 lpkg.IllTyped = false 1219 1220 return tpkg, nil 1221 } 1222 1223 // impliedLoadMode returns loadMode with its dependencies. 1224 func impliedLoadMode(loadMode LoadMode) LoadMode { 1225 if loadMode&NeedTypesInfo != 0 && loadMode&NeedImports == 0 { 1226 // If NeedTypesInfo, go/packages needs to do typechecking itself so it can 1227 // associate type info with the AST. To do so, we need the export data 1228 // for dependencies, which means we need to ask for the direct dependencies. 1229 // NeedImports is used to ask for the direct dependencies. 1230 loadMode |= NeedImports 1231 } 1232 1233 if loadMode&NeedDeps != 0 && loadMode&NeedImports == 0 { 1234 // With NeedDeps we need to load at least direct dependencies. 1235 // NeedImports is used to ask for the direct dependencies. 1236 loadMode |= NeedImports 1237 } 1238 1239 return loadMode 1240 } 1241 1242 func usesExportData(cfg *Config) bool { 1243 return cfg.Mode&NeedExportsFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0 1244 }