| // Copyright 2021 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| //go:generate go run -tags=generate generate.go | |
| // Package command defines the interface provided by gopls for the | |
| // workspace/executeCommand LSP request. | |
| // | |
| // This interface is fully specified by the Interface type, provided it | |
| // conforms to the restrictions outlined in its doc string. | |
| // | |
| // Bindings for server-side command dispatch and client-side serialization are | |
| // also provided by this package, via code generation. | |
| package command | |
| import ( | |
| "context" | |
| "encoding/json" | |
| "errors" | |
| "fmt" | |
| "golang.org/x/tools/gopls/internal/protocol" | |
| "golang.org/x/tools/gopls/internal/vulncheck" | |
| ) | |
| // ErrPendingAnswer reports that a command asked the user something and the | |
| // answer has not arrived. It is not a failure: the command has done nothing | |
| // yet, and runs again once the user has answered. | |
| // | |
| // The questions travel in the command's [*protocol.InteractiveParams]; see the | |
| // [Interface] contract below, and [protocol.Server.ResolveCommand] for the | |
| // handshake that collects the answers. | |
| var ErrPendingAnswer = errors.New("waiting for an answer") | |
| // Interface defines the interface gopls exposes for the | |
| // workspace/executeCommand request. | |
| // | |
| // This interface is used to generate logic for marshaling, | |
| // unmarshaling, and dispatch, so it has some additional restrictions: | |
| // | |
| // 1. All method arguments must be JSON serializable and strictly typed | |
| // (infallible) so they can be safely unmarshaled from the JSON | |
| // Arguments array. The only exception is the final input parameter, | |
| // which may be exactly [*protocol.InteractiveParams]. While this type | |
| // contains an 'any' slice, it is explicitly exempted by the code | |
| // generator because it is passed directly from the top-level | |
| // ExecuteCommandParams rather than unmarshaled from the Arguments | |
| // array. Its dynamic values are validated manually by the command | |
| // handlers at runtime. | |
| // | |
| // 2. Methods must return either error or (T, error), where T is a | |
| // JSON serializable type. | |
| // | |
| // T may instead be [Action], in which case the method reports no result | |
| // to the client: the Action is performed by the dispatcher and is not | |
| // marshaled. A command whose T is an Action must not mutate the user's | |
| // workspace itself -- it must not apply edits or reveal documents -- but | |
| // return an Action that does so. See [Action]. | |
| // | |
| // A command that cannot proceed until the user has answered something | |
| // asks through its [*protocol.InteractiveParams] and returns | |
| // [ErrPendingAnswer]. Asking is not a failure: the command has done | |
| // nothing yet, and runs again once the answers arrive. | |
| // | |
| // 3. The first line of the doc string is special. | |
| // Everything after the colon is considered the command 'Title'. | |
| // For example: | |
| // | |
| // Command: Capitalized verb phrase with no period | |
| // | |
| // Longer description here... | |
| type Interface interface { | |
| // ApplyFix: Apply a fix | |
| // | |
| // Applies a fix to a region of source code. | |
| ApplyFix(context.Context, ApplyFixArgs) (*protocol.WorkspaceEdit, error) | |
| // RunTests: Run tests | |
| // | |
| // Runs `go test` for a specific set of test or benchmark functions. | |
| // | |
| // This command is asynchronous; clients must wait for the 'end' progress notification. | |
| RunTests(context.Context, RunTestsArgs) error | |
| // Generate: Run go generate | |
| // | |
| // Runs `go generate` for a given directory. | |
| Generate(context.Context, GenerateArgs) error | |
| // Doc: Browse package documentation. | |
| // | |
| // Opens the Go package documentation page for the current | |
| // package in a browser. | |
| Doc(context.Context, DocArgs) (protocol.URI, error) | |
| // SplitPackage: organize a package into two or more components | |
| // | |
| // Opens the "split package" tool in a web browser. | |
| SplitPackage(ctx context.Context, viewID, packageID string) error | |
| // RegenerateCgo: Regenerate cgo | |
| // | |
| // Regenerates cgo definitions. | |
| RegenerateCgo(context.Context, URIArg) error | |
| // Tidy: Run go mod tidy | |
| // | |
| // Runs `go mod tidy` for a module. | |
| Tidy(context.Context, URIArgs) error | |
| // Vendor: Run go mod vendor | |
| // | |
| // Runs `go mod vendor` for a module. | |
| Vendor(context.Context, URIArg) error | |
| // EditGoDirective: Run go mod edit -go=version | |
| // | |
| // Runs `go mod edit -go=version` for a module. | |
| EditGoDirective(context.Context, EditGoDirectiveArgs) error | |
| // UpdateGoSum: Update go.sum | |
| // | |
| // Updates the go.sum file for a module. | |
| UpdateGoSum(context.Context, URIArgs) error | |
| // CheckUpgrades: Check for upgrades | |
| // | |
| // Checks for module upgrades. | |
| CheckUpgrades(context.Context, CheckUpgradesArgs) error | |
| // AddDependency: Add a dependency | |
| // | |
| // Adds a dependency to the go.mod file for a module. | |
| AddDependency(context.Context, DependencyArgs) error | |
| // UpgradeDependency: Upgrade a dependency | |
| // | |
| // Upgrades a dependency in the go.mod file for a module. | |
| UpgradeDependency(context.Context, DependencyArgs) error | |
| // RemoveDependency: Remove a dependency | |
| // | |
| // Removes a dependency from the go.mod file of a module. | |
| RemoveDependency(context.Context, RemoveDependencyArgs) error | |
| // ResetGoModDiagnostics: Reset go.mod diagnostics | |
| // | |
| // Reset diagnostics in the go.mod file of a module. | |
| ResetGoModDiagnostics(context.Context, ResetGoModDiagnosticsArgs) error | |
| // GoGetPackage: 'go get' a package | |
| // | |
| // Runs `go get` to fetch a package. | |
| GoGetPackage(context.Context, GoGetPackageArgs) error | |
| // GCDetails: Toggle display of compiler optimization details | |
| // | |
| // Toggle the per-package flag that causes Go compiler | |
| // optimization decisions to be reported as diagnostics. | |
| // | |
| // (The name is a legacy of a time when the Go compiler was | |
| // known as "gc". Renaming the command would break custom | |
| // client-side logic in VS Code.) | |
| GCDetails(context.Context, protocol.DocumentURI) error | |
| // LSP is a command that functions as a generic dispatcher, allowing clients | |
| // to execute any LSP RPC through the "workspace/executeCommand" request. | |
| // | |
| // This serves two primary purposes: | |
| // | |
| // 1. It provides a unified endpoint for clients that are restricted from | |
| // making arbitrary LSP calls directly, giving them full access to the | |
| // server's capabilities. | |
| // | |
| // 2. It allows the client and server to extend the standard protocol. A | |
| // client can send custom parameters that are not part of the official | |
| // LSP, enabling richer functionality. | |
| // | |
| // The command takes the target LSP method name and its parameters as a | |
| // [json.RawMessage], routing the call to the appropriate internal handler. | |
| LSP(context.Context, LSPArgs) (any, error) | |
| // ListKnownPackages: List known packages | |
| // | |
| // Retrieve a list of packages that are importable from the given URI. | |
| ListKnownPackages(context.Context, URIArg) (ListKnownPackagesResult, error) | |
| // ListImports: List imports of a file and its package | |
| // | |
| // Retrieve a list of imports in the given Go file, and the package it | |
| // belongs to. | |
| ListImports(context.Context, URIArg) (ListImportsResult, error) | |
| // AddImport: Add an import | |
| // | |
| // Ask the server to add an import path to a given Go file. The method will | |
| // call applyEdit on the client so that clients don't have to apply the edit | |
| // themselves. | |
| AddImport(context.Context, AddImportArgs) error | |
| // ExtractToNewFile: Move selected declarations to a new file | |
| // | |
| // Used by the code action of the same name. | |
| ExtractToNewFile(context.Context, protocol.Location) error | |
| // StartDebugging: Start the gopls debug server | |
| // | |
| // Start the gopls debug server if it isn't running, and return the debug | |
| // address. | |
| StartDebugging(context.Context, DebuggingArgs) (DebuggingResult, error) | |
| // StartProfile: Start capturing a profile of gopls' execution | |
| // | |
| // Start a new pprof profile. Before using the resulting file, profiling must | |
| // be stopped with a corresponding call to StopProfile. | |
| // | |
| // This command is intended for internal use only, by the gopls benchmark | |
| // runner. | |
| StartProfile(context.Context, StartProfileArgs) (StartProfileResult, error) | |
| // StopProfile: Stop an ongoing profile | |
| // | |
| // This command is intended for internal use only, by the gopls benchmark | |
| // runner. | |
| StopProfile(context.Context, StopProfileArgs) (StopProfileResult, error) | |
| // Vulncheck: run vulncheck synchronously. | |
| // | |
| // Run vulnerability check (`govulncheck`). | |
| // | |
| // This command is synchronous, and returns the govulncheck result. | |
| Vulncheck(context.Context, VulncheckArgs) (VulncheckResult, error) | |
| // RunGovulncheck: Run vulncheck asynchronously. | |
| // | |
| // Run vulnerability check (`govulncheck`). | |
| // | |
| // This command is asynchronous; clients must wait for the 'end' progress | |
| // notification and then retrieve results using gopls.fetch_vulncheck_result. | |
| // | |
| // Deprecated: clients should call gopls.vulncheck instead, which returns the | |
| // actual vulncheck result. | |
| RunGovulncheck(context.Context, VulncheckArgs) (RunVulncheckResult, error) | |
| // FetchVulncheckResult: Get known vulncheck result | |
| // | |
| // Fetch the result of latest vulnerability check (`govulncheck`). | |
| // | |
| // Deprecated: clients should call gopls.vulncheck instead, which returns the | |
| // actual vulncheck result. | |
| FetchVulncheckResult(context.Context, URIArg) (map[protocol.DocumentURI]*vulncheck.Result, error) | |
| // MemStats: Fetch memory statistics | |
| // | |
| // Call runtime.GC multiple times and return memory statistics as reported by | |
| // runtime.MemStats. | |
| // | |
| // This command is used for benchmarking, and may change in the future. | |
| MemStats(context.Context) (MemStatsResult, error) | |
| // WorkspaceStats: Fetch workspace statistics | |
| // | |
| // Query statistics about workspace builds, modules, packages, and files. | |
| // | |
| // This command is intended for internal use only, by the gopls stats | |
| // command. | |
| WorkspaceStats(context.Context) (WorkspaceStatsResult, error) | |
| // RunGoWorkCommand: Run `go work [args...]`, and apply the resulting go.work | |
| // edits to the current go.work file | |
| RunGoWorkCommand(context.Context, RunGoWorkArgs) error | |
| // AddTelemetryCounters: Update the given telemetry counters | |
| // | |
| // Gopls will prepend "fwd/" to all the counters updated using this command | |
| // to avoid conflicts with other counters gopls collects. | |
| AddTelemetryCounters(context.Context, AddTelemetryCountersArgs) error | |
| // AddTest: add test for the selected function | |
| AddTest(context.Context, protocol.Location) (*protocol.WorkspaceEdit, error) | |
| // MaybePromptForTelemetry: Prompt user to enable telemetry | |
| // | |
| // Checks for the right conditions, and then prompts the user | |
| // to ask if they want to enable Go telemetry uploading. If | |
| // the user responds 'Yes', the telemetry mode is set to "on". | |
| MaybePromptForTelemetry(context.Context) error | |
| // ChangeSignature: Perform a "change signature" refactoring | |
| // | |
| // This command is experimental, currently only supporting parameter removal. | |
| // Its signature will certainly change in the future (pun intended). | |
| ChangeSignature(context.Context, ChangeSignatureArgs) (*protocol.WorkspaceEdit, error) | |
| // DiagnoseFiles: Cause server to publish diagnostics for the specified files. | |
| // | |
| // This command is needed by the 'gopls {check,fix}' CLI subcommands. | |
| DiagnoseFiles(context.Context, DiagnoseFilesArgs) error | |
| // Views: List current Views on the server. | |
| // | |
| // This command is intended for use by gopls tests only. | |
| Views(context.Context) ([]View, error) | |
| // FreeSymbols: Browse free symbols referenced by the selection in a browser. | |
| // | |
| // This command is a query over a selected range of Go source | |
| // code. It reports the set of "free" symbols of the | |
| // selection: the set of symbols that are referenced within | |
| // the selection but are declared outside of it. This | |
| // information is useful for understanding at a glance what a | |
| // block of code depends on, perhaps as a precursor to | |
| // extracting it into a separate function. | |
| FreeSymbols(ctx context.Context, viewID string, loc protocol.Location) error | |
| // Assembly: Browse assembly listing of current function in a browser. | |
| // | |
| // This command opens a web-based disassembly listing of the | |
| // specified function symbol (plus any nested lambdas and defers). | |
| // The machine architecture is determined by the view. | |
| Assembly(_ context.Context, viewID, packageID, symbol string) error | |
| // ClientOpenURL: Request that the client open a URL in a browser. | |
| ClientOpenURL(_ context.Context, url string) error | |
| // ScanImports: force a synchronous scan of the imports cache. | |
| // | |
| // This command is intended for use by gopls tests only. | |
| ScanImports(context.Context) error | |
| // Packages: Return information about packages | |
| // | |
| // This command returns an empty result if the specified files | |
| // or directories are not associated with any Views on the | |
| // server yet. | |
| Packages(context.Context, PackagesArgs) (PackagesResult, error) | |
| // Modules: Return information about modules within a directory | |
| // | |
| // This command returns an empty result if there is no module, or if module | |
| // mode is disabled. Modules will not cause any new views to be loaded and | |
| // will only return modules associated with views that have already been | |
| // loaded, regardless of how it is called. Given current usage (by the | |
| // language server client), there should never be a case where Modules is | |
| // called on a path that has not already been loaded. | |
| Modules(context.Context, ModulesArgs) (ModulesResult, error) | |
| // ResolveTarget: Resolve a target query to it's definition. | |
| // | |
| // This command will resolve targets for the closest & longest matching | |
| // package in the workspace, returning multiple only if there is unresolvable | |
| // ambiguity. | |
| // | |
| // See here for a full description of the query logic: | |
| // https://go.dev/gopls/design/design/gopls-cli#target-symbol-resolution | |
| ResolveTarget(context.Context, ResolveTargetParams) (ResolveTargetResult, error) | |
| // PackageSymbols: Return information about symbols in the given file's package. | |
| PackageSymbols(context.Context, PackageSymbolsArgs) (PackageSymbolsResult, error) | |
| // ModifyTags: Add or remove struct tags on a given node. | |
| ModifyTags(context.Context, ModifyTagsArgs, *protocol.InteractiveParams) (Action, error) | |
| // MoveType: Move a type declaration to a different package. | |
| MoveType(context.Context, MoveTypeArgs) error | |
| // ImplementInterface: Add methods to a type to implement an interface. | |
| ImplementInterface(context.Context, ImplementInterfaceArgs, *protocol.InteractiveParams) (Action, error) | |
| // MoveDeclaration: Move a declaration to a different file. | |
| MoveDeclaration(context.Context, MoveDeclarationArgs, *protocol.InteractiveParams) (Action, error) | |
| // DragonSlayer: Slay the dragon | |
| // | |
| // Plays a tiny adventure game demonstrating interactive refactoring. | |
| DragonSlayer(context.Context, DragonSlayerArgs, *protocol.InteractiveParams) (Action, error) | |
| } | |
| type RunTestsArgs struct { | |
| // The test file containing the tests to run. | |
| URI protocol.DocumentURI | |
| // Specific test names to run, e.g. TestFoo. | |
| Tests []string | |
| // Specific benchmarks to run, e.g. BenchmarkFoo. | |
| Benchmarks []string | |
| } | |
| type GenerateArgs struct { | |
| // URI for the directory to generate. | |
| Dir protocol.DocumentURI | |
| // Whether to generate recursively (go generate ./...) | |
| Recursive bool | |
| } | |
| type DocArgs struct { | |
| Location protocol.Location | |
| ShowDocument bool // in addition to returning the URL, send showDocument | |
| } | |
| // TODO(rFindley): document the rest of these once the docgen is fleshed out. | |
| type ApplyFixArgs struct { | |
| // The name of the fix to apply. | |
| // | |
| // For fixes suggested by analyzers, this is a string constant | |
| // advertised by the analyzer that matches the Category of | |
| // the analysis.Diagnostic with a SuggestedFix containing no edits. | |
| // | |
| // For fixes suggested by code actions, this is a string agreed | |
| // upon by the code action and golang.ApplyFix. | |
| Fix string | |
| // The portion of the document to fix. | |
| Location protocol.Location | |
| // Whether to resolve and return the edits. | |
| ResolveEdits bool | |
| } | |
| type URIArg struct { | |
| // The file URI. | |
| URI protocol.DocumentURI | |
| } | |
| type URIArgs struct { | |
| // The file URIs. | |
| URIs []protocol.DocumentURI | |
| } | |
| type CheckUpgradesArgs struct { | |
| // The go.mod file URI. | |
| URI protocol.DocumentURI | |
| // The modules to check. | |
| Modules []string | |
| } | |
| type DependencyArgs struct { | |
| // The go.mod file URI. | |
| URI protocol.DocumentURI | |
| // Additional args to pass to the go command. | |
| GoCmdArgs []string | |
| // Whether to add a require directive. | |
| AddRequire bool | |
| } | |
| type RemoveDependencyArgs struct { | |
| // The go.mod file URI. | |
| URI protocol.DocumentURI | |
| // The module path to remove. | |
| ModulePath string | |
| // If the module is tidied apart from the one unused diagnostic, we can | |
| // run `go get module@none`, and then run `go mod tidy`. Otherwise, we | |
| // must make textual edits. | |
| OnlyDiagnostic bool | |
| } | |
| type EditGoDirectiveArgs struct { | |
| // Any document URI within the relevant module. | |
| URI protocol.DocumentURI | |
| // The version to pass to `go mod edit -go`. | |
| Version string | |
| } | |
| type GoGetPackageArgs struct { | |
| // Any document URI within the relevant module. | |
| URI protocol.DocumentURI | |
| // The package to go get. | |
| Pkg string | |
| AddRequire bool | |
| } | |
| type AddImportArgs struct { | |
| // ImportPath is the target import path that should | |
| // be added to the URI file | |
| ImportPath string | |
| // URI is the file that the ImportPath should be | |
| // added to | |
| URI protocol.DocumentURI | |
| } | |
| type ListKnownPackagesResult struct { | |
| // Packages is a list of packages relative | |
| // to the URIArg passed by the command request. | |
| // In other words, it omits paths that are already | |
| // imported or cannot be imported due to compiler | |
| // restrictions. | |
| Packages []string | |
| } | |
| type ListImportsResult struct { | |
| // Imports is a list of imports in the requested file. | |
| Imports []FileImport | |
| // PackageImports is a list of all imports in the requested file's package. | |
| PackageImports []PackageImport | |
| } | |
| type FileImport struct { | |
| // Path is the import path of the import. | |
| Path string | |
| // Name is the name of the import, e.g. `foo` in `import foo "strings"`. | |
| Name string | |
| } | |
| type PackageImport struct { | |
| // Path is the import path of the import. | |
| Path string | |
| } | |
| type DebuggingArgs struct { | |
| // Optional: the address (including port) for the debug server to listen on. | |
| // If not provided, the debug server will bind to "localhost:0", and the | |
| // full debug URL will be contained in the result. | |
| // | |
| // If there is more than one gopls instance along the serving path (i.e. you | |
| // are using a daemon), each gopls instance will attempt to start debugging. | |
| // If Addr specifies a port, only the daemon will be able to bind to that | |
| // port, and each intermediate gopls instance will fail to start debugging. | |
| // For this reason it is recommended not to specify a port (or equivalently, | |
| // to specify ":0"). | |
| // | |
| // If the server was already debugging this field has no effect, and the | |
| // result will contain the previously configured debug URL(s). | |
| Addr string | |
| } | |
| type DebuggingResult struct { | |
| // The URLs to use to access the debug servers, for all gopls instances in | |
| // the serving path. For the common case of a single gopls instance (i.e. no | |
| // daemon), this will be exactly one address. | |
| // | |
| // In the case of one or more gopls instances forwarding the LSP to a daemon, | |
| // URLs will contain debug addresses for each server in the serving path, in | |
| // serving order. The daemon debug address will be the last entry in the | |
| // slice. If any intermediate gopls instance fails to start debugging, no | |
| // error will be returned but the debug URL for that server in the URLs slice | |
| // will be empty. | |
| URLs []string | |
| } | |
| // StartProfileArgs holds the arguments to the StartProfile command. | |
| // | |
| // It is a placeholder for future compatibility. | |
| type StartProfileArgs struct { | |
| } | |
| // StartProfileResult holds the result of the StartProfile command. | |
| // | |
| // It is a placeholder for future compatibility. | |
| type StartProfileResult struct { | |
| } | |
| // StopProfileArgs holds the arguments to the StopProfile command. | |
| // | |
| // It is a placeholder for future compatibility. | |
| type StopProfileArgs struct { | |
| } | |
| // StopProfileResult holds the result to the StopProfile command. | |
| type StopProfileResult struct { | |
| // File is the profile file name. | |
| File string | |
| } | |
| type ResetGoModDiagnosticsArgs struct { | |
| URIArg | |
| // Optional: source of the diagnostics to reset. | |
| // If not set, all resettable go.mod diagnostics will be cleared. | |
| DiagnosticSource string | |
| } | |
| type VulncheckArgs struct { | |
| // Any document in the directory from which govulncheck will run. | |
| URI protocol.DocumentURI | |
| // Package pattern. E.g. "", ".", "./...". | |
| Pattern string | |
| // TODO: -tests | |
| } | |
| // RunVulncheckResult holds the result of asynchronously starting the vulncheck | |
| // command. | |
| type RunVulncheckResult struct { | |
| // Token holds the progress token for LSP workDone reporting of the vulncheck | |
| // invocation. | |
| Token protocol.ProgressToken | |
| } | |
| // VulncheckResult holds the result of synchronously running the vulncheck | |
| // command. | |
| type VulncheckResult struct { | |
| // Result holds the result of running vulncheck. | |
| Result *vulncheck.Result | |
| // Token holds the progress token used to report progress during back to the | |
| // LSP client during vulncheck execution. | |
| Token protocol.ProgressToken | |
| } | |
| // MemStatsResult holds selected fields from runtime.MemStats. | |
| type MemStatsResult struct { | |
| HeapAlloc uint64 | |
| HeapInUse uint64 | |
| TotalAlloc uint64 | |
| } | |
| // WorkspaceStatsResult returns information about the size and shape of the | |
| // workspace. | |
| type WorkspaceStatsResult struct { | |
| Files FileStats // file stats for the cache | |
| Views []ViewStats // stats for each view in the session | |
| } | |
| // FileStats holds information about a set of files. | |
| type FileStats struct { | |
| Total int // total number of files | |
| Largest int // number of bytes in the largest file | |
| Errs int // number of files that could not be read | |
| } | |
| // ViewStats holds information about a single View in the session. | |
| type ViewStats struct { | |
| GoCommandVersion string // version of the Go command resolved for this view | |
| AllPackages PackageStats // package info for all packages (incl. dependencies) | |
| WorkspacePackages PackageStats // package info for workspace packages | |
| Diagnostics int // total number of diagnostics in the workspace | |
| } | |
| // PackageStats holds information about a collection of packages. | |
| type PackageStats struct { | |
| Packages int // total number of packages | |
| LargestPackage int // number of files in the largest package | |
| CompiledGoFiles int // total number of compiled Go files across all packages | |
| Modules int // total number of unique modules | |
| } | |
| type RunGoWorkArgs struct { | |
| ViewID string // ID of the view to run the command from | |
| InitFirst bool // Whether to run `go work init` first | |
| Args []string // Args to pass to `go work` | |
| } | |
| // AddTelemetryCountersArgs holds the arguments to the AddCounters command | |
| // that updates the telemetry counters. | |
| type AddTelemetryCountersArgs struct { | |
| // Names and Values must have the same length. | |
| Names []string // Name of counters. | |
| Values []int64 // Values added to the corresponding counters. Must be non-negative. | |
| } | |
| // ChangeSignatureArgs specifies a "change signature" refactoring to perform. | |
| // | |
| // The new signature is expressed via the NewParams and NewResults fields. The | |
| // elements of these lists each describe a new field of the signature, by | |
| // either referencing a field in the old signature or by defining a new field: | |
| // - If the element is an integer, it references a positional parameter in the | |
| // old signature. | |
| // - If the element is a string, it is parsed as a new field to add. | |
| // | |
| // Suppose we have a function `F(a, b int) (string, error)`. Here are some | |
| // examples of refactoring this signature in practice, eliding the 'Location' | |
| // and 'ResolveEdits' fields. | |
| // - `{ "NewParams": [0], "NewResults": [0, 1] }` removes the second parameter | |
| // - `{ "NewParams": [1, 0], "NewResults": [0, 1] }` flips the parameter order | |
| // - `{ "NewParams": [0, 1, "a int"], "NewResults": [0, 1] }` adds a new field | |
| // - `{ "NewParams": [1, 2], "NewResults": [1] }` drops the `error` result | |
| type ChangeSignatureArgs struct { | |
| // Location is any range inside the function signature. By convention, this | |
| // is the same location provided in the codeAction request. | |
| Location protocol.Location // a range inside of the function signature, as passed to CodeAction | |
| // NewParams describes parameters of the new signature. | |
| // An int value references a parameter in the old signature by index. | |
| // A string value describes a new parameter field (e.g. "x int"). | |
| NewParams []ChangeSignatureParam | |
| // NewResults describes results of the new signature (see above). | |
| // An int value references a result in the old signature by index. | |
| // A string value describes a new result field (e.g. "err error"). | |
| NewResults []ChangeSignatureParam | |
| // Whether to resolve and return the edits. | |
| ResolveEdits bool | |
| } | |
| // ChangeSignatureParam implements the API described in the doc string of | |
| // [ChangeSignatureArgs]: a union of JSON int | string. | |
| type ChangeSignatureParam struct { | |
| OldIndex int | |
| NewField string | |
| } | |
| func (a *ChangeSignatureParam) UnmarshalJSON(b []byte) error { | |
| var s string | |
| if err := json.Unmarshal(b, &s); err == nil { | |
| a.NewField = s | |
| return nil | |
| } | |
| var i int | |
| if err := json.Unmarshal(b, &i); err == nil { | |
| a.OldIndex = i | |
| return nil | |
| } | |
| return fmt.Errorf("must be int or string") | |
| } | |
| func (a ChangeSignatureParam) MarshalJSON() ([]byte, error) { | |
| if a.NewField != "" { | |
| return json.Marshal(a.NewField) | |
| } | |
| return json.Marshal(a.OldIndex) | |
| } | |
| // DiagnoseFilesArgs specifies a set of files for which diagnostics are wanted. | |
| type DiagnoseFilesArgs struct { | |
| Files []protocol.DocumentURI | |
| } | |
| // A View holds summary information about a cache.View. | |
| type View struct { | |
| ID string // view ID (the index of this view among all views created) | |
| Type string // view type (via cache.ViewType.String) | |
| Root protocol.DocumentURI // root dir of the view (e.g. containing go.mod or go.work) | |
| Folder protocol.DocumentURI // workspace folder associated with the view | |
| EnvOverlay []string // environment variable overrides | |
| } | |
| // PackagesArgs holds arguments for the Packages command. | |
| type PackagesArgs struct { | |
| // Files is a list of files and directories whose associated | |
| // packages should be described by the result. | |
| // | |
| // In some cases, a file may belong to more than one package; | |
| // the result may describe any of them. | |
| Files []protocol.DocumentURI | |
| // Enumerate all packages under the directory loadable with | |
| // the ... pattern. | |
| // The search does not cross the module boundaries and | |
| // does not return packages that are not yet loaded. | |
| // (e.g. those excluded by the gopls directory filter setting, | |
| // or the go.work configuration) | |
| Recursive bool `json:"Recursive,omitempty"` | |
| // Mode controls the types of information returned for each package. | |
| Mode PackagesMode | |
| } | |
| // PackagesMode controls the details to include in PackagesResult. | |
| type PackagesMode uint64 | |
| const ( | |
| // Populate the [TestFile.Tests] field in [Package] returned by the | |
| // Packages command. | |
| NeedTests PackagesMode = 1 << iota | |
| ) | |
| // PackagesResult is the result of the Packages command. | |
| type PackagesResult struct { | |
| // Packages is an unordered list of package metadata. | |
| Packages []Package | |
| // Module maps module path to module metadata for | |
| // all the modules of the returned Packages. | |
| Module map[string]Module | |
| } | |
| // Package describes a Go package (not an empty parent). | |
| type Package struct { | |
| // Package path. | |
| Path string | |
| // Module path. Empty if the package doesn't | |
| // belong to any module. | |
| ModulePath string | |
| // q in a "p [q.test]" package. | |
| ForTest string | |
| // Note: the result does not include the directory name | |
| // of the package because mapping between a package and | |
| // a folder is not possible in certain build systems. | |
| // If directory info is needed, one can guess it | |
| // from the TestFile's file name. | |
| // TestFiles contains the subset of the files of the package | |
| // whose name ends with "_test.go". | |
| // They are ordered deterministically as determined | |
| // by the underlying build system. | |
| TestFiles []TestFile | |
| } | |
| type Module struct { | |
| Path string // module path | |
| Version string // module version if any. | |
| GoMod protocol.DocumentURI // path to the go.mod file. | |
| } | |
| type TestFile struct { | |
| URI protocol.DocumentURI // a *_test.go file | |
| // Tests is the list of tests in File, including subtests. | |
| // | |
| // The set of subtests is not exhaustive as in general they may be | |
| // dynamically generated, so it is impossible for static heuristics | |
| // to enumerate them. | |
| // | |
| // Tests are lexically ordered. | |
| // Since subtest names are prefixed by their top-level test names | |
| // each top-level test precedes its subtests. | |
| Tests []TestCase | |
| } | |
| // TestCase represents a test case. | |
| // A test case can be a top-level Test/Fuzz/Benchmark/Example function, | |
| // as recognized by 'go list' or 'go test -list', or | |
| // a subtest within a top-level function. | |
| type TestCase struct { | |
| // Name is the complete name of the test (Test, Benchmark, Example, or Fuzz) | |
| // or the subtest as it appears in the output of go test -json. | |
| // The server may attempt to infer names of subtests by static | |
| // analysis; if so, it should aim to simulate the actual computed | |
| // name of the test, including any disambiguating suffix such as "#01". | |
| // To run only this test, clients need to compute the -run, -bench, -fuzz | |
| // flag values by first splitting the Name with "/" and | |
| // quoting each element with "^" + regexp.QuoteMeta(Name) + "$". | |
| // e.g. TestToplevel/Inner.Subtest → -run=^TestToplevel$/^Inner\.Subtest$ | |
| Name string | |
| // Loc is the filename and range enclosing this test function | |
| // or the subtest. This is used to place the gutter marker | |
| // and group tests based on location. | |
| // For subtests whose test names can be determined statically, | |
| // this can be either t.Run or the test data table | |
| // for table-driven setup. | |
| // Some testing frameworks allow to declare the actual test | |
| // logic in a different file. For example, one can define | |
| // a testify test suite in suite_test.go and use it from | |
| // main_test.go. | |
| /* | |
| -- main_test.go -- | |
| ... | |
| func TestFoo(t *testing.T) { | |
| suite.Run(t, new(MyTestSuite)) | |
| } | |
| -- suite_test.go -- | |
| type MyTestSuite struct { | |
| suite.Suite | |
| } | |
| func (suite *MyTestSuite) TestBar() { ... } | |
| */ | |
| // In this case, the testing framework creates "TestFoo/TestBar" | |
| // and the corresponding test case belongs to "main_test.go" | |
| // TestFile. However, the test case has "suite_test.go" as its | |
| // file location. | |
| Loc protocol.Location | |
| } | |
| type ModulesArgs struct { | |
| // Dir is the directory in which to search for go.mod files. | |
| Dir protocol.DocumentURI | |
| // MaxDepth is the directory walk limit. | |
| // A value of 0 means inspect only Dir. | |
| // 1 means inspect its child directories too, and so on. | |
| // A negative value removes the limit. | |
| MaxDepth int | |
| } | |
| type ModulesResult struct { | |
| Modules []Module | |
| } | |
| type PackageSymbolsArgs struct { | |
| URI protocol.DocumentURI | |
| } | |
| type PackageSymbolsResult struct { | |
| PackageName string | |
| // Files is a list of files in the given URI's package. | |
| Files []protocol.DocumentURI | |
| Symbols []PackageSymbol | |
| } | |
| // PackageSymbol has the same fields as DocumentSymbol, with an additional int field "File" | |
| // which stores the index of the symbol's file in the PackageSymbolsResult.Files array | |
| type PackageSymbol struct { | |
| Name string `json:"name"` | |
| Detail string `json:"detail,omitempty"` | |
| // protocol.SymbolKind maps an integer to an enum: | |
| // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#symbolKind | |
| // i.e. File = 1 | |
| Kind protocol.SymbolKind `json:"kind"` | |
| Tags []protocol.SymbolTag `json:"tags,omitempty"` | |
| Range protocol.Range `json:"range"` | |
| SelectionRange protocol.Range `json:"selectionRange"` | |
| Children []PackageSymbol `json:"children,omitempty"` | |
| // Index of this symbol's file in PackageSymbolsResult.Files | |
| File int `json:"file,omitempty"` | |
| } | |
| type ImplementInterfaceArgs struct { | |
| // Location is the location where the user invoked the code action. | |
| // This location must be within a type declaration. | |
| Location protocol.Location | |
| // Interface is the fully qualified name of pacakge-level interface type to | |
| // implement. It must follow the pattern "path/to/package.InterfaceName" | |
| // (e.g., "io.Reader"). | |
| Interface string | |
| } | |
| // DragonSlayerArgs holds the arguments to the DragonSlayer command. | |
| type DragonSlayerArgs struct { | |
| // Location is the location where the user invoked the code action. | |
| // This location must be within the name of a package-level variable | |
| // named dragonSlayer. | |
| Location protocol.Location | |
| } | |
| // ModifyTagsArgs holds variables that determine how struct tags are modified. | |
| type ModifyTagsArgs struct { | |
| // NOTE(hxjiang): the mofidication field is important, when resolving a | |
| // command, the title of the code action or code lenses is no longer available. | |
| // The language server is not aware of the original user intention, whether | |
| // the command is meant for tag addition or tag removal. | |
| Modification string | |
| URI protocol.DocumentURI // uri of the file to be modified | |
| Range protocol.Range // range in the file for where to modify struct tags | |
| Add string // comma-separated list of tags to add; i.e. "json,xml" | |
| AddOptions string // comma-separated list of options to add, per tag; i.e. "json=omitempty" | |
| Remove string // comma-separated list of tags to remove | |
| RemoveOptions string // comma-separated list of options to remove | |
| Clear bool // if set, clear all tags. tags are cleared before any new tags are added | |
| ClearOptions bool // if set, clear all tag options; options are cleared before any new options are added | |
| Overwrite bool // if set, replace existing tags when adding | |
| SkipUnexportedFields bool // if set, do not modify tags on unexported struct fields | |
| Transform string // transform rule for adding tags; i.e. "snakecase" | |
| ValueFormat string // format for the tag's value, after transformation; for example "column:{field}" | |
| } | |
| type LSPArgs struct { | |
| Method string `json:"method"` | |
| Param json.RawMessage `json:"param"` | |
| } | |
| // MoveTypeArgs specifies a "move type" refactoring to perform. | |
| type MoveTypeArgs struct { | |
| // The location of the type to move. | |
| Location protocol.Location | |
| // TODO(mkalil): Determine format of the parameter that specifies where to | |
| // move the type to. | |
| } | |
| // MoveDeclarationArgs specifies a "move declaration" refactoring to perform. | |
| type MoveDeclarationArgs struct { | |
| // The location of the declaration to move. | |
| Location protocol.Location | |
| } | |
| // ResolveTargetParams are the arguments for the ResolveTarget command. | |
| type ResolveTargetParams struct { | |
| // TextDocument identifies the document context (e.g. CWD file or -pos file). | |
| TextDocument protocol.TextDocumentIdentifier `json:"textDocument"` | |
| // Target is the literal name or regex pattern (enclosed in slashes). | |
| Target string `json:"target"` | |
| // PkgScope optionally overrides the package search scope (from -pkg). | |
| PkgScope string `json:"pkgScope,omitempty"` | |
| // Range optionally restricts the search to a specific span within the file. | |
| // | |
| // TODO(aputman): Implement support for this. | |
| Range protocol.Range `json:"range,omitempty"` | |
| } | |
| // ResolveTargetResult is the result of the ResolveTarget command. | |
| type ResolveTargetResult struct { | |
| Matches []TargetMatch `json:"matches"` | |
| } | |
| // TargetMatch is a single match returned by the ResolveTarget command. | |
| type TargetMatch struct { | |
| // Package is the Go package path of the symbol. | |
| Package string `json:"package,omitempty"` | |
| // Name is the name of the symbol. | |
| Name string `json:"name"` | |
| // Location is LSP protocol location because gopls.resolve_target | |
| // is an internal utility command to map the target symbol position to | |
| // LSP protocol locations. | |
| Location protocol.Location `json:"location"` | |
| } |