mprobst created this revision. Herald added a subscriber: klimek. 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 `/`). https://reviews.llvm.org/D29634 Files: lib/Format/FormatTokenLexer.cpp unittests/Format/FormatTestJS.cpp Index: unittests/Format/FormatTestJS.cpp =================================================================== --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -941,6 +941,7 @@ 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);"); Index: lib/Format/FormatTokenLexer.cpp =================================================================== --- lib/Format/FormatTokenLexer.cpp +++ lib/Format/FormatTokenLexer.cpp @@ -157,7 +157,9 @@ // 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
Index: unittests/Format/FormatTestJS.cpp =================================================================== --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -941,6 +941,7 @@ 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);"); Index: lib/Format/FormatTokenLexer.cpp =================================================================== --- lib/Format/FormatTokenLexer.cpp +++ lib/Format/FormatTokenLexer.cpp @@ -157,7 +157,9 @@ // 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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits