.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.1-0.20210319172145-bda8f5cee399 / internal / lsp / source / view.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
5 package source
6
7 import (
8         "bytes"
9         "context"
10         "fmt"
11         "go/ast"
12         "go/scanner"
13         "go/token"
14         "go/types"
15         "io"
16         "strings"
17
18         "golang.org/x/mod/modfile"
19         "golang.org/x/mod/module"
20         "golang.org/x/tools/go/analysis"
21         "golang.org/x/tools/internal/gocommand"
22         "golang.org/x/tools/internal/imports"
23         "golang.org/x/tools/internal/lsp/protocol"
24         "golang.org/x/tools/internal/span"
25         errors "golang.org/x/xerrors"
26 )
27
28 // Snapshot represents the current state for the given view.
29 type Snapshot interface {
30         ID() uint64
31
32         // View returns the View associated with this snapshot.
33         View() View
34
35         // BackgroundContext returns a context used for all background processing
36         // on behalf of this snapshot.
37         BackgroundContext() context.Context
38
39         // Fileset returns the Fileset used to parse all the Go files in this snapshot.
40         FileSet() *token.FileSet
41
42         // ValidBuildConfiguration returns true if there is some error in the
43         // user's workspace. In particular, if they are both outside of a module
44         // and their GOPATH.
45         ValidBuildConfiguration() bool
46
47         // WriteEnv writes the view-specific environment to the io.Writer.
48         WriteEnv(ctx context.Context, w io.Writer) error
49
50         // FindFile returns the FileHandle for the given URI, if it is already
51         // in the given snapshot.
52         FindFile(uri span.URI) VersionedFileHandle
53
54         // GetVersionedFile returns the VersionedFileHandle for a given URI,
55         // initializing it if it is not already part of the snapshot.
56         GetVersionedFile(ctx context.Context, uri span.URI) (VersionedFileHandle, error)
57
58         // GetFile returns the FileHandle for a given URI, initializing it if it is
59         // not already part of the snapshot.
60         GetFile(ctx context.Context, uri span.URI) (FileHandle, error)
61
62         // AwaitInitialized waits until the snapshot's view is initialized.
63         AwaitInitialized(ctx context.Context)
64
65         // IsOpen returns whether the editor currently has a file open.
66         IsOpen(uri span.URI) bool
67
68         // IgnoredFile reports if a file would be ignored by a `go list` of the whole
69         // workspace.
70         IgnoredFile(uri span.URI) bool
71
72         // ParseGo returns the parsed AST for the file.
73         // If the file is not available, returns nil and an error.
74         ParseGo(ctx context.Context, fh FileHandle, mode ParseMode) (*ParsedGoFile, error)
75
76         // PosToField is a cache of *ast.Fields by token.Pos. This allows us
77         // to quickly find corresponding *ast.Field node given a *types.Var.
78         // We must refer to the AST to render type aliases properly when
79         // formatting signatures and other types.
80         PosToField(ctx context.Context, pgf *ParsedGoFile) (map[token.Pos]*ast.Field, error)
81
82         // PosToDecl maps certain objects' positions to their surrounding
83         // ast.Decl. This mapping is used when building the documentation
84         // string for the objects.
85         PosToDecl(ctx context.Context, pgf *ParsedGoFile) (map[token.Pos]ast.Decl, error)
86
87         // DiagnosePackage returns basic diagnostics, including list, parse, and type errors
88         // for pkg, grouped by file.
89         DiagnosePackage(ctx context.Context, pkg Package) (map[span.URI][]*Diagnostic, error)
90
91         // Analyze runs the analyses for the given package at this snapshot.
92         Analyze(ctx context.Context, pkgID string, analyzers []*Analyzer) ([]*Diagnostic, error)
93
94         // RunGoCommandPiped runs the given `go` command, writing its output
95         // to stdout and stderr. Verb, Args, and WorkingDir must be specified.
96         RunGoCommandPiped(ctx context.Context, mode InvocationFlags, inv *gocommand.Invocation, stdout, stderr io.Writer) error
97
98         // RunGoCommandDirect runs the given `go` command. Verb, Args, and
99         // WorkingDir must be specified.
100         RunGoCommandDirect(ctx context.Context, mode InvocationFlags, inv *gocommand.Invocation) (*bytes.Buffer, error)
101
102         // RunGoCommands runs a series of `go` commands that updates the go.mod
103         // and go.sum file for wd, and returns their updated contents.
104         RunGoCommands(ctx context.Context, allowNetwork bool, wd string, run func(invoke func(...string) (*bytes.Buffer, error)) error) (bool, []byte, []byte, error)
105
106         // RunProcessEnvFunc runs fn with the process env for this snapshot's view.
107         // Note: the process env contains cached module and filesystem state.
108         RunProcessEnvFunc(ctx context.Context, fn func(*imports.Options) error) error
109
110         // ModFiles are the go.mod files enclosed in the snapshot's view and known
111         // to the snapshot.
112         ModFiles() []span.URI
113
114         // ParseMod is used to parse go.mod files.
115         ParseMod(ctx context.Context, fh FileHandle) (*ParsedModule, error)
116
117         // ModWhy returns the results of `go mod why` for the module specified by
118         // the given go.mod file.
119         ModWhy(ctx context.Context, fh FileHandle) (map[string]string, error)
120
121         // ModTidy returns the results of `go mod tidy` for the module specified by
122         // the given go.mod file.
123         ModTidy(ctx context.Context, pm *ParsedModule) (*TidiedModule, error)
124
125         // GoModForFile returns the URI of the go.mod file for the given URI.
126         GoModForFile(uri span.URI) span.URI
127
128         // BuiltinPackage returns information about the special builtin package.
129         BuiltinPackage(ctx context.Context) (*BuiltinPackage, error)
130
131         // PackagesForFile returns the packages that this file belongs to, checked
132         // in mode.
133         PackagesForFile(ctx context.Context, uri span.URI, mode TypecheckMode) ([]Package, error)
134
135         // PackageForFile returns a single package that this file belongs to,
136         // checked in mode and filtered by the package policy.
137         PackageForFile(ctx context.Context, uri span.URI, mode TypecheckMode, selectPackage PackageFilter) (Package, error)
138
139         // GetActiveReverseDeps returns the active files belonging to the reverse
140         // dependencies of this file's package, checked in TypecheckWorkspace mode.
141         GetReverseDependencies(ctx context.Context, id string) ([]Package, error)
142
143         // CachedImportPaths returns all the imported packages loaded in this
144         // snapshot, indexed by their import path and checked in TypecheckWorkspace
145         // mode.
146         CachedImportPaths(ctx context.Context) (map[string]Package, error)
147
148         // KnownPackages returns all the packages loaded in this snapshot, checked
149         // in TypecheckWorkspace mode.
150         KnownPackages(ctx context.Context) ([]Package, error)
151
152         // WorkspacePackages returns the snapshot's top-level packages.
153         WorkspacePackages(ctx context.Context) ([]Package, error)
154
155         // GetCriticalError returns any critical errors in the workspace.
156         GetCriticalError(ctx context.Context) *CriticalError
157 }
158
159 // PackageFilter sets how a package is filtered out from a set of packages
160 // containing a given file.
161 type PackageFilter int
162
163 const (
164         // NarrowestPackage picks the "narrowest" package for a given file.
165         // By "narrowest" package, we mean the package with the fewest number of
166         // files that includes the given file. This solves the problem of test
167         // variants, as the test will have more files than the non-test package.
168         NarrowestPackage PackageFilter = iota
169
170         // WidestPackage returns the Package containing the most files.
171         // This is useful for something like diagnostics, where we'd prefer to
172         // offer diagnostics for as many files as possible.
173         WidestPackage
174 )
175
176 // InvocationFlags represents the settings of a particular go command invocation.
177 // It is a mode, plus a set of flag bits.
178 type InvocationFlags int
179
180 const (
181         // Normal is appropriate for commands that might be run by a user and don't
182         // deliberately modify go.mod files, e.g. `go test`.
183         Normal InvocationFlags = iota
184         // UpdateUserModFile is for commands that intend to update the user's real
185         // go.mod file, e.g. `go mod tidy` in response to a user's request to tidy.
186         UpdateUserModFile
187         // WriteTemporaryModFile is for commands that need information from a
188         // modified version of the user's go.mod file, e.g. `go mod tidy` used to
189         // generate diagnostics.
190         WriteTemporaryModFile
191         // LoadWorkspace is for packages.Load, and other operations that should
192         // consider the whole workspace at once.
193         LoadWorkspace
194
195         // AllowNetwork is a flag bit that indicates the invocation should be
196         // allowed to access the network.
197         AllowNetwork InvocationFlags = 1 << 10
198 )
199
200 func (m InvocationFlags) Mode() InvocationFlags {
201         return m & (AllowNetwork - 1)
202 }
203
204 func (m InvocationFlags) AllowNetwork() bool {
205         return m&AllowNetwork != 0
206 }
207
208 // View represents a single workspace.
209 // This is the level at which we maintain configuration like working directory
210 // and build tags.
211 type View interface {
212         // Name returns the name this view was constructed with.
213         Name() string
214
215         // Folder returns the folder with which this view was created.
216         Folder() span.URI
217
218         // Shutdown closes this view, and detaches it from its session.
219         Shutdown(ctx context.Context)
220
221         // Options returns a copy of the Options for this view.
222         Options() *Options
223
224         // SetOptions sets the options of this view to new values.
225         // Calling this may cause the view to be invalidated and a replacement view
226         // added to the session. If so the new view will be returned, otherwise the
227         // original one will be.
228         SetOptions(context.Context, *Options) (View, error)
229
230         // Snapshot returns the current snapshot for the view.
231         Snapshot(ctx context.Context) (Snapshot, func())
232
233         // Rebuild rebuilds the current view, replacing the original view in its session.
234         Rebuild(ctx context.Context) (Snapshot, func(), error)
235
236         // IsGoPrivatePath reports whether target is a private import path, as identified
237         // by the GOPRIVATE environment variable.
238         IsGoPrivatePath(path string) bool
239
240         // ModuleUpgrades returns known module upgrades.
241         ModuleUpgrades() map[string]string
242
243         // RegisterModuleUpgrades registers that upgrades exist for the given modules.
244         RegisterModuleUpgrades(upgrades map[string]string)
245 }
246
247 // A FileSource maps uris to FileHandles. This abstraction exists both for
248 // testability, and so that algorithms can be run equally on session and
249 // snapshot files.
250 type FileSource interface {
251         // GetFile returns the FileHandle for a given URI.
252         GetFile(ctx context.Context, uri span.URI) (FileHandle, error)
253 }
254
255 type BuiltinPackage struct {
256         Package    *ast.Package
257         ParsedFile *ParsedGoFile
258 }
259
260 // A ParsedGoFile contains the results of parsing a Go file.
261 type ParsedGoFile struct {
262         URI  span.URI
263         Mode ParseMode
264         File *ast.File
265         Tok  *token.File
266         // Source code used to build the AST. It may be different from the
267         // actual content of the file if we have fixed the AST.
268         Src      []byte
269         Mapper   *protocol.ColumnMapper
270         ParseErr scanner.ErrorList
271 }
272
273 // A ParsedModule contains the results of parsing a go.mod file.
274 type ParsedModule struct {
275         URI         span.URI
276         File        *modfile.File
277         Mapper      *protocol.ColumnMapper
278         ParseErrors []*Diagnostic
279 }
280
281 // A TidiedModule contains the results of running `go mod tidy` on a module.
282 type TidiedModule struct {
283         // Diagnostics representing changes made by `go mod tidy`.
284         Diagnostics []*Diagnostic
285         // The bytes of the go.mod file after it was tidied.
286         TidiedContent []byte
287 }
288
289 // Session represents a single connection from a client.
290 // This is the level at which things like open files are maintained on behalf
291 // of the client.
292 // A session may have many active views at any given time.
293 type Session interface {
294         // NewView creates a new View, returning it and its first snapshot.
295         NewView(ctx context.Context, name string, folder, tempWorkspaceDir span.URI, options *Options) (View, Snapshot, func(), error)
296
297         // Cache returns the cache that created this session, for debugging only.
298         Cache() interface{}
299
300         // View returns a view with a matching name, if the session has one.
301         View(name string) View
302
303         // ViewOf returns a view corresponding to the given URI.
304         ViewOf(uri span.URI) (View, error)
305
306         // Views returns the set of active views built by this session.
307         Views() []View
308
309         // Shutdown the session and all views it has created.
310         Shutdown(ctx context.Context)
311
312         // GetFile returns a handle for the specified file.
313         GetFile(ctx context.Context, uri span.URI) (FileHandle, error)
314
315         // DidModifyFile reports a file modification to the session. It returns
316         // the new snapshots after the modifications have been applied, paired with
317         // the affected file URIs for those snapshots.
318         DidModifyFiles(ctx context.Context, changes []FileModification) (map[Snapshot][]span.URI, []func(), error)
319
320         // ExpandModificationsToDirectories returns the set of changes with the
321         // directory changes removed and expanded to include all of the files in
322         // the directory.
323         ExpandModificationsToDirectories(ctx context.Context, changes []FileModification) []FileModification
324
325         // Overlays returns a slice of file overlays for the session.
326         Overlays() []Overlay
327
328         // Options returns a copy of the SessionOptions for this session.
329         Options() *Options
330
331         // SetOptions sets the options of this session to new values.
332         SetOptions(*Options)
333
334         // FileWatchingGlobPatterns returns glob patterns to watch every directory
335         // known by the view. For views within a module, this is the module root,
336         // any directory in the module root, and any replace targets.
337         FileWatchingGlobPatterns(ctx context.Context) map[string]struct{}
338 }
339
340 // Overlay is the type for a file held in memory on a session.
341 type Overlay interface {
342         VersionedFileHandle
343 }
344
345 // FileModification represents a modification to a file.
346 type FileModification struct {
347         URI    span.URI
348         Action FileAction
349
350         // OnDisk is true if a watched file is changed on disk.
351         // If true, Version will be -1 and Text will be nil.
352         OnDisk bool
353
354         // Version will be -1 and Text will be nil when they are not supplied,
355         // specifically on textDocument/didClose and for on-disk changes.
356         Version int32
357         Text    []byte
358
359         // LanguageID is only sent from the language client on textDocument/didOpen.
360         LanguageID string
361 }
362
363 type FileAction int
364
365 const (
366         UnknownFileAction = FileAction(iota)
367         Open
368         Change
369         Close
370         Save
371         Create
372         Delete
373         InvalidateMetadata
374 )
375
376 func (a FileAction) String() string {
377         switch a {
378         case Open:
379                 return "Open"
380         case Change:
381                 return "Change"
382         case Close:
383                 return "Close"
384         case Save:
385                 return "Save"
386         case Create:
387                 return "Create"
388         case Delete:
389                 return "Delete"
390         case InvalidateMetadata:
391                 return "InvalidateMetadata"
392         default:
393                 return "Unknown"
394         }
395 }
396
397 var ErrTmpModfileUnsupported = errors.New("-modfile is unsupported for this Go version")
398 var ErrNoModOnDisk = errors.New("go.mod file is not on disk")
399
400 func IsNonFatalGoModError(err error) bool {
401         return err == ErrTmpModfileUnsupported || err == ErrNoModOnDisk
402 }
403
404 // ParseMode controls the content of the AST produced when parsing a source file.
405 type ParseMode int
406
407 const (
408         // ParseHeader specifies that the main package declaration and imports are needed.
409         // This is the mode used when attempting to examine the package graph structure.
410         ParseHeader ParseMode = iota
411
412         // ParseExported specifies that the public symbols are needed, but things like
413         // private symbols and function bodies are not.
414         // This mode is used for things where a package is being consumed only as a
415         // dependency.
416         ParseExported
417
418         // ParseFull specifies the full AST is needed.
419         // This is used for files of direct interest where the entire contents must
420         // be considered.
421         ParseFull
422 )
423
424 // TypecheckMode controls what kind of parsing should be done (see ParseMode)
425 // while type checking a package.
426 type TypecheckMode int
427
428 const (
429         // Invalid default value.
430         TypecheckUnknown TypecheckMode = iota
431         // TypecheckFull means to use ParseFull.
432         TypecheckFull
433         // TypecheckWorkspace means to use ParseFull for workspace packages, and
434         // ParseExported for others.
435         TypecheckWorkspace
436         // TypecheckAll means ParseFull for workspace packages, and both Full and
437         // Exported for others. Only valid for some functions.
438         TypecheckAll
439 )
440
441 type VersionedFileHandle interface {
442         FileHandle
443         Version() int32
444         Session() string
445
446         // LSPIdentity returns the version identity of a file.
447         VersionedFileIdentity() VersionedFileIdentity
448 }
449
450 type VersionedFileIdentity struct {
451         URI span.URI
452
453         // SessionID is the ID of the LSP session.
454         SessionID string
455
456         // Version is the version of the file, as specified by the client. It should
457         // only be set in combination with SessionID.
458         Version int32
459 }
460
461 // FileHandle represents a handle to a specific version of a single file.
462 type FileHandle interface {
463         URI() span.URI
464         Kind() FileKind
465
466         // FileIdentity returns a FileIdentity for the file, even if there was an
467         // error reading it.
468         FileIdentity() FileIdentity
469         // Read reads the contents of a file.
470         // If the file is not available, returns a nil slice and an error.
471         Read() ([]byte, error)
472         // Saved reports whether the file has the same content on disk.
473         Saved() bool
474 }
475
476 // FileIdentity uniquely identifies a file at a version from a FileSystem.
477 type FileIdentity struct {
478         URI span.URI
479
480         // Identifier represents a unique identifier for the file's content.
481         Hash string
482
483         // Kind is the file's kind.
484         Kind FileKind
485 }
486
487 func (id FileIdentity) String() string {
488         return fmt.Sprintf("%s%s%s", id.URI, id.Hash, id.Kind)
489 }
490
491 // FileKind describes the kind of the file in question.
492 // It can be one of Go, mod, or sum.
493 type FileKind int
494
495 const (
496         // UnknownKind is a file type we don't know about.
497         UnknownKind = FileKind(iota)
498
499         // Go is a normal go source file.
500         Go
501         // Mod is a go.mod file.
502         Mod
503         // Sum is a go.sum file.
504         Sum
505 )
506
507 // Analyzer represents a go/analysis analyzer with some boolean properties
508 // that let the user know how to use the analyzer.
509 type Analyzer struct {
510         Analyzer *analysis.Analyzer
511
512         // Enabled reports whether the analyzer is enabled. This value can be
513         // configured per-analysis in user settings. For staticcheck analyzers,
514         // the value of the Staticcheck setting overrides this field.
515         Enabled bool
516
517         // Fix is the name of the suggested fix name used to invoke the suggested
518         // fixes for the analyzer. It is non-empty if we expect this analyzer to
519         // provide its fix separately from its diagnostics. That is, we should apply
520         // the analyzer's suggested fixes through a Command, not a TextEdit.
521         Fix string
522
523         // ActionKind is the kind of code action this analyzer produces. If
524         // unspecified the type defaults to quickfix.
525         ActionKind protocol.CodeActionKind
526 }
527
528 func (a Analyzer) IsEnabled(view View) bool {
529         // Staticcheck analyzers can only be enabled when staticcheck is on.
530         if _, ok := view.Options().StaticcheckAnalyzers[a.Analyzer.Name]; ok {
531                 if !view.Options().Staticcheck {
532                         return false
533                 }
534         }
535         if enabled, ok := view.Options().Analyses[a.Analyzer.Name]; ok {
536                 return enabled
537         }
538         return a.Enabled
539 }
540
541 // Package represents a Go package that has been type-checked. It maintains
542 // only the relevant fields of a *go/packages.Package.
543 type Package interface {
544         ID() string
545         Name() string
546         PkgPath() string
547         CompiledGoFiles() []*ParsedGoFile
548         File(uri span.URI) (*ParsedGoFile, error)
549         GetSyntax() []*ast.File
550         GetTypes() *types.Package
551         GetTypesInfo() *types.Info
552         GetTypesSizes() types.Sizes
553         IsIllTyped() bool
554         ForTest() string
555         GetImport(pkgPath string) (Package, error)
556         MissingDependencies() []string
557         Imports() []Package
558         Version() *module.Version
559         HasListOrParseErrors() bool
560         HasTypeErrors() bool
561 }
562
563 type CriticalError struct {
564         // MainError is the primary error. Must be non-nil.
565         MainError error
566         // DiagList contains any supplemental (structured) diagnostics.
567         DiagList []*Diagnostic
568 }
569
570 // An Diagnostic corresponds to an LSP Diagnostic.
571 // https://microsoft.github.io/language-server-protocol/specification#diagnostic
572 type Diagnostic struct {
573         URI      span.URI
574         Range    protocol.Range
575         Severity protocol.DiagnosticSeverity
576         Code     string
577         CodeHref string
578
579         // Source is a human-readable description of the source of the error.
580         // Diagnostics generated by an analysis.Analyzer set it to Analyzer.Name.
581         Source DiagnosticSource
582
583         Message string
584
585         Tags    []protocol.DiagnosticTag
586         Related []RelatedInformation
587
588         // Fields below are used internally to generate quick fixes. They aren't
589         // part of the LSP spec and don't leave the server.
590         SuggestedFixes []SuggestedFix
591         Analyzer       *Analyzer
592 }
593
594 type DiagnosticSource string
595
596 const (
597         UnknownError             DiagnosticSource = "<Unknown source>"
598         ListError                DiagnosticSource = "go list"
599         ParseError               DiagnosticSource = "syntax"
600         TypeError                DiagnosticSource = "compiler"
601         ModTidyError             DiagnosticSource = "go mod tidy"
602         OptimizationDetailsError DiagnosticSource = "optimizer details"
603         UpgradeNotification      DiagnosticSource = "upgrade available"
604 )
605
606 func AnalyzerErrorKind(name string) DiagnosticSource {
607         return DiagnosticSource(name)
608 }
609
610 var (
611         PackagesLoadError = errors.New("packages.Load error")
612 )
613
614 // WorkspaceModuleVersion is the nonexistent pseudoversion suffix used in the
615 // construction of the workspace module. It is exported so that we can make
616 // sure not to show this version to end users in error messages, to avoid
617 // confusion.
618 // The major version is not included, as that depends on the module path.
619 //
620 // If workspace module A is dependent on workspace module B, we need our
621 // nonexistant version to be greater than the version A mentions.
622 // Otherwise, the go command will try to update to that version. Use a very
623 // high minor version to make that more likely.
624 const workspaceModuleVersion = ".9999999.0-goplsworkspace"
625
626 func IsWorkspaceModuleVersion(version string) bool {
627         return strings.HasSuffix(version, workspaceModuleVersion)
628 }
629
630 func WorkspaceModuleVersion(majorVersion string) string {
631         // Use the highest compatible major version to avoid unwanted upgrades.
632         // See the comment on workspaceModuleVersion.
633         if majorVersion == "v0" {
634                 majorVersion = "v1"
635         }
636         return majorVersion + workspaceModuleVersion
637 }