summaryrefslogtreecommitdiffstats
path: root/clang/lib/Format/Format.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Format/Format.cpp')
-rw-r--r--clang/lib/Format/Format.cpp43
1 files changed, 39 insertions, 4 deletions
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index efb790b3592..c57993386f3 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -1215,10 +1215,13 @@ private:
return;
if (Style.Language == FormatStyle::LK_JavaScript) {
- static tok::TokenKind JSIdentity[] = { tok::equalequal, tok::equal };
- static tok::TokenKind JSNotIdentity[] = { tok::exclaimequal, tok::equal };
- static tok::TokenKind JSShiftEqual[] = { tok::greater, tok::greater,
- tok::greaterequal };
+ if (tryMergeJSRegexLiteral())
+ return;
+
+ static tok::TokenKind JSIdentity[] = {tok::equalequal, tok::equal};
+ static tok::TokenKind JSNotIdentity[] = {tok::exclaimequal, tok::equal};
+ static tok::TokenKind JSShiftEqual[] = {tok::greater, tok::greater,
+ tok::greaterequal};
// FIXME: We probably need to change token type to mimic operator with the
// correct priority.
if (tryMergeTokens(JSIdentity))
@@ -1252,6 +1255,38 @@ private:
return true;
}
+ // Try to determine whether the current token ends a JavaScript regex literal.
+ // We heuristically assume that this is a regex literal if we find two
+ // unescaped slashes on a line and the token before the first slash is one of
+ // "(;,{}![:?" or a binary operator, as those cannot be followed by a
+ // division.
+ bool tryMergeJSRegexLiteral() {
+ if (Tokens.size() < 2 || Tokens.back()->isNot(tok::slash) ||
+ Tokens[Tokens.size() - 2]->is(tok::unknown))
+ return false;
+ unsigned TokenCount = 0;
+ unsigned LastColumn = Tokens.back()->OriginalColumn;
+ for (auto I = Tokens.rbegin() + 1, E = Tokens.rend(); I != E; ++I) {
+ ++TokenCount;
+ if (I[0]->is(tok::slash) && I + 1 != E &&
+ (I[1]->isOneOf(tok::l_paren, tok::semi, tok::l_brace,
+ tok::r_brace, tok::exclaim, tok::l_square,
+ tok::colon, tok::comma, tok::question) ||
+ I[1]->isBinaryOperator())) {
+ Tokens.resize(Tokens.size() - TokenCount);
+ Tokens.back()->Tok.setKind(tok::unknown);
+ Tokens.back()->Type = TT_RegexLiteral;
+ Tokens.back()->ColumnWidth += LastColumn - I[0]->OriginalColumn;
+ return true;
+ }
+
+ // There can't be a newline inside a regex literal.
+ if (I[0]->NewlinesBefore > 0)
+ return false;
+ }
+ return false;
+ }
+
bool tryMerge_TMacro() {
if (Tokens.size() < 4)
return false;
OpenPOWER on IntegriCloud