Browse Source

Added an option to avoid splitting certain kinds of comments into lines.

Summary: Added CommentPragmas option for this.

Reviewers: djasper, klimek

Reviewed By: klimek

CC: cfe-commits, klimek

Differential Revision: http://llvm-reviews.chandlerc.com/D2460

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@198310 91177308-0d34-0410-b5e6-96231b3b80d8
Alexander Kornienko 11 years ago
parent
commit
e2ba1f6663

+ 6 - 1
include/clang/Format/Format.h

@@ -283,6 +283,10 @@ struct FormatStyle {
   /// \brief Indent width for line continuations.
   /// \brief Indent width for line continuations.
   unsigned ContinuationIndentWidth;
   unsigned ContinuationIndentWidth;
 
 
+  /// \brief A regular expression that describes comments with special meaning,
+  /// which should not be split into lines or otherwise changed.
+  std::string CommentPragmas;
+
   bool operator==(const FormatStyle &R) const {
   bool operator==(const FormatStyle &R) const {
     return AccessModifierOffset == R.AccessModifierOffset &&
     return AccessModifierOffset == R.AccessModifierOffset &&
            ConstructorInitializerIndentWidth ==
            ConstructorInitializerIndentWidth ==
@@ -334,7 +338,8 @@ struct FormatStyle {
            SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses &&
            SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses &&
            SpaceBeforeParens == R.SpaceBeforeParens &&
            SpaceBeforeParens == R.SpaceBeforeParens &&
            SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators &&
            SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators &&
-           ContinuationIndentWidth == R.ContinuationIndentWidth;
+           ContinuationIndentWidth == R.ContinuationIndentWidth &&
+           CommentPragmas == R.CommentPragmas;
   }
   }
 };
 };
 
 

+ 6 - 1
lib/Format/ContinuationIndenter.cpp

@@ -63,7 +63,8 @@ ContinuationIndenter::ContinuationIndenter(const FormatStyle &Style,
                                            bool BinPackInconclusiveFunctions)
                                            bool BinPackInconclusiveFunctions)
     : Style(Style), SourceMgr(SourceMgr), Whitespaces(Whitespaces),
     : Style(Style), SourceMgr(SourceMgr), Whitespaces(Whitespaces),
       Encoding(Encoding),
       Encoding(Encoding),
-      BinPackInconclusiveFunctions(BinPackInconclusiveFunctions) {}
+      BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
+      CommentPragmasRegex(Style.CommentPragmas) {}
 
 
 LineState ContinuationIndenter::getInitialState(unsigned FirstIndent,
 LineState ContinuationIndenter::getInitialState(unsigned FirstIndent,
                                                 const AnnotatedLine *Line,
                                                 const AnnotatedLine *Line,
@@ -810,12 +811,16 @@ unsigned ContinuationIndenter::breakProtrudingToken(const FormatToken &Current,
       return 0;
       return 0;
     }
     }
   } else if (Current.Type == TT_BlockComment && Current.isTrailingComment()) {
   } else if (Current.Type == TT_BlockComment && Current.isTrailingComment()) {
+    if (CommentPragmasRegex.match(Current.TokenText.substr(2)))
+      return 0;
     Token.reset(new BreakableBlockComment(
     Token.reset(new BreakableBlockComment(
         Current, State.Line->Level, StartColumn, Current.OriginalColumn,
         Current, State.Line->Level, StartColumn, Current.OriginalColumn,
         !Current.Previous, State.Line->InPPDirective, Encoding, Style));
         !Current.Previous, State.Line->InPPDirective, Encoding, Style));
   } else if (Current.Type == TT_LineComment &&
   } else if (Current.Type == TT_LineComment &&
              (Current.Previous == NULL ||
              (Current.Previous == NULL ||
               Current.Previous->Type != TT_ImplicitStringLiteral)) {
               Current.Previous->Type != TT_ImplicitStringLiteral)) {
+    if (CommentPragmasRegex.match(Current.TokenText.substr(2)))
+      return 0;
     Token.reset(new BreakableLineComment(Current, State.Line->Level,
     Token.reset(new BreakableLineComment(Current, State.Line->Level,
                                          StartColumn, /*InPPDirective=*/false,
                                          StartColumn, /*InPPDirective=*/false,
                                          Encoding, Style));
                                          Encoding, Style));

+ 2 - 0
lib/Format/ContinuationIndenter.h

@@ -18,6 +18,7 @@
 
 
 #include "Encoding.h"
 #include "Encoding.h"
 #include "clang/Format/Format.h"
 #include "clang/Format/Format.h"
+#include "llvm/Support/Regex.h"
 
 
 namespace clang {
 namespace clang {
 class SourceManager;
 class SourceManager;
@@ -122,6 +123,7 @@ private:
   WhitespaceManager &Whitespaces;
   WhitespaceManager &Whitespaces;
   encoding::Encoding Encoding;
   encoding::Encoding Encoding;
   bool BinPackInconclusiveFunctions;
   bool BinPackInconclusiveFunctions;
+  llvm::Regex CommentPragmasRegex;
 };
 };
 
 
 struct ParenState {
 struct ParenState {

+ 2 - 0
lib/Format/Format.cpp

@@ -193,6 +193,7 @@ template <> struct MappingTraits<FormatStyle> {
     IO.mapOptional("SpaceBeforeAssignmentOperators",
     IO.mapOptional("SpaceBeforeAssignmentOperators",
                    Style.SpaceBeforeAssignmentOperators);
                    Style.SpaceBeforeAssignmentOperators);
     IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth);
     IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth);
+    IO.mapOptional("CommentPragmas", Style.CommentPragmas);
 
 
     // For backward compatibility.
     // For backward compatibility.
     if (!IO.outputting()) {
     if (!IO.outputting()) {
@@ -275,6 +276,7 @@ FormatStyle getLLVMStyle() {
   LLVMStyle.SpaceBeforeAssignmentOperators = true;
   LLVMStyle.SpaceBeforeAssignmentOperators = true;
   LLVMStyle.ContinuationIndentWidth = 4;
   LLVMStyle.ContinuationIndentWidth = 4;
   LLVMStyle.SpacesInAngles = false;
   LLVMStyle.SpacesInAngles = false;
+  LLVMStyle.CommentPragmas = "^ IWYU pragma:";
 
 
   LLVMStyle.PenaltyBreakComment = 300;
   LLVMStyle.PenaltyBreakComment = 300;
   LLVMStyle.PenaltyBreakFirstLessLess = 120;
   LLVMStyle.PenaltyBreakFirstLessLess = 120;

+ 11 - 0
unittests/Format/FormatTest.cpp

@@ -1045,6 +1045,17 @@ TEST_F(FormatTest, DontSplitLineCommentsWithEscapedNewlines) {
                    getLLVMStyleWithColumns(49)));
                    getLLVMStyleWithColumns(49)));
 }
 }
 
 
+TEST_F(FormatTest, DontSplitLineCommentsWithPragmas) {
+  FormatStyle Pragmas = getLLVMStyleWithColumns(30);
+  Pragmas.CommentPragmas = "^ IWYU pragma:";
+  EXPECT_EQ(
+      "// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb",
+      format("// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", Pragmas));
+  EXPECT_EQ(
+      "/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */",
+      format("/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", Pragmas));
+}
+
 TEST_F(FormatTest, PriorityOfCommentBreaking) {
 TEST_F(FormatTest, PriorityOfCommentBreaking) {
   EXPECT_EQ("if (xxx ==\n"
   EXPECT_EQ("if (xxx ==\n"
             "        yyy && // aaaaaaaaaaaa bbbbbbbbb\n"
             "        yyy && // aaaaaaaaaaaa bbbbbbbbb\n"