clang-format: [JS] handle comments in template strings.

Patch by Martin Probst. Thank you.

llvm-svn: 235078
This commit is contained in:
Daniel Jasper 2015-04-16 08:20:51 +00:00
parent 7d9d941b9b
commit 0d6ac27b86
2 changed files with 44 additions and 2 deletions

View File

@ -780,7 +780,15 @@ private:
return false;
FormatToken *EndBacktick = Tokens.back();
if (!(EndBacktick->is(tok::unknown) && EndBacktick->TokenText == "`"))
// Backticks get lexed as tok:unknown tokens. If a template string contains
// a comment start, it gets lexed as a tok::comment, or tok::unknown if
// unterminated.
if (!EndBacktick->isOneOf(tok::comment, tok::unknown))
return false;
size_t CommentBacktickPos = EndBacktick->TokenText.find('`');
// Unknown token that's not actually a backtick, or a comment that doesn't
// contain a backtick.
if (CommentBacktickPos == StringRef::npos)
return false;
unsigned TokenCount = 0;
@ -812,7 +820,14 @@ private:
Tokens.resize(Tokens.size() - TokenCount);
Tokens.back()->Type = TT_TemplateString;
const char *EndOffset = EndBacktick->TokenText.data() + 1;
const char *EndOffset =
EndBacktick->TokenText.data() + 1 + CommentBacktickPos;
if (CommentBacktickPos != 0) {
// If the backtick was not the first character (e.g. in a comment),
// re-lex after the backtick position.
SourceLocation Loc = EndBacktick->Tok.getLocation();
resetLexer(SourceMgr.getFileOffset(Loc) + CommentBacktickPos + 1);
}
Tokens.back()->TokenText =
StringRef(Tokens.back()->TokenText.data(),
EndOffset - Tokens.back()->TokenText.data());

View File

@ -648,6 +648,33 @@ TEST_F(FormatTestJS, TemplateStrings) {
// Two template strings.
verifyFormat("var x = `hello` == `hello`;");
// Comments in template strings.
EXPECT_EQ("var x = `//a`;\n"
"var y;",
format("var x =\n `//a`;\n"
"var y ;"));
EXPECT_EQ("var x = `/*a`;\n"
"var y;",
format("var x =\n `/*a`;\n"
"var y;"));
// Backticks in a comment - not a template string.
EXPECT_EQ("var x = 1 // `/*a`;\n"
" ;",
format("var x =\n 1 // `/*a`;\n"
" ;"));
EXPECT_EQ("/* ` */ var x = 1; /* ` */",
format("/* ` */ var x\n= 1; /* ` */"));
// Comment spans multiple template strings.
EXPECT_EQ("var x = `/*a`;\n"
"var y = ` */ `;",
format("var x =\n `/*a`;\n"
"var y =\n ` */ `;"));
// Escaped backtick.
EXPECT_EQ("var x = ` \\` a`;\n"
"var y;",
format("var x = ` \\` a`;\n"
"var y;"));
}
TEST_F(FormatTestJS, CastSyntax) {