1
2
3
4
5 package packages
6
7
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"
19 "io/ioutil"
20 "log"
21 "os"
22 "path/filepath"
23 "runtime"
24 "strings"
25 "sync"
26 "time"
27
28 "golang.org/x/tools/go/gcexportdata"
29 "golang.org/x/tools/internal/gocommand"
30 "golang.org/x/tools/internal/packagesinternal"
31 "golang.org/x/tools/internal/typeparams"
32 "golang.org/x/tools/internal/typesinternal"
33 )
34
35
36
37
38
39
40
41
42 type LoadMode int
43
44 const (
45
46 NeedName LoadMode = 1 << iota
47
48
49 NeedFiles
50
51
52 NeedCompiledGoFiles
53
54
55
56 NeedImports
57
58
59 NeedDeps
60
61
62 NeedExportFile
63
64
65 NeedTypes
66
67
68 NeedSyntax
69
70
71 NeedTypesInfo
72
73
74 NeedTypesSizes
75
76
77 needInternalDepsErrors
78
79
80
81 needInternalForTest
82
83
84
85 typecheckCgo
86
87
88 NeedModule
89
90
91 NeedEmbedFiles
92
93
94 NeedEmbedPatterns
95 )
96
97 const (
98
99
100 LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles
101
102
103
104 LoadImports = LoadFiles | NeedImports
105
106
107
108 LoadTypes = LoadImports | NeedTypes | NeedTypesSizes
109
110
111
112 LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo
113
114
115
116 LoadAllSyntax = LoadSyntax | NeedDeps
117
118
119 NeedExportsFile = NeedExportFile
120 )
121
122
123
124
125 type Config struct {
126
127 Mode LoadMode
128
129
130
131
132
133 Context context.Context
134
135
136
137
138
139 Logf func(format string, args ...interface{})
140
141
142
143
144 Dir string
145
146
147
148
149
150
151
152
153
154 Env []string
155
156
157 gocmdRunner *gocommand.Runner
158
159
160
161 BuildFlags []string
162
163
164 modFile string
165
166
167 modFlag string
168
169
170
171 Fset *token.FileSet
172
173
174
175
176
177
178
179
180
181
182
183
184
185 ParseFile func(fset *token.FileSet, filename string, src []byte) (*ast.File, error)
186
187
188
189
190
191
192
193
194
195
196
197
198
199 Tests bool
200
201
202
203
204
205
206
207 Overlay map[string][]byte
208 }
209
210
211
212 type driver func(cfg *Config, patterns ...string) (*driverResponse, error)
213
214
215 type driverResponse struct {
216
217
218
219
220
221 NotHandled bool
222
223
224 Sizes *types.StdSizes
225
226
227
228
229
230 Roots []string `json:",omitempty"`
231
232
233
234
235
236
237 Packages []*Package
238
239
240
241
242 GoVersion int
243 }
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259 func Load(cfg *Config, patterns ...string) ([]*Package, error) {
260 l := newLoader(cfg)
261 response, err := defaultDriver(&l.Config, patterns...)
262 if err != nil {
263 return nil, err
264 }
265 l.sizes = response.Sizes
266 return l.refine(response)
267 }
268
269
270
271
272
273 func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
274 driver := findExternalDriver(cfg)
275 if driver == nil {
276 driver = goListDriver
277 }
278 response, err := driver(cfg, patterns...)
279 if err != nil {
280 return response, err
281 } else if response.NotHandled {
282 return goListDriver(cfg, patterns...)
283 }
284 return response, nil
285 }
286
287
288 type Package struct {
289
290
291
292
293
294
295 ID string
296
297
298 Name string
299
300
301 PkgPath string
302
303
304
305 Errors []Error
306
307
308 TypeErrors []types.Error
309
310
311 GoFiles []string
312
313
314
315
316 CompiledGoFiles []string
317
318
319
320 OtherFiles []string
321
322
323
324 EmbedFiles []string
325
326
327
328 EmbedPatterns []string
329
330
331
332
333 IgnoredFiles []string
334
335
336
337 ExportFile string
338
339
340
341 Imports map[string]*Package
342
343
344
345
346
347 Types *types.Package
348
349
350
351 Fset *token.FileSet
352
353
354
355 IllTyped bool
356
357
358
359
360
361
362
363
364
365 Syntax []*ast.File
366
367
368
369 TypesInfo *types.Info
370
371
372 TypesSizes types.Sizes
373
374
375 forTest string
376
377
378 depsErrors []*packagesinternal.PackageError
379
380
381 Module *Module
382 }
383
384
385 type Module struct {
386 Path string
387 Version string
388 Replace *Module
389 Time *time.Time
390 Main bool
391 Indirect bool
392 Dir string
393 GoMod string
394 GoVersion string
395 Error *ModuleError
396 }
397
398
399 type ModuleError struct {
400 Err string
401 }
402
403 func init() {
404 packagesinternal.GetForTest = func(p interface{}) string {
405 return p.(*Package).forTest
406 }
407 packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError {
408 return p.(*Package).depsErrors
409 }
410 packagesinternal.GetGoCmdRunner = func(config interface{}) *gocommand.Runner {
411 return config.(*Config).gocmdRunner
412 }
413 packagesinternal.SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {
414 config.(*Config).gocmdRunner = runner
415 }
416 packagesinternal.SetModFile = func(config interface{}, value string) {
417 config.(*Config).modFile = value
418 }
419 packagesinternal.SetModFlag = func(config interface{}, value string) {
420 config.(*Config).modFlag = value
421 }
422 packagesinternal.TypecheckCgo = int(typecheckCgo)
423 packagesinternal.DepsErrors = int(needInternalDepsErrors)
424 packagesinternal.ForTest = int(needInternalForTest)
425 }
426
427
428 type Error struct {
429 Pos string
430 Msg string
431 Kind ErrorKind
432 }
433
434
435
436
437 type ErrorKind int
438
439 const (
440 UnknownError ErrorKind = iota
441 ListError
442 ParseError
443 TypeError
444 )
445
446 func (err Error) Error() string {
447 pos := err.Pos
448 if pos == "" {
449 pos = "-"
450 }
451 return pos + ": " + err.Msg
452 }
453
454
455
456
457
458
459 type flatPackage struct {
460 ID string
461 Name string `json:",omitempty"`
462 PkgPath string `json:",omitempty"`
463 Errors []Error `json:",omitempty"`
464 GoFiles []string `json:",omitempty"`
465 CompiledGoFiles []string `json:",omitempty"`
466 OtherFiles []string `json:",omitempty"`
467 EmbedFiles []string `json:",omitempty"`
468 EmbedPatterns []string `json:",omitempty"`
469 IgnoredFiles []string `json:",omitempty"`
470 ExportFile string `json:",omitempty"`
471 Imports map[string]string `json:",omitempty"`
472 }
473
474
475
476
477
478
479
480
481
482
483 func (p *Package) MarshalJSON() ([]byte, error) {
484 flat := &flatPackage{
485 ID: p.ID,
486 Name: p.Name,
487 PkgPath: p.PkgPath,
488 Errors: p.Errors,
489 GoFiles: p.GoFiles,
490 CompiledGoFiles: p.CompiledGoFiles,
491 OtherFiles: p.OtherFiles,
492 EmbedFiles: p.EmbedFiles,
493 EmbedPatterns: p.EmbedPatterns,
494 IgnoredFiles: p.IgnoredFiles,
495 ExportFile: p.ExportFile,
496 }
497 if len(p.Imports) > 0 {
498 flat.Imports = make(map[string]string, len(p.Imports))
499 for path, ipkg := range p.Imports {
500 flat.Imports[path] = ipkg.ID
501 }
502 }
503 return json.Marshal(flat)
504 }
505
506
507
508 func (p *Package) UnmarshalJSON(b []byte) error {
509 flat := &flatPackage{}
510 if err := json.Unmarshal(b, &flat); err != nil {
511 return err
512 }
513 *p = Package{
514 ID: flat.ID,
515 Name: flat.Name,
516 PkgPath: flat.PkgPath,
517 Errors: flat.Errors,
518 GoFiles: flat.GoFiles,
519 CompiledGoFiles: flat.CompiledGoFiles,
520 OtherFiles: flat.OtherFiles,
521 EmbedFiles: flat.EmbedFiles,
522 EmbedPatterns: flat.EmbedPatterns,
523 ExportFile: flat.ExportFile,
524 }
525 if len(flat.Imports) > 0 {
526 p.Imports = make(map[string]*Package, len(flat.Imports))
527 for path, id := range flat.Imports {
528 p.Imports[path] = &Package{ID: id}
529 }
530 }
531 return nil
532 }
533
534 func (p *Package) String() string { return p.ID }
535
536
537 type loaderPackage struct {
538 *Package
539 importErrors map[string]error
540 loadOnce sync.Once
541 color uint8
542 needsrc bool
543 needtypes bool
544 initial bool
545 goVersion int
546 }
547
548
549 type loader struct {
550 pkgs map[string]*loaderPackage
551 Config
552 sizes types.Sizes
553 parseCache map[string]*parseValue
554 parseCacheMu sync.Mutex
555 exportMu sync.Mutex
556
557
558
559
560
561
562
563 requestedMode LoadMode
564 }
565
566 type parseValue struct {
567 f *ast.File
568 err error
569 ready chan struct{}
570 }
571
572 func newLoader(cfg *Config) *loader {
573 ld := &loader{
574 parseCache: map[string]*parseValue{},
575 }
576 if cfg != nil {
577 ld.Config = *cfg
578
579 ld.Config.Logf = cfg.Logf
580 }
581 if ld.Config.Logf == nil {
582
583
584 if debug {
585 ld.Config.Logf = log.Printf
586 } else {
587 ld.Config.Logf = func(format string, args ...interface{}) {}
588 }
589 }
590 if ld.Config.Mode == 0 {
591 ld.Config.Mode = NeedName | NeedFiles | NeedCompiledGoFiles
592 }
593 if ld.Config.Env == nil {
594 ld.Config.Env = os.Environ()
595 }
596 if ld.Config.gocmdRunner == nil {
597 ld.Config.gocmdRunner = &gocommand.Runner{}
598 }
599 if ld.Context == nil {
600 ld.Context = context.Background()
601 }
602 if ld.Dir == "" {
603 if dir, err := os.Getwd(); err == nil {
604 ld.Dir = dir
605 }
606 }
607
608
609 ld.requestedMode = ld.Mode
610 ld.Mode = impliedLoadMode(ld.Mode)
611
612 if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
613 if ld.Fset == nil {
614 ld.Fset = token.NewFileSet()
615 }
616
617
618
619 if ld.ParseFile == nil {
620 ld.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) {
621 const mode = parser.AllErrors | parser.ParseComments
622 return parser.ParseFile(fset, filename, src, mode)
623 }
624 }
625 }
626
627 return ld
628 }
629
630
631
632 func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
633 roots := response.Roots
634 rootMap := make(map[string]int, len(roots))
635 for i, root := range roots {
636 rootMap[root] = i
637 }
638 ld.pkgs = make(map[string]*loaderPackage)
639
640 var initial = make([]*loaderPackage, len(roots))
641 for _, pkg := range response.Packages {
642 rootIndex := -1
643 if i, found := rootMap[pkg.ID]; found {
644 rootIndex = i
645 }
646
647
648
649 exportDataInvalid := len(ld.Overlay) > 0 || pkg.ExportFile == "" && pkg.PkgPath != "unsafe"
650
651
652 needtypes := (ld.Mode&NeedTypes|NeedTypesInfo != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0))
653
654
655 needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) ||
656
657
658 (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe"
659 lpkg := &loaderPackage{
660 Package: pkg,
661 needtypes: needtypes,
662 needsrc: needsrc,
663 goVersion: response.GoVersion,
664 }
665 ld.pkgs[lpkg.ID] = lpkg
666 if rootIndex >= 0 {
667 initial[rootIndex] = lpkg
668 lpkg.initial = true
669 }
670 }
671 for i, root := range roots {
672 if initial[i] == nil {
673 return nil, fmt.Errorf("root package %v is missing", root)
674 }
675 }
676
677
678
679 const (
680 white = 0
681 grey = 1
682 black = 2
683 )
684
685
686
687
688
689
690
691
692
693
694
695 var stack []*loaderPackage
696 var visit func(lpkg *loaderPackage) bool
697 var srcPkgs []*loaderPackage
698 visit = func(lpkg *loaderPackage) bool {
699 switch lpkg.color {
700 case black:
701 return lpkg.needsrc
702 case grey:
703 panic("internal error: grey node")
704 }
705 lpkg.color = grey
706 stack = append(stack, lpkg)
707 stubs := lpkg.Imports
708
709 if ld.Mode&NeedImports != 0 {
710 lpkg.Imports = make(map[string]*Package, len(stubs))
711 for importPath, ipkg := range stubs {
712 var importErr error
713 imp := ld.pkgs[ipkg.ID]
714 if imp == nil {
715
716 importErr = fmt.Errorf("missing package: %q", ipkg.ID)
717 } else if imp.color == grey {
718 importErr = fmt.Errorf("import cycle: %s", stack)
719 }
720 if importErr != nil {
721 if lpkg.importErrors == nil {
722 lpkg.importErrors = make(map[string]error)
723 }
724 lpkg.importErrors[importPath] = importErr
725 continue
726 }
727
728 if visit(imp) {
729 lpkg.needsrc = true
730 }
731 lpkg.Imports[importPath] = imp.Package
732 }
733 }
734 if lpkg.needsrc {
735 srcPkgs = append(srcPkgs, lpkg)
736 }
737 if ld.Mode&NeedTypesSizes != 0 {
738 lpkg.TypesSizes = ld.sizes
739 }
740 stack = stack[:len(stack)-1]
741 lpkg.color = black
742
743 return lpkg.needsrc
744 }
745
746 if ld.Mode&NeedImports == 0 {
747
748 for _, lpkg := range initial {
749 lpkg.Imports = nil
750 }
751 } else {
752
753 for _, lpkg := range initial {
754 visit(lpkg)
755 }
756 }
757 if ld.Mode&NeedImports != 0 && ld.Mode&NeedTypes != 0 {
758 for _, lpkg := range srcPkgs {
759
760
761 for _, ipkg := range lpkg.Imports {
762 imp := ld.pkgs[ipkg.ID]
763 imp.needtypes = true
764 }
765 }
766 }
767
768
769 if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
770 var wg sync.WaitGroup
771 for _, lpkg := range initial {
772 wg.Add(1)
773 go func(lpkg *loaderPackage) {
774 ld.loadRecursive(lpkg)
775 wg.Done()
776 }(lpkg)
777 }
778 wg.Wait()
779 }
780
781 result := make([]*Package, len(initial))
782 for i, lpkg := range initial {
783 result[i] = lpkg.Package
784 }
785 for i := range ld.pkgs {
786
787
788 if ld.requestedMode&NeedName == 0 {
789 ld.pkgs[i].Name = ""
790 ld.pkgs[i].PkgPath = ""
791 }
792 if ld.requestedMode&NeedFiles == 0 {
793 ld.pkgs[i].GoFiles = nil
794 ld.pkgs[i].OtherFiles = nil
795 ld.pkgs[i].IgnoredFiles = nil
796 }
797 if ld.requestedMode&NeedEmbedFiles == 0 {
798 ld.pkgs[i].EmbedFiles = nil
799 }
800 if ld.requestedMode&NeedEmbedPatterns == 0 {
801 ld.pkgs[i].EmbedPatterns = nil
802 }
803 if ld.requestedMode&NeedCompiledGoFiles == 0 {
804 ld.pkgs[i].CompiledGoFiles = nil
805 }
806 if ld.requestedMode&NeedImports == 0 {
807 ld.pkgs[i].Imports = nil
808 }
809 if ld.requestedMode&NeedExportFile == 0 {
810 ld.pkgs[i].ExportFile = ""
811 }
812 if ld.requestedMode&NeedTypes == 0 {
813 ld.pkgs[i].Types = nil
814 ld.pkgs[i].Fset = nil
815 ld.pkgs[i].IllTyped = false
816 }
817 if ld.requestedMode&NeedSyntax == 0 {
818 ld.pkgs[i].Syntax = nil
819 }
820 if ld.requestedMode&NeedTypesInfo == 0 {
821 ld.pkgs[i].TypesInfo = nil
822 }
823 if ld.requestedMode&NeedTypesSizes == 0 {
824 ld.pkgs[i].TypesSizes = nil
825 }
826 if ld.requestedMode&NeedModule == 0 {
827 ld.pkgs[i].Module = nil
828 }
829 }
830
831 return result, nil
832 }
833
834
835
836
837
838 func (ld *loader) loadRecursive(lpkg *loaderPackage) {
839 lpkg.loadOnce.Do(func() {
840
841 var wg sync.WaitGroup
842 for _, ipkg := range lpkg.Imports {
843 imp := ld.pkgs[ipkg.ID]
844 wg.Add(1)
845 go func(imp *loaderPackage) {
846 ld.loadRecursive(imp)
847 wg.Done()
848 }(imp)
849 }
850 wg.Wait()
851 ld.loadPackage(lpkg)
852 })
853 }
854
855
856
857
858
859 func (ld *loader) loadPackage(lpkg *loaderPackage) {
860 if lpkg.PkgPath == "unsafe" {
861
862 lpkg.Types = types.Unsafe
863 lpkg.Fset = ld.Fset
864 lpkg.Syntax = []*ast.File{}
865 lpkg.TypesInfo = new(types.Info)
866 lpkg.TypesSizes = ld.sizes
867 return
868 }
869
870
871
872
873 lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name)
874 lpkg.Fset = ld.Fset
875
876
877
878
879
880
881
882 if !lpkg.needtypes && !lpkg.needsrc {
883 return
884 }
885 if !lpkg.needsrc {
886 ld.loadFromExportData(lpkg)
887 return
888 }
889
890 appendError := func(err error) {
891
892 var errs []Error
893 switch err := err.(type) {
894 case Error:
895
896 errs = append(errs, err)
897
898 case *os.PathError:
899
900 errs = append(errs, Error{
901 Pos: err.Path + ":1",
902 Msg: err.Err.Error(),
903 Kind: ParseError,
904 })
905
906 case scanner.ErrorList:
907
908 for _, err := range err {
909 errs = append(errs, Error{
910 Pos: err.Pos.String(),
911 Msg: err.Msg,
912 Kind: ParseError,
913 })
914 }
915
916 case types.Error:
917
918 lpkg.TypeErrors = append(lpkg.TypeErrors, err)
919 errs = append(errs, Error{
920 Pos: err.Fset.Position(err.Pos).String(),
921 Msg: err.Msg,
922 Kind: TypeError,
923 })
924
925 default:
926
927 errs = append(errs, Error{
928 Pos: "-",
929 Msg: err.Error(),
930 Kind: UnknownError,
931 })
932
933
934 log.Printf("internal error: error %q (%T) without position", err, err)
935 }
936
937 lpkg.Errors = append(lpkg.Errors, errs...)
938 }
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956 var runtimeVersion int
957 if _, err := fmt.Sscanf(runtime.Version(), "go1.%d", &runtimeVersion); err == nil && runtimeVersion < lpkg.goVersion {
958 defer func() {
959 if len(lpkg.Errors) > 0 {
960 appendError(Error{
961 Pos: "-",
962 Msg: fmt.Sprintf("This application uses version go1.%d of the source-processing packages but runs version go1.%d of 'go list'. It may fail to process source files that rely on newer language features. If so, rebuild the application using a newer version of Go.", runtimeVersion, lpkg.goVersion),
963 Kind: UnknownError,
964 })
965 }
966 }()
967 }
968
969 if ld.Config.Mode&NeedTypes != 0 && len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" {
970
971
972 appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError})
973 ld.loadFromExportData(lpkg)
974 return
975 }
976
977 files, errs := ld.parseFiles(lpkg.CompiledGoFiles)
978 for _, err := range errs {
979 appendError(err)
980 }
981
982 lpkg.Syntax = files
983 if ld.Config.Mode&NeedTypes == 0 {
984 return
985 }
986
987 lpkg.TypesInfo = &types.Info{
988 Types: make(map[ast.Expr]types.TypeAndValue),
989 Defs: make(map[*ast.Ident]types.Object),
990 Uses: make(map[*ast.Ident]types.Object),
991 Implicits: make(map[ast.Node]types.Object),
992 Scopes: make(map[ast.Node]*types.Scope),
993 Selections: make(map[*ast.SelectorExpr]*types.Selection),
994 }
995 typeparams.InitInstanceInfo(lpkg.TypesInfo)
996 lpkg.TypesSizes = ld.sizes
997
998 importer := importerFunc(func(path string) (*types.Package, error) {
999 if path == "unsafe" {
1000 return types.Unsafe, nil
1001 }
1002
1003
1004 ipkg := lpkg.Imports[path]
1005 if ipkg == nil {
1006 if err := lpkg.importErrors[path]; err != nil {
1007 return nil, err
1008 }
1009
1010
1011
1012
1013 return nil, fmt.Errorf("no metadata for %s", path)
1014 }
1015
1016 if ipkg.Types != nil && ipkg.Types.Complete() {
1017 return ipkg.Types, nil
1018 }
1019 log.Fatalf("internal error: package %q without types was imported from %q", path, lpkg)
1020 panic("unreachable")
1021 })
1022
1023
1024 tc := &types.Config{
1025 Importer: importer,
1026
1027
1028
1029
1030 IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial,
1031
1032 Error: appendError,
1033 Sizes: ld.sizes,
1034 }
1035 if (ld.Mode & typecheckCgo) != 0 {
1036 if !typesinternal.SetUsesCgo(tc) {
1037 appendError(Error{
1038 Msg: "typecheckCgo requires Go 1.15+",
1039 Kind: ListError,
1040 })
1041 return
1042 }
1043 }
1044 types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax)
1045
1046 lpkg.importErrors = nil
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056 if tc.FakeImportC {
1057 outer:
1058 for _, f := range lpkg.Syntax {
1059 for _, imp := range f.Imports {
1060 if imp.Path.Value == `"C"` {
1061 err := types.Error{Fset: ld.Fset, Pos: imp.Pos(), Msg: `import "C" ignored`}
1062 appendError(err)
1063 break outer
1064 }
1065 }
1066 }
1067 }
1068
1069
1070 illTyped := len(lpkg.Errors) > 0
1071 if !illTyped {
1072 for _, imp := range lpkg.Imports {
1073 if imp.IllTyped {
1074 illTyped = true
1075 break
1076 }
1077 }
1078 }
1079 lpkg.IllTyped = illTyped
1080 }
1081
1082
1083
1084 type importerFunc func(path string) (*types.Package, error)
1085
1086 func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) }
1087
1088
1089
1090 var ioLimit = make(chan bool, 20)
1091
1092 func (ld *loader) parseFile(filename string) (*ast.File, error) {
1093 ld.parseCacheMu.Lock()
1094 v, ok := ld.parseCache[filename]
1095 if ok {
1096
1097 ld.parseCacheMu.Unlock()
1098 <-v.ready
1099 } else {
1100
1101 v = &parseValue{ready: make(chan struct{})}
1102 ld.parseCache[filename] = v
1103 ld.parseCacheMu.Unlock()
1104
1105 var src []byte
1106 for f, contents := range ld.Config.Overlay {
1107 if sameFile(f, filename) {
1108 src = contents
1109 }
1110 }
1111 var err error
1112 if src == nil {
1113 ioLimit <- true
1114 src, err = ioutil.ReadFile(filename)
1115 <-ioLimit
1116 }
1117 if err != nil {
1118 v.err = err
1119 } else {
1120 v.f, v.err = ld.ParseFile(ld.Fset, filename, src)
1121 }
1122
1123 close(v.ready)
1124 }
1125 return v.f, v.err
1126 }
1127
1128
1129
1130
1131
1132
1133
1134 func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) {
1135 var wg sync.WaitGroup
1136 n := len(filenames)
1137 parsed := make([]*ast.File, n)
1138 errors := make([]error, n)
1139 for i, file := range filenames {
1140 if ld.Config.Context.Err() != nil {
1141 parsed[i] = nil
1142 errors[i] = ld.Config.Context.Err()
1143 continue
1144 }
1145 wg.Add(1)
1146 go func(i int, filename string) {
1147 parsed[i], errors[i] = ld.parseFile(filename)
1148 wg.Done()
1149 }(i, file)
1150 }
1151 wg.Wait()
1152
1153
1154 var o int
1155 for _, f := range parsed {
1156 if f != nil {
1157 parsed[o] = f
1158 o++
1159 }
1160 }
1161 parsed = parsed[:o]
1162
1163 o = 0
1164 for _, err := range errors {
1165 if err != nil {
1166 errors[o] = err
1167 o++
1168 }
1169 }
1170 errors = errors[:o]
1171
1172 return parsed, errors
1173 }
1174
1175
1176
1177 func sameFile(x, y string) bool {
1178 if x == y {
1179
1180
1181
1182
1183
1184
1185 return true
1186 }
1187 if strings.EqualFold(filepath.Base(x), filepath.Base(y)) {
1188 if xi, err := os.Stat(x); err == nil {
1189 if yi, err := os.Stat(y); err == nil {
1190 return os.SameFile(xi, yi)
1191 }
1192 }
1193 }
1194 return false
1195 }
1196
1197
1198
1199 func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error) {
1200 if lpkg.PkgPath == "" {
1201 log.Fatalf("internal error: Package %s has no PkgPath", lpkg)
1202 }
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216 ld.exportMu.Lock()
1217 defer ld.exportMu.Unlock()
1218
1219 if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() {
1220 return tpkg, nil
1221 }
1222
1223 lpkg.IllTyped = true
1224
1225 if lpkg.ExportFile == "" {
1226
1227 return nil, fmt.Errorf("no export data file")
1228 }
1229 f, err := os.Open(lpkg.ExportFile)
1230 if err != nil {
1231 return nil, err
1232 }
1233 defer f.Close()
1234
1235
1236
1237
1238
1239
1240
1241 r, err := gcexportdata.NewReader(f)
1242 if err != nil {
1243 return nil, fmt.Errorf("reading %s: %v", lpkg.ExportFile, err)
1244 }
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267 view := make(map[string]*types.Package)
1268 seen := make(map[*loaderPackage]bool)
1269 var visit func(pkgs map[string]*Package)
1270 visit = func(pkgs map[string]*Package) {
1271 for _, p := range pkgs {
1272 lpkg := ld.pkgs[p.ID]
1273 if !seen[lpkg] {
1274 seen[lpkg] = true
1275 view[lpkg.PkgPath] = lpkg.Types
1276 visit(lpkg.Imports)
1277 }
1278 }
1279 }
1280 visit(lpkg.Imports)
1281
1282 viewLen := len(view) + 1
1283
1284
1285 tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath)
1286 if err != nil {
1287 return nil, fmt.Errorf("reading %s: %v", lpkg.ExportFile, err)
1288 }
1289 if _, ok := view["go.shape"]; ok {
1290
1291
1292 viewLen++
1293 }
1294 if viewLen != len(view) {
1295 log.Panicf("golang.org/x/tools/go/packages: unexpected new packages during load of %s", lpkg.PkgPath)
1296 }
1297
1298 lpkg.Types = tpkg
1299 lpkg.IllTyped = false
1300
1301 return tpkg, nil
1302 }
1303
1304
1305 func impliedLoadMode(loadMode LoadMode) LoadMode {
1306 if loadMode&(NeedDeps|NeedTypes|NeedTypesInfo) != 0 {
1307
1308 loadMode |= NeedImports
1309 }
1310
1311 return loadMode
1312 }
1313
1314 func usesExportData(cfg *Config) bool {
1315 return cfg.Mode&NeedExportFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0
1316 }
1317
1318 var _ interface{} = io.Discard
1319
View as plain text