aboutsummaryrefslogtreecommitdiff
path: root/go/tools/builders/nogo_main.go
diff options
context:
space:
mode:
Diffstat (limited to 'go/tools/builders/nogo_main.go')
-rw-r--r--go/tools/builders/nogo_main.go52
1 files changed, 51 insertions, 1 deletions
diff --git a/go/tools/builders/nogo_main.go b/go/tools/builders/nogo_main.go
index b9423fb4..c6156e1d 100644
--- a/go/tools/builders/nogo_main.go
+++ b/go/tools/builders/nogo_main.go
@@ -202,6 +202,33 @@ func checkPackage(analyzers []*analysis.Analyzer, packagePath string, packageFil
act.pkg = pkg
}
+ // Process nolint directives similar to golangci-lint.
+ for _, f := range pkg.syntax {
+ // CommentMap will correctly associate comments to the largest node group
+ // applicable. This handles inline comments that might trail a large
+ // assignment and will apply the comment to the entire assignment.
+ commentMap := ast.NewCommentMap(pkg.fset, f, f.Comments)
+ for node, groups := range commentMap {
+ rng := &Range{
+ from: pkg.fset.Position(node.Pos()),
+ to: pkg.fset.Position(node.End()).Line,
+ }
+ for _, group := range groups {
+ for _, comm := range group.List {
+ linters, ok := parseNolint(comm.Text)
+ if !ok {
+ continue
+ }
+ for analyzer, act := range actions {
+ if linters == nil || linters[analyzer.Name] {
+ act.nolint = append(act.nolint, rng)
+ }
+ }
+ }
+ }
+ }
+ }
+
// Execute the analyzers.
execAll(roots)
@@ -211,6 +238,11 @@ func checkPackage(analyzers []*analysis.Analyzer, packagePath string, packageFil
return diagnostics, facts, nil
}
+type Range struct {
+ from token.Position
+ to int
+}
+
// An action represents one unit of analysis work: the application of
// one analysis to one package. Actions form a DAG within a
// package (as different analyzers are applied, either in sequence or
@@ -226,6 +258,7 @@ type action struct {
diagnostics []analysis.Diagnostic
usesFacts bool
err error
+ nolint []*Range
}
func (act *action) String() string {
@@ -273,6 +306,23 @@ func (act *action) execOnce() {
inputs[dep.a] = dep.result
}
+ ignoreNolintReporter := func(d analysis.Diagnostic) {
+ pos := act.pkg.fset.Position(d.Pos)
+ for _, rng := range act.nolint {
+ // The list of nolint ranges is built for the entire package. Make sure we
+ // only apply ranges to the correct file.
+ if pos.Filename != rng.from.Filename {
+ continue
+ }
+ if pos.Line < rng.from.Line || pos.Line > rng.to {
+ continue
+ }
+ // Found a nolint range. Ignore the issue.
+ return
+ }
+ act.diagnostics = append(act.diagnostics, d)
+ }
+
// Run the analysis.
factFilter := make(map[reflect.Type]bool)
for _, f := range act.a.FactTypes {
@@ -285,7 +335,7 @@ func (act *action) execOnce() {
Pkg: act.pkg.types,
TypesInfo: act.pkg.typesInfo,
ResultOf: inputs,
- Report: func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) },
+ Report: ignoreNolintReporter,
ImportPackageFact: act.pkg.facts.ImportPackageFact,
ExportPackageFact: act.pkg.facts.ExportPackageFact,
ImportObjectFact: act.pkg.facts.ImportObjectFact,