mprobst updated this revision to Diff 48946.
mprobst marked an inline comment as done.
mprobst added a comment.
- Move code closer together by piping Replacements into the FormatTokenLexer.
- remove sstream import
http://reviews.llvm.org/D17385
Files:
lib/Format/Format.cpp
unittests/Format/FormatTestJS.cpp
Index: unittests/Format/FormatTestJS.cpp
===================================================================
--- unittests/Format/FormatTestJS.cpp
+++ unittests/Format/FormatTestJS.cpp
@@ -250,7 +250,7 @@
verifyFormat("f({'a': [{}]});");
}
-TEST_F(FormatTestJS, SingleQuoteStrings) {
+TEST_F(FormatTestJS, SingleQuotedStrings) {
verifyFormat("this.function('', true);");
}
@@ -1085,5 +1085,16 @@
getGoogleJSStyleWithColumns(20)));
}
+TEST_F(FormatTestJS, RequoteDoubleQuotedStrings) {
+ EXPECT_EQ("var x = 'foo';", format("var x = \"foo\";"));
+ EXPECT_EQ("var x = 'fo\\'o\\'';", format("var x = \"fo'o'\";"));
+ EXPECT_EQ("var x = 'fo\\'o\\'';", format("var x = \"fo\\'o'\";"));
+ EXPECT_EQ("var x =\n"
+ " 'foo\\'';",
+ // Code below is 15 chars wide, doesn't fit into the line with the
+ // \ escape added.
+ format("var x = \"foo'\";", getGoogleJSStyleWithColumns(15)));
+}
+
} // end namespace tooling
} // end namespace clang
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -766,13 +766,13 @@
class FormatTokenLexer {
public:
FormatTokenLexer(SourceManager &SourceMgr, FileID ID, FormatStyle &Style,
- encoding::Encoding Encoding)
+ encoding::Encoding Encoding, tooling::Replacements &Replaces)
: FormatTok(nullptr), IsFirstToken(true), GreaterStashed(false),
LessStashed(false), Column(0), TrailingWhitespace(0),
SourceMgr(SourceMgr), ID(ID), Style(Style),
IdentTable(getFormattingLangOpts(Style)), Keywords(IdentTable),
- Encoding(Encoding), FirstInLineIndex(0), FormattingDisabled(false),
- MacroBlockBeginRegex(Style.MacroBlockBegin),
+ Encoding(Encoding), Replaces(Replaces), FirstInLineIndex(0),
+ FormattingDisabled(false), MacroBlockBeginRegex(Style.MacroBlockBegin),
MacroBlockEndRegex(Style.MacroBlockEnd) {
Lex.reset(new Lexer(ID, SourceMgr.getBuffer(ID), SourceMgr,
getFormattingLangOpts(Style)));
@@ -791,6 +791,8 @@
if (Style.Language == FormatStyle::LK_JavaScript)
tryParseJSRegexLiteral();
tryMergePreviousTokens();
+ if (Style.Language == FormatStyle::LK_JavaScript)
+ tryRequoteJSStringLiteral();
if (Tokens.back()->NewlinesBefore > 0 || Tokens.back()->IsMultiline)
FirstInLineIndex = Tokens.size() - 1;
} while (Tokens.back()->Tok.isNot(tok::eof));
@@ -1061,6 +1063,48 @@
return false;
}
+ // If the last token is a double-quoted string literal, generates a
+ // replacement with a single quoted string literal, escaping the contents in
+ // the process.
+ void tryRequoteJSStringLiteral() {
+ FormatToken *FormatTok = Tokens.back();
+ if (!FormatTok->isStringLiteral() || !FormatTok->TokenText.startswith("\""))
+ return;
+
+ StringRef Input = FormatTok->TokenText;
+ size_t ColumnWidth = FormatTok->TokenText.size();
+ std::string Res("'");
+ llvm::raw_string_ostream Out(Res);
+ bool Escaped = false;
+ for (size_t i = 1; i < Input.size() - 1; i++) {
+ switch (Input[i]) {
+ case '\\':
+ Escaped = !Escaped;
+ break;
+ case '\'':
+ if (!Escaped) {
+ Out << '\\';
+ ColumnWidth++;
+ }
+ Escaped = false;
+ break;
+ default:
+ Escaped = false;
+ break;
+ }
+ Out << Input[i];
+ }
+ Out << '\'';
+
+ // For formatting, count the number of non-escaped single quotes in them
+ // and adjust ColumnWidth to take the added escapes into account.
+ FormatTok->ColumnWidth = ColumnWidth;
+
+ SourceRange Range(FormatTok->Tok.getLocation(), FormatTok->Tok.getEndLoc());
+ Replaces.insert(tooling::Replacement(
+ SourceMgr, CharSourceRange::getCharRange(Range), Out.str()));
+ }
+
bool tryMerge_TMacro() {
if (Tokens.size() < 4)
return false;
@@ -1359,6 +1403,7 @@
IdentifierTable IdentTable;
AdditionalKeywords Keywords;
encoding::Encoding Encoding;
+ tooling::Replacements &Replaces;
llvm::SpecificBumpPtrAllocator<FormatToken> Allocator;
// Index (in 'Tokens') of the last token that starts a new line.
unsigned FirstInLineIndex;
@@ -1443,7 +1488,7 @@
tooling::Replacements format(bool *IncompleteFormat) {
tooling::Replacements Result;
- FormatTokenLexer Tokens(SourceMgr, ID, Style, Encoding);
+ FormatTokenLexer Tokens(SourceMgr, ID, Style, Encoding, Result);
UnwrappedLineParser Parser(Style, Tokens.getKeywords(), Tokens.lex(),
*this);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits