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