From 0bca2aa405d0329e5cafb32cd88457cc25811178 Mon Sep 17 00:00:00 2001 From: Iskander Sharipov Date: Sun, 19 Jul 2020 15:30:49 +0300 Subject: [PATCH] ruleguard: ignore match expr width limit for suggestions It does make sense to truncate output when printing the suggestions to the stdout. It's bad if we try to apply the truncated suggestions to a file though, it leads to a broken syntax with meta variables inserted instead of the actual replacements. 1. For the command-line output, increase the width limit to 60 (instead of 40). 2. When applying -fix suggestions, ignore the width limit. Fixes #57 Signed-off-by: Iskander Sharipov --- analyzer/testdata/src/extra/file.go | 18 ++++++++++++++++++ analyzer/testdata/src/extra/rules.go | 2 ++ ruleguard/runner.go | 8 ++++---- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/analyzer/testdata/src/extra/file.go b/analyzer/testdata/src/extra/file.go index 57a7ceb9..77df7c6d 100644 --- a/analyzer/testdata/src/extra/file.go +++ b/analyzer/testdata/src/extra/file.go @@ -311,3 +311,21 @@ func testEmptyVarBlock() { type () // want `\Qempty type() block` const () // want `\Qempty const() block` } + +func testYodaExpr() { + var clusterContext struct { + PostInstallData struct { + CoreDNSUpdateFunction func() + AnotherNestedStruct struct { + DeeplyNestedField *int + } + } + } + + // This is on the boundary of being too long to be displayed in the CLI output. + if nil != clusterContext.PostInstallData.CoreDNSUpdateFunction { // want `\Qsuggestion: clusterContext.PostInstallData.CoreDNSUpdateFunction != nil` + } + // This is far too long, so it's shortened in the output. + if nil != clusterContext.PostInstallData.AnotherNestedStruct.DeeplyNestedField { // want `\Qsuggestion: $s != nil` + } +} diff --git a/analyzer/testdata/src/extra/rules.go b/analyzer/testdata/src/extra/rules.go index 54c23843..73b9e482 100644 --- a/analyzer/testdata/src/extra/rules.go +++ b/analyzer/testdata/src/extra/rules.go @@ -135,4 +135,6 @@ func _(m fluent.Matcher) { m.Match(`byte($x)`).Where(m["x"].Type.Is("byte")).Suggest(`$x`) m.Match(`rune($x)`).Where(m["x"].Type.Is("rune")).Suggest(`$x`) + + m.Match(`nil != $s`).Where(!m["s"].Const).Suggest(`$s != nil`) } diff --git a/ruleguard/runner.go b/ruleguard/runner.go index 6d1f0403..0b3f1e7b 100644 --- a/ruleguard/runner.go +++ b/ruleguard/runner.go @@ -145,7 +145,7 @@ func (rr *rulesRunner) handleMatch(rule goRule, m gogrep.MatchData) bool { if rule.severity != "" { prefix = rule.severity + ": " } - message := prefix + rr.renderMessage(rule.msg, m.Node, m.Values) + message := prefix + rr.renderMessage(rule.msg, m.Node, m.Values, true) node := m.Node if rule.location != "" { node = m.Values[rule.location] @@ -153,7 +153,7 @@ func (rr *rulesRunner) handleMatch(rule goRule, m gogrep.MatchData) bool { var suggestion *Suggestion if rule.suggestion != "" { suggestion = &Suggestion{ - Replacement: []byte(rr.renderMessage(rule.suggestion, m.Node, m.Values)), + Replacement: []byte(rr.renderMessage(rule.suggestion, m.Node, m.Values, false)), From: node.Pos(), To: node.End(), } @@ -162,7 +162,7 @@ func (rr *rulesRunner) handleMatch(rule goRule, m gogrep.MatchData) bool { return true } -func (rr *rulesRunner) renderMessage(msg string, n ast.Node, nodes map[string]ast.Node) string { +func (rr *rulesRunner) renderMessage(msg string, n ast.Node, nodes map[string]ast.Node, truncate bool) string { var buf strings.Builder if strings.Contains(msg, "$$") { buf.Write(rr.nodeText(n)) @@ -180,7 +180,7 @@ func (rr *rulesRunner) renderMessage(msg string, n ast.Node, nodes map[string]as buf.Write(rr.nodeText(n)) // Don't interpolate strings that are too long. var replacement string - if buf.Len() > 40 { + if truncate && buf.Len() > 60 { replacement = key } else { replacement = buf.String()