diff options
| author | Robert Griesemer <gri@golang.org> | 2023-01-05 14:51:31 -0800 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2023-01-17 19:55:02 +0000 |
| commit | d4639ecdfc9051a7adcfb8945d93a45da56576ae (patch) | |
| tree | 5d03beaee0469842c4e6063acfec9f8f1b9954c8 /src/cmd/compile | |
| parent | cf5dbd44591ca885fe8deb14c1500447c915e6b8 (diff) | |
| download | go-d4639ecdfc9051a7adcfb8945d93a45da56576ae.tar.xz | |
go/types, types2: test that error format strings have matching parentheses/brackets
Also, for go/types, switch to using syntax.Inspect instead of
(deprecated) syntax.Crawl.
Change-Id: I8333079040e9676e0a61c23d09d41ca790526eeb
Reviewed-on: https://go-review.googlesource.com/c/go/+/460759
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Diffstat (limited to 'src/cmd/compile')
| -rw-r--r-- | src/cmd/compile/internal/types2/errorcalls_test.go | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/src/cmd/compile/internal/types2/errorcalls_test.go b/src/cmd/compile/internal/types2/errorcalls_test.go index edf2a5195d..6153b42a34 100644 --- a/src/cmd/compile/internal/types2/errorcalls_test.go +++ b/src/cmd/compile/internal/types2/errorcalls_test.go @@ -6,13 +6,18 @@ package types2_test import ( "cmd/compile/internal/syntax" + "strconv" "testing" ) -const errorfMinArgCount = 4 +const ( + errorfMinArgCount = 4 + errorfFormatIndex = 2 +) // TestErrorCalls makes sure that check.errorf calls have at least -// errorfMinArgCount arguments (otherwise we should use check.error). +// errorfMinArgCount arguments (otherwise we should use check.error) +// and use balanced parentheses/brackets. func TestErrorCalls(t *testing.T) { files, err := pkgFiles(".") if err != nil { @@ -20,17 +25,17 @@ func TestErrorCalls(t *testing.T) { } for _, file := range files { - syntax.Crawl(file, func(n syntax.Node) bool { + syntax.Inspect(file, func(n syntax.Node) bool { call, _ := n.(*syntax.CallExpr) if call == nil { - return false + return true } selx, _ := call.Fun.(*syntax.SelectorExpr) if selx == nil { - return false + return true } if !(isName(selx.X, "check") && isName(selx.Sel, "errorf")) { - return false + return true } // check.errorf calls should have at least errorfMinArgCount arguments: // position, code, format string, and arguments to format @@ -38,6 +43,18 @@ func TestErrorCalls(t *testing.T) { t.Errorf("%s: got %d arguments, want at least %d", call.Pos(), n, errorfMinArgCount) return false } + format := call.ArgList[errorfFormatIndex] + syntax.Inspect(format, func(n syntax.Node) bool { + if lit, _ := n.(*syntax.BasicLit); lit != nil && lit.Kind == syntax.StringLit { + if s, err := strconv.Unquote(lit.Value); err == nil { + if !balancedParentheses(s) { + t.Errorf("%s: unbalanced parentheses/brackets", lit.Pos()) + } + } + return false + } + return true + }) return false }) } @@ -49,3 +66,30 @@ func isName(n syntax.Node, name string) bool { } return false } + +func balancedParentheses(s string) bool { + var stack []byte + for _, ch := range s { + var open byte + switch ch { + case '(', '[', '{': + stack = append(stack, byte(ch)) + continue + case ')': + open = '(' + case ']': + open = '[' + case '}': + open = '{' + default: + continue + } + // closing parenthesis/bracket must have matching opening + top := len(stack) - 1 + if top < 0 || stack[top] != open { + return false + } + stack = stack[:top] + } + return len(stack) == 0 +} |
