Skip to content
Snippets Groups Projects
Commit 86396e9b authored by Daniel Jasper's avatar Daniel Jasper
Browse files

clang-format: [JS] Basic support for escape sequences in regex literals.

Before:
  var regex = /\\/ g; // This isn't even recognized as regex.

After:
  var regex = /\\/g; // It now is.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@208539 91177308-0d34-0410-b5e6-96231b3b80d8
parent 5473fec7
No related branches found
No related tags found
No related merge requests found
......@@ -1216,6 +1216,8 @@ private:
return;
if (Style.Language == FormatStyle::LK_JavaScript) {
if (tryMergeEscapeSequence())
return;
if (tryMergeJSRegexLiteral())
return;
......@@ -1256,6 +1258,23 @@ private:
return true;
}
// Tries to merge an escape sequence, i.e. a "\\" and the following
// charachter. Use e.g. inside JavaScript regex literals.
bool tryMergeEscapeSequence() {
if (Tokens.size() < 2)
return false;
FormatToken *Previous = Tokens[Tokens.size() - 2];
if (Previous->isNot(tok::unknown) || Previous->TokenText != "\\" ||
Tokens.back()->NewlinesBefore != 0)
return false;
Previous->ColumnWidth += Tokens.back()->ColumnWidth;
StringRef Text = Previous->TokenText;
Previous->TokenText =
StringRef(Text.data(), Text.size() + Tokens.back()->TokenText.size());
Tokens.resize(Tokens.size() - 1);
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
......@@ -1263,7 +1282,8 @@ private:
// a division.
bool tryMergeJSRegexLiteral() {
if (Tokens.size() < 2 || Tokens.back()->isNot(tok::slash) ||
Tokens[Tokens.size() - 2]->is(tok::unknown))
(Tokens[Tokens.size() - 2]->is(tok::unknown) &&
Tokens[Tokens.size() - 2]->TokenText == "\\"))
return false;
unsigned TokenCount = 0;
unsigned LastColumn = Tokens.back()->OriginalColumn;
......
......@@ -180,6 +180,9 @@ TEST_F(FormatTestJS, RegexLiteralSpecialCharacters) {
verifyFormat("var regex = /\\W/;");
verifyFormat("var regex = /a(a)\\1/;");
verifyFormat("var regex = /\\0/;");
verifyFormat("var regex = /\\\\/g;");
verifyFormat("var regex = /\\a\\\\/g;");
verifyFormat("var regex = /\a\\//g;");
}
TEST_F(FormatTestJS, RegexLiteralModifiers) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment