]> granicus.if.org Git - clang/commitdiff
Multi-line comment alignment
authorAlexander Kornienko <alexfh@google.com>
Thu, 14 Mar 2013 16:10:54 +0000 (16:10 +0000)
committerAlexander Kornienko <alexfh@google.com>
Thu, 14 Mar 2013 16:10:54 +0000 (16:10 +0000)
Summary:
Aligns continuation lines of multi-line comments to the base
indentation level +1:
class A {
  /*
   * test
   */
  void f() {}
};

The first revision is work in progress. The implementation is not yet complete.

Reviewers: djasper

Reviewed By: djasper

CC: cfe-commits, klimek
Differential Revision: http://llvm-reviews.chandlerc.com/D541

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177080 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Format/Format.cpp
unittests/Format/FormatTest.cpp

index ab895c7d1c725818c385fcd422a4898d23ded87e..777d5e8f72ac9762081e2c2d6a9ace651014b8cd 100644 (file)
@@ -128,16 +128,14 @@ public:
       if (Tok.Parent != NULL || !Comments.empty()) {
         if (Style.ColumnLimit >=
             Spaces + WhitespaceStartColumn + Tok.FormatTok.TokenLength) {
-          Comments.push_back(StoredComment());
-          Comments.back().Tok = Tok.FormatTok;
-          Comments.back().Spaces = Spaces;
-          Comments.back().NewLines = NewLines;
-          if (NewLines == 0)
-            Comments.back().MinColumn = WhitespaceStartColumn + Spaces;
-          else
-            Comments.back().MinColumn = Spaces;
-          Comments.back().MaxColumn =
-              Style.ColumnLimit - Tok.FormatTok.TokenLength;
+          StoredComment Comment;
+          Comment.Tok = Tok.FormatTok;
+          Comment.Spaces = Spaces;
+          Comment.NewLines = NewLines;
+          Comment.MinColumn =
+              NewLines > 0 ? Spaces : WhitespaceStartColumn + Spaces;
+          Comment.MaxColumn = Style.ColumnLimit - Tok.FormatTok.TokenLength;
+          Comments.push_back(Comment);
           return;
         }
       }
@@ -146,6 +144,10 @@ public:
     // If this line does not have a trailing comment, align the stored comments.
     if (Tok.Children.empty() && !isTrailingComment(Tok))
       alignComments();
+
+    if (Tok.Type == TT_BlockComment)
+      indentBlockComment(Tok.FormatTok, Spaces);
+
     storeReplacement(Tok.FormatTok, getNewLineText(NewLines, Spaces));
   }
 
@@ -191,6 +193,38 @@ public:
   }
 
 private:
+  void indentBlockComment(const FormatToken &Tok, int BaseIndent) {
+    SourceLocation TokenLoc = Tok.Tok.getLocation();
+    const char *Start = SourceMgr.getCharacterData(TokenLoc);
+    const char *Current = Start;
+    const char *TokEnd = Current + Tok.TokenLength;
+    while (Current < TokEnd) {
+      if (*Current == '\n') {
+        ++Current;
+        SourceLocation Loc = TokenLoc.getLocWithOffset(Current - Start);
+        int Indent = BaseIndent;
+        int Spaces = 0;
+        while (Current < TokEnd && *Current == ' ') {
+          ++Spaces;
+          ++Current;
+        }
+        if (Current < TokEnd && *Current == '*')
+          ++Indent;
+        else
+          Indent += 3;
+
+        if (Spaces < Indent)
+          Replaces.insert(tooling::Replacement(
+              SourceMgr, Loc, 0, std::string(Indent - Spaces, ' ')));
+        else if (Spaces > Indent)
+          Replaces.insert(
+              tooling::Replacement(SourceMgr, Loc, Spaces - Indent, ""));
+      } else {
+        ++Current;
+      }
+    }
+  }
+
   std::string getNewLineText(unsigned NewLines, unsigned Spaces) {
     return std::string(NewLines, '\n') + std::string(Spaces, ' ');
   }
@@ -227,8 +261,7 @@ private:
     unsigned MinColumn = 0;
     unsigned MaxColumn = UINT_MAX;
     comment_iterator Start = Comments.begin();
-    for (comment_iterator I = Comments.begin(), E = Comments.end(); I != E;
-         ++I) {
+    for (comment_iterator I = Start, E = Comments.end(); I != E; ++I) {
       if (I->MinColumn > MaxColumn || I->MaxColumn < MinColumn) {
         alignComments(Start, I, MinColumn);
         MinColumn = I->MinColumn;
index 3044c69cd002a32b6d772cf352479a4d7679d8a6..ca7ed62ed1ec0926cfc9fa4bfe234d6d9885ded6 100644 (file)
@@ -608,6 +608,41 @@ TEST_F(FormatTest, UnderstandsMultiLineComments) {
                NoBinPacking);
 }
 
+TEST_F(FormatTest, AlignsMultiLineComments) {
+  EXPECT_EQ("/*\n"
+            " * Really multi-line\n"
+            " * comment.\n"
+            " */\n"
+            "void f() {}",
+            format("  /*\n"
+                   "   * Really multi-line\n"
+                   "   * comment.\n"
+                   "   */\n"
+                   "  void f() {}"));
+  EXPECT_EQ("/*\n"
+            "   A comment.\n"
+            " */\n"
+            "void f() {}",
+            format("  /*\n"
+                   "           A comment.\n"
+                   "   */\n"
+                   "   void f() {}"));
+  EXPECT_EQ("class C {\n"
+            "  /*\n"
+            "   * Another multi-line\n"
+            "   * comment.\n"
+            "   */\n"
+            "  void f() {}\n"
+            "};",
+            format("class C {\n"
+                   "/*\n"
+                   " * Another multi-line\n"
+                   " * comment.\n"
+                   " */\n"
+                   "void f() {}\n"
+                   "};"));
+}
+
 TEST_F(FormatTest, CommentsInStaticInitializers) {
   EXPECT_EQ(
       "static SomeType type = { aaaaaaaaaaaaaaaaaaaa, /* comment */\n"