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