GoPLS Viewer

Home|gopls/internal/imports/mod.go
1// Copyright 2019 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 imports
6
7import (
8    "bytes"
9    "context"
10    "encoding/json"
11    "fmt"
12    "io/ioutil"
13    "os"
14    "path"
15    "path/filepath"
16    "regexp"
17    "sort"
18    "strconv"
19    "strings"
20
21    "golang.org/x/mod/module"
22    "golang.org/x/tools/internal/gocommand"
23    "golang.org/x/tools/internal/gopathwalk"
24)
25
26// ModuleResolver implements resolver for modules using the go command as little
27// as feasible.
28type ModuleResolver struct {
29    env            *ProcessEnv
30    moduleCacheDir string
31    dummyVendorMod *gocommand.ModuleJSON // If vendoring is enabled, the pseudo-module that represents the /vendor directory.
32    roots          []gopathwalk.Root
33    scanSema       chan struct{} // scanSema prevents concurrent scans and guards scannedRoots.
34    scannedRoots   map[gopathwalk.Root]bool
35
36    initialized   bool
37    mains         []*gocommand.ModuleJSON
38    mainByDir     map[string]*gocommand.ModuleJSON
39    modsByModPath []*gocommand.ModuleJSON // All modules, ordered by # of path components in module Path...
40    modsByDir     []*gocommand.ModuleJSON // ...or Dir.
41
42    // moduleCacheCache stores information about the module cache.
43    moduleCacheCache *dirInfoCache
44    otherCache       *dirInfoCache
45}
46
47func newModuleResolver(e *ProcessEnv) *ModuleResolver {
48    r := &ModuleResolver{
49        env:      e,
50        scanSemamake(chan struct{}, 1),
51    }
52    r.scanSema <- struct{}{}
53    return r
54}
55
56func (r *ModuleResolverinit() error {
57    if r.initialized {
58        return nil
59    }
60
61    goenverr := r.env.goEnv()
62    if err != nil {
63        return err
64    }
65    inv := gocommand.Invocation{
66        BuildFlagsr.env.BuildFlags,
67        ModFlag:    r.env.ModFlag,
68        ModFile:    r.env.ModFile,
69        Env:        r.env.env(),
70        Logf:       r.env.Logf,
71        WorkingDirr.env.WorkingDir,
72    }
73
74    vendorEnabled := false
75    var mainModVendor *gocommand.ModuleJSON
76
77    // Module vendor directories are ignored in workspace mode:
78    // https://go.googlesource.com/proposal/+/master/design/45713-workspace.md
79    if len(r.env.Env["GOWORK"]) == 0 {
80        vendorEnabledmainModVendorerr = gocommand.VendorEnabled(context.TODO(), invr.env.GocmdRunner)
81        if err != nil {
82            return err
83        }
84    }
85
86    if mainModVendor != nil && vendorEnabled {
87        // Vendor mode is on, so all the non-Main modules are irrelevant,
88        // and we need to search /vendor for everything.
89        r.mains = []*gocommand.ModuleJSON{mainModVendor}
90        r.dummyVendorMod = &gocommand.ModuleJSON{
91            Path"",
92            Dir:  filepath.Join(mainModVendor.Dir"vendor"),
93        }
94        r.modsByModPath = []*gocommand.ModuleJSON{mainModVendorr.dummyVendorMod}
95        r.modsByDir = []*gocommand.ModuleJSON{mainModVendorr.dummyVendorMod}
96    } else {
97        // Vendor mode is off, so run go list -m ... to find everything.
98        err := r.initAllMods()
99        // We expect an error when running outside of a module with
100        // GO111MODULE=on. Other errors are fatal.
101        if err != nil {
102            if errMsg := err.Error(); !strings.Contains(errMsg"working directory is not part of a module") && !strings.Contains(errMsg"go.mod file not found") {
103                return err
104            }
105        }
106    }
107
108    if gmc := r.env.Env["GOMODCACHE"]; gmc != "" {
109        r.moduleCacheDir = gmc
110    } else {
111        gopaths := filepath.SplitList(goenv["GOPATH"])
112        if len(gopaths) == 0 {
113            return fmt.Errorf("empty GOPATH")
114        }
115        r.moduleCacheDir = filepath.Join(gopaths[0], "/pkg/mod")
116    }
117
118    sort.Slice(r.modsByModPath, func(ij intbool {
119        count := func(x intint {
120            return strings.Count(r.modsByModPath[x].Path"/")
121        }
122        return count(j) < count(i// descending order
123    })
124    sort.Slice(r.modsByDir, func(ij intbool {
125        count := func(x intint {
126            return strings.Count(r.modsByDir[x].Dir"/")
127        }
128        return count(j) < count(i// descending order
129    })
130
131    r.roots = []gopathwalk.Root{
132        {Pathfilepath.Join(goenv["GOROOT"], "/src"), Typegopathwalk.RootGOROOT},
133    }
134    r.mainByDir = make(map[string]*gocommand.ModuleJSON)
135    for _main := range r.mains {
136        r.roots = append(r.rootsgopathwalk.Root{Pathmain.DirTypegopathwalk.RootCurrentModule})
137        r.mainByDir[main.Dir] = main
138    }
139    if vendorEnabled {
140        r.roots = append(r.rootsgopathwalk.Root{Pathr.dummyVendorMod.DirTypegopathwalk.RootOther})
141    } else {
142        addDep := func(mod *gocommand.ModuleJSON) {
143            if mod.Replace == nil {
144                // This is redundant with the cache, but we'll skip it cheaply enough.
145                r.roots = append(r.rootsgopathwalk.Root{Pathmod.DirTypegopathwalk.RootModuleCache})
146            } else {
147                r.roots = append(r.rootsgopathwalk.Root{Pathmod.DirTypegopathwalk.RootOther})
148            }
149        }
150        // Walk dependent modules before scanning the full mod cache, direct deps first.
151        for _mod := range r.modsByModPath {
152            if !mod.Indirect && !mod.Main {
153                addDep(mod)
154            }
155        }
156        for _mod := range r.modsByModPath {
157            if mod.Indirect && !mod.Main {
158                addDep(mod)
159            }
160        }
161        r.roots = append(r.rootsgopathwalk.Root{Pathr.moduleCacheDirTypegopathwalk.RootModuleCache})
162    }
163
164    r.scannedRoots = map[gopathwalk.Root]bool{}
165    if r.moduleCacheCache == nil {
166        r.moduleCacheCache = &dirInfoCache{
167            dirs:      map[string]*directoryPackageInfo{},
168            listeners: map[*int]cacheListener{},
169        }
170    }
171    if r.otherCache == nil {
172        r.otherCache = &dirInfoCache{
173            dirs:      map[string]*directoryPackageInfo{},
174            listeners: map[*int]cacheListener{},
175        }
176    }
177    r.initialized = true
178    return nil
179}
180
181func (r *ModuleResolverinitAllMods() error {
182    stdouterr := r.env.invokeGo(context.TODO(), "list""-m""-e""-json""...")
183    if err != nil {
184        return err
185    }
186    for dec := json.NewDecoder(stdout); dec.More(); {
187        mod := &gocommand.ModuleJSON{}
188        if err := dec.Decode(mod); err != nil {
189            return err
190        }
191        if mod.Dir == "" {
192            if r.env.Logf != nil {
193                r.env.Logf("module %v has not been downloaded and will be ignored"mod.Path)
194            }
195            // Can't do anything with a module that's not downloaded.
196            continue
197        }
198        // golang/go#36193: the go command doesn't always clean paths.
199        mod.Dir = filepath.Clean(mod.Dir)
200        r.modsByModPath = append(r.modsByModPathmod)
201        r.modsByDir = append(r.modsByDirmod)
202        if mod.Main {
203            r.mains = append(r.mainsmod)
204        }
205    }
206    return nil
207}
208
209func (r *ModuleResolverClearForNewScan() {
210    <-r.scanSema
211    r.scannedRoots = map[gopathwalk.Root]bool{}
212    r.otherCache = &dirInfoCache{
213        dirs:      map[string]*directoryPackageInfo{},
214        listeners: map[*int]cacheListener{},
215    }
216    r.scanSema <- struct{}{}
217}
218
219func (r *ModuleResolverClearForNewMod() {
220    <-r.scanSema
221    *r = ModuleResolver{
222        env:              r.env,
223        moduleCacheCacher.moduleCacheCache,
224        otherCache:       r.otherCache,
225        scanSema:         r.scanSema,
226    }
227    r.init()
228    r.scanSema <- struct{}{}
229}
230
231// findPackage returns the module and directory that contains the package at
232// the given import path, or returns nil, "" if no module is in scope.
233func (r *ModuleResolverfindPackage(importPath string) (*gocommand.ModuleJSONstring) {
234    // This can't find packages in the stdlib, but that's harmless for all
235    // the existing code paths.
236    for _m := range r.modsByModPath {
237        if !strings.HasPrefix(importPathm.Path) {
238            continue
239        }
240        pathInModule := importPath[len(m.Path):]
241        pkgDir := filepath.Join(m.DirpathInModule)
242        if r.dirIsNestedModule(pkgDirm) {
243            continue
244        }
245
246        if infook := r.cacheLoad(pkgDir); ok {
247            if loadederr := info.reachedStatus(nameLoaded); loaded {
248                if err != nil {
249                    continue // No package in this dir.
250                }
251                return mpkgDir
252            }
253            if scannederr := info.reachedStatus(directoryScanned); scanned && err != nil {
254                continue // Dir is unreadable, etc.
255            }
256            // This is slightly wrong: a directory doesn't have to have an
257            // importable package to count as a package for package-to-module
258            // resolution. package main or _test files should count but
259            // don't.
260            // TODO(heschi): fix this.
261            if _err := r.cachePackageName(info); err == nil {
262                return mpkgDir
263            }
264        }
265
266        // Not cached. Read the filesystem.
267        pkgFileserr := ioutil.ReadDir(pkgDir)
268        if err != nil {
269            continue
270        }
271        // A module only contains a package if it has buildable go
272        // files in that directory. If not, it could be provided by an
273        // outer module. See #29736.
274        for _fi := range pkgFiles {
275            if ok_ := r.env.matchFile(pkgDirfi.Name()); ok {
276                return mpkgDir
277            }
278        }
279    }
280    return nil""
281}
282
283func (r *ModuleResolvercacheLoad(dir string) (directoryPackageInfobool) {
284    if infook := r.moduleCacheCache.Load(dir); ok {
285        return infook
286    }
287    return r.otherCache.Load(dir)
288}
289
290func (r *ModuleResolvercacheStore(info directoryPackageInfo) {
291    if info.rootType == gopathwalk.RootModuleCache {
292        r.moduleCacheCache.Store(info.dirinfo)
293    } else {
294        r.otherCache.Store(info.dirinfo)
295    }
296}
297
298func (r *ModuleResolvercacheKeys() []string {
299    return append(r.moduleCacheCache.Keys(), r.otherCache.Keys()...)
300}
301
302// cachePackageName caches the package name for a dir already in the cache.
303func (r *ModuleResolvercachePackageName(info directoryPackageInfo) (stringerror) {
304    if info.rootType == gopathwalk.RootModuleCache {
305        return r.moduleCacheCache.CachePackageName(info)
306    }
307    return r.otherCache.CachePackageName(info)
308}
309
310func (r *ModuleResolvercacheExports(ctx context.Contextenv *ProcessEnvinfo directoryPackageInfo) (string, []stringerror) {
311    if info.rootType == gopathwalk.RootModuleCache {
312        return r.moduleCacheCache.CacheExports(ctxenvinfo)
313    }
314    return r.otherCache.CacheExports(ctxenvinfo)
315}
316
317// findModuleByDir returns the module that contains dir, or nil if no such
318// module is in scope.
319func (r *ModuleResolverfindModuleByDir(dir string) *gocommand.ModuleJSON {
320    // This is quite tricky and may not be correct. dir could be:
321    // - a package in the main module.
322    // - a replace target underneath the main module's directory.
323    //    - a nested module in the above.
324    // - a replace target somewhere totally random.
325    //    - a nested module in the above.
326    // - in the mod cache.
327    // - in /vendor/ in -mod=vendor mode.
328    //    - nested module? Dunno.
329    // Rumor has it that replace targets cannot contain other replace targets.
330    for _m := range r.modsByDir {
331        if !strings.HasPrefix(dirm.Dir) {
332            continue
333        }
334
335        if r.dirIsNestedModule(dirm) {
336            continue
337        }
338
339        return m
340    }
341    return nil
342}
343
344// dirIsNestedModule reports if dir is contained in a nested module underneath
345// mod, not actually in mod.
346func (r *ModuleResolverdirIsNestedModule(dir stringmod *gocommand.ModuleJSONbool {
347    if !strings.HasPrefix(dirmod.Dir) {
348        return false
349    }
350    if r.dirInModuleCache(dir) {
351        // Nested modules in the module cache are pruned,
352        // so it cannot be a nested module.
353        return false
354    }
355    if mod != nil && mod == r.dummyVendorMod {
356        // The /vendor pseudomodule is flattened and doesn't actually count.
357        return false
358    }
359    modDir_ := r.modInfo(dir)
360    if modDir == "" {
361        return false
362    }
363    return modDir != mod.Dir
364}
365
366func (r *ModuleResolvermodInfo(dir string) (modDir stringmodName string) {
367    readModName := func(modFile stringstring {
368        modByteserr := ioutil.ReadFile(modFile)
369        if err != nil {
370            return ""
371        }
372        return modulePath(modBytes)
373    }
374
375    if r.dirInModuleCache(dir) {
376        if matches := modCacheRegexp.FindStringSubmatch(dir); len(matches) == 3 {
377            index := strings.Index(dirmatches[1]+"@"+matches[2])
378            modDir := filepath.Join(dir[:index], matches[1]+"@"+matches[2])
379            return modDirreadModName(filepath.Join(modDir"go.mod"))
380        }
381    }
382    for {
383        if infook := r.cacheLoad(dir); ok {
384            return info.moduleDirinfo.moduleName
385        }
386        f := filepath.Join(dir"go.mod")
387        infoerr := os.Stat(f)
388        if err == nil && !info.IsDir() {
389            return dirreadModName(f)
390        }
391
392        d := filepath.Dir(dir)
393        if len(d) >= len(dir) {
394            return """" // reached top of file system, no go.mod
395        }
396        dir = d
397    }
398}
399
400func (r *ModuleResolverdirInModuleCache(dir stringbool {
401    if r.moduleCacheDir == "" {
402        return false
403    }
404    return strings.HasPrefix(dirr.moduleCacheDir)
405}
406
407func (r *ModuleResolverloadPackageNames(importPaths []stringsrcDir string) (map[string]stringerror) {
408    if err := r.init(); err != nil {
409        return nilerr
410    }
411    names := map[string]string{}
412    for _path := range importPaths {
413        _packageDir := r.findPackage(path)
414        if packageDir == "" {
415            continue
416        }
417        nameerr := packageDirToName(packageDir)
418        if err != nil {
419            continue
420        }
421        names[path] = name
422    }
423    return namesnil
424}
425
426func (r *ModuleResolverscan(ctx context.Contextcallback *scanCallbackerror {
427    if err := r.init(); err != nil {
428        return err
429    }
430
431    processDir := func(info directoryPackageInfo) {
432        // Skip this directory if we were not able to get the package information successfully.
433        if scannederr := info.reachedStatus(directoryScanned); !scanned || err != nil {
434            return
435        }
436        pkgerr := r.canonicalize(info)
437        if err != nil {
438            return
439        }
440
441        if !callback.dirFound(pkg) {
442            return
443        }
444        pkg.packageNameerr = r.cachePackageName(info)
445        if err != nil {
446            return
447        }
448
449        if !callback.packageNameLoaded(pkg) {
450            return
451        }
452        _exportserr := r.loadExports(ctxpkgfalse)
453        if err != nil {
454            return
455        }
456        callback.exportsLoaded(pkgexports)
457    }
458
459    // Start processing everything in the cache, and listen for the new stuff
460    // we discover in the walk below.
461    stop1 := r.moduleCacheCache.ScanAndListen(ctxprocessDir)
462    defer stop1()
463    stop2 := r.otherCache.ScanAndListen(ctxprocessDir)
464    defer stop2()
465
466    // We assume cached directories are fully cached, including all their
467    // children, and have not changed. We can skip them.
468    skip := func(root gopathwalk.Rootdir stringbool {
469        if r.env.SkipPathInScan != nil && root.Type == gopathwalk.RootCurrentModule {
470            if root.Path == dir {
471                return false
472            }
473
474            if r.env.SkipPathInScan(filepath.Clean(dir)) {
475                return true
476            }
477        }
478
479        infook := r.cacheLoad(dir)
480        if !ok {
481            return false
482        }
483        // This directory can be skipped as long as we have already scanned it.
484        // Packages with errors will continue to have errors, so there is no need
485        // to rescan them.
486        packageScanned_ := info.reachedStatus(directoryScanned)
487        return packageScanned
488    }
489
490    // Add anything new to the cache, and process it if we're still listening.
491    add := func(root gopathwalk.Rootdir string) {
492        r.cacheStore(r.scanDirForPackage(rootdir))
493    }
494
495    // r.roots and the callback are not necessarily safe to use in the
496    // goroutine below. Process them eagerly.
497    roots := filterRoots(r.rootscallback.rootFound)
498    // We can't cancel walks, because we need them to finish to have a usable
499    // cache. Instead, run them in a separate goroutine and detach.
500    scanDone := make(chan struct{})
501    go func() {
502        select {
503        case <-ctx.Done():
504            return
505        case <-r.scanSema:
506        }
507        defer func() { r.scanSema <- struct{}{} }()
508        // We have the lock on r.scannedRoots, and no other scans can run.
509        for _root := range roots {
510            if ctx.Err() != nil {
511                return
512            }
513
514            if r.scannedRoots[root] {
515                continue
516            }
517            gopathwalk.WalkSkip([]gopathwalk.Root{root}, addskipgopathwalk.Options{Logfr.env.LogfModulesEnabledtrue})
518            r.scannedRoots[root] = true
519        }
520        close(scanDone)
521    }()
522    select {
523    case <-ctx.Done():
524    case <-scanDone:
525    }
526    return nil
527}
528
529func (r *ModuleResolverscoreImportPath(ctx context.Contextpath stringfloat64 {
530    if _ok := stdlib[path]; ok {
531        return MaxRelevance
532    }
533    mod_ := r.findPackage(path)
534    return modRelevance(mod)
535}
536
537func modRelevance(mod *gocommand.ModuleJSONfloat64 {
538    var relevance float64
539    switch {
540    case mod == nil// out of scope
541        return MaxRelevance - 4
542    case mod.Indirect:
543        relevance = MaxRelevance - 3
544    case !mod.Main:
545        relevance = MaxRelevance - 2
546    default:
547        relevance = MaxRelevance - 1 // main module ties with stdlib
548    }
549
550    _versionStringok := module.SplitPathVersion(mod.Path)
551    if ok {
552        index := strings.Index(versionString"v")
553        if index == -1 {
554            return relevance
555        }
556        if versionNumbererr := strconv.ParseFloat(versionString[index+1:], 64); err == nil {
557            relevance += versionNumber / 1000
558        }
559    }
560
561    return relevance
562}
563
564// canonicalize gets the result of canonicalizing the packages using the results
565// of initializing the resolver from 'go list -m'.
566func (r *ModuleResolvercanonicalize(info directoryPackageInfo) (*pkgerror) {
567    // Packages in GOROOT are already canonical, regardless of the std/cmd modules.
568    if info.rootType == gopathwalk.RootGOROOT {
569        return &pkg{
570            importPathShortinfo.nonCanonicalImportPath,
571            dir:             info.dir,
572            packageName:     path.Base(info.nonCanonicalImportPath),
573            relevance:       MaxRelevance,
574        }, nil
575    }
576
577    importPath := info.nonCanonicalImportPath
578    mod := r.findModuleByDir(info.dir)
579    // Check if the directory is underneath a module that's in scope.
580    if mod != nil {
581        // It is. If dir is the target of a replace directive,
582        // our guessed import path is wrong. Use the real one.
583        if mod.Dir == info.dir {
584            importPath = mod.Path
585        } else {
586            dirInMod := info.dir[len(mod.Dir)+len("/"):]
587            importPath = path.Join(mod.Pathfilepath.ToSlash(dirInMod))
588        }
589    } else if !strings.HasPrefix(importPathinfo.moduleName) {
590        // The module's name doesn't match the package's import path. It
591        // probably needs a replace directive we don't have.
592        return nilfmt.Errorf("package in %q is not valid without a replace statement"info.dir)
593    }
594
595    res := &pkg{
596        importPathShortimportPath,
597        dir:             info.dir,
598        relevance:       modRelevance(mod),
599    }
600    // We may have discovered a package that has a different version
601    // in scope already. Canonicalize to that one if possible.
602    if _canonicalDir := r.findPackage(importPath); canonicalDir != "" {
603        res.dir = canonicalDir
604    }
605    return resnil
606}
607
608func (r *ModuleResolverloadExports(ctx context.Contextpkg *pkgincludeTest bool) (string, []stringerror) {
609    if err := r.init(); err != nil {
610        return ""nilerr
611    }
612    if infook := r.cacheLoad(pkg.dir); ok && !includeTest {
613        return r.cacheExports(ctxr.envinfo)
614    }
615    return loadExportsFromFiles(ctxr.envpkg.dirincludeTest)
616}
617
618func (r *ModuleResolverscanDirForPackage(root gopathwalk.Rootdir stringdirectoryPackageInfo {
619    subdir := ""
620    if dir != root.Path {
621        subdir = dir[len(root.Path)+len("/"):]
622    }
623    importPath := filepath.ToSlash(subdir)
624    if strings.HasPrefix(importPath"vendor/") {
625        // Only enter vendor directories if they're explicitly requested as a root.
626        return directoryPackageInfo{
627            statusdirectoryScanned,
628            err:    fmt.Errorf("unwanted vendor directory"),
629        }
630    }
631    switch root.Type {
632    case gopathwalk.RootCurrentModule:
633        importPath = path.Join(r.mainByDir[root.Path].Pathfilepath.ToSlash(subdir))
634    case gopathwalk.RootModuleCache:
635        matches := modCacheRegexp.FindStringSubmatch(subdir)
636        if len(matches) == 0 {
637            return directoryPackageInfo{
638                statusdirectoryScanned,
639                err:    fmt.Errorf("invalid module cache path: %v"subdir),
640            }
641        }
642        modPatherr := module.UnescapePath(filepath.ToSlash(matches[1]))
643        if err != nil {
644            if r.env.Logf != nil {
645                r.env.Logf("decoding module cache path %q: %v"subdirerr)
646            }
647            return directoryPackageInfo{
648                statusdirectoryScanned,
649                err:    fmt.Errorf("decoding module cache path %q: %v"subdirerr),
650            }
651        }
652        importPath = path.Join(modPathfilepath.ToSlash(matches[3]))
653    }
654
655    modDirmodName := r.modInfo(dir)
656    result := directoryPackageInfo{
657        status:                 directoryScanned,
658        dir:                    dir,
659        rootType:               root.Type,
660        nonCanonicalImportPathimportPath,
661        moduleDir:              modDir,
662        moduleName:             modName,
663    }
664    if root.Type == gopathwalk.RootGOROOT {
665        // stdlib packages are always in scope, despite the confusing go.mod
666        return result
667    }
668    return result
669}
670
671// modCacheRegexp splits a path in a module cache into module, module version, and package.
672var modCacheRegexp = regexp.MustCompile(`(.*)@([^/\\]*)(.*)`)
673
674var (
675    slashSlash = []byte("//")
676    moduleStr  = []byte("module")
677)
678
679// modulePath returns the module path from the gomod file text.
680// If it cannot find a module path, it returns an empty string.
681// It is tolerant of unrelated problems in the go.mod file.
682//
683// Copied from cmd/go/internal/modfile.
684func modulePath(mod []bytestring {
685    for len(mod) > 0 {
686        line := mod
687        mod = nil
688        if i := bytes.IndexByte(line'\n'); i >= 0 {
689            linemod = line[:i], line[i+1:]
690        }
691        if i := bytes.Index(lineslashSlash); i >= 0 {
692            line = line[:i]
693        }
694        line = bytes.TrimSpace(line)
695        if !bytes.HasPrefix(linemoduleStr) {
696            continue
697        }
698        line = line[len(moduleStr):]
699        n := len(line)
700        line = bytes.TrimSpace(line)
701        if len(line) == n || len(line) == 0 {
702            continue
703        }
704
705        if line[0] == '"' || line[0] == '`' {
706            perr := strconv.Unquote(string(line))
707            if err != nil {
708                return "" // malformed quoted string or multiline module path
709            }
710            return p
711        }
712
713        return string(line)
714    }
715    return "" // missing module path
716}
717
MembersX
ModuleResolver.init.err
ModuleResolver.dirIsNestedModule.r
ModuleResolver.scan.BlockStmt.pkg
ModuleResolver.init.BlockStmt.err
ModuleResolver.cacheStore.info
ModuleResolver.loadExports.pkg
ModuleResolver.scanDirForPackage.modName
ModuleResolver.findPackage.RangeStmt_6959.BlockStmt.BlockStmt.scanned
ModuleResolver.scan.roots
ModuleResolver.scanDirForPackage.BlockStmt.matches
ModuleResolver.env
ModuleResolver.moduleCacheDir
ModuleResolver.initAllMods
ModuleResolver.findPackage.RangeStmt_6959.BlockStmt.BlockStmt.loaded
ModuleResolver.loadPackageNames.err
ModuleResolver.loadExports.r
ModuleResolver.modInfo.modName
ModuleResolver.scan
ModuleResolver.cachePackageName.r
ModuleResolver.cacheExports
modRelevance.relevance
modulePath.BlockStmt.line
ModuleResolver.mains
ModuleResolver.findPackage.RangeStmt_6959.BlockStmt.pkgDir
ModuleResolver.cacheExports.info
ModuleResolver.findModuleByDir.dir
ModuleResolver.scoreImportPath._
modRelevance._
ModuleResolver.canonicalize.info
ModuleResolver.scanDirForPackage.BlockStmt.modPath
module
ModuleResolver.ClearForNewScan
ModuleResolver.loadPackageNames.RangeStmt_12057.BlockStmt._
modulePath.BlockStmt.BlockStmt.err
ModuleResolver.cacheLoad.dir
ModuleResolver.dirIsNestedModule._
ModuleResolver.modInfo.BlockStmt.modBytes
ModuleResolver.modInfo.BlockStmt.BlockStmt.modDir
ModuleResolver.scan.BlockStmt._
ModuleResolver.scan.BlockStmt.exports
modRelevance
ModuleResolver.scanDirForPackage.r
ModuleResolver.findPackage
ModuleResolver.modInfo.BlockStmt.ok
ModuleResolver.dirInModuleCache.r
modRelevance.versionString
ModuleResolver.loadExports.ok
ModuleResolver.scanDirForPackage
ModuleResolver.init.vendorEnabled
ModuleResolver.findPackage.RangeStmt_6959.BlockStmt.RangeStmt_8129.fi
ModuleResolver.cacheLoad
ModuleResolver.modInfo
ModuleResolver.scan.r
ModuleResolver.scan.err
ModuleResolver.scoreImportPath.path
ModuleResolver.canonicalize.canonicalDir
ModuleResolver.cacheLoad.info
ModuleResolver.modsByModPath
ModuleResolver.modInfo.BlockStmt.BlockStmt.index
ModuleResolver.dirInModuleCache
modRelevance.BlockStmt.versionNumber
ModuleResolver.init.BlockStmt.BlockStmt.errMsg
ModuleResolver.cachePackageName.info
ModuleResolver.findModuleByDir.RangeStmt_10022.m
ModuleResolver.scan.ctx
modRelevance.mod
ModuleResolver.modsByDir
ModuleResolver.ClearForNewScan.r
ModuleResolver.findModuleByDir
ModuleResolver.dirIsNestedModule.modDir
ModuleResolver.loadPackageNames
ModuleResolver.loadPackageNames.RangeStmt_12057.BlockStmt.name
newModuleResolver.r
ModuleResolver.modInfo.modDir
ModuleResolver.loadPackageNames.names
ModuleResolver.canonicalize.mod
ModuleResolver.loadExports.ctx
modulePath.BlockStmt.i
ModuleResolver.dummyVendorMod
ModuleResolver.init.RangeStmt_3887.main
ModuleResolver.findPackage.RangeStmt_6959.BlockStmt.ok
ModuleResolver.loadPackageNames.RangeStmt_12057.BlockStmt.packageDir
ModuleResolver.loadExports.includeTest
ModuleResolver.loadExports.err
ModuleResolver.loadExports.info
ModuleResolver.scanDirForPackage.dir
ModuleResolver.otherCache
ModuleResolver.init.BlockStmt.gopaths
ModuleResolver.initAllMods.BlockStmt.err
ModuleResolver.findPackage.RangeStmt_6959.m
ModuleResolver.findPackage.RangeStmt_6959.BlockStmt.RangeStmt_8129.BlockStmt.ok
ModuleResolver.findPackage.RangeStmt_6959.BlockStmt.RangeStmt_8129.BlockStmt._
ModuleResolver.cacheKeys
ModuleResolver.cacheExports.ctx
modRelevance.ok
ModuleResolver.mainByDir
ModuleResolver.init.inv
ModuleResolver.initAllMods.dec
ModuleResolver.ClearForNewMod
ModuleResolver.findPackage.importPath
ModuleResolver.cacheExports.env
ModuleResolver.modInfo.BlockStmt.err
modRelevance.BlockStmt.err
ModuleResolver.scanDirForPackage.result
modulePath.BlockStmt.BlockStmt.p
ModuleResolver.roots
newModuleResolver
ModuleResolver.init.goenv
ModuleResolver.init.mainModVendor
ModuleResolver.initAllMods.r
ModuleResolver.initAllMods.err
ModuleResolver.scoreImportPath.ctx
ModuleResolver.scanDirForPackage.modDir
newModuleResolver.e
ModuleResolver.findPackage.RangeStmt_6959.BlockStmt.info
ModuleResolver.dirInModuleCache.dir
ModuleResolver.loadPackageNames.importPaths
ModuleResolver.scan.BlockStmt.info
ModuleResolver.scan.scanDone
ModuleResolver.canonicalize
ModuleResolver.findPackage.RangeStmt_6959.BlockStmt.BlockStmt._
ModuleResolver.cacheLoad.ok
ModuleResolver.modInfo.BlockStmt.info
ModuleResolver.scan.stop2
ModuleResolver.scan.BlockStmt.packageScanned
ModuleResolver.init.BlockStmt.RangeStmt_4720.mod
ModuleResolver.ClearForNewMod.r
ModuleResolver.findPackage.RangeStmt_6959.BlockStmt.BlockStmt.err
ModuleResolver.findPackage.RangeStmt_6959.BlockStmt.err
ModuleResolver.cacheLoad.r
ModuleResolver.findModuleByDir.r
ModuleResolver.dirIsNestedModule
ModuleResolver.loadPackageNames.RangeStmt_12057.BlockStmt.err
ModuleResolver.scan.BlockStmt.scanned
ModuleResolver.scan.BlockStmt.err
ModuleResolver.scanDirForPackage.root
ModuleResolver.dirIsNestedModule.mod
ModuleResolver.modInfo.dir
ModuleResolver.scan.BlockStmt.RangeStmt_14711.root
ModuleResolver.scoreImportPath.r
ModuleResolver.canonicalize.res
ModuleResolver.canonicalize._
modulePath
ModuleResolver.init
ModuleResolver.initAllMods.stdout
ModuleResolver.initAllMods.BlockStmt.mod
ModuleResolver.cacheStore
ModuleResolver.modInfo.r
ModuleResolver.modInfo.BlockStmt.d
ModuleResolver.loadPackageNames.r
ModuleResolver.scan.stop1
ModuleResolver.scoreImportPath
ModuleResolver.canonicalize.importPath
ModuleResolver.moduleCacheCache
ModuleResolver.init.r
modulePath.BlockStmt.n
ModuleResolver.scannedRoots
ModuleResolver.cacheExports.r
ModuleResolver.dirIsNestedModule.dir
ModuleResolver.loadPackageNames.srcDir
ModuleResolver
ModuleResolver.init.BlockStmt.RangeStmt_4620.mod
ModuleResolver.findPackage.r
ModuleResolver.cacheStore.r
ModuleResolver.cacheKeys.r
ModuleResolver.cachePackageName
ModuleResolver.canonicalize.r
ModuleResolver.loadExports
ModuleResolver.scanDirForPackage.importPath
ModuleResolver.scanDirForPackage.BlockStmt.err
ModuleResolver.scanSema
ModuleResolver.scan.callback
ModuleResolver.scanDirForPackage.subdir
ModuleResolver.initialized
ModuleResolver.scoreImportPath.mod
modulePath.mod
ModuleResolver.findPackage.RangeStmt_6959.BlockStmt.pkgFiles
ModuleResolver.modInfo.BlockStmt.matches
ModuleResolver.modInfo.BlockStmt.f
ModuleResolver.loadPackageNames.RangeStmt_12057.path
ModuleResolver.scan.BlockStmt.ok
modRelevance.BlockStmt.index
Members
X