1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
10 "golang.org/x/tools/internal/lsp/protocol"
11 "golang.org/x/tools/internal/span"
14 type SuggestedFix struct {
16 Edits map[span.URI][]protocol.TextEdit
17 Command *protocol.Command
20 type RelatedInformation struct {
26 func Analyze(ctx context.Context, snapshot Snapshot, pkg Package, includeConvenience bool) (map[span.URI][]*Diagnostic, error) {
27 // Exit early if the context has been canceled. This also protects us
28 // from a race on Options, see golang/go#36699.
33 categories := []map[string]*Analyzer{}
34 if includeConvenience {
35 categories = append(categories, snapshot.View().Options().ConvenienceAnalyzers)
37 // If we had type errors, don't run any other analyzers.
38 if !pkg.HasTypeErrors() {
39 categories = append(categories, snapshot.View().Options().DefaultAnalyzers, snapshot.View().Options().StaticcheckAnalyzers)
41 var analyzers []*Analyzer
42 for _, cat := range categories {
43 for _, a := range cat {
44 analyzers = append(analyzers, a)
48 analysisDiagnostics, err := snapshot.Analyze(ctx, pkg.ID(), analyzers)
53 reports := map[span.URI][]*Diagnostic{}
54 // Report diagnostics and errors from root analyzers.
55 for _, diag := range analysisDiagnostics {
56 reports[diag.URI] = append(reports[diag.URI], diag)
61 func FileDiagnostics(ctx context.Context, snapshot Snapshot, uri span.URI) (VersionedFileIdentity, []*Diagnostic, error) {
62 fh, err := snapshot.GetVersionedFile(ctx, uri)
64 return VersionedFileIdentity{}, nil, err
66 pkg, _, err := GetParsedFile(ctx, snapshot, fh, NarrowestPackage)
68 return VersionedFileIdentity{}, nil, err
70 diagnostics, err := snapshot.DiagnosePackage(ctx, pkg)
72 return VersionedFileIdentity{}, nil, err
74 fileDiags := diagnostics[fh.URI()]
75 if !pkg.HasListOrParseErrors() {
76 analysisDiags, err := Analyze(ctx, snapshot, pkg, false)
78 return VersionedFileIdentity{}, nil, err
80 fileDiags = append(fileDiags, analysisDiags[fh.URI()]...)
82 return fh.VersionedFileIdentity(), fileDiags, nil
85 func isConvenienceAnalyzer(category string) bool {
86 for _, a := range DefaultOptions().ConvenienceAnalyzers {
87 if category == a.Analyzer.Name {