summaryrefslogtreecommitdiffhomepage
path: root/tools/nogo/matchers.go
diff options
context:
space:
mode:
Diffstat (limited to 'tools/nogo/matchers.go')
-rw-r--r--tools/nogo/matchers.go138
1 files changed, 138 insertions, 0 deletions
diff --git a/tools/nogo/matchers.go b/tools/nogo/matchers.go
new file mode 100644
index 000000000..bc5772303
--- /dev/null
+++ b/tools/nogo/matchers.go
@@ -0,0 +1,138 @@
+// Copyright 2019 The gVisor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package nogo
+
+import (
+ "go/token"
+ "path/filepath"
+ "regexp"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+type matcher interface {
+ ShouldReport(d analysis.Diagnostic, fs *token.FileSet) bool
+}
+
+// pathRegexps excludes explicit paths.
+type pathRegexps struct {
+ expr []*regexp.Regexp
+ whitelist bool
+}
+
+// buildRegexps builds a list of regular expressions.
+//
+// This will panic on error.
+func buildRegexps(prefix string, args ...string) []*regexp.Regexp {
+ result := make([]*regexp.Regexp, 0, len(args))
+ for _, arg := range args {
+ result = append(result, regexp.MustCompile(filepath.Join(prefix, arg)))
+ }
+ return result
+}
+
+// ShouldReport implements matcher.ShouldReport.
+func (p *pathRegexps) ShouldReport(d analysis.Diagnostic, fs *token.FileSet) bool {
+ fullPos := fs.Position(d.Pos).String()
+ for _, path := range p.expr {
+ if path.MatchString(fullPos) {
+ return p.whitelist
+ }
+ }
+ return !p.whitelist
+}
+
+// internalExcluded excludes specific internal paths.
+func internalExcluded(paths ...string) *pathRegexps {
+ return &pathRegexps{
+ expr: buildRegexps(internalPrefix, paths...),
+ whitelist: false,
+ }
+}
+
+// excludedExcluded excludes specific external paths.
+func externalExcluded(paths ...string) *pathRegexps {
+ return &pathRegexps{
+ expr: buildRegexps(externalPrefix, paths...),
+ whitelist: false,
+ }
+}
+
+// internalMatches returns a path matcher for internal packages.
+func internalMatches() *pathRegexps {
+ return &pathRegexps{
+ expr: buildRegexps(internalPrefix, ".*"),
+ whitelist: true,
+ }
+}
+
+// resultExcluded excludes explicit message contents.
+type resultExcluded []string
+
+// ShouldReport implements matcher.ShouldReport.
+func (r resultExcluded) ShouldReport(d analysis.Diagnostic, _ *token.FileSet) bool {
+ for _, str := range r {
+ if strings.Contains(d.Message, str) {
+ return false
+ }
+ }
+ return true // Not blacklisted.
+}
+
+// andMatcher is a composite matcher.
+type andMatcher struct {
+ first matcher
+ second matcher
+}
+
+// ShouldReport implements matcher.ShouldReport.
+func (a *andMatcher) ShouldReport(d analysis.Diagnostic, fs *token.FileSet) bool {
+ return a.first.ShouldReport(d, fs) && a.second.ShouldReport(d, fs)
+}
+
+// and is a syntactic convension for andMatcher.
+func and(first matcher, second matcher) *andMatcher {
+ return &andMatcher{
+ first: first,
+ second: second,
+ }
+}
+
+// anyMatcher matches everything.
+type anyMatcher struct{}
+
+// ShouldReport implements matcher.ShouldReport.
+func (anyMatcher) ShouldReport(analysis.Diagnostic, *token.FileSet) bool {
+ return true
+}
+
+// alwaysMatches returns an anyMatcher instance.
+func alwaysMatches() anyMatcher {
+ return anyMatcher{}
+}
+
+// neverMatcher will never match.
+type neverMatcher struct{}
+
+// ShouldReport implements matcher.ShouldReport.
+func (neverMatcher) ShouldReport(analysis.Diagnostic, *token.FileSet) bool {
+ return false
+}
+
+// disableMatches returns a neverMatcher instance.
+func disableMatches() neverMatcher {
+ return neverMatcher{}
+}