r324995 - [clang-format] Support text proto extensions

Krasimir Georgiev via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 13 02:20:39 PST 2018


Author: krasimir
Date: Tue Feb 13 02:20:39 2018
New Revision: 324995

URL: http://llvm.org/viewvc/llvm-project?rev=324995&view=rev
Log:
[clang-format] Support text proto extensions

Summary:
This adds support for text proto extensions, like:
```
msg {
  [type.type/ext] {
    key: value
  }
}
```

Reviewers: djasper

Reviewed By: djasper

Subscribers: klimek, cfe-commits

Differential Revision: https://reviews.llvm.org/D43180

Modified:
    cfe/trunk/lib/Format/ContinuationIndenter.cpp
    cfe/trunk/lib/Format/FormatToken.h
    cfe/trunk/lib/Format/TokenAnnotator.cpp
    cfe/trunk/unittests/Format/FormatTestProto.cpp
    cfe/trunk/unittests/Format/FormatTestTextProto.cpp

Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=324995&r1=324994&r2=324995&view=diff
==============================================================================
--- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original)
+++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Tue Feb 13 02:20:39 2018
@@ -943,6 +943,8 @@ unsigned ContinuationIndenter::getNewLin
   if (Previous.is(tok::r_paren) && !Current.isBinaryOperator() &&
       !Current.isOneOf(tok::colon, tok::comment))
     return ContinuationIndent;
+  if (Current.is(TT_ProtoExtensionLSquare))
+    return State.Stack.back().Indent;
   if (State.Stack.back().Indent == State.FirstIndent && PreviousNonComment &&
       PreviousNonComment->isNot(tok::r_brace))
     // Ensure that we fall back to the continuation indent width instead of

Modified: cfe/trunk/lib/Format/FormatToken.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=324995&r1=324994&r2=324995&view=diff
==============================================================================
--- cfe/trunk/lib/Format/FormatToken.h (original)
+++ cfe/trunk/lib/Format/FormatToken.h Tue Feb 13 02:20:39 2018
@@ -88,6 +88,7 @@ namespace format {
   TYPE(TemplateCloser)                                                         \
   TYPE(TemplateOpener)                                                         \
   TYPE(TemplateString)                                                         \
+  TYPE(ProtoExtensionLSquare)                                                  \
   TYPE(TrailingAnnotation)                                                     \
   TYPE(TrailingReturnArrow)                                                    \
   TYPE(TrailingUnaryOperator)                                                  \

Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=324995&r1=324994&r2=324995&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Tue Feb 13 02:20:39 2018
@@ -368,12 +368,35 @@ private:
                  Parent->is(TT_TemplateCloser)) {
         Left->Type = TT_ArraySubscriptLSquare;
       } else if (Style.Language == FormatStyle::LK_Proto ||
-                 (!CppArrayTemplates && Parent &&
-                  Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
-                                  tok::comma, tok::l_paren, tok::l_square,
-                                  tok::question, tok::colon, tok::kw_return,
-                                  // Should only be relevant to JavaScript:
-                                  tok::kw_default))) {
+                 Style.Language == FormatStyle::LK_TextProto) {
+        // Square braces in LK_Proto can either be message field attributes:
+        //
+        // optional Aaa aaa = 1 [
+        //   (aaa) = aaa
+        // ];
+        //
+        // or text proto extensions (in options):
+        //
+        // option (Aaa.options) = {
+        //   [type.type/type] {
+        //     key: value
+        //   }
+        // }
+        //
+        // In the first 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)) {
+          Left->Type = TT_ProtoExtensionLSquare;
+          BindingIncrease = 10;
+        }
+      } else if (!CppArrayTemplates && Parent &&
+                 Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
+                                 tok::comma, tok::l_paren, tok::l_square,
+                                 tok::question, tok::colon, tok::kw_return,
+                                 // Should only be relevant to JavaScript:
+                                 tok::kw_default)) {
         Left->Type = TT_ArrayInitializerLSquare;
       } else {
         BindingIncrease = 10;
@@ -2396,6 +2419,12 @@ bool TokenAnnotator::spaceRequiredBefore
       return true;
     if (Right.isOneOf(tok::l_brace, tok::less) && Left.is(TT_SelectorName))
       return true;
+    // Slashes occur in text protocol extension syntax: [type/type] { ... }.
+    if (Left.is(tok::slash) || Right.is(tok::slash))
+      return false;
+    if (Left.MatchingParen && Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&
+        Right.isOneOf(tok::l_brace, tok::less))
+      return !Style.Cpp11BracedListStyle;
   } else if (Style.Language == FormatStyle::LK_JavaScript) {
     if (Left.is(TT_JsFatArrow))
       return true;
@@ -2732,6 +2761,9 @@ bool TokenAnnotator::mustBreakBefore(con
       (Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations))
     return true;
 
+  if (Right.is(TT_ProtoExtensionLSquare))
+    return true;
+
   return false;
 }
 

Modified: cfe/trunk/unittests/Format/FormatTestProto.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestProto.cpp?rev=324995&r1=324994&r2=324995&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTestProto.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestProto.cpp Tue Feb 13 02:20:39 2018
@@ -421,5 +421,16 @@ TEST_F(FormatTestProto, KeepsLongStringL
       "}");
 }
 
+TEST_F(FormatTestProto, FormatsOptionsExtensions) {
+  verifyFormat("option (MyProto.options) = {\n"
+               "  msg_field: { field_d: 123 }\n"
+               "  [ext.t/u] { key: value }\n"
+               "  key: value\n"
+               "  [t.u/v] <\n"
+               "    [ext] { key: value }\n"
+               "  >\n"
+               "};");
+}
+
 } // end namespace tooling
 } // end namespace clang

Modified: cfe/trunk/unittests/Format/FormatTestTextProto.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestTextProto.cpp?rev=324995&r1=324994&r2=324995&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTestTextProto.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestTextProto.cpp Tue Feb 13 02:20:39 2018
@@ -325,5 +325,66 @@ TEST_F(FormatTestTextProto, KeepsComment
                "cccccccccccccccccccccccc: 3849");
 }
 
+TEST_F(FormatTestTextProto, FormatsExtensions) {
+  verifyFormat("[type] { key: value }");
+  verifyFormat("[type] {\n"
+               "  keyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: value\n"
+               "}");
+  verifyFormat("[type.type] { key: value }");
+  verifyFormat("[type.type] < key: value >");
+  verifyFormat("[type.type/type.type] { key: value }");
+  verifyFormat("msg {\n"
+               "  [type.type] { key: value }\n"
+               "}");
+  verifyFormat("msg {\n"
+               "  [type.type] {\n"
+               "    keyyyyyyyyyyyyyy: valuuuuuuuuuuuuuuuuuuuuuuuuue\n"
+               "  }\n"
+               "}");
+  verifyFormat("key: value\n"
+               "[a.b] { key: value }");
+  verifyFormat("msg: <\n"
+               "  key: value\n"
+               "  [a.b.c/d.e]: < key: value >\n"
+               "  [f.g]: <\n"
+               "    key: valueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\n"
+               "    key: {}\n"
+               "  >\n"
+               "  key {}\n"
+               "  [h.i.j] < key: value >\n"
+               "  [a]: {\n"
+               "    [b.c]: {}\n"
+               "    [d] <>\n"
+               "    [e/f]: 1\n"
+               "  }\n"
+               ">");
+  verifyFormat("[longg.long.long.long.long.long.long.long.long.long.long\n"
+               "     .longg.longlong] { key: value }");
+  verifyFormat("[longg.long.long.long.long.long.long.long.long.long.long\n"
+               "     .longg.longlong] {\n"
+               "  key: value\n"
+               "  key: value\n"
+               "  key: value\n"
+               "  key: value\n"
+               "}");
+  verifyFormat("[longg.long.long.long.long.long.long.long.long.long\n"
+               "     .long/longg.longlong] { key: value }");
+  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/\n"
+               " bbbbbbbbbbbbbb] { key: value }");
+  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+               "] { key: value }");
+  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+               "] {\n"
+               "  [type.type] {\n"
+               "    keyyyyyyyyyyyyyy: valuuuuuuuuuuuuuuuuuuuuuuuuue\n"
+               "  }\n"
+               "}");
+  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/\n"
+               " bbbbbbb] {\n"
+               "  [type.type] {\n"
+               "    keyyyyyyyyyyyyyy: valuuuuuuuuuuuuuuuuuuuuuuuuue\n"
+               "  }\n"
+               "}");
+}
 } // end namespace tooling
 } // end namespace clang




More information about the cfe-commits mailing list