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  }