Index: cfe/trunk/lib/Format/TokenAnnotator.cpp =================================================================== --- cfe/trunk/lib/Format/TokenAnnotator.cpp +++ cfe/trunk/lib/Format/TokenAnnotator.cpp @@ -383,11 +383,18 @@ // } // } // - // In the first case we want to spread the contents inside the square - // braces; in the second we want to keep them inline. + // or repeated fields (in options): + // + // option (Aaa.options) = { + // keys: [ 1, 2, 3 ] + // } + // + // In the first and the third case we want to spread the contents inside + // the square braces; in the second we want to keep them inline. Left->Type = TT_ArrayInitializerLSquare; if (!Left->endsSequence(tok::l_square, tok::numeric_constant, - tok::equal)) { + tok::equal) && + !Left->endsSequence(tok::l_square, tok::colon, TT_SelectorName)) { Left->Type = TT_ProtoExtensionLSquare; BindingIncrease = 10; } @@ -2331,16 +2338,26 @@ !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon)); if (Right.is(tok::star) && Left.is(tok::l_paren)) return false; + const auto SpaceRequiredForArrayInitializerLSquare = + [](const FormatToken &LSquareTok, const FormatStyle &Style) { + return Style.SpacesInContainerLiterals || + ((Style.Language == FormatStyle::LK_Proto || + Style.Language == FormatStyle::LK_TextProto) && + !Style.Cpp11BracedListStyle && + LSquareTok.endsSequence(tok::l_square, tok::colon, + TT_SelectorName)); + }; if (Left.is(tok::l_square)) - return (Left.is(TT_ArrayInitializerLSquare) && - Style.SpacesInContainerLiterals && Right.isNot(tok::r_square)) || + return (Left.is(TT_ArrayInitializerLSquare) && Right.isNot(tok::r_square) && + SpaceRequiredForArrayInitializerLSquare(Left, Style)) || (Left.isOneOf(TT_ArraySubscriptLSquare, TT_StructuredBindingLSquare) && Style.SpacesInSquareBrackets && Right.isNot(tok::r_square)); if (Right.is(tok::r_square)) return Right.MatchingParen && - ((Style.SpacesInContainerLiterals && - Right.MatchingParen->is(TT_ArrayInitializerLSquare)) || + ((Right.MatchingParen->is(TT_ArrayInitializerLSquare) && + SpaceRequiredForArrayInitializerLSquare(*Right.MatchingParen, + Style)) || (Style.SpacesInSquareBrackets && Right.MatchingParen->isOneOf(TT_ArraySubscriptLSquare, TT_StructuredBindingLSquare))); Index: cfe/trunk/unittests/Format/FormatTestProto.cpp =================================================================== --- cfe/trunk/unittests/Format/FormatTestProto.cpp +++ cfe/trunk/unittests/Format/FormatTestProto.cpp @@ -438,5 +438,35 @@ "};"); } +TEST_F(FormatTestProto, FormatsRepeatedListInitializersInOptions) { + verifyFormat("option (MyProto.options) = {\n" + " key: item\n" + " keys: [\n" + " 'ala',\n" + " 'bala',\n" + " 'porto',\n" + " 'kala',\n" + " 'too',\n" + " 'long',\n" + " 'long',\n" + " 'long'\n" + " ]\n" + " key: [ item ]\n" + " msg {\n" + " key: item\n" + " keys: [\n" + " 'ala',\n" + " 'bala',\n" + " 'porto',\n" + " 'kala',\n" + " 'too',\n" + " 'long',\n" + " 'long'\n" + " ]\n" + " }\n" + " key: value\n" + "};"); +} + } // end namespace tooling } // end namespace clang Index: cfe/trunk/unittests/Format/FormatTestTextProto.cpp =================================================================== --- cfe/trunk/unittests/Format/FormatTestTextProto.cpp +++ cfe/trunk/unittests/Format/FormatTestTextProto.cpp @@ -31,14 +31,18 @@ return *Result; } - static std::string format(llvm::StringRef Code) { - FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); - Style.ColumnLimit = 60; // To make writing tests easier. + static std::string format(llvm::StringRef Code, const FormatStyle &Style) { return format(Code, 0, Code.size(), Style); } + static void verifyFormat(llvm::StringRef Code, const FormatStyle &Style) { + EXPECT_EQ(Code.str(), format(test::messUp(Code), Style)); + } + static void verifyFormat(llvm::StringRef Code) { - EXPECT_EQ(Code.str(), format(test::messUp(Code))); + FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); + Style.ColumnLimit = 60; // To make writing tests easier. + verifyFormat(Code, Style); } }; @@ -390,5 +394,43 @@ TEST_F(FormatTestTextProto, NoSpaceAfterPercent) { verifyFormat("key: %d"); } + +TEST_F(FormatTestTextProto, FormatsRepeatedListInitializers) { + verifyFormat("keys: []"); + verifyFormat("keys: [ 1 ]"); + verifyFormat("keys: [ 'ala', 'bala' ]"); + verifyFormat("keys:\n" + " [ 'ala', 'bala', 'porto', 'kala', 'too', 'long', 'ng' ]"); + verifyFormat("key: item\n" + "keys: [\n" + " 'ala',\n" + " 'bala',\n" + " 'porto',\n" + " 'kala',\n" + " 'too',\n" + " 'long',\n" + " 'long',\n" + " 'long'\n" + "]\n" + "key: item\n" + "msg {\n" + " key: item\n" + " keys: [\n" + " 'ala',\n" + " 'bala',\n" + " 'porto',\n" + " 'kala',\n" + " 'too',\n" + " 'long',\n" + " 'long'\n" + " ]\n" + "}\n" + "key: value" + ); + FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); + Style.ColumnLimit = 60; // To make writing tests easier. + Style.Cpp11BracedListStyle = true; + verifyFormat("keys: [1]", Style); +} } // end namespace tooling } // end namespace clang