Disable tab expansion when counting the columns in block comments.

To fully support this, we also need to expand tabs in the text before
the block comment. This patch breaks indentation when there was a
non-standard mixture of spaces and tabs used for indentation, but
fixes a regression in the simple case:
{
  /*
   * Comment.
   */
  int i;
}
Is now formatted correctly, if there were tabs used for indentation
before.

llvm-svn: 182760
This commit is contained in:
Manuel Klimek 2013-05-28 10:01:59 +00:00
parent 6347551e45
commit 34d15151c4
2 changed files with 44 additions and 33 deletions

View File

@ -256,15 +256,6 @@ void BreakableBlockComment::adjustWhitespace(const FormatStyle &Style,
size_t StartOfLine = Lines[LineIndex].find_first_not_of(" \t"); size_t StartOfLine = Lines[LineIndex].find_first_not_of(" \t");
if (StartOfLine == StringRef::npos) if (StartOfLine == StringRef::npos)
StartOfLine = Lines[LineIndex].size(); StartOfLine = Lines[LineIndex].size();
// FIXME: Tabs are not always 8 characters. Make configurable in the style.
unsigned Column = 0;
StringRef OriginalIndentText = Lines[LineIndex].substr(0, StartOfLine);
for (int i = 0, e = OriginalIndentText.size(); i != e; ++i) {
if (Lines[LineIndex][i] == '\t')
Column += 8 - (Column % 8);
else
++Column;
}
// Adjust Lines to only contain relevant text. // Adjust Lines to only contain relevant text.
Lines[LineIndex - 1] = Lines[LineIndex - 1].substr(0, EndOfPreviousLine); Lines[LineIndex - 1] = Lines[LineIndex - 1].substr(0, EndOfPreviousLine);
@ -273,8 +264,15 @@ void BreakableBlockComment::adjustWhitespace(const FormatStyle &Style,
// to the current line. // to the current line.
LeadingWhitespace[LineIndex] = LeadingWhitespace[LineIndex] =
Lines[LineIndex].begin() - Lines[LineIndex - 1].end(); Lines[LineIndex].begin() - Lines[LineIndex - 1].end();
// FIXME: We currently count tabs as 1 character. To solve this, we need to
// get the correct indentation width of the start of the comment, which
// requires correct counting of the tab expansions before the comment, and
// a configurable tab width. Since the current implementation only breaks
// if leading tabs are intermixed with spaces, that is not a high priority.
// Adjust the start column uniformly accross all lines. // Adjust the start column uniformly accross all lines.
StartOfLineColumn[LineIndex] = std::max<int>(0, Column + IndentDelta); StartOfLineColumn[LineIndex] = std::max<int>(0, StartOfLine + IndentDelta);
} }
unsigned BreakableBlockComment::getLineCount() const { return Lines.size(); } unsigned BreakableBlockComment::getLineCount() const { return Lines.size(); }

View File

@ -4495,35 +4495,48 @@ TEST_F(FormatTest, ConfigurableUseOfTab) {
"\t\t parameter2); \\\n" "\t\t parameter2); \\\n"
"\t}", "\t}",
Tab); Tab);
EXPECT_EQ("/*\n"
"\t a\t\tcomment\n"
"\t in multiple lines\n"
" */",
format(" /*\t \t \n"
" \t \t a\t\tcomment\t \t\n"
" \t \t in multiple lines\t\n"
" \t */",
Tab));
Tab.UseTab = false;
// FIXME: Change this test to a different tab size than
// 8 once configurable.
EXPECT_EQ("/*\n"
" a\t\tcomment\n"
" in multiple lines\n"
" */",
format(" /*\t \t \n"
" \t \t a\t\tcomment\t \t\n"
" \t \t in multiple lines\t\n"
" \t */",
Tab));
// FIXME: This is broken, as the spelling column number we
// get from the SourceManager counts tab as '1'. // FIXME: To correctly count mixed whitespace we need to
// also correctly count mixed whitespace in front of the comment.
//
// EXPECT_EQ("/*\n"
// "\t a\t\tcomment\n"
// "\t in multiple lines\n"
// " */",
// format(" /*\t \t \n"
// " \t \t a\t\tcomment\t \t\n"
// " \t \t in multiple lines\t\n"
// " \t */",
// Tab));
// Tab.UseTab = false;
// EXPECT_EQ("/*\n"
// " a\t\tcomment\n"
// " in multiple lines\n"
// " */",
// format(" /*\t \t \n"
// " \t \t a\t\tcomment\t \t\n"
// " \t \t in multiple lines\t\n"
// " \t */",
// Tab));
// EXPECT_EQ("/* some\n" // EXPECT_EQ("/* some\n"
// " comment */", // " comment */",
// format(" \t \t /* some\n" // format(" \t \t /* some\n"
// " \t \t comment */", // " \t \t comment */",
// Tab)); // Tab));
EXPECT_EQ("{\n"
" /*\n"
" * Comment\n"
" */\n"
" int i;\n"
"}",
format("{\n"
"\t/*\n"
"\t * Comment\n"
"\t */\n"
"\t int i;\n"
"}"));
} }
TEST_F(FormatTest, LinuxBraceBreaking) { TEST_F(FormatTest, LinuxBraceBreaking) {