From df3167650dd04ae5c03a44caa3d4ce4beb0c3cbd Mon Sep 17 00:00:00 2001 From: Martin Probst Date: Tue, 7 Feb 2017 14:08:03 +0000 Subject: [PATCH] clang-format: [JS] exclaim preceding regex literals. Summary: Regex detection would incorrectly classify a trailing `!` operator (nullability cast) followed by a `/` as the start of a regular expression literal. This fixes code such as: var foo = x()! / 10; Which would previously parse a regexp all the way to the end of the source file (or next `/`). Reviewers: djasper Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D29634 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@294304 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/FormatTokenLexer.cpp | 4 +++- unittests/Format/FormatTestJS.cpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/Format/FormatTokenLexer.cpp b/lib/Format/FormatTokenLexer.cpp index 46a32a917d..5bd1168587 100644 --- a/lib/Format/FormatTokenLexer.cpp +++ b/lib/Format/FormatTokenLexer.cpp @@ -157,7 +157,9 @@ bool FormatTokenLexer::canPrecedeRegexLiteral(FormatToken *Prev) { // postfix unary operators. If the '++' is followed by a non-operand // introducing token, the slash here is the operand and not the start of a // regex. - if (Prev->isOneOf(tok::plusplus, tok::minusminus)) + // `!` is an unary prefix operator, but also a post-fix operator that casts + // away nullability, so the same check applies. + if (Prev->isOneOf(tok::plusplus, tok::minusminus, tok::exclaim)) return (Tokens.size() < 3 || precedesOperand(Tokens[Tokens.size() - 3])); // The previous token must introduce an operand location where regex diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp index b64d13ad50..61acce3a97 100644 --- a/unittests/Format/FormatTestJS.cpp +++ b/unittests/Format/FormatTestJS.cpp @@ -941,6 +941,7 @@ TEST_F(FormatTestJS, RegexLiteralClassification) { verifyFormat("var x = a ? /abc/ : /abc/;"); verifyFormat("for (var i = 0; /abc/.test(s[i]); i++) {\n}"); verifyFormat("var x = !/abc/.test(y);"); + verifyFormat("var x = foo()! / 10;"); verifyFormat("var x = a && /abc/.test(y);"); verifyFormat("var x = a || /abc/.test(y);"); verifyFormat("var x = a + /abc/.search(y);"); -- 2.40.0