From e9e7993cfc92c020a5ed40b1214e5b404516df34 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Mon, 12 Oct 2015 03:13:48 +0000 Subject: [PATCH] clang-format: [JS] handle character classes in regexes. Slashes in regular expressions do not need to be escaped and do not terminate the regular expression even without a preceding backslash. Patch by Martin Probst. Thank you. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@250009 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/Format.cpp | 13 ++++++++++++- unittests/Format/FormatTestJS.cpp | 6 ++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 6bfd9cb5ce..0afa9aa9ce 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -876,12 +876,23 @@ private: return false; unsigned TokenCount = 0; + bool InCharacterClass = false; for (auto I = Tokens.rbegin() + 1, E = Tokens.rend(); I != E; ++I) { ++TokenCount; auto Prev = I + 1; while (Prev != E && Prev[0]->is(tok::comment)) ++Prev; - if (I[0]->isOneOf(tok::slash, tok::slashequal) && + // Slashes in character classes (delimited by [ and ]) do not need + // escaping. Escaping of the squares themselves is already handled by + // \c tryMergeEscapeSequence(), a plain tok::r_square must be non-escaped. + if (I[0]->is(tok::r_square)) + InCharacterClass = true; + if (I[0]->is(tok::l_square)) { + if (!InCharacterClass) + return false; + InCharacterClass = false; + } + if (!InCharacterClass && I[0]->isOneOf(tok::slash, tok::slashequal) && (Prev == E || ((Prev[0]->isOneOf(tok::l_paren, tok::semi, tok::l_brace, tok::r_brace, tok::exclaim, tok::l_square, diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp index f09df28142..d63a24d805 100644 --- a/unittests/Format/FormatTestJS.cpp +++ b/unittests/Format/FormatTestJS.cpp @@ -617,9 +617,15 @@ TEST_F(FormatTestJS, RegexLiteralSpecialCharacters) { verifyFormat("var regex = /x|y/;"); verifyFormat("var regex = /a{2}/;"); verifyFormat("var regex = /a{1,3}/;"); + verifyFormat("var regex = /[abc]/;"); verifyFormat("var regex = /[^abc]/;"); verifyFormat("var regex = /[\\b]/;"); + verifyFormat("var regex = /[/]/;"); + verifyFormat("var regex = /[\\/]/;"); + verifyFormat("var regex = /\\[/;"); + verifyFormat("var regex = /\\\\[/]/;"); + verifyFormat("var regex = /\\b/;"); verifyFormat("var regex = /\\B/;"); verifyFormat("var regex = /\\d/;"); -- 2.40.0