krasimir updated this revision to Diff 103352.
krasimir added a comment.
- Remove newline
https://reviews.llvm.org/D34441
Files:
include/clang/Format/Format.h
lib/Format/ContinuationIndenter.cpp
lib/Format/Format.cpp
lib/Format/TokenAnnotator.cpp
lib/Format/UnwrappedLineParser.cpp
lib/Format/UnwrappedLineParser.h
unittests/Format/CMakeLists.txt
unittests/Format/FormatTestTextProto.cpp
Index: unittests/Format/FormatTestTextProto.cpp
===================================================================
--- /dev/null
+++ unittests/Format/FormatTestTextProto.cpp
@@ -0,0 +1,131 @@
+//===- unittest/Format/FormatTestProto.cpp --------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "FormatTestUtils.h"
+#include "clang/Format/Format.h"
+#include "llvm/Support/Debug.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "format-test"
+
+namespace clang {
+namespace format {
+
+class FormatTestTextProto : public ::testing::Test {
+protected:
+ static std::string format(llvm::StringRef Code, unsigned Offset,
+ unsigned Length, const FormatStyle &Style) {
+ DEBUG(llvm::errs() << "---\n");
+ DEBUG(llvm::errs() << Code << "\n\n");
+ std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
+ tooling::Replacements Replaces = reformat(Style, Code, Ranges);
+ auto Result = applyAllReplacements(Code, Replaces);
+ EXPECT_TRUE(static_cast<bool>(Result));
+ DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+ return *Result;
+ }
+
+ static std::string format(llvm::StringRef Code) {
+ FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto);
+ Style.ColumnLimit = 60; // To make writing tests easier.
+ return format(Code, 0, Code.size(), Style);
+ }
+
+ static void verifyFormat(llvm::StringRef Code) {
+ EXPECT_EQ(Code.str(), format(test::messUp(Code)));
+ }
+};
+
+TEST_F(FormatTestTextProto, KeepsTopLevelEntriesFittingALine) {
+ verifyFormat("field_a: OK field_b: OK field_c: OK field_d: OK field_e: OK");
+}
+
+TEST_F(FormatTestTextProto, SupportsMessageFields) {
+ verifyFormat("msg_field: {}");
+
+ verifyFormat("msg_field: {field_a: A}");
+
+ verifyFormat("msg_field: {field_a: \"OK\" field_b: 123}");
+
+ verifyFormat("msg_field: {\n"
+ " field_a: 1\n"
+ " field_b: OK\n"
+ " field_c: \"OK\"\n"
+ " field_d: 123\n"
+ " field_e: 23\n"
+ "}");
+
+ verifyFormat("msg_field{}");
+
+ verifyFormat("msg_field{field_a: A}");
+
+ verifyFormat("msg_field{field_a: \"OK\" field_b: 123}");
+
+ verifyFormat("msg_field{\n"
+ " field_a: 1\n"
+ " field_b: OK\n"
+ " field_c: \"OK\"\n"
+ " field_d: 123\n"
+ " field_e: 23.0\n"
+ " field_f: false\n"
+ " field_g: 'lala'\n"
+ " field_h: 1234.567e-89\n"
+ "}");
+
+ verifyFormat("msg_field: {msg_field{field_a: 1}}");
+
+ verifyFormat("id: \"ala.bala\"\n"
+ "item{type: ITEM_A rank: 1 score: 90.0}\n"
+ "item{type: ITEM_B rank: 2 score: 70.5}\n"
+ "item{\n"
+ " type: ITEM_A\n"
+ " rank: 3\n"
+ " score: 20.0\n"
+ " description: \"the third item has a description\"\n"
+ "}");
+}
+
+TEST_F(FormatTestTextProto, AvoidsTopLevelBinPacking) {
+ verifyFormat("field_a: OK\n"
+ "field_b: OK\n"
+ "field_c: OK\n"
+ "field_d: OK\n"
+ "field_e: OK\n"
+ "field_f: OK");
+
+ verifyFormat("field_a: OK\n"
+ "field_b: \"OK\"\n"
+ "field_c: \"OK\"\n"
+ "msg_field: {field_d: 123}\n"
+ "field_e: OK\n"
+ "field_f: OK");
+
+ verifyFormat("field_a: OK\n"
+ "field_b: \"OK\"\n"
+ "field_c: \"OK\"\n"
+ "msg_field: {field_d: 123 field_e: OK}");
+}
+
+TEST_F(FormatTestTextProto, AddsNewlinesAfterTrailingComments) {
+ verifyFormat("field_a: OK // Comment\n"
+ "field_b: 1");
+
+ verifyFormat("field_a: OK\n"
+ "msg_field: {\n"
+ " field_b: OK // Comment\n"
+ "}");
+
+ verifyFormat("field_a: OK\n"
+ "msg_field{\n"
+ " field_b: OK // Comment\n"
+ "}");
+}
+
+} // end namespace tooling
+} // end namespace clang
Index: unittests/Format/CMakeLists.txt
===================================================================
--- unittests/Format/CMakeLists.txt
+++ unittests/Format/CMakeLists.txt
@@ -11,6 +11,7 @@
FormatTestObjC.cpp
FormatTestProto.cpp
FormatTestSelective.cpp
+ FormatTestTextProto.cpp
NamespaceEndCommentsFixerTest.cpp
SortImportsTestJS.cpp
SortIncludesTest.cpp
Index: lib/Format/UnwrappedLineParser.h
===================================================================
--- lib/Format/UnwrappedLineParser.h
+++ lib/Format/UnwrappedLineParser.h
@@ -93,7 +93,7 @@
void readTokenWithJavaScriptASI();
void parseStructuralElement();
bool tryToParseBracedList();
- bool parseBracedList(bool ContinueOnSemicolons = false);
+ bool parseBracedList(bool ContinueOnSemicolons = false, bool StartInside = false);
void parseParens();
void parseSquare();
void parseIfThenElse();
Index: lib/Format/UnwrappedLineParser.cpp
===================================================================
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -286,7 +286,10 @@
!Line->InPPDirective && Style.Language != FormatStyle::LK_JavaScript;
ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
MustBeDeclaration);
- parseLevel(/*HasOpeningBrace=*/false);
+ if (Style.Language == FormatStyle::LK_TextProto)
+ parseBracedList(/*ContinueOnSemicolon=*/false, /*StartInside=*/true);
+ else
+ parseLevel(/*HasOpeningBrace=*/false);
// Make sure to format the remaining tokens.
flushComments(true);
addUnwrappedLine();
@@ -1346,9 +1349,10 @@
return true;
}
-bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
+bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons,
+ bool StartInside) {
bool HasError = false;
- nextToken();
+ if (!StartInside) nextToken();
// FIXME: Once we have an expression parser in the UnwrappedLineParser,
// replace this by using parseAssigmentExpression() inside.
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -444,7 +444,8 @@
FormatToken *Previous = CurrentToken->getPreviousNonComment();
if (((CurrentToken->is(tok::colon) &&
(!Contexts.back().ColonIsDictLiteral || !Style.isCpp())) ||
- Style.Language == FormatStyle::LK_Proto) &&
+ Style.Language == FormatStyle::LK_Proto ||
+ Style.Language == FormatStyle::LK_TextProto) &&
(Previous->Tok.getIdentifierInfo() ||
Previous->is(tok::string_literal)))
Previous->Type = TT_SelectorName;
@@ -527,8 +528,13 @@
}
}
if (Contexts.back().ColonIsDictLiteral ||
- Style.Language == FormatStyle::LK_Proto) {
+ Style.Language == FormatStyle::LK_Proto ||
+ Style.Language == FormatStyle::LK_TextProto) {
Tok->Type = TT_DictLiteral;
+ if (Style.Language == FormatStyle::LK_TextProto) {
+ if (FormatToken *Previous = Tok->getPreviousNonComment())
+ Previous->Type = TT_SelectorName;
+ }
} else if (Contexts.back().ColonIsObjCMethodExpr ||
Line.startsWith(TT_ObjCMethodSpecifier)) {
Tok->Type = TT_ObjCMethodExpr;
@@ -626,6 +632,11 @@
return false;
break;
case tok::l_brace:
+ if (Style.Language == FormatStyle::LK_TextProto) {
+ FormatToken *Previous =Tok->getPreviousNonComment();
+ if (Previous && Previous->Type != TT_DictLiteral)
+ Previous->Type = TT_SelectorName;
+ }
if (!parseBrace())
return false;
break;
@@ -2263,7 +2274,8 @@
if (Style.isCpp()) {
if (Left.is(tok::kw_operator))
return Right.is(tok::coloncolon);
- } else if (Style.Language == FormatStyle::LK_Proto) {
+ } else if (Style.Language == FormatStyle::LK_Proto ||
+ Style.Language == FormatStyle::LK_TextProto) {
if (Right.is(tok::period) &&
Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
Keywords.kw_repeated, Keywords.kw_extend))
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -56,6 +56,7 @@
IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC);
IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);
IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen);
+ IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);
}
};
@@ -622,6 +623,12 @@
}
FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
+ if (Language == FormatStyle::LK_TextProto) {
+ FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_Proto);
+ GoogleStyle.Language = FormatStyle::LK_TextProto;
+ return GoogleStyle;
+ }
+
FormatStyle GoogleStyle = getLLVMStyle();
GoogleStyle.Language = Language;
Index: lib/Format/ContinuationIndenter.cpp
===================================================================
--- lib/Format/ContinuationIndenter.cpp
+++ lib/Format/ContinuationIndenter.cpp
@@ -92,6 +92,11 @@
State.LowestLevelOnLine = 0;
State.IgnoreStackForComparison = false;
+ if (Style.Language == FormatStyle::LK_TextProto) {
+ State.Stack.back().AvoidBinPacking = true;
+ State.Stack.back().BreakBeforeParameter = true;
+ }
+
// The first token has already been indented and thus consumed.
moveStateToNextToken(State, DryRun, /*Newline=*/false);
return State;
Index: include/clang/Format/Format.h
===================================================================
--- include/clang/Format/Format.h
+++ include/clang/Format/Format.h
@@ -1081,7 +1081,10 @@
/// (https://developers.google.com/protocol-buffers/).
LK_Proto,
/// Should be used for TableGen code.
- LK_TableGen
+ LK_TableGen,
+ /// Should be used for Protocol Buffer messages in text format
+ /// (https://developers.google.com/protocol-buffers/).
+ LK_TextProto
};
bool isCpp() const { return Language == LK_Cpp || Language == LK_ObjC; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits