github.com/chenfeining/golangci-lint@v1.0.2-0.20230730162517-14c6c67868df/pkg/result/issue.go (about)

     1  package result
     2  
     3  import (
     4  	"crypto/md5" //nolint:gosec
     5  	"fmt"
     6  	"go/token"
     7  
     8  	"golang.org/x/tools/go/packages"
     9  )
    10  
    11  type Range struct {
    12  	From, To int
    13  }
    14  
    15  type Replacement struct {
    16  	NeedOnlyDelete bool     // need to delete all lines of the issue without replacement with new lines
    17  	NewLines       []string // if NeedDelete is false it's the replacement lines
    18  	Inline         *InlineFix
    19  }
    20  
    21  type InlineFix struct {
    22  	StartCol  int // zero-based
    23  	Length    int // length of chunk to be replaced
    24  	NewString string
    25  }
    26  
    27  type Issue struct {
    28  	FromLinter string
    29  	Text       string
    30  
    31  	Severity string
    32  
    33  	// Source lines of a code with the issue to show
    34  	SourceLines []string
    35  
    36  	// If we know how to fix the issue we can provide replacement lines
    37  	Replacement *Replacement
    38  
    39  	// Pkg is needed for proper caching of linting results
    40  	Pkg *packages.Package `json:"-"`
    41  
    42  	LineRange *Range `json:",omitempty"`
    43  
    44  	Pos token.Position
    45  
    46  	// HunkPos is used only when golangci-lint is run over a diff
    47  	HunkPos int `json:",omitempty"`
    48  
    49  	// If we are expecting a nolint (because this is from nolintlint), record the expected linter
    50  	ExpectNoLint         bool
    51  	ExpectedNoLintLinter string
    52  }
    53  
    54  func (i *Issue) FilePath() string {
    55  	return i.Pos.Filename
    56  }
    57  
    58  func (i *Issue) Line() int {
    59  	return i.Pos.Line
    60  }
    61  
    62  func (i *Issue) Column() int {
    63  	return i.Pos.Column
    64  }
    65  
    66  func (i *Issue) GetLineRange() Range {
    67  	if i.LineRange == nil {
    68  		return Range{
    69  			From: i.Line(),
    70  			To:   i.Line(),
    71  		}
    72  	}
    73  
    74  	if i.LineRange.From == 0 {
    75  		return Range{
    76  			From: i.Line(),
    77  			To:   i.Line(),
    78  		}
    79  	}
    80  
    81  	return *i.LineRange
    82  }
    83  
    84  func (i *Issue) Description() string {
    85  	return fmt.Sprintf("%s: %s", i.FromLinter, i.Text)
    86  }
    87  
    88  func (i *Issue) Fingerprint() string {
    89  	firstLine := ""
    90  	if len(i.SourceLines) > 0 {
    91  		firstLine = i.SourceLines[0]
    92  	}
    93  
    94  	hash := md5.New() //nolint:gosec
    95  	_, _ = fmt.Fprintf(hash, "%s%s%s", i.Pos.Filename, i.Text, firstLine)
    96  
    97  	return fmt.Sprintf("%X", hash.Sum(nil))
    98  }