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