kosx

options.go

Dec 27th, 2020
1,540
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. // Copyright 2019 The Go Authors. All rights reserved.
  3. // Use of this source code is governed by a BSD-style
  4. // license that can be found in the LICENSE file.
  5. package source
  6. import (
  7.     "context"
  8.     "fmt"
  9.     "path/filepath"
  10.     "regexp"
  11.     "strings"
  12.     "sync"
  13.     "time"
  14.     "golang.org/x/tools/go/analysis"
  15.     "golang.org/x/tools/go/analysis/passes/asmdecl"
  16.     "golang.org/x/tools/go/analysis/passes/assign"
  17.     "golang.org/x/tools/go/analysis/passes/atomic"
  18.     "golang.org/x/tools/go/analysis/passes/atomicalign"
  19.     "golang.org/x/tools/go/analysis/passes/bools"
  20.     "golang.org/x/tools/go/analysis/passes/buildtag"
  21.     "golang.org/x/tools/go/analysis/passes/cgocall"
  22.     "golang.org/x/tools/go/analysis/passes/composite"
  23.     "golang.org/x/tools/go/analysis/passes/copylock"
  24.     "golang.org/x/tools/go/analysis/passes/deepequalerrors"
  25.     "golang.org/x/tools/go/analysis/passes/errorsas"
  26.     "golang.org/x/tools/go/analysis/passes/fieldalignment"
  27.     "golang.org/x/tools/go/analysis/passes/httpresponse"
  28.     "golang.org/x/tools/go/analysis/passes/ifaceassert"
  29.     "golang.org/x/tools/go/analysis/passes/loopclosure"
  30.     "golang.org/x/tools/go/analysis/passes/lostcancel"
  31.     "golang.org/x/tools/go/analysis/passes/nilfunc"
  32.     "golang.org/x/tools/go/analysis/passes/printf"
  33.     "golang.org/x/tools/go/analysis/passes/shadow"
  34.     "golang.org/x/tools/go/analysis/passes/shift"
  35.     "golang.org/x/tools/go/analysis/passes/sortslice"
  36.     "golang.org/x/tools/go/analysis/passes/stdmethods"
  37.     "golang.org/x/tools/go/analysis/passes/stringintconv"
  38.     "golang.org/x/tools/go/analysis/passes/structtag"
  39.     "golang.org/x/tools/go/analysis/passes/testinggoroutine"
  40.     "golang.org/x/tools/go/analysis/passes/tests"
  41.     "golang.org/x/tools/go/analysis/passes/unmarshal"
  42.     "golang.org/x/tools/go/analysis/passes/unreachable"
  43.     "golang.org/x/tools/go/analysis/passes/unsafeptr"
  44.     "golang.org/x/tools/go/analysis/passes/unusedresult"
  45.     "golang.org/x/tools/internal/lsp/analysis/fillreturns"
  46.     "golang.org/x/tools/internal/lsp/analysis/fillstruct"
  47.     "golang.org/x/tools/internal/lsp/analysis/nonewvars"
  48.     "golang.org/x/tools/internal/lsp/analysis/noresultvalues"
  49.     "golang.org/x/tools/internal/lsp/analysis/simplifycompositelit"
  50.     "golang.org/x/tools/internal/lsp/analysis/simplifyrange"
  51.     "golang.org/x/tools/internal/lsp/analysis/simplifyslice"
  52.     "golang.org/x/tools/internal/lsp/analysis/undeclaredname"
  53.     "golang.org/x/tools/internal/lsp/analysis/unusedparams"
  54.     "golang.org/x/tools/internal/lsp/diff"
  55.     "golang.org/x/tools/internal/lsp/diff/myers"
  56.     "golang.org/x/tools/internal/lsp/protocol"
  57.     errors "golang.org/x/xerrors"
  58. )
  59. var (
  60.     optionsOnce    sync.Once
  61.     defaultOptions *Options
  62. )
  63. //go:generate go run golang.org/x/tools/internal/lsp/source/genapijson -output api_json.go
  64. // DefaultOptions is the options that are used for Gopls execution independent
  65. // of any externally provided configuration (LSP initialization, command
  66. // invokation, etc.).
  67. func DefaultOptions() *Options {
  68.     optionsOnce.Do(func() {
  69.         var commands []string
  70.         for _, c := range Commands {
  71.             commands = append(commands, c.ID())
  72.         }
  73.         defaultOptions = &Options{
  74.             ClientOptions: ClientOptions{
  75.                 InsertTextFormat:                  protocol.PlainTextTextFormat,
  76.                 PreferredContentFormat:            protocol.Markdown,
  77.                 ConfigurationSupported:            true,
  78.                 DynamicConfigurationSupported:     true,
  79.                 DynamicWatchedFilesSupported:      true,
  80.                 LineFoldingOnly:                   false,
  81.                 HierarchicalDocumentSymbolSupport: true,
  82.             },
  83.             ServerOptions: ServerOptions{
  84.                 SupportedCodeActions: map[FileKind]map[protocol.CodeActionKind]bool{
  85.                     Go: {
  86.                         protocol.SourceFixAll:          true,
  87.                         protocol.SourceOrganizeImports: true,
  88.                         protocol.QuickFix:              true,
  89.                         protocol.RefactorRewrite:       true,
  90.                         protocol.RefactorExtract:       true,
  91.                     },
  92.                     Mod: {
  93.                         protocol.SourceOrganizeImports: true,
  94.                     },
  95.                     Sum: {},
  96.                 },
  97.                 SupportedCommands: commands,
  98.             },
  99.             UserOptions: UserOptions{
  100.                 HoverKind:  FullDocumentation,
  101.                 LinkTarget: "pkg.go.dev",
  102.                 Codelenses: map[string]bool{
  103.                     CommandGenerate.Name:          true,
  104.                     CommandRegenerateCgo.Name:     true,
  105.                     CommandTidy.Name:              true,
  106.                     CommandToggleDetails.Name:     false,
  107.                     CommandUpgradeDependency.Name: true,
  108.                     CommandVendor.Name:            true,
  109.                 },
  110.                 LinksInHover:   true,
  111.                 ImportShortcut: Both,
  112.                 Matcher:        Fuzzy,
  113.                 SymbolMatcher:  SymbolFuzzy,
  114.                 SymbolStyle:    DynamicSymbols,
  115.             },
  116.             DebuggingOptions: DebuggingOptions{
  117.                 CompletionBudget: 100 * time.Millisecond,
  118.             },
  119.             ExperimentalOptions: ExperimentalOptions{
  120.                 ExpandWorkspaceToModule:      true,
  121.                 ExperimentalPackageCacheKey:  true,
  122.                 ExperimentalDiagnosticsDelay: 250 * time.Millisecond,
  123.             },
  124.             InternalOptions: InternalOptions{
  125.                 LiteralCompletions:      true,
  126.                 TempModfile:             true,
  127.                 CompleteUnimported:      true,
  128.                 CompletionDocumentation: true,
  129.                 DeepCompletion:          true,
  130.             },
  131.             Hooks: Hooks{
  132.                 ComputeEdits:         myers.ComputeEdits,
  133.                 URLRegexp:            urlRegexp(),
  134.                 DefaultAnalyzers:     defaultAnalyzers(),
  135.                 TypeErrorAnalyzers:   typeErrorAnalyzers(),
  136.                 ConvenienceAnalyzers: convenienceAnalyzers(),
  137.                 StaticcheckAnalyzers: map[string]Analyzer{},
  138.                 GoDiff:               true,
  139.             },
  140.         }
  141.     })
  142.     return defaultOptions
  143. }
  144. // Options holds various configuration that affects Gopls execution, organized
  145. // by the nature or origin of the settings.
  146. type Options struct {
  147.     ClientOptions
  148.     ServerOptions
  149.     UserOptions
  150.     DebuggingOptions
  151.     ExperimentalOptions
  152.     InternalOptions
  153.     Hooks
  154. }
  155. // ClientOptions holds LSP-specific configuration that is provided by the
  156. // client.
  157. type ClientOptions struct {
  158.     InsertTextFormat                  protocol.InsertTextFormat
  159.     ConfigurationSupported            bool
  160.     DynamicConfigurationSupported     bool
  161.     DynamicWatchedFilesSupported      bool
  162.     PreferredContentFormat            protocol.MarkupKind
  163.     LineFoldingOnly                   bool
  164.     HierarchicalDocumentSymbolSupport bool
  165.     SemanticTypes                     []string
  166.     SemanticMods                      []string
  167. }
  168. // ServerOptions holds LSP-specific configuration that is provided by the
  169. // server.
  170. type ServerOptions struct {
  171.     SupportedCodeActions map[FileKind]map[protocol.CodeActionKind]bool
  172.     SupportedCommands    []string
  173. }
  174. // UserOptions holds custom Gopls configuration (not part of the LSP) that is
  175. // modified by the client.
  176. type UserOptions struct {
  177.     // BuildFlags is the set of flags passed on to the build system when invoked.
  178.     // It is applied to queries like `go list`, which is used when discovering files.
  179.     // The most common use is to set `-tags`.
  180.     BuildFlags []string
  181.     // Env adds environment variables to external commands run by `gopls`, most notably `go list`.
  182.     Env map[string]string
  183.     // HoverKind controls the information that appears in the hover text.
  184.     // SingleLine and Structured are intended for use only by authors of editor plugins.
  185.     HoverKind HoverKind
  186.     // Placeholders enables placeholders for function parameters or struct fields in completion responses.
  187.     UsePlaceholders bool
  188.     // LinkTarget controls where documentation links go.
  189.     // It might be one of:
  190.     //
  191.     // * `"godoc.org"`
  192.     // * `"pkg.go.dev"`
  193.     //
  194.     // If company chooses to use its own `godoc.org`, its address can be used as well.
  195.     LinkTarget string
  196.     // Local is the equivalent of the `goimports -local` flag, which puts imports beginning with this string after 3rd-party packages.
  197.     // It should be the prefix of the import path whose imports should be grouped separately.
  198.     Local string
  199.     // Gofumpt indicates if we should run gofumpt formatting.
  200.     Gofumpt bool
  201.     // Analyses specify analyses that the user would like to enable or disable.
  202.     // A map of the names of analysis passes that should be enabled/disabled.
  203.     // A full list of analyzers that gopls uses can be found [here](analyzers.md)
  204.     //
  205.     // Example Usage:
  206.     // ```json5
  207.     // ...
  208.     // "analyses": {
  209.     //   "unreachable": false, // Disable the unreachable analyzer.
  210.     //   "unusedparams": true  // Enable the unusedparams analyzer.
  211.     // }
  212.     // ...
  213.     // ```
  214.     Analyses map[string]bool
  215.     // Codelenses overrides the enabled/disabled state of code lenses. See the "Code Lenses"
  216.     // section of settings.md for the list of supported lenses.
  217.     //
  218.     // Example Usage:
  219.     // ```json5
  220.     // "gopls": {
  221.     // ...
  222.     //   "codelenses": {
  223.     //     "generate": false,  // Don't show the `go generate` lens.
  224.     //     "gc_details": true  // Show a code lens toggling the display of gc's choices.
  225.     //   }
  226.     // ...
  227.     // }
  228.     // ```
  229.     Codelenses map[string]bool
  230.     // LinksInHover toggles the presence of links to documentation in hover.
  231.     LinksInHover bool
  232.     // ImportShortcut specifies whether import statements should link to
  233.     // documentation or go to definitions.
  234.     ImportShortcut ImportShortcut
  235.     // Matcher sets the algorithm that is used when calculating completion candidates.
  236.     Matcher Matcher
  237.     // SymbolMatcher sets the algorithm that is used when finding workspace symbols.
  238.     SymbolMatcher SymbolMatcher
  239.     // SymbolStyle controls how symbols are qualified in symbol responses.
  240.     //
  241.     // Example Usage:
  242.     // ```json5
  243.     // "gopls": {
  244.     // ...
  245.     //   "symbolStyle": "dynamic",
  246.     // ...
  247.     // }
  248.     // ```
  249.     SymbolStyle SymbolStyle
  250.     // DirectoryFilters can be used to exclude unwanted directories from the
  251.     // workspace. By default, all directories are included. Filters are an
  252.     // operator, `+` to include and `-` to exclude, followed by a path prefix
  253.     // relative to the workspace folder. They are evaluated in order, and
  254.     // the last filter that applies to a path controls whether it is included.
  255.     // The path prefix can be empty, so an initial `-` excludes everything.
  256.     //
  257.     // Examples:
  258.     // Exclude node_modules: `-node_modules`
  259.     // Include only project_a: `-` (exclude everything), `+project_a`
  260.     // Include only project_a, but not node_modules inside it: `-`, `+project_a`, `-project_a/node_modules`
  261.     DirectoryFilters []string
  262. }
  263. // EnvSlice returns Env as a slice of k=v strings.
  264. func (u *UserOptions) EnvSlice() []string {
  265.     var result []string
  266.     for k, v := range u.Env {
  267.         result = append(result, fmt.Sprintf("%v=%v", k, v))
  268.     }
  269.     return result
  270. }
  271. // SetEnvSlice sets Env from a slice of k=v strings.
  272. func (u *UserOptions) SetEnvSlice(env []string) {
  273.     u.Env = map[string]string{}
  274.     for _, kv := range env {
  275.         split := strings.SplitN(kv, "=", 2)
  276.         if len(split) != 2 {
  277.             continue
  278.         }
  279.         u.Env[split[0]] = split[1]
  280.     }
  281. }
  282. // Hooks contains configuration that is provided to the Gopls command by the
  283. // main package.
  284. type Hooks struct {
  285.     GoDiff               bool
  286.     ComputeEdits         diff.ComputeEdits
  287.     URLRegexp            *regexp.Regexp
  288.     GofumptFormat        func(ctx context.Context, src []byte) ([]byte, error)
  289.     DefaultAnalyzers     map[string]Analyzer
  290.     TypeErrorAnalyzers   map[string]Analyzer
  291.     ConvenienceAnalyzers map[string]Analyzer
  292.     StaticcheckAnalyzers map[string]Analyzer
  293. }
  294. // ExperimentalOptions defines configuration for features under active
  295. // development. WARNING: This configuration will be changed in the future. It
  296. // only exists while these features are under development.
  297. type ExperimentalOptions struct {
  298.     // Annotations suppress various kinds of optimization diagnostics
  299.     // that would be reported by the gc_details command.
  300.     //  * noNilcheck suppresses display of nilchecks.
  301.     //  * noEscape suppresses escape choices.
  302.     //  * noInline suppresses inlining choices.
  303.     //  * noBounds suppresses bounds checking diagnostics.
  304.     Annotations map[string]bool
  305.     // Staticcheck enables additional analyses from staticcheck.io.
  306.     Staticcheck bool
  307.     // SemanticTokens controls whether the LSP server will send
  308.     // semantic tokens to the client.
  309.     SemanticTokens bool
  310.     // ExpandWorkspaceToModule instructs `gopls` to adjust the scope of the
  311.     // workspace to find the best available module root. `gopls` first looks for
  312.     // a go.mod file in any parent directory of the workspace folder, expanding
  313.     // the scope to that directory if it exists. If no viable parent directory is
  314.     // found, gopls will check if there is exactly one child directory containing
  315.     // a go.mod file, narrowing the scope to that directory if it exists.
  316.     ExpandWorkspaceToModule bool
  317.     // ExperimentalWorkspaceModule opts a user into the experimental support
  318.     // for multi-module workspaces.
  319.     ExperimentalWorkspaceModule bool
  320.     // ExperimentalDiagnosticsDelay controls the amount of time that gopls waits
  321.     // after the most recent file modification before computing deep diagnostics.
  322.     // Simple diagnostics (parsing and type-checking) are always run immediately
  323.     // on recently modified packages.
  324.     //
  325.     // This option must be set to a valid duration string, for example `"250ms"`.
  326.     ExperimentalDiagnosticsDelay time.Duration
  327.     // ExperimentalPackageCacheKey controls whether to use a coarser cache key
  328.     // for package type information to increase cache hits. This setting removes
  329.     // the user's environment, build flags, and working directory from the cache
  330.     // key, which should be a safe change as all relevant inputs into the type
  331.     // checking pass are already hashed into the key. This is temporarily guarded
  332.     // by an experiment because caching behavior is subtle and difficult to
  333.     // comprehensively test.
  334.     ExperimentalPackageCacheKey bool
  335.     // AllowModfileModifications disables -mod=readonly, allowing imports from
  336.     // out-of-scope modules. This option will eventually be removed.
  337.     AllowModfileModifications bool
  338.     // AllowImplicitNetworkAccess disables GOPROXY=off, allowing implicit module
  339.     // downloads rather than requiring user action. This option will eventually
  340.     // be removed.
  341.     AllowImplicitNetworkAccess bool
  342. }
  343. // DebuggingOptions should not affect the logical execution of Gopls, but may
  344. // be altered for debugging purposes.
  345. type DebuggingOptions struct {
  346.     // VerboseOutput enables additional debug logging.
  347.     VerboseOutput bool
  348.     // CompletionBudget is the soft latency goal for completion requests. Most
  349.     // requests finish in a couple milliseconds, but in some cases deep
  350.     // completions can take much longer. As we use up our budget we
  351.     // dynamically reduce the search scope to ensure we return timely
  352.     // results. Zero means unlimited.
  353.     CompletionBudget time.Duration
  354. }
  355. // InternalOptions contains settings that are not intended for use by the
  356. // average user. These may be settings used by tests or outdated settings that
  357. // will soon be deprecated. Some of these settings may not even be configurable
  358. // by the user.
  359. type InternalOptions struct {
  360.     // LiteralCompletions controls whether literal candidates such as
  361.     // "&someStruct{}" are offered. Tests disable this flag to simplify
  362.     // their expected values.
  363.     LiteralCompletions bool
  364.     // VerboseWorkDoneProgress controls whether the LSP server should send
  365.     // progress reports for all work done outside the scope of an RPC.
  366.     // Used by the regression tests.
  367.     VerboseWorkDoneProgress bool
  368.     // The following options were previously available to users, but they
  369.     // really shouldn't be configured by anyone other than "power users".
  370.     // CompletionDocumentation enables documentation with completion results.
  371.     CompletionDocumentation bool
  372.     // CompleteUnimported enables completion for packages that you do not
  373.     // currently import.
  374.     CompleteUnimported bool
  375.     // DeepCompletion enables the ability to return completions from deep
  376.     // inside relevant entities, rather than just the locally accessible ones.
  377.     //
  378.     // Consider this example:
  379.     //
  380.     // ```go
  381.     // package main
  382.     //
  383.     // import "fmt"
  384.     //
  385.     // type wrapString struct {
  386.     //     str string
  387.     // }
  388.     //
  389.     // func main() {
  390.     //     x := wrapString{"hello world"}
  391.     //     fmt.Printf(<>)
  392.     // }
  393.     // ```
  394.     //
  395.     // At the location of the `<>` in this program, deep completion would suggest the result `x.str`.
  396.     DeepCompletion bool
  397.     // TempModfile controls the use of the -modfile flag in Go 1.14.
  398.     TempModfile bool
  399. }
  400. type ImportShortcut string
  401. const (
  402.     Both       ImportShortcut = "Both"
  403.     Link       ImportShortcut = "Link"
  404.     Definition ImportShortcut = "Definition"
  405. )
  406. func (s ImportShortcut) ShowLinks() bool {
  407.     return s == Both || s == Link
  408. }
  409. func (s ImportShortcut) ShowDefinition() bool {
  410.     return s == Both || s == Definition
  411. }
  412. type Matcher string
  413. const (
  414.     Fuzzy           Matcher = "Fuzzy"
  415.     CaseInsensitive Matcher = "CaseInsensitive"
  416.     CaseSensitive   Matcher = "CaseSensitive"
  417. )
  418. type SymbolMatcher string
  419. const (
  420.     SymbolFuzzy           SymbolMatcher = "Fuzzy"
  421.     SymbolCaseInsensitive SymbolMatcher = "CaseInsensitive"
  422.     SymbolCaseSensitive   SymbolMatcher = "CaseSensitive"
  423. )
  424. type SymbolStyle string
  425. const (
  426.     // PackageQualifiedSymbols is package qualified symbols i.e.
  427.     // "pkg.Foo.Field".
  428.     PackageQualifiedSymbols SymbolStyle = "Package"
  429.     // FullyQualifiedSymbols is fully qualified symbols, i.e.
  430.     // "path/to/pkg.Foo.Field".
  431.     FullyQualifiedSymbols SymbolStyle = "Full"
  432.     // DynamicSymbols uses whichever qualifier results in the highest scoring
  433.     // match for the given symbol query. Here a "qualifier" is any "/" or "."
  434.     // delimited suffix of the fully qualified symbol. i.e. "to/pkg.Foo.Field" or
  435.     // just "Foo.Field".
  436.     DynamicSymbols SymbolStyle = "Dynamic"
  437. )
  438. type HoverKind string
  439. const (
  440.     SingleLine            HoverKind = "SingleLine"
  441.     NoDocumentation       HoverKind = "NoDocumentation"
  442.     SynopsisDocumentation HoverKind = "SynopsisDocumentation"
  443.     FullDocumentation     HoverKind = "FullDocumentation"
  444.     // Structured is an experimental setting that returns a structured hover format.
  445.     // This format separates the signature from the documentation, so that the client
  446.     // can do more manipulation of these fields.
  447.     //
  448.     // This should only be used by clients that support this behavior.
  449.     Structured HoverKind = "Structured"
  450. )
  451. type OptionResults []OptionResult
  452. type OptionResult struct {
  453.     Name  string
  454.     Value interface{}
  455.     Error error
  456.     State       OptionState
  457.     Replacement string
  458. }
  459. type OptionState int
  460. const (
  461.     OptionHandled = OptionState(iota)
  462.     OptionDeprecated
  463.     OptionUnexpected
  464. )
  465. type LinkTarget string
  466. func SetOptions(options *Options, opts interface{}) OptionResults {
  467.     var results OptionResults
  468.     switch opts := opts.(type) {
  469.     case nil:
  470.     case map[string]interface{}:
  471.         // If the user's settings contains "allExperiments", set that first,
  472.         // and then let them override individual settings independently.
  473.         var enableExperiments bool
  474.         for name, value := range opts {
  475.             if b, ok := value.(bool); name == "allExperiments" && ok && b {
  476.                 enableExperiments = true
  477.                 options.enableAllExperiments()
  478.             }
  479.         }
  480.         for name, value := range opts {
  481.             results = append(results, options.set(name, value))
  482.         }
  483.         // Finally, enable any experimental features that are specified in
  484.         // maps, which allows users to individually toggle them on or off.
  485.         if enableExperiments {
  486.             options.enableAllExperimentMaps()
  487.         }
  488.     default:
  489.         results = append(results, OptionResult{
  490.             Value: opts,
  491.             Error: errors.Errorf("Invalid options type %T", opts),
  492.         })
  493.     }
  494.     return results
  495. }
  496. func (o *Options) ForClientCapabilities(caps protocol.ClientCapabilities) {
  497.     // Check if the client supports snippets in completion items.
  498.     if c := caps.TextDocument.Completion; c.CompletionItem.SnippetSupport {
  499.         o.InsertTextFormat = protocol.SnippetTextFormat
  500.     }
  501.     // Check if the client supports configuration messages.
  502.     o.ConfigurationSupported = caps.Workspace.Configuration
  503.     o.DynamicConfigurationSupported = caps.Workspace.DidChangeConfiguration.DynamicRegistration
  504.     o.DynamicWatchedFilesSupported = caps.Workspace.DidChangeWatchedFiles.DynamicRegistration
  505.     // Check which types of content format are supported by this client.
  506.     if hover := caps.TextDocument.Hover; len(hover.ContentFormat) > 0 {
  507.         o.PreferredContentFormat = hover.ContentFormat[0]
  508.     }
  509.     // Check if the client supports only line folding.
  510.     fr := caps.TextDocument.FoldingRange
  511.     o.LineFoldingOnly = fr.LineFoldingOnly
  512.     // Check if the client supports hierarchical document symbols.
  513.     o.HierarchicalDocumentSymbolSupport = caps.TextDocument.DocumentSymbol.HierarchicalDocumentSymbolSupport
  514.     // Check if the client supports semantic tokens
  515.     o.SemanticTypes = caps.TextDocument.SemanticTokens.TokenTypes
  516.     o.SemanticMods = caps.TextDocument.SemanticTokens.TokenModifiers
  517.     // we don't need Requests, as we support full functionality
  518.     // we don't need Formats, as there is only one, for now
  519. }
  520. func (o *Options) Clone() *Options {
  521.     result := &Options{
  522.         ClientOptions:       o.ClientOptions,
  523.         DebuggingOptions:    o.DebuggingOptions,
  524.         ExperimentalOptions: o.ExperimentalOptions,
  525.         InternalOptions:     o.InternalOptions,
  526.         Hooks: Hooks{
  527.             GoDiff:        o.Hooks.GoDiff,
  528.             ComputeEdits:  o.Hooks.ComputeEdits,
  529.             GofumptFormat: o.GofumptFormat,
  530.             URLRegexp:     o.URLRegexp,
  531.         },
  532.         ServerOptions: o.ServerOptions,
  533.         UserOptions:   o.UserOptions,
  534.     }
  535.     // Fully clone any slice or map fields. Only Hooks, ExperimentalOptions,
  536.     // and UserOptions can be modified.
  537.     copyStringMap := func(src map[string]bool) map[string]bool {
  538.         dst := make(map[string]bool)
  539.         for k, v := range src {
  540.             dst[k] = v
  541.         }
  542.         return dst
  543.     }
  544.     result.Analyses = copyStringMap(o.Analyses)
  545.     result.Annotations = copyStringMap(o.Annotations)
  546.     result.Codelenses = copyStringMap(o.Codelenses)
  547.     copySlice := func(src []string) []string {
  548.         dst := make([]string, len(src))
  549.         copy(dst, src)
  550.         return dst
  551.     }
  552.     result.SetEnvSlice(o.EnvSlice())
  553.     result.BuildFlags = copySlice(o.BuildFlags)
  554.     result.DirectoryFilters = copySlice(o.DirectoryFilters)
  555.     copyAnalyzerMap := func(src map[string]Analyzer) map[string]Analyzer {
  556.         dst := make(map[string]Analyzer)
  557.         for k, v := range src {
  558.             dst[k] = v
  559.         }
  560.         return dst
  561.     }
  562.     result.DefaultAnalyzers = copyAnalyzerMap(o.DefaultAnalyzers)
  563.     result.TypeErrorAnalyzers = copyAnalyzerMap(o.TypeErrorAnalyzers)
  564.     result.ConvenienceAnalyzers = copyAnalyzerMap(o.ConvenienceAnalyzers)
  565.     result.StaticcheckAnalyzers = copyAnalyzerMap(o.StaticcheckAnalyzers)
  566.     return result
  567. }
  568. func (o *Options) AddStaticcheckAnalyzer(a *analysis.Analyzer) {
  569.     o.StaticcheckAnalyzers[a.Name] = Analyzer{Analyzer: a, Enabled: true}
  570. }
  571. // enableAllExperiments turns on all of the experimental "off-by-default"
  572. // features offered by gopls. Any experimental features specified in maps
  573. // should be enabled in enableAllExperimentMaps.
  574. func (o *Options) enableAllExperiments() {
  575.     // There are currently no experimental features in development.
  576. }
  577. func (o *Options) enableAllExperimentMaps() {
  578.     if _, ok := o.Codelenses[CommandToggleDetails.Name]; !ok {
  579.         o.Codelenses[CommandToggleDetails.Name] = true
  580.     }
  581.     if _, ok := o.Analyses[unusedparams.Analyzer.Name]; !ok {
  582.         o.Analyses[unusedparams.Analyzer.Name] = true
  583.     }
  584. }
  585. func (o *Options) set(name string, value interface{}) OptionResult {
  586.     result := OptionResult{Name: name, Value: value}
  587.     switch name {
  588.     case "env":
  589.         menv, ok := value.(map[string]interface{})
  590.         if !ok {
  591.             result.errorf("invalid type %T, expect map", value)
  592.             break
  593.         }
  594.         if o.Env == nil {
  595.             o.Env = make(map[string]string)
  596.         }
  597.         for k, v := range menv {
  598.             o.Env[k] = fmt.Sprint(v)
  599.         }
  600.     case "buildFlags":
  601.         iflags, ok := value.([]interface{})
  602.         if !ok {
  603.             result.errorf("invalid type %T, expect list", value)
  604.             break
  605.         }
  606.         flags := make([]string, 0, len(iflags))
  607.         for _, flag := range iflags {
  608.             flags = append(flags, fmt.Sprintf("%s", flag))
  609.         }
  610.         o.BuildFlags = flags
  611.     case "directoryFilters":
  612.         ifilters, ok := value.([]interface{})
  613.         if !ok {
  614.             result.errorf("invalid type %T, expect list", value)
  615.             break
  616.         }
  617.         var filters []string
  618.         for _, ifilter := range ifilters {
  619.             filter := fmt.Sprint(ifilter)
  620.             if filter[0] != '+' && filter[0] != '-' {
  621.                 result.errorf("invalid filter %q, must start with + or -", filter)
  622.                 return result
  623.             }
  624.             filters = append(filters, filepath.FromSlash(filter))
  625.         }
  626.         o.DirectoryFilters = filters
  627.     case "completionDocumentation":
  628.         result.setBool(&o.CompletionDocumentation)
  629.     case "usePlaceholders":
  630.         result.setBool(&o.UsePlaceholders)
  631.     case "deepCompletion":
  632.         result.setBool(&o.DeepCompletion)
  633.     case "completeUnimported":
  634.         result.setBool(&o.CompleteUnimported)
  635.     case "completionBudget":
  636.         result.setDuration(&o.CompletionBudget)
  637.     case "matcher":
  638.         if s, ok := result.asOneOf(
  639.             string(Fuzzy),
  640.             string(CaseSensitive),
  641.             string(CaseInsensitive),
  642.         ); ok {
  643.             o.Matcher = Matcher(s)
  644.         }
  645.     case "symbolMatcher":
  646.         if s, ok := result.asOneOf(
  647.             string(SymbolFuzzy),
  648.             string(SymbolCaseInsensitive),
  649.             string(SymbolCaseSensitive),
  650.         ); ok {
  651.             o.SymbolMatcher = SymbolMatcher(s)
  652.         }
  653.     case "symbolStyle":
  654.         if s, ok := result.asOneOf(
  655.             string(FullyQualifiedSymbols),
  656.             string(PackageQualifiedSymbols),
  657.             string(DynamicSymbols),
  658.         ); ok {
  659.             o.SymbolStyle = SymbolStyle(s)
  660.         }
  661.     case "hoverKind":
  662.         if s, ok := result.asOneOf(
  663.             string(NoDocumentation),
  664.             string(SingleLine),
  665.             string(SynopsisDocumentation),
  666.             string(FullDocumentation),
  667.             string(Structured),
  668.         ); ok {
  669.             o.HoverKind = HoverKind(s)
  670.         }
  671.     case "linkTarget":
  672.         result.setString(&o.LinkTarget)
  673.     case "linksInHover":
  674.         result.setBool(&o.LinksInHover)
  675.     case "importShortcut":
  676.         if s, ok := result.asOneOf(string(Both), string(Link), string(Definition)); ok {
  677.             o.ImportShortcut = ImportShortcut(s)
  678.         }
  679.     case "analyses":
  680.         result.setBoolMap(&o.Analyses)
  681.     case "annotations":
  682.         result.setBoolMap(&o.Annotations)
  683.         for k := range o.Annotations {
  684.             switch k {
  685.             case "noEscape", "noNilcheck", "noInline", "noBounds":
  686.                 continue
  687.             default:
  688.                 result.Name += ":" + k // put mistake(s) in the message
  689.                 result.State = OptionUnexpected
  690.             }
  691.         }
  692.     case "codelenses", "codelens":
  693.         var lensOverrides map[string]bool
  694.         result.setBoolMap(&lensOverrides)
  695.         if result.Error == nil {
  696.             if o.Codelenses == nil {
  697.                 o.Codelenses = make(map[string]bool)
  698.             }
  699.             for lens, enabled := range lensOverrides {
  700.                 o.Codelenses[lens] = enabled
  701.             }
  702.         }
  703.         // codelens is deprecated, but still works for now.
  704.         // TODO(rstambler): Remove this for the gopls/v0.7.0 release.
  705.         if name == "codelens" {
  706.             result.State = OptionDeprecated
  707.             result.Replacement = "codelenses"
  708.         }
  709.     case "staticcheck":
  710.         result.setBool(&o.Staticcheck)
  711.     case "local":
  712.         result.setString(&o.Local)
  713.     case "verboseOutput":
  714.         result.setBool(&o.VerboseOutput)
  715.     case "verboseWorkDoneProgress":
  716.         result.setBool(&o.VerboseWorkDoneProgress)
  717.     case "tempModfile":
  718.         result.setBool(&o.TempModfile)
  719.     case "gofumpt":
  720.         result.setBool(&o.Gofumpt)
  721.     case "semanticTokens":
  722.         result.setBool(&o.SemanticTokens)
  723.     case "expandWorkspaceToModule":
  724.         result.setBool(&o.ExpandWorkspaceToModule)
  725.     case "experimentalWorkspaceModule":
  726.         result.setBool(&o.ExperimentalWorkspaceModule)
  727.     case "experimentalDiagnosticsDelay":
  728.         result.setDuration(&o.ExperimentalDiagnosticsDelay)
  729.     case "experimentalPackageCacheKey":
  730.         result.setBool(&o.ExperimentalPackageCacheKey)
  731.     case "allowModfileModifications":
  732.         result.setBool(&o.AllowModfileModifications)
  733.     case "allowImplicitNetworkAccess":
  734.         result.setBool(&o.AllowImplicitNetworkAccess)
  735.     case "allExperiments":
  736.         // This setting should be handled before all of the other options are
  737.         // processed, so do nothing here.
  738.     // Replaced settings.
  739.     case "experimentalDisabledAnalyses":
  740.         result.State = OptionDeprecated
  741.         result.Replacement = "analyses"
  742.     case "disableDeepCompletion":
  743.         result.State = OptionDeprecated
  744.         result.Replacement = "deepCompletion"
  745.     case "disableFuzzyMatching":
  746.         result.State = OptionDeprecated
  747.         result.Replacement = "fuzzyMatching"
  748.     case "wantCompletionDocumentation":
  749.         result.State = OptionDeprecated
  750.         result.Replacement = "completionDocumentation"
  751.     case "wantUnimportedCompletions":
  752.         result.State = OptionDeprecated
  753.         result.Replacement = "completeUnimported"
  754.     case "fuzzyMatching":
  755.         result.State = OptionDeprecated
  756.         result.Replacement = "matcher"
  757.     case "caseSensitiveCompletion":
  758.         result.State = OptionDeprecated
  759.         result.Replacement = "matcher"
  760.     // Deprecated settings.
  761.     case "wantSuggestedFixes":
  762.         result.State = OptionDeprecated
  763.     case "noIncrementalSync":
  764.         result.State = OptionDeprecated
  765.     case "watchFileChanges":
  766.         result.State = OptionDeprecated
  767.     case "go-diff":
  768.         result.State = OptionDeprecated
  769.     default:
  770.         result.State = OptionUnexpected
  771.     }
  772.     return result
  773. }
  774. func (r *OptionResult) errorf(msg string, values ...interface{}) {
  775.     prefix := fmt.Sprintf("parsing setting %q: ", r.Name)
  776.     r.Error = errors.Errorf(prefix+msg, values...)
  777. }
  778. func (r *OptionResult) asBool() (bool, bool) {
  779.     b, ok := r.Value.(bool)
  780.     if !ok {
  781.         r.errorf("invalid type %T, expect bool", r.Value)
  782.         return false, false
  783.     }
  784.     return b, true
  785. }
  786. func (r *OptionResult) setBool(b *bool) {
  787.     if v, ok := r.asBool(); ok {
  788.         *b = v
  789.     }
  790. }
  791. func (r *OptionResult) setDuration(d *time.Duration) {
  792.     if v, ok := r.asString(); ok {
  793.         parsed, err := time.ParseDuration(v)
  794.         if err != nil {
  795.             r.errorf("failed to parse duration %q: %v", v, err)
  796.             return
  797.         }
  798.         *d = parsed
  799.     }
  800. }
  801. func (r *OptionResult) setBoolMap(bm *map[string]bool) {
  802.     all, ok := r.Value.(map[string]interface{})
  803.     if !ok {
  804.         r.errorf("invalid type %T for map[string]bool option", r.Value)
  805.         return
  806.     }
  807.     m := make(map[string]bool)
  808.     for a, enabled := range all {
  809.         if enabled, ok := enabled.(bool); ok {
  810.             m[a] = enabled
  811.         } else {
  812.             r.errorf("invalid type %T for map key %q", enabled, a)
  813.             return
  814.         }
  815.     }
  816.     *bm = m
  817. }
  818. func (r *OptionResult) asString() (string, bool) {
  819.     b, ok := r.Value.(string)
  820.     if !ok {
  821.         r.errorf("invalid type %T, expect string", r.Value)
  822.         return "", false
  823.     }
  824.     return b, true
  825. }
  826. func (r *OptionResult) asOneOf(options ...string) (string, bool) {
  827.     s, ok := r.asString()
  828.     if !ok {
  829.         return "", false
  830.     }
  831.     lower := strings.ToLower(s)
  832.     for _, opt := range options {
  833.         if strings.ToLower(opt) == lower {
  834.             return opt, true
  835.         }
  836.     }
  837.     r.errorf("invalid option %q for enum", r.Value)
  838.     return "", false
  839. }
  840. func (r *OptionResult) setString(s *string) {
  841.     if v, ok := r.asString(); ok {
  842.         *s = v
  843.     }
  844. }
  845. // EnabledAnalyzers returns all of the analyzers enabled for the given
  846. // snapshot.
  847. func EnabledAnalyzers(snapshot Snapshot) (analyzers []Analyzer) {
  848.     for _, a := range snapshot.View().Options().DefaultAnalyzers {
  849.         if a.IsEnabled(snapshot.View()) {
  850.             analyzers = append(analyzers, a)
  851.         }
  852.     }
  853.     for _, a := range snapshot.View().Options().TypeErrorAnalyzers {
  854.         if a.IsEnabled(snapshot.View()) {
  855.             analyzers = append(analyzers, a)
  856.         }
  857.     }
  858.     for _, a := range snapshot.View().Options().ConvenienceAnalyzers {
  859.         if a.IsEnabled(snapshot.View()) {
  860.             analyzers = append(analyzers, a)
  861.         }
  862.     }
  863.     for _, a := range snapshot.View().Options().StaticcheckAnalyzers {
  864.         if a.IsEnabled(snapshot.View()) {
  865.             analyzers = append(analyzers, a)
  866.         }
  867.     }
  868.     return analyzers
  869. }
  870. func typeErrorAnalyzers() map[string]Analyzer {
  871.     return map[string]Analyzer{
  872.         fillreturns.Analyzer.Name: {
  873.             Analyzer:       fillreturns.Analyzer,
  874.             FixesError:     fillreturns.FixesError,
  875.             HighConfidence: true,
  876.             Enabled:        true,
  877.         },
  878.         nonewvars.Analyzer.Name: {
  879.             Analyzer:   nonewvars.Analyzer,
  880.             FixesError: nonewvars.FixesError,
  881.             Enabled:    true,
  882.         },
  883.         noresultvalues.Analyzer.Name: {
  884.             Analyzer:   noresultvalues.Analyzer,
  885.             FixesError: noresultvalues.FixesError,
  886.             Enabled:    true,
  887.         },
  888.         undeclaredname.Analyzer.Name: {
  889.             Analyzer:   undeclaredname.Analyzer,
  890.             FixesError: undeclaredname.FixesError,
  891.             Command:    CommandUndeclaredName,
  892.             Enabled:    true,
  893.         },
  894.     }
  895. }
  896. func convenienceAnalyzers() map[string]Analyzer {
  897.     return map[string]Analyzer{
  898.         fillstruct.Analyzer.Name: {
  899.             Analyzer: fillstruct.Analyzer,
  900.             Command:  CommandFillStruct,
  901.             Enabled:  true,
  902.         },
  903.     }
  904. }
  905. func defaultAnalyzers() map[string]Analyzer {
  906.     return map[string]Analyzer{
  907.         // The traditional vet suite:
  908.         asmdecl.Analyzer.Name:       {Analyzer: asmdecl.Analyzer, Enabled: true},
  909.         assign.Analyzer.Name:        {Analyzer: assign.Analyzer, Enabled: true},
  910.         atomic.Analyzer.Name:        {Analyzer: atomic.Analyzer, Enabled: true},
  911.         bools.Analyzer.Name:         {Analyzer: bools.Analyzer, Enabled: true},
  912.         buildtag.Analyzer.Name:      {Analyzer: buildtag.Analyzer, Enabled: true},
  913.         cgocall.Analyzer.Name:       {Analyzer: cgocall.Analyzer, Enabled: true},
  914.         composite.Analyzer.Name:     {Analyzer: composite.Analyzer, Enabled: true},
  915.         copylock.Analyzer.Name:      {Analyzer: copylock.Analyzer, Enabled: true},
  916.         errorsas.Analyzer.Name:      {Analyzer: errorsas.Analyzer, Enabled: true},
  917.         httpresponse.Analyzer.Name:  {Analyzer: httpresponse.Analyzer, Enabled: true},
  918.         ifaceassert.Analyzer.Name:   {Analyzer: ifaceassert.Analyzer, Enabled: true},
  919.         loopclosure.Analyzer.Name:   {Analyzer: loopclosure.Analyzer, Enabled: true},
  920.         lostcancel.Analyzer.Name:    {Analyzer: lostcancel.Analyzer, Enabled: true},
  921.         nilfunc.Analyzer.Name:       {Analyzer: nilfunc.Analyzer, Enabled: true},
  922.         printf.Analyzer.Name:        {Analyzer: printf.Analyzer, Enabled: true},
  923.         shift.Analyzer.Name:         {Analyzer: shift.Analyzer, Enabled: true},
  924.         stdmethods.Analyzer.Name:    {Analyzer: stdmethods.Analyzer, Enabled: true},
  925.         stringintconv.Analyzer.Name: {Analyzer: stringintconv.Analyzer, Enabled: true},
  926.         structtag.Analyzer.Name:     {Analyzer: structtag.Analyzer, Enabled: true},
  927.         tests.Analyzer.Name:         {Analyzer: tests.Analyzer, Enabled: true},
  928.         unmarshal.Analyzer.Name:     {Analyzer: unmarshal.Analyzer, Enabled: true},
  929.         unreachable.Analyzer.Name:   {Analyzer: unreachable.Analyzer, Enabled: true},
  930.         unsafeptr.Analyzer.Name:     {Analyzer: unsafeptr.Analyzer, Enabled: true},
  931.         unusedresult.Analyzer.Name:  {Analyzer: unusedresult.Analyzer, Enabled: true},
  932.         // Non-vet analyzers:
  933.         atomicalign.Analyzer.Name:      {Analyzer: atomicalign.Analyzer, Enabled: true},
  934.         deepequalerrors.Analyzer.Name:  {Analyzer: deepequalerrors.Analyzer, Enabled: true},
  935.         fieldalignment.Analyzer.Name:   {Analyzer: fieldalignment.Analyzer, Enabled: false},
  936.         shadow.Analyzer.Name:           {Analyzer: shadow.Analyzer, Enabled: false},
  937.         sortslice.Analyzer.Name:        {Analyzer: sortslice.Analyzer, Enabled: true},
  938.         testinggoroutine.Analyzer.Name: {Analyzer: testinggoroutine.Analyzer, Enabled: true},
  939.         unusedparams.Analyzer.Name:     {Analyzer: unusedparams.Analyzer, Enabled: false},
  940.         // gofmt -s suite:
  941.         simplifycompositelit.Analyzer.Name: {Analyzer: simplifycompositelit.Analyzer, Enabled: true, HighConfidence: true},
  942.         simplifyrange.Analyzer.Name:        {Analyzer: simplifyrange.Analyzer, Enabled: true, HighConfidence: true},
  943.         simplifyslice.Analyzer.Name:        {Analyzer: simplifyslice.Analyzer, Enabled: true, HighConfidence: true},
  944.     }
  945. }
  946. func urlRegexp() *regexp.Regexp {
  947.     // Ensure links are matched as full words, not anywhere.
  948.     re := regexp.MustCompile(`\b(http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?\b`)
  949.     re.Longest()
  950.     return re
  951. }
  952. type APIJSON struct {
  953.     Options  map[string][]*OptionJSON
  954.     Commands []*CommandJSON
  955.     Lenses   []*LensJSON
  956. }
  957. type OptionJSON struct {
  958.     Name       string
  959.     Type       string
  960.     Doc        string
  961.     EnumValues []EnumValue
  962.     Default    string
  963. }
  964. type EnumValue struct {
  965.     Value string
  966.     Doc   string
  967. }
  968. type CommandJSON struct {
  969.     Command string
  970.     Title   string
  971.     Doc     string
  972. }
  973. type LensJSON struct {
  974.     Lens  string
  975.     Title string
  976.     Doc   string
  977. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×