Author: mprobst Date: Tue Aug 8 07:52:42 2017 New Revision: 310365 URL: http://llvm.org/viewvc/llvm-project?rev=310365&view=rev Log: clang-format: [JS] handle single lines comments ending in `\\`.
Summary: Previously, clang-format would consider the following code line to be part of the comment and incorrectly format the rest of the file. Reviewers: djasper Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D36159 Modified: cfe/trunk/lib/Format/FormatTokenLexer.cpp cfe/trunk/unittests/Format/FormatTestJS.cpp Modified: cfe/trunk/lib/Format/FormatTokenLexer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatTokenLexer.cpp?rev=310365&r1=310364&r2=310365&view=diff ============================================================================== --- cfe/trunk/lib/Format/FormatTokenLexer.cpp (original) +++ cfe/trunk/lib/Format/FormatTokenLexer.cpp Tue Aug 8 07:52:42 2017 @@ -529,6 +529,34 @@ FormatToken *FormatTokenLexer::getNextTo readRawToken(*FormatTok); } + // JavaScript and Java do not allow to escape the end of the line with a + // backslash. Backslashes are syntax errors in plain source, but can occur in + // comments. When a single line comment ends with a \, it'll cause the next + // line of code to be lexed as a comment, breaking formatting. The code below + // finds comments that contain a backslash followed by a line break, truncates + // the comment token at the backslash, and resets the lexer to restart behind + // the backslash. + if ((Style.Language == FormatStyle::LK_JavaScript || + Style.Language == FormatStyle::LK_Java) && + FormatTok->is(tok::comment) && FormatTok->TokenText.startswith("//")) { + size_t BackslashPos = FormatTok->TokenText.find('\\'); + while (BackslashPos != StringRef::npos) { + if (BackslashPos + 1 < FormatTok->TokenText.size() && + FormatTok->TokenText[BackslashPos + 1] == '\n') { + const char *Offset = Lex->getBufferLocation(); + Offset -= FormatTok->TokenText.size(); + Offset += BackslashPos + 1; + resetLexer(SourceMgr.getFileOffset(Lex->getSourceLocation(Offset))); + FormatTok->TokenText = FormatTok->TokenText.substr(0, BackslashPos + 1); + FormatTok->ColumnWidth = encoding::columnWidthWithTabs( + FormatTok->TokenText, FormatTok->OriginalColumn, Style.TabWidth, + Encoding); + break; + } + BackslashPos = FormatTok->TokenText.find('\\', BackslashPos + 1); + } + } + // In case the token starts with escaped newlines, we want to // take them into account as whitespace - this pattern is quite frequent // in macro definitions. Modified: cfe/trunk/unittests/Format/FormatTestJS.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestJS.cpp?rev=310365&r1=310364&r2=310365&view=diff ============================================================================== --- cfe/trunk/unittests/Format/FormatTestJS.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestJS.cpp Tue Aug 8 07:52:42 2017 @@ -2074,5 +2074,27 @@ TEST_F(FormatTestJS, NestedLiterals) { "};", FourSpaces); } +TEST_F(FormatTestJS, BackslashesInComments) { + verifyFormat("// hello \\\n" + "if (x) foo();\n", + "// hello \\\n" + " if ( x) \n" + " foo();\n"); + verifyFormat("/* ignore \\\n" + " */\n" + "if (x) foo();\n", + "/* ignore \\\n" + " */\n" + " if ( x) foo();\n"); + verifyFormat("// st \\ art\\\n" + "// comment" + "// continue \\\n" + "formatMe();\n", + "// st \\ art\\\n" + "// comment" + "// continue \\\n" + "formatMe( );\n"); +} + } // end namespace tooling } // end namespace clang _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits