[clang-format] Handle Java text blocks (#141334)
Fix #61954 (cherry picked from commit b7f5950bb3b97eac979925a3bbf015530c26962e)
This commit is contained in:
parent
0e1ef696f1
commit
4b6e5a2866
@ -636,6 +636,36 @@ bool FormatTokenLexer::canPrecedeRegexLiteral(FormatToken *Prev) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FormatTokenLexer::tryParseJavaTextBlock() {
|
||||||
|
if (FormatTok->TokenText != "\"\"")
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto *S = Lex->getBufferLocation();
|
||||||
|
const auto *End = Lex->getBuffer().end();
|
||||||
|
|
||||||
|
if (S == End || *S != '\"')
|
||||||
|
return;
|
||||||
|
|
||||||
|
++S; // Skip the `"""` that begins a text block.
|
||||||
|
|
||||||
|
// Find the `"""` that ends the text block.
|
||||||
|
for (int Count = 0; Count < 3 && S < End; ++S) {
|
||||||
|
switch (*S) {
|
||||||
|
case '\\':
|
||||||
|
Count = -1;
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
++Count;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore the possibly invalid text block.
|
||||||
|
resetLexer(SourceMgr.getFileOffset(Lex->getSourceLocation(S)));
|
||||||
|
}
|
||||||
|
|
||||||
// Tries to parse a JavaScript Regex literal starting at the current token,
|
// Tries to parse a JavaScript Regex literal starting at the current token,
|
||||||
// if that begins with a slash and is in a location where JavaScript allows
|
// if that begins with a slash and is in a location where JavaScript allows
|
||||||
// regex literals. Changes the current token to a regex literal and updates
|
// regex literals. Changes the current token to a regex literal and updates
|
||||||
@ -1326,6 +1356,9 @@ FormatToken *FormatTokenLexer::getNextToken() {
|
|||||||
FormatTok->TokenText = FormatTok->TokenText.substr(0, 1);
|
FormatTok->TokenText = FormatTok->TokenText.substr(0, 1);
|
||||||
++Column;
|
++Column;
|
||||||
StateStack.push(LexerState::TOKEN_STASHED);
|
StateStack.push(LexerState::TOKEN_STASHED);
|
||||||
|
} else if (Style.Language == FormatStyle::LK_Java &&
|
||||||
|
FormatTok->is(tok::string_literal)) {
|
||||||
|
tryParseJavaTextBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Style.isVerilog() && Tokens.size() > 0 &&
|
if (Style.isVerilog() && Tokens.size() > 0 &&
|
||||||
|
@ -71,6 +71,8 @@ private:
|
|||||||
|
|
||||||
bool canPrecedeRegexLiteral(FormatToken *Prev);
|
bool canPrecedeRegexLiteral(FormatToken *Prev);
|
||||||
|
|
||||||
|
void tryParseJavaTextBlock();
|
||||||
|
|
||||||
// Tries to parse a JavaScript Regex literal starting at the current token,
|
// Tries to parse a JavaScript Regex literal starting at the current token,
|
||||||
// if that begins with a slash and is in a location where JavaScript allows
|
// if that begins with a slash and is in a location where JavaScript allows
|
||||||
// regex literals. Changes the current token to a regex literal and updates
|
// regex literals. Changes the current token to a regex literal and updates
|
||||||
|
@ -789,6 +789,63 @@ TEST_F(FormatTestJava, AlignCaseArrows) {
|
|||||||
Style);
|
Style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(FormatTestJava, TextBlock) {
|
||||||
|
verifyNoChange("String myStr = \"\"\"\n"
|
||||||
|
"hello\n"
|
||||||
|
"there\n"
|
||||||
|
"\"\"\";");
|
||||||
|
|
||||||
|
verifyNoChange("String tb = \"\"\"\n"
|
||||||
|
" the new\"\"\";");
|
||||||
|
|
||||||
|
verifyNoChange("System.out.println(\"\"\"\n"
|
||||||
|
" This is the first line\n"
|
||||||
|
" This is the second line\n"
|
||||||
|
" \"\"\");");
|
||||||
|
|
||||||
|
verifyNoChange("void writeHTML() {\n"
|
||||||
|
" String html = \"\"\" \n"
|
||||||
|
" <html>\n"
|
||||||
|
" <p>Hello World.</p>\n"
|
||||||
|
" </html>\n"
|
||||||
|
"\"\"\";\n"
|
||||||
|
" writeOutput(html);\n"
|
||||||
|
"}");
|
||||||
|
|
||||||
|
verifyNoChange("String colors = \"\"\"\t\n"
|
||||||
|
" red\n"
|
||||||
|
" green\n"
|
||||||
|
" blue\"\"\".indent(4);");
|
||||||
|
|
||||||
|
verifyNoChange("String code = \"\"\"\n"
|
||||||
|
" String source = \\\"\"\"\n"
|
||||||
|
" String message = \"Hello, World!\";\n"
|
||||||
|
" System.out.println(message);\n"
|
||||||
|
" \\\"\"\";\n"
|
||||||
|
" \"\"\";");
|
||||||
|
|
||||||
|
verifyNoChange(
|
||||||
|
"class Outer {\n"
|
||||||
|
" void printPoetry() {\n"
|
||||||
|
" String lilacs = \"\"\"\n"
|
||||||
|
"Passing the apple-tree blows of white and pink in the orchards\n"
|
||||||
|
"\"\"\";\n"
|
||||||
|
" System.out.println(lilacs);\n"
|
||||||
|
" }\n"
|
||||||
|
"}");
|
||||||
|
|
||||||
|
verifyNoChange("String name = \"\"\"\r\n"
|
||||||
|
" red\n"
|
||||||
|
" green\n"
|
||||||
|
" blue\\\n"
|
||||||
|
" \"\"\";");
|
||||||
|
|
||||||
|
verifyFormat("String name = \"\"\"Pat Q. Smith\"\"\";");
|
||||||
|
|
||||||
|
verifyNoChange("String name = \"\"\"\n"
|
||||||
|
" Pat Q. Smith");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace format
|
} // namespace format
|
||||||
|
Loading…
x
Reference in New Issue
Block a user