]> granicus.if.org Git - clang/commitdiff
clang-format: [JS] Basic support for escape sequences in regex literals.
authorDaniel Jasper <djasper@google.com>
Mon, 12 May 2014 11:29:50 +0000 (11:29 +0000)
committerDaniel Jasper <djasper@google.com>
Mon, 12 May 2014 11:29:50 +0000 (11:29 +0000)
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

lib/Format/Format.cpp
unittests/Format/FormatTestJS.cpp

index 30dc88994e2f93e7cd72759b22c5603c08f8a8a1..60706b1b3bef6e1cb8084f6d07c075c96f97760e 100644 (file)
@@ -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;
index cc67416493013f93ad702f9d531d8329de0b368e..7a853b037819ab3182347332109abd194cf1e820 100644 (file)
@@ -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) {