GoPLS Viewer

Home|gopls/go/packages/golist.go
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
5package packages
6
7import (
8    "bytes"
9    "context"
10    "encoding/json"
11    "fmt"
12    "go/types"
13    "io/ioutil"
14    "log"
15    "os"
16    "path"
17    "path/filepath"
18    "reflect"
19    "sort"
20    "strconv"
21    "strings"
22    "sync"
23    "unicode"
24
25    exec "golang.org/x/sys/execabs"
26    "golang.org/x/tools/go/internal/packagesdriver"
27    "golang.org/x/tools/internal/gocommand"
28    "golang.org/x/tools/internal/packagesinternal"
29)
30
31// debug controls verbose logging.
32var debug_ = strconv.ParseBool(os.Getenv("GOPACKAGESDEBUG"))
33
34// A goTooOldError reports that the go command
35// found by exec.LookPath is too old to use the new go list behavior.
36type goTooOldError struct {
37    error
38}
39
40// responseDeduper wraps a driverResponse, deduplicating its contents.
41type responseDeduper struct {
42    seenRoots    map[string]bool
43    seenPackages map[string]*Package
44    dr           *driverResponse
45}
46
47func newDeduper() *responseDeduper {
48    return &responseDeduper{
49        dr:           &driverResponse{},
50        seenRoots:    map[string]bool{},
51        seenPackages: map[string]*Package{},
52    }
53}
54
55// addAll fills in r with a driverResponse.
56func (r *responseDeduperaddAll(dr *driverResponse) {
57    for _pkg := range dr.Packages {
58        r.addPackage(pkg)
59    }
60    for _root := range dr.Roots {
61        r.addRoot(root)
62    }
63    r.dr.GoVersion = dr.GoVersion
64}
65
66func (r *responseDeduperaddPackage(p *Package) {
67    if r.seenPackages[p.ID] != nil {
68        return
69    }
70    r.seenPackages[p.ID] = p
71    r.dr.Packages = append(r.dr.Packagesp)
72}
73
74func (r *responseDeduperaddRoot(id string) {
75    if r.seenRoots[id] {
76        return
77    }
78    r.seenRoots[id] = true
79    r.dr.Roots = append(r.dr.Rootsid)
80}
81
82type golistState struct {
83    cfg *Config
84    ctx context.Context
85
86    envOnce    sync.Once
87    goEnvError error
88    goEnv      map[string]string
89
90    rootsOnce     sync.Once
91    rootDirsError error
92    rootDirs      map[string]string
93
94    goVersionOnce  sync.Once
95    goVersionError error
96    goVersion      int // The X in Go 1.X.
97
98    // vendorDirs caches the (non)existence of vendor directories.
99    vendorDirs map[string]bool
100}
101
102// getEnv returns Go environment variables. Only specific variables are
103// populated -- computing all of them is slow.
104func (state *golistStategetEnv() (map[string]stringerror) {
105    state.envOnce.Do(func() {
106        var b *bytes.Buffer
107        bstate.goEnvError = state.invokeGo("env""-json""GOMOD""GOPATH")
108        if state.goEnvError != nil {
109            return
110        }
111
112        state.goEnv = make(map[string]string)
113        decoder := json.NewDecoder(b)
114        if state.goEnvError = decoder.Decode(&state.goEnv); state.goEnvError != nil {
115            return
116        }
117    })
118    return state.goEnvstate.goEnvError
119}
120
121// mustGetEnv is a convenience function that can be used if getEnv has already succeeded.
122func (state *golistStatemustGetEnv() map[string]string {
123    enverr := state.getEnv()
124    if err != nil {
125        panic(fmt.Sprintf("mustGetEnv: %v"err))
126    }
127    return env
128}
129
130// goListDriver uses the go list command to interpret the patterns and produce
131// the build system package structure.
132// See driver for more details.
133func goListDriver(cfg *Configpatterns ...string) (*driverResponseerror) {
134    // Make sure that any asynchronous go commands are killed when we return.
135    parentCtx := cfg.Context
136    if parentCtx == nil {
137        parentCtx = context.Background()
138    }
139    ctxcancel := context.WithCancel(parentCtx)
140    defer cancel()
141
142    response := newDeduper()
143
144    state := &golistState{
145        cfg:        cfg,
146        ctx:        ctx,
147        vendorDirs: map[string]bool{},
148    }
149
150    // Fill in response.Sizes asynchronously if necessary.
151    var sizeserr error
152    var sizeswg sync.WaitGroup
153    if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&NeedTypes != 0 {
154        sizeswg.Add(1)
155        go func() {
156            var sizes types.Sizes
157            sizessizeserr = packagesdriver.GetSizesGolist(ctxstate.cfgInvocation(), cfg.gocmdRunner)
158            // types.SizesFor always returns nil or a *types.StdSizes.
159            response.dr.Sizes_ = sizes.(*types.StdSizes)
160            sizeswg.Done()
161        }()
162    }
163
164    // Determine files requested in contains patterns
165    var containFiles []string
166    restPatterns := make([]string0len(patterns))
167    // Extract file= and other [querytype]= patterns. Report an error if querytype
168    // doesn't exist.
169extractQueries:
170    for _pattern := range patterns {
171        eqidx := strings.Index(pattern"=")
172        if eqidx < 0 {
173            restPatterns = append(restPatternspattern)
174        } else {
175            queryvalue := pattern[:eqidx], pattern[eqidx+len("="):]
176            switch query {
177            case "file":
178                containFiles = append(containFilesvalue)
179            case "pattern":
180                restPatterns = append(restPatternsvalue)
181            case ""// not a reserved query
182                restPatterns = append(restPatternspattern)
183            default:
184                for _rune := range query {
185                    if rune < 'a' || rune > 'z' { // not a reserved query
186                        restPatterns = append(restPatternspattern)
187                        continue extractQueries
188                    }
189                }
190                // Reject all other patterns containing "="
191                return nilfmt.Errorf("invalid query type %q in query pattern %q"querypattern)
192            }
193        }
194    }
195
196    // See if we have any patterns to pass through to go list. Zero initial
197    // patterns also requires a go list call, since it's the equivalent of
198    // ".".
199    if len(restPatterns) > 0 || len(patterns) == 0 {
200        drerr := state.createDriverResponse(restPatterns...)
201        if err != nil {
202            return nilerr
203        }
204        response.addAll(dr)
205    }
206
207    if len(containFiles) != 0 {
208        if err := state.runContainsQueries(responsecontainFiles); err != nil {
209            return nilerr
210        }
211    }
212
213    // Only use go/packages' overlay processing if we're using a Go version
214    // below 1.16. Otherwise, go list handles it.
215    if goVersionerr := state.getGoVersion(); err == nil && goVersion < 16 {
216        modifiedPkgsneedPkgserr := state.processGolistOverlay(response)
217        if err != nil {
218            return nilerr
219        }
220
221        var containsCandidates []string
222        if len(containFiles) > 0 {
223            containsCandidates = append(containsCandidatesmodifiedPkgs...)
224            containsCandidates = append(containsCandidatesneedPkgs...)
225        }
226        if err := state.addNeededOverlayPackages(responseneedPkgs); err != nil {
227            return nilerr
228        }
229        // Check candidate packages for containFiles.
230        if len(containFiles) > 0 {
231            for _id := range containsCandidates {
232                pkgok := response.seenPackages[id]
233                if !ok {
234                    response.addPackage(&Package{
235                        IDid,
236                        Errors: []Error{{
237                            KindListError,
238                            Msg:  fmt.Sprintf("package %s expected but not seen"id),
239                        }},
240                    })
241                    continue
242                }
243                for _f := range containFiles {
244                    for _g := range pkg.GoFiles {
245                        if sameFile(fg) {
246                            response.addRoot(id)
247                        }
248                    }
249                }
250            }
251        }
252        // Add root for any package that matches a pattern. This applies only to
253        // packages that are modified by overlays, since they are not added as
254        // roots automatically.
255        for _pattern := range restPatterns {
256            match := matchPattern(pattern)
257            for _pkgID := range modifiedPkgs {
258                pkgok := response.seenPackages[pkgID]
259                if !ok {
260                    continue
261                }
262                if match(pkg.PkgPath) {
263                    response.addRoot(pkg.ID)
264                }
265            }
266        }
267    }
268
269    sizeswg.Wait()
270    if sizeserr != nil {
271        return nilsizeserr
272    }
273    return response.drnil
274}
275
276func (state *golistStateaddNeededOverlayPackages(response *responseDeduperpkgs []stringerror {
277    if len(pkgs) == 0 {
278        return nil
279    }
280    drerr := state.createDriverResponse(pkgs...)
281    if err != nil {
282        return err
283    }
284    for _pkg := range dr.Packages {
285        response.addPackage(pkg)
286    }
287    _needPkgserr := state.processGolistOverlay(response)
288    if err != nil {
289        return err
290    }
291    return state.addNeededOverlayPackages(responseneedPkgs)
292}
293
294func (state *golistStaterunContainsQueries(response *responseDeduperqueries []stringerror {
295    for _query := range queries {
296        // TODO(matloob): Do only one query per directory.
297        fdir := filepath.Dir(query)
298        // Pass absolute path of directory to go list so that it knows to treat it as a directory,
299        // not a package path.
300        patternerr := filepath.Abs(fdir)
301        if err != nil {
302            return fmt.Errorf("could not determine absolute path of file= query path %q: %v"queryerr)
303        }
304        dirResponseerr := state.createDriverResponse(pattern)
305
306        // If there was an error loading the package, or no packages are returned,
307        // or the package is returned with errors, try to load the file as an
308        // ad-hoc package.
309        // Usually the error will appear in a returned package, but may not if we're
310        // in module mode and the ad-hoc is located outside a module.
311        if err != nil || len(dirResponse.Packages) == 0 || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 &&
312            len(dirResponse.Packages[0].Errors) == 1 {
313            var queryErr error
314            if dirResponsequeryErr = state.adhocPackage(patternquery); queryErr != nil {
315                return err // return the original error
316            }
317        }
318        isRoot := make(map[string]boollen(dirResponse.Roots))
319        for _root := range dirResponse.Roots {
320            isRoot[root] = true
321        }
322        for _pkg := range dirResponse.Packages {
323            // Add any new packages to the main set
324            // We don't bother to filter packages that will be dropped by the changes of roots,
325            // that will happen anyway during graph construction outside this function.
326            // Over-reporting packages is not a problem.
327            response.addPackage(pkg)
328            // if the package was not a root one, it cannot have the file
329            if !isRoot[pkg.ID] {
330                continue
331            }
332            for _pkgFile := range pkg.GoFiles {
333                if filepath.Base(query) == filepath.Base(pkgFile) {
334                    response.addRoot(pkg.ID)
335                    break
336                }
337            }
338        }
339    }
340    return nil
341}
342
343// adhocPackage attempts to load or construct an ad-hoc package for a given
344// query, if the original call to the driver produced inadequate results.
345func (state *golistStateadhocPackage(patternquery string) (*driverResponseerror) {
346    responseerr := state.createDriverResponse(query)
347    if err != nil {
348        return nilerr
349    }
350    // If we get nothing back from `go list`,
351    // try to make this file into its own ad-hoc package.
352    // TODO(rstambler): Should this check against the original response?
353    if len(response.Packages) == 0 {
354        response.Packages = append(response.Packages, &Package{
355            ID:              "command-line-arguments",
356            PkgPath:         query,
357            GoFiles:         []string{query},
358            CompiledGoFiles: []string{query},
359            Imports:         make(map[string]*Package),
360        })
361        response.Roots = append(response.Roots"command-line-arguments")
362    }
363    // Handle special cases.
364    if len(response.Packages) == 1 {
365        // golang/go#33482: If this is a file= query for ad-hoc packages where
366        // the file only exists on an overlay, and exists outside of a module,
367        // add the file to the package and remove the errors.
368        if response.Packages[0].ID == "command-line-arguments" ||
369            filepath.ToSlash(response.Packages[0].PkgPath) == filepath.ToSlash(query) {
370            if len(response.Packages[0].GoFiles) == 0 {
371                filename := filepath.Join(patternfilepath.Base(query)) // avoid recomputing abspath
372                // TODO(matloob): check if the file is outside of a root dir?
373                for path := range state.cfg.Overlay {
374                    if path == filename {
375                        response.Packages[0].Errors = nil
376                        response.Packages[0].GoFiles = []string{path}
377                        response.Packages[0].CompiledGoFiles = []string{path}
378                    }
379                }
380            }
381        }
382    }
383    return responsenil
384}
385
386// Fields must match go list;
387// see $GOROOT/src/cmd/go/internal/load/pkg.go.
388type jsonPackage struct {
389    ImportPath        string
390    Dir               string
391    Name              string
392    Export            string
393    GoFiles           []string
394    CompiledGoFiles   []string
395    IgnoredGoFiles    []string
396    IgnoredOtherFiles []string
397    EmbedPatterns     []string
398    EmbedFiles        []string
399    CFiles            []string
400    CgoFiles          []string
401    CXXFiles          []string
402    MFiles            []string
403    HFiles            []string
404    FFiles            []string
405    SFiles            []string
406    SwigFiles         []string
407    SwigCXXFiles      []string
408    SysoFiles         []string
409    Imports           []string
410    ImportMap         map[string]string
411    Deps              []string
412    Module            *Module
413    TestGoFiles       []string
414    TestImports       []string
415    XTestGoFiles      []string
416    XTestImports      []string
417    ForTest           string // q in a "p [q.test]" package, else ""
418    DepOnly           bool
419
420    Error      *packagesinternal.PackageError
421    DepsErrors []*packagesinternal.PackageError
422}
423
424type jsonPackageError struct {
425    ImportStack []string
426    Pos         string
427    Err         string
428}
429
430func otherFiles(p *jsonPackage) [][]string {
431    return [][]string{p.CFilesp.CXXFilesp.MFilesp.HFilesp.FFilesp.SFilesp.SwigFilesp.SwigCXXFilesp.SysoFiles}
432}
433
434// createDriverResponse uses the "go list" command to expand the pattern
435// words and return a response for the specified packages.
436func (state *golistStatecreateDriverResponse(words ...string) (*driverResponseerror) {
437    // go list uses the following identifiers in ImportPath and Imports:
438    //
439    //     "p"            -- importable package or main (command)
440    //     "q.test"        -- q's test executable
441    //     "p [q.test]"        -- variant of p as built for q's test executable
442    //     "q_test [q.test]"    -- q's external test package
443    //
444    // The packages p that are built differently for a test q.test
445    // are q itself, plus any helpers used by the external test q_test,
446    // typically including "testing" and all its dependencies.
447
448    // Run "go list" for complete
449    // information on the specified packages.
450    goVersionerr := state.getGoVersion()
451    if err != nil {
452        return nilerr
453    }
454    buferr := state.invokeGo("list"golistargs(state.cfgwordsgoVersion)...)
455    if err != nil {
456        return nilerr
457    }
458
459    seen := make(map[string]*jsonPackage)
460    pkgs := make(map[string]*Package)
461    additionalErrors := make(map[string][]Error)
462    // Decode the JSON and convert it to Package form.
463    response := &driverResponse{
464        GoVersiongoVersion,
465    }
466    for dec := json.NewDecoder(buf); dec.More(); {
467        p := new(jsonPackage)
468        if err := dec.Decode(p); err != nil {
469            return nilfmt.Errorf("JSON decoding failed: %v"err)
470        }
471
472        if p.ImportPath == "" {
473            // The documentation for go list says that “[e]rroneous packages will have
474            // a non-empty ImportPath”. If for some reason it comes back empty, we
475            // prefer to error out rather than silently discarding data or handing
476            // back a package without any way to refer to it.
477            if p.Error != nil {
478                return nilError{
479                    Posp.Error.Pos,
480                    Msgp.Error.Err,
481                }
482            }
483            return nilfmt.Errorf("package missing import path: %+v"p)
484        }
485
486        // Work around https://golang.org/issue/33157:
487        // go list -e, when given an absolute path, will find the package contained at
488        // that directory. But when no package exists there, it will return a fake package
489        // with an error and the ImportPath set to the absolute path provided to go list.
490        // Try to convert that absolute path to what its package path would be if it's
491        // contained in a known module or GOPATH entry. This will allow the package to be
492        // properly "reclaimed" when overlays are processed.
493        if filepath.IsAbs(p.ImportPath) && p.Error != nil {
494            pkgPathokerr := state.getPkgPath(p.ImportPath)
495            if err != nil {
496                return nilerr
497            }
498            if ok {
499                p.ImportPath = pkgPath
500            }
501        }
502
503        if oldfound := seen[p.ImportPath]; found {
504            // If one version of the package has an error, and the other doesn't, assume
505            // that this is a case where go list is reporting a fake dependency variant
506            // of the imported package: When a package tries to invalidly import another
507            // package, go list emits a variant of the imported package (with the same
508            // import path, but with an error on it, and the package will have a
509            // DepError set on it). An example of when this can happen is for imports of
510            // main packages: main packages can not be imported, but they may be
511            // separately matched and listed by another pattern.
512            // See golang.org/issue/36188 for more details.
513
514            // The plan is that eventually, hopefully in Go 1.15, the error will be
515            // reported on the importing package rather than the duplicate "fake"
516            // version of the imported package. Once all supported versions of Go
517            // have the new behavior this logic can be deleted.
518            // TODO(matloob): delete the workaround logic once all supported versions of
519            // Go return the errors on the proper package.
520
521            // There should be exactly one version of a package that doesn't have an
522            // error.
523            if old.Error == nil && p.Error == nil {
524                if !reflect.DeepEqual(pold) {
525                    return nilfmt.Errorf("internal error: go list gives conflicting information for package %v"p.ImportPath)
526                }
527                continue
528            }
529
530            // Determine if this package's error needs to be bubbled up.
531            // This is a hack, and we expect for go list to eventually set the error
532            // on the package.
533            if old.Error != nil {
534                var errkind string
535                if strings.Contains(old.Error.Err"not an importable package") {
536                    errkind = "not an importable package"
537                } else if strings.Contains(old.Error.Err"use of internal package") && strings.Contains(old.Error.Err"not allowed") {
538                    errkind = "use of internal package not allowed"
539                }
540                if errkind != "" {
541                    if len(old.Error.ImportStack) < 1 {
542                        return nilfmt.Errorf(`internal error: go list gave a %q error with empty import stack`errkind)
543                    }
544                    importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-1]
545                    if importingPkg == old.ImportPath {
546                        // Using an older version of Go which put this package itself on top of import
547                        // stack, instead of the importer. Look for importer in second from top
548                        // position.
549                        if len(old.Error.ImportStack) < 2 {
550                            return nilfmt.Errorf(`internal error: go list gave a %q error with an import stack without importing package`errkind)
551                        }
552                        importingPkg = old.Error.ImportStack[len(old.Error.ImportStack)-2]
553                    }
554                    additionalErrors[importingPkg] = append(additionalErrors[importingPkg], Error{
555                        Pos:  old.Error.Pos,
556                        Msg:  old.Error.Err,
557                        KindListError,
558                    })
559                }
560            }
561
562            // Make sure that if there's a version of the package without an error,
563            // that's the one reported to the user.
564            if old.Error == nil {
565                continue
566            }
567
568            // This package will replace the old one at the end of the loop.
569        }
570        seen[p.ImportPath] = p
571
572        pkg := &Package{
573            Name:            p.Name,
574            ID:              p.ImportPath,
575            GoFiles:         absJoin(p.Dirp.GoFilesp.CgoFiles),
576            CompiledGoFilesabsJoin(p.Dirp.CompiledGoFiles),
577            OtherFiles:      absJoin(p.DirotherFiles(p)...),
578            EmbedFiles:      absJoin(p.Dirp.EmbedFiles),
579            EmbedPatterns:   absJoin(p.Dirp.EmbedPatterns),
580            IgnoredFiles:    absJoin(p.Dirp.IgnoredGoFilesp.IgnoredOtherFiles),
581            forTest:         p.ForTest,
582            depsErrors:      p.DepsErrors,
583            Module:          p.Module,
584        }
585
586        if (state.cfg.Mode&typecheckCgo) != 0 && len(p.CgoFiles) != 0 {
587            if len(p.CompiledGoFiles) > len(p.GoFiles) {
588                // We need the cgo definitions, which are in the first
589                // CompiledGoFile after the non-cgo ones. This is a hack but there
590                // isn't currently a better way to find it. We also need the pure
591                // Go files and unprocessed cgo files, all of which are already
592                // in pkg.GoFiles.
593                cgoTypes := p.CompiledGoFiles[len(p.GoFiles)]
594                pkg.CompiledGoFiles = append([]string{cgoTypes}, pkg.GoFiles...)
595            } else {
596                // golang/go#38990: go list silently fails to do cgo processing
597                pkg.CompiledGoFiles = nil
598                pkg.Errors = append(pkg.ErrorsError{
599                    Msg:  "go list failed to return CompiledGoFiles. This may indicate failure to perform cgo processing; try building at the command line. See https://golang.org/issue/38990.",
600                    KindListError,
601                })
602            }
603        }
604
605        // Work around https://golang.org/issue/28749:
606        // cmd/go puts assembly, C, and C++ files in CompiledGoFiles.
607        // Remove files from CompiledGoFiles that are non-go files
608        // (or are not files that look like they are from the cache).
609        if len(pkg.CompiledGoFiles) > 0 {
610            out := pkg.CompiledGoFiles[:0]
611            for _f := range pkg.CompiledGoFiles {
612                if ext := filepath.Ext(f); ext != ".go" && ext != "" { // ext == "" means the file is from the cache, so probably cgo-processed file
613                    continue
614                }
615                out = append(outf)
616            }
617            pkg.CompiledGoFiles = out
618        }
619
620        // Extract the PkgPath from the package's ID.
621        if i := strings.IndexByte(pkg.ID' '); i >= 0 {
622            pkg.PkgPath = pkg.ID[:i]
623        } else {
624            pkg.PkgPath = pkg.ID
625        }
626
627        if pkg.PkgPath == "unsafe" {
628            pkg.GoFiles = nil // ignore fake unsafe.go file
629        }
630
631        // Assume go list emits only absolute paths for Dir.
632        if p.Dir != "" && !filepath.IsAbs(p.Dir) {
633            log.Fatalf("internal error: go list returned non-absolute Package.Dir: %s"p.Dir)
634        }
635
636        if p.Export != "" && !filepath.IsAbs(p.Export) {
637            pkg.ExportFile = filepath.Join(p.Dirp.Export)
638        } else {
639            pkg.ExportFile = p.Export
640        }
641
642        // imports
643        //
644        // Imports contains the IDs of all imported packages.
645        // ImportsMap records (path, ID) only where they differ.
646        ids := make(map[string]bool)
647        for _id := range p.Imports {
648            ids[id] = true
649        }
650        pkg.Imports = make(map[string]*Package)
651        for pathid := range p.ImportMap {
652            pkg.Imports[path] = &Package{IDid// non-identity import
653            delete(idsid)
654        }
655        for id := range ids {
656            if id == "C" {
657                continue
658            }
659
660            pkg.Imports[id] = &Package{IDid// identity import
661        }
662        if !p.DepOnly {
663            response.Roots = append(response.Rootspkg.ID)
664        }
665
666        // Work around for pre-go.1.11 versions of go list.
667        // TODO(matloob): they should be handled by the fallback.
668        // Can we delete this?
669        if len(pkg.CompiledGoFiles) == 0 {
670            pkg.CompiledGoFiles = pkg.GoFiles
671        }
672
673        // Temporary work-around for golang/go#39986. Parse filenames out of
674        // error messages. This happens if there are unrecoverable syntax
675        // errors in the source, so we can't match on a specific error message.
676        if err := p.Errorerr != nil && state.shouldAddFilenameFromError(p) {
677            addFilenameFromPos := func(pos stringbool {
678                split := strings.Split(pos":")
679                if len(split) < 1 {
680                    return false
681                }
682                filename := strings.TrimSpace(split[0])
683                if filename == "" {
684                    return false
685                }
686                if !filepath.IsAbs(filename) {
687                    filename = filepath.Join(state.cfg.Dirfilename)
688                }
689                info_ := os.Stat(filename)
690                if info == nil {
691                    return false
692                }
693                pkg.CompiledGoFiles = append(pkg.CompiledGoFilesfilename)
694                pkg.GoFiles = append(pkg.GoFilesfilename)
695                return true
696            }
697            found := addFilenameFromPos(err.Pos)
698            // In some cases, go list only reports the error position in the
699            // error text, not the error position. One such case is when the
700            // file's package name is a keyword (see golang.org/issue/39763).
701            if !found {
702                addFilenameFromPos(err.Err)
703            }
704        }
705
706        if p.Error != nil {
707            msg := strings.TrimSpace(p.Error.Err// Trim to work around golang.org/issue/32363.
708            // Address golang.org/issue/35964 by appending import stack to error message.
709            if msg == "import cycle not allowed" && len(p.Error.ImportStack) != 0 {
710                msg += fmt.Sprintf(": import stack: %v"p.Error.ImportStack)
711            }
712            pkg.Errors = append(pkg.ErrorsError{
713                Pos:  p.Error.Pos,
714                Msg:  msg,
715                KindListError,
716            })
717        }
718
719        pkgs[pkg.ID] = pkg
720    }
721
722    for iderrs := range additionalErrors {
723        if pok := pkgs[id]; ok {
724            p.Errors = append(p.Errorserrs...)
725        }
726    }
727    for _pkg := range pkgs {
728        response.Packages = append(response.Packagespkg)
729    }
730    sort.Slice(response.Packages, func(ij intbool { return response.Packages[i].ID < response.Packages[j].ID })
731
732    return responsenil
733}
734
735func (state *golistStateshouldAddFilenameFromError(p *jsonPackagebool {
736    if len(p.GoFiles) > 0 || len(p.CompiledGoFiles) > 0 {
737        return false
738    }
739
740    goVerr := state.getGoVersion()
741    if err != nil {
742        return false
743    }
744
745    // On Go 1.14 and earlier, only add filenames from errors if the import stack is empty.
746    // The import stack behaves differently for these versions than newer Go versions.
747    if goV < 15 {
748        return len(p.Error.ImportStack) == 0
749    }
750
751    // On Go 1.15 and later, only parse filenames out of error if there's no import stack,
752    // or the current package is at the top of the import stack. This is not guaranteed
753    // to work perfectly, but should avoid some cases where files in errors don't belong to this
754    // package.
755    return len(p.Error.ImportStack) == 0 || p.Error.ImportStack[len(p.Error.ImportStack)-1] == p.ImportPath
756}
757
758// getGoVersion returns the effective minor version of the go command.
759func (state *golistStategetGoVersion() (interror) {
760    state.goVersionOnce.Do(func() {
761        state.goVersionstate.goVersionError = gocommand.GoVersion(state.ctxstate.cfgInvocation(), state.cfg.gocmdRunner)
762    })
763    return state.goVersionstate.goVersionError
764}
765
766// getPkgPath finds the package path of a directory if it's relative to a root
767// directory.
768func (state *golistStategetPkgPath(dir string) (stringboolerror) {
769    absDirerr := filepath.Abs(dir)
770    if err != nil {
771        return ""falseerr
772    }
773    rootserr := state.determineRootDirs()
774    if err != nil {
775        return ""falseerr
776    }
777
778    for rdirrpath := range roots {
779        // Make sure that the directory is in the module,
780        // to avoid creating a path relative to another module.
781        if !strings.HasPrefix(absDirrdir) {
782            continue
783        }
784        // TODO(matloob): This doesn't properly handle symlinks.
785        rerr := filepath.Rel(rdirdir)
786        if err != nil {
787            continue
788        }
789        if rpath != "" {
790            // We choose only one root even though the directory even it can belong in multiple modules
791            // or GOPATH entries. This is okay because we only need to work with absolute dirs when a
792            // file is missing from disk, for instance when gopls calls go/packages in an overlay.
793            // Once the file is saved, gopls, or the next invocation of the tool will get the correct
794            // result straight from golist.
795            // TODO(matloob): Implement module tiebreaking?
796            return path.Join(rpathfilepath.ToSlash(r)), truenil
797        }
798        return filepath.ToSlash(r), truenil
799    }
800    return ""falsenil
801}
802
803// absJoin absolutizes and flattens the lists of files.
804func absJoin(dir stringfileses ...[]string) (res []string) {
805    for _files := range fileses {
806        for _file := range files {
807            if !filepath.IsAbs(file) {
808                file = filepath.Join(dirfile)
809            }
810            res = append(resfile)
811        }
812    }
813    return res
814}
815
816func jsonFlag(cfg *ConfiggoVersion intstring {
817    if goVersion < 19 {
818        return "-json"
819    }
820    var fields []string
821    added := make(map[string]bool)
822    addFields := func(fs ...string) {
823        for _f := range fs {
824            if !added[f] {
825                added[f] = true
826                fields = append(fieldsf)
827            }
828        }
829    }
830    addFields("Name""ImportPath""Error"// These fields are always needed
831    if cfg.Mode&NeedFiles != 0 || cfg.Mode&NeedTypes != 0 {
832        addFields("Dir""GoFiles""IgnoredGoFiles""IgnoredOtherFiles""CFiles",
833            "CgoFiles""CXXFiles""MFiles""HFiles""FFiles""SFiles",
834            "SwigFiles""SwigCXXFiles""SysoFiles")
835        if cfg.Tests {
836            addFields("TestGoFiles""XTestGoFiles")
837        }
838    }
839    if cfg.Mode&NeedTypes != 0 {
840        // CompiledGoFiles seems to be required for the test case TestCgoNoSyntax,
841        // even when -compiled isn't passed in.
842        // TODO(#52435): Should we make the test ask for -compiled, or automatically
843        // request CompiledGoFiles in certain circumstances?
844        addFields("Dir""CompiledGoFiles")
845    }
846    if cfg.Mode&NeedCompiledGoFiles != 0 {
847        addFields("Dir""CompiledGoFiles""Export")
848    }
849    if cfg.Mode&NeedImports != 0 {
850        // When imports are requested, DepOnly is used to distinguish between packages
851        // explicitly requested and transitive imports of those packages.
852        addFields("DepOnly""Imports""ImportMap")
853        if cfg.Tests {
854            addFields("TestImports""XTestImports")
855        }
856    }
857    if cfg.Mode&NeedDeps != 0 {
858        addFields("DepOnly")
859    }
860    if usesExportData(cfg) {
861        // Request Dir in the unlikely case Export is not absolute.
862        addFields("Dir""Export")
863    }
864    if cfg.Mode&needInternalForTest != 0 {
865        addFields("ForTest")
866    }
867    if cfg.Mode&needInternalDepsErrors != 0 {
868        addFields("DepsErrors")
869    }
870    if cfg.Mode&NeedModule != 0 {
871        addFields("Module")
872    }
873    if cfg.Mode&NeedEmbedFiles != 0 {
874        addFields("EmbedFiles")
875    }
876    if cfg.Mode&NeedEmbedPatterns != 0 {
877        addFields("EmbedPatterns")
878    }
879    return "-json=" + strings.Join(fields",")
880}
881
882func golistargs(cfg *Configwords []stringgoVersion int) []string {
883    const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo
884    fullargs := []string{
885        "-e"jsonFlag(cfggoVersion),
886        fmt.Sprintf("-compiled=%t"cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypes|NeedTypesInfo|NeedTypesSizes) != 0),
887        fmt.Sprintf("-test=%t"cfg.Tests),
888        fmt.Sprintf("-export=%t"usesExportData(cfg)),
889        fmt.Sprintf("-deps=%t"cfg.Mode&NeedImports != 0),
890        // go list doesn't let you pass -test and -find together,
891        // probably because you'd just get the TestMain.
892        fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0 && !usesExportData(cfg)),
893    }
894    fullargs = append(fullargscfg.BuildFlags...)
895    fullargs = append(fullargs"--")
896    fullargs = append(fullargswords...)
897    return fullargs
898}
899
900// cfgInvocation returns an Invocation that reflects cfg's settings.
901func (state *golistStatecfgInvocation() gocommand.Invocation {
902    cfg := state.cfg
903    return gocommand.Invocation{
904        BuildFlagscfg.BuildFlags,
905        ModFile:    cfg.modFile,
906        ModFlag:    cfg.modFlag,
907        CleanEnv:   cfg.Env != nil,
908        Env:        cfg.Env,
909        Logf:       cfg.Logf,
910        WorkingDircfg.Dir,
911    }
912}
913
914// invokeGo returns the stdout of a go command invocation.
915func (state *golistStateinvokeGo(verb stringargs ...string) (*bytes.Buffererror) {
916    cfg := state.cfg
917
918    inv := state.cfgInvocation()
919
920    // For Go versions 1.16 and above, `go list` accepts overlays directly via
921    // the -overlay flag. Set it, if it's available.
922    //
923    // The check for "list" is not necessarily required, but we should avoid
924    // getting the go version if possible.
925    if verb == "list" {
926        goVersionerr := state.getGoVersion()
927        if err != nil {
928            return nilerr
929        }
930        if goVersion >= 16 {
931            filenamecleanuperr := state.writeOverlays()
932            if err != nil {
933                return nilerr
934            }
935            defer cleanup()
936            inv.Overlay = filename
937        }
938    }
939    inv.Verb = verb
940    inv.Args = args
941    gocmdRunner := cfg.gocmdRunner
942    if gocmdRunner == nil {
943        gocmdRunner = &gocommand.Runner{}
944    }
945    stdoutstderrfriendlyErrerr := gocmdRunner.RunRaw(cfg.Contextinv)
946    if err != nil {
947        // Check for 'go' executable not being found.
948        if eeok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound {
949            return nilfmt.Errorf("'go list' driver requires 'go', but %s"exec.ErrNotFound)
950        }
951
952        exitErrok := err.(*exec.ExitError)
953        if !ok {
954            // Catastrophic error:
955            // - context cancellation
956            return nilfmt.Errorf("couldn't run 'go': %w"err)
957        }
958
959        // Old go version?
960        if strings.Contains(stderr.String(), "flag provided but not defined") {
961            return nilgoTooOldError{fmt.Errorf("unsupported version of go: %s: %s"exitErrstderr)}
962        }
963
964        // Related to #24854
965        if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "unexpected directory layout") {
966            return nilfriendlyErr
967        }
968
969        // Is there an error running the C compiler in cgo? This will be reported in the "Error" field
970        // and should be suppressed by go list -e.
971        //
972        // This condition is not perfect yet because the error message can include other error messages than runtime/cgo.
973        isPkgPathRune := func(r runebool {
974            // From https://golang.org/ref/spec#Import_declarations:
975            //    Implementation restriction: A compiler may restrict ImportPaths to non-empty strings
976            //    using only characters belonging to Unicode's L, M, N, P, and S general categories
977            //    (the Graphic characters without spaces) and may also exclude the
978            //    characters !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement character U+FFFD.
979            return unicode.IsOneOf([]*unicode.RangeTable{unicode.Lunicode.Municode.Nunicode.Punicode.S}, r) &&
980                !strings.ContainsRune("!\"#$%&'()*,:;<=>?[\\]^`{|}\uFFFD"r)
981        }
982        // golang/go#36770: Handle case where cmd/go prints module download messages before the error.
983        msg := stderr.String()
984        for strings.HasPrefix(msg"go: downloading") {
985            msg = msg[strings.IndexRune(msg'\n')+1:]
986        }
987        if len(stderr.String()) > 0 && strings.HasPrefix(stderr.String(), "# ") {
988            msg := msg[len("# "):]
989            if strings.HasPrefix(strings.TrimLeftFunc(msgisPkgPathRune), "\n") {
990                return stdoutnil
991            }
992            // Treat pkg-config errors as a special case (golang.org/issue/36770).
993            if strings.HasPrefix(msg"pkg-config") {
994                return stdoutnil
995            }
996        }
997
998        // This error only appears in stderr. See golang.org/cl/166398 for a fix in go list to show
999        // the error in the Err section of stdout in case -e option is provided.
1000        // This fix is provided for backwards compatibility.
1001        if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must be .go files") {
1002            output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
1003                strings.Trim(stderr.String(), "\n"))
1004            return bytes.NewBufferString(output), nil
1005        }
1006
1007        // Similar to the previous error, but currently lacks a fix in Go.
1008        if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must all be in one directory") {
1009            output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
1010                strings.Trim(stderr.String(), "\n"))
1011            return bytes.NewBufferString(output), nil
1012        }
1013
1014        // Backwards compatibility for Go 1.11 because 1.12 and 1.13 put the directory in the ImportPath.
1015        // If the package doesn't exist, put the absolute path of the directory into the error message,
1016        // as Go 1.13 list does.
1017        const noSuchDirectory = "no such directory"
1018        if len(stderr.String()) > 0 && strings.Contains(stderr.String(), noSuchDirectory) {
1019            errstr := stderr.String()
1020            abspath := strings.TrimSpace(errstr[strings.Index(errstrnoSuchDirectory)+len(noSuchDirectory):])
1021            output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
1022                abspathstrings.Trim(stderr.String(), "\n"))
1023            return bytes.NewBufferString(output), nil
1024        }
1025
1026        // Workaround for #29280: go list -e has incorrect behavior when an ad-hoc package doesn't exist.
1027        // Note that the error message we look for in this case is different that the one looked for above.
1028        if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no such file or directory") {
1029            output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
1030                strings.Trim(stderr.String(), "\n"))
1031            return bytes.NewBufferString(output), nil
1032        }
1033
1034        // Workaround for #34273. go list -e with GO111MODULE=on has incorrect behavior when listing a
1035        // directory outside any module.
1036        if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside available modules") {
1037            output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
1038                // TODO(matloob): command-line-arguments isn't correct here.
1039                "command-line-arguments"strings.Trim(stderr.String(), "\n"))
1040            return bytes.NewBufferString(output), nil
1041        }
1042
1043        // Another variation of the previous error
1044        if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside module root") {
1045            output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
1046                // TODO(matloob): command-line-arguments isn't correct here.
1047                "command-line-arguments"strings.Trim(stderr.String(), "\n"))
1048            return bytes.NewBufferString(output), nil
1049        }
1050
1051        // Workaround for an instance of golang.org/issue/26755: go list -e  will return a non-zero exit
1052        // status if there's a dependency on a package that doesn't exist. But it should return
1053        // a zero exit status and set an error on that package.
1054        if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no Go files in") {
1055            // Don't clobber stdout if `go list` actually returned something.
1056            if len(stdout.String()) > 0 {
1057                return stdoutnil
1058            }
1059            // try to extract package name from string
1060            stderrStr := stderr.String()
1061            var importPath string
1062            colon := strings.Index(stderrStr":")
1063            if colon > 0 && strings.HasPrefix(stderrStr"go build ") {
1064                importPath = stderrStr[len("go build "):colon]
1065            }
1066            output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
1067                importPathstrings.Trim(stderrStr"\n"))
1068            return bytes.NewBufferString(output), nil
1069        }
1070
1071        // Export mode entails a build.
1072        // If that build fails, errors appear on stderr
1073        // (despite the -e flag) and the Export field is blank.
1074        // Do not fail in that case.
1075        // The same is true if an ad-hoc package given to go list doesn't exist.
1076        // TODO(matloob): Remove these once we can depend on go list to exit with a zero status with -e even when
1077        // packages don't exist or a build fails.
1078        if !usesExportData(cfg) && !containsGoFile(args) {
1079            return nilfriendlyErr
1080        }
1081    }
1082    return stdoutnil
1083}
1084
1085// OverlayJSON is the format overlay files are expected to be in.
1086// The Replace map maps from overlaid paths to replacement paths:
1087// the Go command will forward all reads trying to open
1088// each overlaid path to its replacement path, or consider the overlaid
1089// path not to exist if the replacement path is empty.
1090//
1091// From golang/go#39958.
1092type OverlayJSON struct {
1093    Replace map[string]string `json:"replace,omitempty"`
1094}
1095
1096// writeOverlays writes out files for go list's -overlay flag, as described
1097// above.
1098func (state *golistStatewriteOverlays() (filename stringcleanup func(), err error) {
1099    // Do nothing if there are no overlays in the config.
1100    if len(state.cfg.Overlay) == 0 {
1101        return "", func() {}, nil
1102    }
1103    direrr := ioutil.TempDir("""gopackages-*")
1104    if err != nil {
1105        return ""nilerr
1106    }
1107    // The caller must clean up this directory, unless this function returns an
1108    // error.
1109    cleanup = func() {
1110        os.RemoveAll(dir)
1111    }
1112    defer func() {
1113        if err != nil {
1114            cleanup()
1115        }
1116    }()
1117    overlays := map[string]string{}
1118    for kv := range state.cfg.Overlay {
1119        // Create a unique filename for the overlaid files, to avoid
1120        // creating nested directories.
1121        noSeparator := strings.Join(strings.Split(filepath.ToSlash(k), "/"), "")
1122        ferr := ioutil.TempFile(dirfmt.Sprintf("*-%s"noSeparator))
1123        if err != nil {
1124            return "", func() {}, err
1125        }
1126        if _err := f.Write(v); err != nil {
1127            return "", func() {}, err
1128        }
1129        if err := f.Close(); err != nil {
1130            return "", func() {}, err
1131        }
1132        overlays[k] = f.Name()
1133    }
1134    berr := json.Marshal(OverlayJSON{Replaceoverlays})
1135    if err != nil {
1136        return "", func() {}, err
1137    }
1138    // Write out the overlay file that contains the filepath mappings.
1139    filename = filepath.Join(dir"overlay.json")
1140    if err := ioutil.WriteFile(filenameb0665); err != nil {
1141        return "", func() {}, err
1142    }
1143    return filenamecleanupnil
1144}
1145
1146func containsGoFile(s []stringbool {
1147    for _f := range s {
1148        if strings.HasSuffix(f".go") {
1149            return true
1150        }
1151    }
1152    return false
1153}
1154
1155func cmdDebugStr(cmd *exec.Cmdstring {
1156    env := make(map[string]string)
1157    for _kv := range cmd.Env {
1158        split := strings.SplitN(kv"="2)
1159        kv := split[0], split[1]
1160        env[k] = v
1161    }
1162
1163    var args []string
1164    for _arg := range cmd.Args {
1165        quoted := strconv.Quote(arg)
1166        if quoted[1:len(quoted)-1] != arg || strings.Contains(arg" ") {
1167            args = append(argsquoted)
1168        } else {
1169            args = append(argsarg)
1170        }
1171    }
1172    return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v"env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args" "))
1173}
1174
MembersX
reflect
golistState.createDriverResponse.goVersion
responseDeduper.addPackage
jsonPackage.Error
golistState.runContainsQueries
golistState.vendorDirs
goListDriver.BlockStmt.RangeStmt_6778.BlockStmt.RangeStmt_6854.pkgID
jsonPackage.EmbedFiles
golistState.createDriverResponse.BlockStmt.BlockStmt.BlockStmt._
golistState.shouldAddFilenameFromError.err
log
responseDeduper.addRoot
cmdDebugStr.cmd
golistState.mustGetEnv.err
jsonFlag.BlockStmt.RangeStmt_26492.f
unicode
golistState.writeOverlays.RangeStmt_38071.BlockStmt.noSeparator
jsonPackage.IgnoredOtherFiles
golistState.getGoVersion
absJoin.RangeStmt_26127.BlockStmt.RangeStmt_26161.file
golistState.writeOverlays
golistState.writeOverlays.overlays
goListDriver.sizeswg
golistState.runContainsQueries.RangeStmt_7673.BlockStmt.RangeStmt_8901.BlockStmt.RangeStmt_9339.pkgFile
golistState.createDriverResponse.BlockStmt.BlockStmt.RangeStmt_19981.BlockStmt.ext
golistState.invokeGo.BlockStmt.BlockStmt.colon
golistState.runContainsQueries.RangeStmt_7673.BlockStmt.dirResponse
otherFiles.p
golistState.shouldAddFilenameFromError.state
golistState.runContainsQueries.RangeStmt_7673.BlockStmt.err
golistState.adhocPackage.pattern
golistState.runContainsQueries.RangeStmt_7673.BlockStmt.isRoot
golistargs.goVersion
golistState.rootsOnce
golistState.goVersion
golistState.invokeGo.stderr
golistState.writeOverlays.RangeStmt_38071.BlockStmt._
golistState.cfg
goListDriver.BlockStmt.BlockStmt.sizes
golistState.getEnv.state
jsonPackage.TestImports
jsonPackageError.ImportStack
golistState.invokeGo
cmdDebugStr.RangeStmt_39257.arg
responseDeduper
responseDeduper.addAll
golistState.createDriverResponse.BlockStmt.RangeStmt_21221.id
responseDeduper.addRoot.r
golistState.adhocPackage.response
responseDeduper.seenPackages
packagesinternal
responseDeduper.addAll.r
goListDriver.cfg
goListDriver.sizeserr
golistState.createDriverResponse.BlockStmt.BlockStmt.ok
absJoin.fileses
packagesdriver
gocommand
golistState.mustGetEnv.env
jsonPackage.Deps
jsonPackage.XTestImports
golistState.createDriverResponse.BlockStmt.err
golistState.createDriverResponse.BlockStmt.BlockStmt.BlockStmt.errkind
golistState.createDriverResponse.BlockStmt.BlockStmt.BlockStmt.split
golistState.rootDirsError
golistState.mustGetEnv
golistState.getPkgPath.state
golistState.writeOverlays.RangeStmt_38071.BlockStmt.err
responseDeduper.addAll.RangeStmt_1318.root
golistState.createDriverResponse.BlockStmt.BlockStmt.pkgPath
golistState.createDriverResponse.BlockStmt.BlockStmt.RangeStmt_19981.f
golistState.getPkgPath.dir
golistState.adhocPackage.state
jsonPackage.GoFiles
otherFiles
golistState.createDriverResponse.words
golistState.getPkgPath.RangeStmt_25071.rdir
golistState.runContainsQueries.RangeStmt_7673.query
jsonPackageError.Err
jsonPackage.ForTest
golistState.createDriverResponse.response
golistState.createDriverResponse.BlockStmt.BlockStmt.found
golistState.goVersionOnce
golistState.getEnv.BlockStmt.decoder
golistState.adhocPackage.query
jsonPackage.DepsErrors
jsonPackage.Imports
golistState.adhocPackage.BlockStmt.BlockStmt.BlockStmt.RangeStmt_10974.path
jsonPackage.EmbedPatterns
golistState.createDriverResponse.BlockStmt.BlockStmt.err
jsonFlag.goVersion
golistState.invokeGo.inv
goListDriver.RangeStmt_4214.BlockStmt.eqidx
golistState.adhocPackage
golistState.addNeededOverlayPackages._
golistState.invokeGo.BlockStmt.BlockStmt.filename
golistState.goEnv
golistState.createDriverResponse.BlockStmt.BlockStmt.BlockStmt.info
cmdDebugStr.RangeStmt_39257.BlockStmt.quoted
golistState.rootDirs
golistState.addNeededOverlayPackages.pkgs
goListDriver.goVersion
golistState.runContainsQueries.RangeStmt_7673.BlockStmt.RangeStmt_8831.root
ioutil
golistState.getEnv.BlockStmt.b
jsonFlag.added
golistState.invokeGo.state
golistState.invokeGo.gocmdRunner
cmdDebugStr.RangeStmt_39124.BlockStmt.split
goListDriver.restPatterns
jsonPackage.DepOnly
golistargs
golistState.invokeGo.cfg
golistState.writeOverlays.b
golistState.runContainsQueries.response
jsonPackage.Dir
golistState.addNeededOverlayPackages.response
jsonPackage.Module
cmdDebugStr.args
goListDriver.ctx
goListDriver.state
jsonFlag.cfg
responseDeduper.dr
golistState.runContainsQueries.RangeStmt_7673.BlockStmt.BlockStmt.queryErr
golistState.createDriverResponse.BlockStmt.pkg
jsonFlag
golistState.getEnv
golistState.createDriverResponse.seen
responseDeduper.addRoot.id
golistState.runContainsQueries.RangeStmt_7673.BlockStmt.pattern
context
goListDriver.err
golistState.writeOverlays.state
golistState.adhocPackage.err
jsonPackage.HFiles
golistState.createDriverResponse
golistState.createDriverResponse.dec
golistState.createDriverResponse.BlockStmt.BlockStmt.msg
absJoin.RangeStmt_26127.files
golistState.mustGetEnv.state
goListDriver.BlockStmt.err
golistState.writeOverlays.cleanup
golistState.getPkgPath.RangeStmt_25071.BlockStmt.r
golistState.invokeGo.err
golistState.goEnvError
golistState.createDriverResponse.err
goListDriver.BlockStmt.needPkgs
goListDriver.BlockStmt.BlockStmt.RangeStmt_6149.BlockStmt.RangeStmt_6448.BlockStmt.RangeStmt_6486.g
jsonPackage.SysoFiles
golistState.createDriverResponse.BlockStmt.BlockStmt.BlockStmt.filename
golistState.shouldAddFilenameFromError.goV
sync
responseDeduper.addAll.dr
OverlayJSON.Replace
goListDriver.containFiles
jsonPackage.TestGoFiles
golistState.createDriverResponse.BlockStmt.i
golistState.createDriverResponse.RangeStmt_23229.errs
golistState.writeOverlays.err
responseDeduper.addAll.RangeStmt_1260.pkg
goListDriver.response
golistState.runContainsQueries.RangeStmt_7673.BlockStmt.RangeStmt_8901.pkg
golistState.shouldAddFilenameFromError.p
golistState.getGoVersion.state
golistState
golistState.addNeededOverlayPackages.RangeStmt_7357.pkg
golistState.invokeGo.BlockStmt.BlockStmt.cleanup
golistState.writeOverlays.RangeStmt_38071.k
cmdDebugStr.env
goListDriver.RangeStmt_4214.BlockStmt.BlockStmt.BlockStmt.RangeStmt_4673.rune
golistState.createDriverResponse.BlockStmt.ids
golistState.invokeGo.friendlyErr
golistState.invokeGo.BlockStmt.BlockStmt.importPath
jsonPackage.CgoFiles
golistState.getPkgPath.absDir
golistState.getPkgPath.RangeStmt_25071.BlockStmt.err
goListDriver.BlockStmt.BlockStmt.RangeStmt_6149.id
jsonPackage.CFiles
golistState.addNeededOverlayPackages.err
golistState.createDriverResponse.state
golistState.createDriverResponse.additionalErrors
golistState.invokeGo.BlockStmt.BlockStmt.errstr
goListDriver.parentCtx
goListDriver.BlockStmt.containsCandidates
golistState.adhocPackage.BlockStmt.BlockStmt.BlockStmt.filename
jsonPackage
golistState.createDriverResponse.BlockStmt.RangeStmt_21000.id
types
sort
golistState.runContainsQueries.state
jsonPackage.ImportPath
golistState.createDriverResponse.BlockStmt.RangeStmt_21097.id
golistState.createDriverResponse.RangeStmt_23347.pkg
golistState.invokeGo.verb
golistState.writeOverlays.RangeStmt_38071.BlockStmt.f
responseDeduper.seenRoots
golistState.addNeededOverlayPackages.dr
jsonPackage.SFiles
jsonPackage.ImportMap
jsonPackageError.Pos
responseDeduper.addPackage.r
goListDriver.BlockStmt.RangeStmt_6778.BlockStmt.match
golistState.createDriverResponse.BlockStmt.RangeStmt_21097.path
golistState.cfgInvocation.cfg
golistState.writeOverlays.RangeStmt_38071.v
goListDriver.BlockStmt.modifiedPkgs
jsonPackage.SwigFiles
golistState.invokeGo.BlockStmt.BlockStmt.abspath
OverlayJSON
containsGoFile.s
newDeduper
golistState.createDriverResponse.BlockStmt.p
jsonPackage.IgnoredGoFiles
jsonPackage.FFiles
jsonPackage.XTestGoFiles
golistargs.cfg
golistState.ctx
goListDriver.BlockStmt.RangeStmt_6778.pattern
golistState.invokeGo.BlockStmt.noSuchDirectory
strconv
goListDriver.cancel
golistargs.fullargs
jsonPackage.Export
golistargs.words
golistState.cfgInvocation
golistState.invokeGo.BlockStmt.err
golistState.invokeGo.BlockStmt.BlockStmt.err
golistState.invokeGo.BlockStmt.BlockStmt.output
filepath
goListDriver.patterns
golistState.getPkgPath.RangeStmt_25071.rpath
absJoin
golistState.writeOverlays.dir
cmdDebugStr.RangeStmt_39124.kv
golistState.addNeededOverlayPackages
jsonPackage.SwigCXXFiles
golistState.runContainsQueries.RangeStmt_7673.BlockStmt.fdir
jsonPackage.CXXFiles
golistState.addNeededOverlayPackages.needPkgs
containsGoFile.RangeStmt_38954.f
goListDriver.BlockStmt.dr
jsonPackage.CompiledGoFiles
jsonPackage.MFiles
jsonPackageError
jsonFlag.fields
goTooOldError
goListDriver.RangeStmt_4214.pattern
golistState.addNeededOverlayPackages.state
golistState.getPkgPath.err
golistState.invokeGo.args
responseDeduper.addPackage.p
goListDriver.BlockStmt.BlockStmt.RangeStmt_6149.BlockStmt.RangeStmt_6448.f
golistState.createDriverResponse.RangeStmt_23229.id
golistState.getPkgPath
golistState.getPkgPath.roots
absJoin.dir
absJoin.res
golistState.invokeGo.stdout
golistState.envOnce
golistState.createDriverResponse.buf
golistState.invokeGo.BlockStmt.msg
golistState.writeOverlays.filename
containsGoFile
goListDriver
golistState.cfgInvocation.state
golistState.shouldAddFilenameFromError
golistState.invokeGo.BlockStmt.BlockStmt.stderrStr
golistState.goVersionError
golistState.createDriverResponse.pkgs
jsonPackage.Name
golistState.invokeGo.BlockStmt.goVersion
cmdDebugStr
path
golistState.runContainsQueries.queries
Members
X