github.com/april1989/origin-go-tools@v0.0.32/internal/lsp/source/options.go (about) 1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package source 6 7 import ( 8 "context" 9 "fmt" 10 "os" 11 "regexp" 12 "time" 13 14 "github.com/april1989/origin-go-tools/go/analysis" 15 "github.com/april1989/origin-go-tools/go/analysis/passes/asmdecl" 16 "github.com/april1989/origin-go-tools/go/analysis/passes/assign" 17 "github.com/april1989/origin-go-tools/go/analysis/passes/atomic" 18 "github.com/april1989/origin-go-tools/go/analysis/passes/atomicalign" 19 "github.com/april1989/origin-go-tools/go/analysis/passes/bools" 20 "github.com/april1989/origin-go-tools/go/analysis/passes/buildtag" 21 "github.com/april1989/origin-go-tools/go/analysis/passes/cgocall" 22 "github.com/april1989/origin-go-tools/go/analysis/passes/composite" 23 "github.com/april1989/origin-go-tools/go/analysis/passes/copylock" 24 "github.com/april1989/origin-go-tools/go/analysis/passes/deepequalerrors" 25 "github.com/april1989/origin-go-tools/go/analysis/passes/errorsas" 26 "github.com/april1989/origin-go-tools/go/analysis/passes/httpresponse" 27 "github.com/april1989/origin-go-tools/go/analysis/passes/loopclosure" 28 "github.com/april1989/origin-go-tools/go/analysis/passes/lostcancel" 29 "github.com/april1989/origin-go-tools/go/analysis/passes/nilfunc" 30 "github.com/april1989/origin-go-tools/go/analysis/passes/printf" 31 "github.com/april1989/origin-go-tools/go/analysis/passes/shift" 32 "github.com/april1989/origin-go-tools/go/analysis/passes/sortslice" 33 "github.com/april1989/origin-go-tools/go/analysis/passes/stdmethods" 34 "github.com/april1989/origin-go-tools/go/analysis/passes/structtag" 35 "github.com/april1989/origin-go-tools/go/analysis/passes/testinggoroutine" 36 "github.com/april1989/origin-go-tools/go/analysis/passes/tests" 37 "github.com/april1989/origin-go-tools/go/analysis/passes/unmarshal" 38 "github.com/april1989/origin-go-tools/go/analysis/passes/unreachable" 39 "github.com/april1989/origin-go-tools/go/analysis/passes/unsafeptr" 40 "github.com/april1989/origin-go-tools/go/analysis/passes/unusedresult" 41 "github.com/april1989/origin-go-tools/internal/lsp/analysis/fillreturns" 42 "github.com/april1989/origin-go-tools/internal/lsp/analysis/fillstruct" 43 "github.com/april1989/origin-go-tools/internal/lsp/analysis/nonewvars" 44 "github.com/april1989/origin-go-tools/internal/lsp/analysis/noresultvalues" 45 "github.com/april1989/origin-go-tools/internal/lsp/analysis/simplifycompositelit" 46 "github.com/april1989/origin-go-tools/internal/lsp/analysis/simplifyrange" 47 "github.com/april1989/origin-go-tools/internal/lsp/analysis/simplifyslice" 48 "github.com/april1989/origin-go-tools/internal/lsp/analysis/undeclaredname" 49 "github.com/april1989/origin-go-tools/internal/lsp/analysis/unusedparams" 50 "github.com/april1989/origin-go-tools/internal/lsp/diff" 51 "github.com/april1989/origin-go-tools/internal/lsp/diff/myers" 52 "github.com/april1989/origin-go-tools/internal/lsp/protocol" 53 errors "golang.org/x/xerrors" 54 ) 55 56 // DefaultOptions is the options that are used for Gopls execution independent 57 // of any externally provided configuration (LSP initialization, command 58 // invokation, etc.). 59 func DefaultOptions() Options { 60 var commands []string 61 for _, c := range Commands { 62 commands = append(commands, c.Name) 63 } 64 return Options{ 65 ClientOptions: ClientOptions{ 66 InsertTextFormat: protocol.PlainTextTextFormat, 67 PreferredContentFormat: protocol.Markdown, 68 ConfigurationSupported: true, 69 DynamicConfigurationSupported: true, 70 DynamicWatchedFilesSupported: true, 71 LineFoldingOnly: false, 72 HierarchicalDocumentSymbolSupport: true, 73 }, 74 ServerOptions: ServerOptions{ 75 SupportedCodeActions: map[FileKind]map[protocol.CodeActionKind]bool{ 76 Go: { 77 protocol.SourceFixAll: true, 78 protocol.SourceOrganizeImports: true, 79 protocol.QuickFix: true, 80 protocol.RefactorRewrite: true, 81 protocol.RefactorExtract: true, 82 }, 83 Mod: { 84 protocol.SourceOrganizeImports: true, 85 }, 86 Sum: {}, 87 }, 88 SupportedCommands: commands, 89 }, 90 UserOptions: UserOptions{ 91 Env: os.Environ(), 92 HoverKind: FullDocumentation, 93 LinkTarget: "pkg.go.dev", 94 LinksInHover: true, 95 Matcher: Fuzzy, 96 SymbolMatcher: SymbolFuzzy, 97 DeepCompletion: true, 98 UnimportedCompletion: true, 99 CompletionDocumentation: true, 100 EnabledCodeLens: map[string]bool{ 101 CommandGenerate.Name: true, 102 CommandRegenerateCgo.Name: true, 103 CommandTidy.Name: true, 104 CommandToggleDetails.Name: false, 105 CommandUpgradeDependency.Name: true, 106 CommandVendor.Name: true, 107 }, 108 ExpandWorkspaceToModule: true, 109 }, 110 DebuggingOptions: DebuggingOptions{ 111 CompletionBudget: 100 * time.Millisecond, 112 LiteralCompletions: true, 113 }, 114 ExperimentalOptions: ExperimentalOptions{ 115 TempModfile: true, 116 }, 117 Hooks: Hooks{ 118 ComputeEdits: myers.ComputeEdits, 119 URLRegexp: urlRegexp(), 120 DefaultAnalyzers: defaultAnalyzers(), 121 TypeErrorAnalyzers: typeErrorAnalyzers(), 122 ConvenienceAnalyzers: convenienceAnalyzers(), 123 GoDiff: true, 124 }, 125 } 126 } 127 128 // Options holds various configuration that affects Gopls execution, organized 129 // by the nature or origin of the settings. 130 type Options struct { 131 ClientOptions 132 ServerOptions 133 UserOptions 134 DebuggingOptions 135 ExperimentalOptions 136 Hooks 137 } 138 139 // ClientOptions holds LSP-specific configuration that is provided by the 140 // client. 141 type ClientOptions struct { 142 InsertTextFormat protocol.InsertTextFormat 143 ConfigurationSupported bool 144 DynamicConfigurationSupported bool 145 DynamicWatchedFilesSupported bool 146 PreferredContentFormat protocol.MarkupKind 147 LineFoldingOnly bool 148 HierarchicalDocumentSymbolSupport bool 149 } 150 151 // ServerOptions holds LSP-specific configuration that is provided by the 152 // server. 153 type ServerOptions struct { 154 SupportedCodeActions map[FileKind]map[protocol.CodeActionKind]bool 155 SupportedCommands []string 156 } 157 158 // UserOptions holds custom Gopls configuration (not part of the LSP) that is 159 // modified by the client. 160 type UserOptions struct { 161 // Env is the current set of environment overrides on this view. 162 Env []string 163 164 // BuildFlags is used to adjust the build flags applied to the view. 165 BuildFlags []string 166 167 // HoverKind specifies the format of the content for hover requests. 168 HoverKind HoverKind 169 170 // UserEnabledAnalyses specifies analyses that the user would like to enable 171 // or disable. A map of the names of analysis passes that should be 172 // enabled/disabled. A full list of analyzers that gopls uses can be found 173 // [here](analyzers.md). 174 // 175 // Example Usage: 176 // ... 177 // "analyses": { 178 // "unreachable": false, // Disable the unreachable analyzer. 179 // "unusedparams": true // Enable the unusedparams analyzer. 180 // } 181 UserEnabledAnalyses map[string]bool 182 183 // EnabledCodeLens specifies which codelens are enabled, keyed by the gopls 184 // command that they provide. 185 EnabledCodeLens map[string]bool 186 187 // StaticCheck enables additional analyses from staticcheck.io. 188 StaticCheck bool 189 190 // LinkTarget is the website used for documentation. If empty, no link is 191 // provided. 192 LinkTarget string 193 194 // LinksInHover toggles the presence of links to documentation in hover. 195 LinksInHover bool 196 197 // ImportShortcut specifies whether import statements should link to 198 // documentation or go to definitions. The default is both. 199 ImportShortcut ImportShortcut 200 201 // LocalPrefix is used to specify goimports's -local behavior. 202 LocalPrefix string 203 204 // Matcher specifies the type of matcher to use for completion requests. 205 Matcher Matcher 206 207 // SymbolMatcher specifies the type of matcher to use for symbol requests. 208 SymbolMatcher SymbolMatcher 209 210 // SymbolStyle specifies what style of symbols to return in symbol requests 211 // (package qualified, fully qualified, etc). 212 SymbolStyle SymbolStyle 213 214 // DeepCompletion allows completion to perform nested searches through 215 // possible candidates. 216 DeepCompletion bool 217 218 // UnimportedCompletion enables completion for unimported packages. 219 UnimportedCompletion bool 220 221 // CompletionDocumentation returns additional documentation with completion 222 // requests. 223 CompletionDocumentation bool 224 225 // Placeholders adds placeholders to parameters and structs in completion 226 // results. 227 Placeholders bool 228 229 // Gofumpt indicates if we should run gofumpt formatting. 230 Gofumpt bool 231 232 // ExpandWorkspaceToModule is true if we should expand the scope of the 233 // workspace to include the modules containing the workspace folders. 234 ExpandWorkspaceToModule bool 235 } 236 237 type ImportShortcut int 238 239 const ( 240 Both ImportShortcut = iota 241 Link 242 Definition 243 ) 244 245 func (s ImportShortcut) ShowLinks() bool { 246 return s == Both || s == Link 247 } 248 249 func (s ImportShortcut) ShowDefinition() bool { 250 return s == Both || s == Definition 251 } 252 253 type completionOptions struct { 254 deepCompletion bool 255 unimported bool 256 documentation bool 257 fullDocumentation bool 258 placeholders bool 259 literal bool 260 matcher Matcher 261 budget time.Duration 262 } 263 264 // Hooks contains configuration that is provided to the Gopls command by the 265 // main package. 266 type Hooks struct { 267 GoDiff bool 268 ComputeEdits diff.ComputeEdits 269 URLRegexp *regexp.Regexp 270 DefaultAnalyzers map[string]Analyzer 271 TypeErrorAnalyzers map[string]Analyzer 272 ConvenienceAnalyzers map[string]Analyzer 273 GofumptFormat func(ctx context.Context, src []byte) ([]byte, error) 274 } 275 276 func (o Options) AddDefaultAnalyzer(a *analysis.Analyzer) { 277 o.DefaultAnalyzers[a.Name] = Analyzer{Analyzer: a, enabled: true} 278 } 279 280 // ExperimentalOptions defines configuration for features under active 281 // development. WARNING: This configuration will be changed in the future. It 282 // only exists while these features are under development. 283 type ExperimentalOptions struct { 284 // TempModfile controls the use of the -modfile flag in Go 1.14. 285 TempModfile bool 286 287 // VerboseWorkDoneProgress controls whether the LSP server should send 288 // progress reports for all work done outside the scope of an RPC. 289 VerboseWorkDoneProgress bool 290 291 // Annotations suppress various kinds of optimization diagnostics 292 // that would be reported by the gc_details command. 293 // noNilcheck suppresses display of nilchecks. 294 // noEscape suppresses escape choices. 295 // noInline suppresses inlining choices. 296 // noBounds suppresses bounds checking diagnositcs. 297 Annotations map[string]bool 298 } 299 300 // DebuggingOptions should not affect the logical execution of Gopls, but may 301 // be altered for debugging purposes. 302 type DebuggingOptions struct { 303 VerboseOutput bool 304 305 // CompletionBudget is the soft latency goal for completion requests. Most 306 // requests finish in a couple milliseconds, but in some cases deep 307 // completions can take much longer. As we use up our budget we 308 // dynamically reduce the search scope to ensure we return timely 309 // results. Zero means unlimited. 310 CompletionBudget time.Duration 311 312 // LiteralCompletions controls whether literal candidates such as 313 // "&someStruct{}" are offered. Tests disable this flag to simplify 314 // their expected values. 315 LiteralCompletions bool 316 } 317 318 type Matcher int 319 320 const ( 321 Fuzzy = Matcher(iota) 322 CaseInsensitive 323 CaseSensitive 324 ) 325 326 type SymbolMatcher int 327 328 const ( 329 SymbolFuzzy = SymbolMatcher(iota) 330 SymbolCaseInsensitive 331 SymbolCaseSensitive 332 ) 333 334 type SymbolStyle int 335 336 const ( 337 PackageQualifiedSymbols = SymbolStyle(iota) 338 FullyQualifiedSymbols 339 DynamicSymbols 340 ) 341 342 type HoverKind int 343 344 const ( 345 SingleLine = HoverKind(iota) 346 NoDocumentation 347 SynopsisDocumentation 348 FullDocumentation 349 350 // Structured is an experimental setting that returns a structured hover format. 351 // This format separates the signature from the documentation, so that the client 352 // can do more manipulation of these fields. 353 // 354 // This should only be used by clients that support this behavior. 355 Structured 356 ) 357 358 type OptionResults []OptionResult 359 360 type OptionResult struct { 361 Name string 362 Value interface{} 363 Error error 364 365 State OptionState 366 Replacement string 367 } 368 369 type OptionState int 370 371 const ( 372 OptionHandled = OptionState(iota) 373 OptionDeprecated 374 OptionUnexpected 375 ) 376 377 type LinkTarget string 378 379 func SetOptions(options *Options, opts interface{}) OptionResults { 380 var results OptionResults 381 switch opts := opts.(type) { 382 case nil: 383 case map[string]interface{}: 384 for name, value := range opts { 385 results = append(results, options.set(name, value)) 386 } 387 default: 388 results = append(results, OptionResult{ 389 Value: opts, 390 Error: errors.Errorf("Invalid options type %T", opts), 391 }) 392 } 393 return results 394 } 395 396 func (o *Options) ForClientCapabilities(caps protocol.ClientCapabilities) { 397 // Check if the client supports snippets in completion items. 398 if c := caps.TextDocument.Completion; c.CompletionItem.SnippetSupport { 399 o.InsertTextFormat = protocol.SnippetTextFormat 400 } 401 // Check if the client supports configuration messages. 402 o.ConfigurationSupported = caps.Workspace.Configuration 403 o.DynamicConfigurationSupported = caps.Workspace.DidChangeConfiguration.DynamicRegistration 404 o.DynamicWatchedFilesSupported = caps.Workspace.DidChangeWatchedFiles.DynamicRegistration 405 406 // Check which types of content format are supported by this client. 407 if hover := caps.TextDocument.Hover; len(hover.ContentFormat) > 0 { 408 o.PreferredContentFormat = hover.ContentFormat[0] 409 } 410 // Check if the client supports only line folding. 411 fr := caps.TextDocument.FoldingRange 412 o.LineFoldingOnly = fr.LineFoldingOnly 413 // Check if the client supports hierarchical document symbols. 414 o.HierarchicalDocumentSymbolSupport = caps.TextDocument.DocumentSymbol.HierarchicalDocumentSymbolSupport 415 } 416 417 func (o *Options) set(name string, value interface{}) OptionResult { 418 result := OptionResult{Name: name, Value: value} 419 switch name { 420 case "env": 421 menv, ok := value.(map[string]interface{}) 422 if !ok { 423 result.errorf("invalid config gopls.env type %T", value) 424 break 425 } 426 for k, v := range menv { 427 o.Env = append(o.Env, fmt.Sprintf("%s=%s", k, v)) 428 } 429 430 case "buildFlags": 431 iflags, ok := value.([]interface{}) 432 if !ok { 433 result.errorf("invalid config gopls.buildFlags type %T", value) 434 break 435 } 436 flags := make([]string, 0, len(iflags)) 437 for _, flag := range iflags { 438 flags = append(flags, fmt.Sprintf("%s", flag)) 439 } 440 o.BuildFlags = flags 441 442 case "completionDocumentation": 443 result.setBool(&o.CompletionDocumentation) 444 case "usePlaceholders": 445 result.setBool(&o.Placeholders) 446 case "deepCompletion": 447 result.setBool(&o.DeepCompletion) 448 case "completeUnimported": 449 result.setBool(&o.UnimportedCompletion) 450 case "completionBudget": 451 if v, ok := result.asString(); ok { 452 d, err := time.ParseDuration(v) 453 if err != nil { 454 result.errorf("failed to parse duration %q: %v", v, err) 455 break 456 } 457 o.CompletionBudget = d 458 } 459 460 case "matcher": 461 matcher, ok := result.asString() 462 if !ok { 463 break 464 } 465 switch matcher { 466 case "fuzzy": 467 o.Matcher = Fuzzy 468 case "caseSensitive": 469 o.Matcher = CaseSensitive 470 default: 471 o.Matcher = CaseInsensitive 472 } 473 474 case "symbolMatcher": 475 matcher, ok := result.asString() 476 if !ok { 477 break 478 } 479 switch matcher { 480 case "fuzzy": 481 o.SymbolMatcher = SymbolFuzzy 482 case "caseSensitive": 483 o.SymbolMatcher = SymbolCaseSensitive 484 default: 485 o.SymbolMatcher = SymbolCaseInsensitive 486 } 487 488 case "symbolStyle": 489 style, ok := result.asString() 490 if !ok { 491 break 492 } 493 switch style { 494 case "full": 495 o.SymbolStyle = FullyQualifiedSymbols 496 case "dynamic": 497 o.SymbolStyle = DynamicSymbols 498 case "package": 499 o.SymbolStyle = PackageQualifiedSymbols 500 default: 501 result.errorf("Unsupported symbol style %q", style) 502 } 503 504 case "hoverKind": 505 hoverKind, ok := result.asString() 506 if !ok { 507 break 508 } 509 switch hoverKind { 510 case "NoDocumentation": 511 o.HoverKind = NoDocumentation 512 case "SingleLine": 513 o.HoverKind = SingleLine 514 case "SynopsisDocumentation": 515 o.HoverKind = SynopsisDocumentation 516 case "FullDocumentation": 517 o.HoverKind = FullDocumentation 518 case "Structured": 519 o.HoverKind = Structured 520 default: 521 result.errorf("Unsupported hover kind %q", hoverKind) 522 } 523 524 case "linkTarget": 525 result.setString(&o.LinkTarget) 526 527 case "linksInHover": 528 result.setBool(&o.LinksInHover) 529 530 case "importShortcut": 531 var s string 532 result.setString(&s) 533 switch s { 534 case "both": 535 o.ImportShortcut = Both 536 case "link": 537 o.ImportShortcut = Link 538 case "definition": 539 o.ImportShortcut = Definition 540 } 541 542 case "analyses": 543 result.setBoolMap(&o.UserEnabledAnalyses) 544 545 case "annotations": 546 result.setBoolMap(&o.Annotations) 547 for k := range o.Annotations { 548 switch k { 549 case "noEscape", "noNilcheck", "noInline", "noBounds": 550 continue 551 default: 552 result.Name += ":" + k // put mistake(s) in the message 553 result.State = OptionUnexpected 554 } 555 } 556 557 case "codelens": 558 var lensOverrides map[string]bool 559 result.setBoolMap(&lensOverrides) 560 if result.Error == nil { 561 if o.EnabledCodeLens == nil { 562 o.EnabledCodeLens = make(map[string]bool) 563 } 564 for lens, enabled := range lensOverrides { 565 o.EnabledCodeLens[lens] = enabled 566 } 567 } 568 569 case "staticcheck": 570 result.setBool(&o.StaticCheck) 571 572 case "local": 573 result.setString(&o.LocalPrefix) 574 575 case "verboseOutput": 576 result.setBool(&o.VerboseOutput) 577 578 case "verboseWorkDoneProgress": 579 result.setBool(&o.VerboseWorkDoneProgress) 580 581 case "tempModfile": 582 result.setBool(&o.TempModfile) 583 584 case "gofumpt": 585 result.setBool(&o.Gofumpt) 586 587 case "expandWorkspaceToModule": 588 result.setBool(&o.ExpandWorkspaceToModule) 589 590 // Replaced settings. 591 case "experimentalDisabledAnalyses": 592 result.State = OptionDeprecated 593 result.Replacement = "analyses" 594 595 case "disableDeepCompletion": 596 result.State = OptionDeprecated 597 result.Replacement = "deepCompletion" 598 599 case "disableFuzzyMatching": 600 result.State = OptionDeprecated 601 result.Replacement = "fuzzyMatching" 602 603 case "wantCompletionDocumentation": 604 result.State = OptionDeprecated 605 result.Replacement = "completionDocumentation" 606 607 case "wantUnimportedCompletions": 608 result.State = OptionDeprecated 609 result.Replacement = "completeUnimported" 610 611 case "fuzzyMatching": 612 result.State = OptionDeprecated 613 result.Replacement = "matcher" 614 615 case "caseSensitiveCompletion": 616 result.State = OptionDeprecated 617 result.Replacement = "matcher" 618 619 // Deprecated settings. 620 case "wantSuggestedFixes": 621 result.State = OptionDeprecated 622 623 case "noIncrementalSync": 624 result.State = OptionDeprecated 625 626 case "watchFileChanges": 627 result.State = OptionDeprecated 628 629 case "go-diff": 630 result.State = OptionDeprecated 631 632 default: 633 result.State = OptionUnexpected 634 } 635 return result 636 } 637 638 func (r *OptionResult) errorf(msg string, values ...interface{}) { 639 r.Error = errors.Errorf(msg, values...) 640 } 641 642 func (r *OptionResult) asBool() (bool, bool) { 643 b, ok := r.Value.(bool) 644 if !ok { 645 r.errorf("Invalid type %T for bool option %q", r.Value, r.Name) 646 return false, false 647 } 648 return b, true 649 } 650 651 func (r *OptionResult) setBool(b *bool) { 652 if v, ok := r.asBool(); ok { 653 *b = v 654 } 655 } 656 657 func (r *OptionResult) setBoolMap(bm *map[string]bool) { 658 all, ok := r.Value.(map[string]interface{}) 659 if !ok { 660 r.errorf("Invalid type %T for map[string]interface{} option %q", r.Value, r.Name) 661 return 662 } 663 m := make(map[string]bool) 664 for a, enabled := range all { 665 if enabled, ok := enabled.(bool); ok { 666 m[a] = enabled 667 } else { 668 r.errorf("Invalid type %d for map key %q in option %q", a, r.Name) 669 return 670 } 671 } 672 *bm = m 673 } 674 675 func (r *OptionResult) asString() (string, bool) { 676 b, ok := r.Value.(string) 677 if !ok { 678 r.errorf("Invalid type %T for string option %q", r.Value, r.Name) 679 return "", false 680 } 681 return b, true 682 } 683 684 func (r *OptionResult) setString(s *string) { 685 if v, ok := r.asString(); ok { 686 *s = v 687 } 688 } 689 690 // EnabledAnalyzers returns all of the analyzers enabled for the given 691 // snapshot. 692 func EnabledAnalyzers(snapshot Snapshot) (analyzers []Analyzer) { 693 for _, a := range snapshot.View().Options().DefaultAnalyzers { 694 if a.Enabled(snapshot.View()) { 695 analyzers = append(analyzers, a) 696 } 697 } 698 for _, a := range snapshot.View().Options().TypeErrorAnalyzers { 699 if a.Enabled(snapshot.View()) { 700 analyzers = append(analyzers, a) 701 } 702 } 703 for _, a := range snapshot.View().Options().ConvenienceAnalyzers { 704 if a.Enabled(snapshot.View()) { 705 analyzers = append(analyzers, a) 706 } 707 } 708 return analyzers 709 } 710 711 func typeErrorAnalyzers() map[string]Analyzer { 712 return map[string]Analyzer{ 713 fillreturns.Analyzer.Name: { 714 Analyzer: fillreturns.Analyzer, 715 FixesError: fillreturns.FixesError, 716 HighConfidence: true, 717 enabled: true, 718 }, 719 nonewvars.Analyzer.Name: { 720 Analyzer: nonewvars.Analyzer, 721 FixesError: nonewvars.FixesError, 722 enabled: true, 723 }, 724 noresultvalues.Analyzer.Name: { 725 Analyzer: noresultvalues.Analyzer, 726 FixesError: noresultvalues.FixesError, 727 enabled: true, 728 }, 729 undeclaredname.Analyzer.Name: { 730 Analyzer: undeclaredname.Analyzer, 731 FixesError: undeclaredname.FixesError, 732 Command: CommandUndeclaredName, 733 enabled: true, 734 }, 735 } 736 } 737 738 func convenienceAnalyzers() map[string]Analyzer { 739 return map[string]Analyzer{ 740 fillstruct.Analyzer.Name: { 741 Analyzer: fillstruct.Analyzer, 742 Command: CommandFillStruct, 743 enabled: true, 744 }, 745 } 746 } 747 748 func defaultAnalyzers() map[string]Analyzer { 749 return map[string]Analyzer{ 750 // The traditional vet suite: 751 asmdecl.Analyzer.Name: {Analyzer: asmdecl.Analyzer, enabled: true}, 752 assign.Analyzer.Name: {Analyzer: assign.Analyzer, enabled: true}, 753 atomic.Analyzer.Name: {Analyzer: atomic.Analyzer, enabled: true}, 754 atomicalign.Analyzer.Name: {Analyzer: atomicalign.Analyzer, enabled: true}, 755 bools.Analyzer.Name: {Analyzer: bools.Analyzer, enabled: true}, 756 buildtag.Analyzer.Name: {Analyzer: buildtag.Analyzer, enabled: true}, 757 cgocall.Analyzer.Name: {Analyzer: cgocall.Analyzer, enabled: true}, 758 composite.Analyzer.Name: {Analyzer: composite.Analyzer, enabled: true}, 759 copylock.Analyzer.Name: {Analyzer: copylock.Analyzer, enabled: true}, 760 errorsas.Analyzer.Name: {Analyzer: errorsas.Analyzer, enabled: true}, 761 httpresponse.Analyzer.Name: {Analyzer: httpresponse.Analyzer, enabled: true}, 762 loopclosure.Analyzer.Name: {Analyzer: loopclosure.Analyzer, enabled: true}, 763 lostcancel.Analyzer.Name: {Analyzer: lostcancel.Analyzer, enabled: true}, 764 nilfunc.Analyzer.Name: {Analyzer: nilfunc.Analyzer, enabled: true}, 765 printf.Analyzer.Name: {Analyzer: printf.Analyzer, enabled: true}, 766 shift.Analyzer.Name: {Analyzer: shift.Analyzer, enabled: true}, 767 stdmethods.Analyzer.Name: {Analyzer: stdmethods.Analyzer, enabled: true}, 768 structtag.Analyzer.Name: {Analyzer: structtag.Analyzer, enabled: true}, 769 tests.Analyzer.Name: {Analyzer: tests.Analyzer, enabled: true}, 770 unmarshal.Analyzer.Name: {Analyzer: unmarshal.Analyzer, enabled: true}, 771 unreachable.Analyzer.Name: {Analyzer: unreachable.Analyzer, enabled: true}, 772 unsafeptr.Analyzer.Name: {Analyzer: unsafeptr.Analyzer, enabled: true}, 773 unusedresult.Analyzer.Name: {Analyzer: unusedresult.Analyzer, enabled: true}, 774 775 // Non-vet analyzers: 776 deepequalerrors.Analyzer.Name: {Analyzer: deepequalerrors.Analyzer, enabled: true}, 777 sortslice.Analyzer.Name: {Analyzer: sortslice.Analyzer, enabled: true}, 778 testinggoroutine.Analyzer.Name: {Analyzer: testinggoroutine.Analyzer, enabled: true}, 779 unusedparams.Analyzer.Name: {Analyzer: unusedparams.Analyzer, enabled: false}, 780 781 // gofmt -s suite: 782 simplifycompositelit.Analyzer.Name: {Analyzer: simplifycompositelit.Analyzer, enabled: true, HighConfidence: true}, 783 simplifyrange.Analyzer.Name: {Analyzer: simplifyrange.Analyzer, enabled: true, HighConfidence: true}, 784 simplifyslice.Analyzer.Name: {Analyzer: simplifyslice.Analyzer, enabled: true, HighConfidence: true}, 785 } 786 } 787 788 func urlRegexp() *regexp.Regexp { 789 // Ensure links are matched as full words, not anywhere. 790 re := regexp.MustCompile(`\b(http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?\b`) 791 re.Longest() 792 return re 793 }