summaryrefslogtreecommitdiffstats
path: root/clang/lib/Format
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2014-05-08 07:01:45 +0000
committerDaniel Jasper <djasper@google.com>2014-05-08 07:01:45 +0000
commitf9ae312fc0dc17e24bff22b570cbe3f44b0d317c (patch)
tree4fedbdad323bbcb2c4373f50a63f4c27dc3d07e7 /clang/lib/Format
parentf1186c5a8f504efce819a38cec02ba3b12fe5df0 (diff)
downloadbcm5719-llvm-f9ae312fc0dc17e24bff22b570cbe3f44b0d317c.tar.gz
bcm5719-llvm-f9ae312fc0dc17e24bff22b570cbe3f44b0d317c.zip
clang-format: [JS] Initial support for regex literals.
llvm-svn: 208281
Diffstat (limited to 'clang/lib/Format')
-rw-r--r--clang/lib/Format/Format.cpp43
-rw-r--r--clang/lib/Format/FormatToken.h1
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp7
3 files changed, 44 insertions, 7 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;
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index 749dfcb3e46..056d4bdd1bb 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -60,6 +60,7 @@ enum TokenType {
TT_PointerOrReference,
TT_PureVirtualSpecifier,
TT_RangeBasedForLoopColon,
+ TT_RegexLiteral,
TT_StartOfName,
TT_TemplateCloser,
TT_TemplateOpener,
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 21cec905a8e..2f8457c61b3 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -609,6 +609,7 @@ private:
if (CurrentToken->Type != TT_LambdaLSquare &&
CurrentToken->Type != TT_FunctionLBrace &&
CurrentToken->Type != TT_ImplicitStringLiteral &&
+ CurrentToken->Type != TT_RegexLiteral &&
CurrentToken->Type != TT_TrailingReturnArrow)
CurrentToken->Type = TT_Unknown;
if (CurrentToken->Role)
@@ -622,10 +623,8 @@ private:
determineTokenType(*CurrentToken);
CurrentToken->BindingStrength = Contexts.back().BindingStrength;
CurrentToken->NestingLevel = Contexts.size() - 1;
- }
-
- if (CurrentToken != NULL)
CurrentToken = CurrentToken->Next;
+ }
resetTokenMetadata(CurrentToken);
}
@@ -1555,6 +1554,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
return true;
if (Tok.Type == TT_TrailingUnaryOperator)
return false;
+ if (Tok.Previous->Type == TT_RegexLiteral)
+ return false;
return spaceRequiredBetween(Line, *Tok.Previous, Tok);
}
OpenPOWER on IntegriCloud