github.com/v2fly/tools@v0.100.0/internal/lsp/source/diagnostics.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package source 6 7 import ( 8 "context" 9 10 "github.com/v2fly/tools/internal/lsp/protocol" 11 "github.com/v2fly/tools/internal/span" 12 ) 13 14 type SuggestedFix struct { 15 Title string 16 Edits map[span.URI][]protocol.TextEdit 17 Command *protocol.Command 18 ActionKind protocol.CodeActionKind 19 } 20 21 type RelatedInformation struct { 22 URI span.URI 23 Range protocol.Range 24 Message string 25 } 26 27 func Analyze(ctx context.Context, snapshot Snapshot, pkg Package, includeConvenience bool) (map[span.URI][]*Diagnostic, error) { 28 // Exit early if the context has been canceled. This also protects us 29 // from a race on Options, see golang/go#36699. 30 if ctx.Err() != nil { 31 return nil, ctx.Err() 32 } 33 34 categories := []map[string]*Analyzer{} 35 if includeConvenience { 36 categories = append(categories, snapshot.View().Options().ConvenienceAnalyzers) 37 } 38 // If we had type errors, don't run any other analyzers. 39 if !pkg.HasTypeErrors() { 40 categories = append(categories, snapshot.View().Options().DefaultAnalyzers, snapshot.View().Options().StaticcheckAnalyzers) 41 } 42 var analyzers []*Analyzer 43 for _, cat := range categories { 44 for _, a := range cat { 45 analyzers = append(analyzers, a) 46 } 47 } 48 49 analysisDiagnostics, err := snapshot.Analyze(ctx, pkg.ID(), analyzers) 50 if err != nil { 51 return nil, err 52 } 53 54 reports := map[span.URI][]*Diagnostic{} 55 // Report diagnostics and errors from root analyzers. 56 for _, diag := range analysisDiagnostics { 57 reports[diag.URI] = append(reports[diag.URI], diag) 58 } 59 return reports, nil 60 } 61 62 func FileDiagnostics(ctx context.Context, snapshot Snapshot, uri span.URI) (VersionedFileIdentity, []*Diagnostic, error) { 63 fh, err := snapshot.GetVersionedFile(ctx, uri) 64 if err != nil { 65 return VersionedFileIdentity{}, nil, err 66 } 67 pkg, _, err := GetParsedFile(ctx, snapshot, fh, NarrowestPackage) 68 if err != nil { 69 return VersionedFileIdentity{}, nil, err 70 } 71 diagnostics, err := snapshot.DiagnosePackage(ctx, pkg) 72 if err != nil { 73 return VersionedFileIdentity{}, nil, err 74 } 75 fileDiags := diagnostics[fh.URI()] 76 if !pkg.HasListOrParseErrors() { 77 analysisDiags, err := Analyze(ctx, snapshot, pkg, false) 78 if err != nil { 79 return VersionedFileIdentity{}, nil, err 80 } 81 fileDiags = append(fileDiags, analysisDiags[fh.URI()]...) 82 } 83 return fh.VersionedFileIdentity(), fileDiags, nil 84 } 85 86 func isConvenienceAnalyzer(category string) bool { 87 for _, a := range DefaultOptions().ConvenienceAnalyzers { 88 if category == a.Analyzer.Name { 89 return true 90 } 91 } 92 return false 93 }