[PATCH] Multi-line comment alignment

Alexander Kornienko alexfh at google.com
Thu Mar 14 09:08:17 PDT 2013


  Addressed djasper's comments.

Hi djasper,

http://llvm-reviews.chandlerc.com/D541

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D541?vs=1290&id=1291#toc

BRANCH
  svn

ARCANIST PROJECT
  clang

Files:
  lib/Format/Format.cpp
  unittests/Format/FormatTest.cpp

Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -128,24 +128,26 @@
       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;
         }
       }
     }
 
     // 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 @@
   }
 
 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 @@
     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: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -608,6 +608,41 @@
                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"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D541.3.patch
Type: text/x-patch
Size: 4645 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130314/0519d5eb/attachment.bin>


More information about the cfe-commits mailing list