[PATCH] D44831: [clang-format] Refine ObjC guesser to handle child lines of child lines

Ben Hamilton via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 26 09:12:27 PDT 2018


benhamilton updated this revision to Diff 139802.
benhamilton added a comment.

- Use recursion. Split lambda out into its own static method since recursion on lambdas is quite ugly until C++14


Repository:
  rC Clang

https://reviews.llvm.org/D44831

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


Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -12171,6 +12171,12 @@
             guessLanguage("foo.h", "#define FOO ({ std::string s; })"));
   EXPECT_EQ(FormatStyle::LK_ObjC,
             guessLanguage("foo.h", "#define FOO ({ NSString *s; })"));
+  EXPECT_EQ(
+      FormatStyle::LK_Cpp,
+      guessLanguage("foo.h", "#define FOO ({ foo(); ({ std::string s; }) })"));
+  EXPECT_EQ(
+      FormatStyle::LK_ObjC,
+      guessLanguage("foo.h", "#define FOO ({ foo(); ({ NSString *s; }) })"));
 }
 
 } // end namespace
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -1446,6 +1446,14 @@
 private:
   static bool guessIsObjC(const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
                           const AdditionalKeywords &Keywords) {
+    for (auto Line : AnnotatedLines)
+      if (LineContainsObjCCode(*Line, Keywords))
+        return true;
+    return false;
+  }
+
+  static bool LineContainsObjCCode(const AnnotatedLine &Line,
+                                   const AdditionalKeywords &Keywords) {
     // Keep this array sorted, since we are binary searching over it.
     static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
         "CGFloat",
@@ -1514,40 +1522,32 @@
         "UIView",
     };
 
-    auto LineContainsObjCCode = [&Keywords](const AnnotatedLine &Line) {
-      for (const FormatToken *FormatTok = Line.First; FormatTok;
-           FormatTok = FormatTok->Next) {
-        if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
-             (FormatTok->isObjCAtKeyword(tok::objc_interface) ||
-              FormatTok->isObjCAtKeyword(tok::objc_implementation) ||
-              FormatTok->isObjCAtKeyword(tok::objc_protocol) ||
-              FormatTok->isObjCAtKeyword(tok::objc_end) ||
-              FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
-                                 tok::l_brace))) ||
-            (FormatTok->Tok.isAnyIdentifier() &&
-             std::binary_search(std::begin(FoundationIdentifiers),
-                                std::end(FoundationIdentifiers),
-                                FormatTok->TokenText)) ||
-            FormatTok->is(TT_ObjCStringLiteral) ||
-            FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
-                               TT_ObjCBlockLBrace, TT_ObjCBlockLParen,
-                               TT_ObjCDecl, TT_ObjCForIn, TT_ObjCMethodExpr,
-                               TT_ObjCMethodSpecifier, TT_ObjCProperty)) {
-          return true;
-        }
-      }
-      return false;
-    };
-    for (auto Line : AnnotatedLines) {
-      if (LineContainsObjCCode(*Line))
+    for (const FormatToken *FormatTok = Line.First; FormatTok;
+         FormatTok = FormatTok->Next) {
+      if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
+           (FormatTok->isObjCAtKeyword(tok::objc_interface) ||
+            FormatTok->isObjCAtKeyword(tok::objc_implementation) ||
+            FormatTok->isObjCAtKeyword(tok::objc_protocol) ||
+            FormatTok->isObjCAtKeyword(tok::objc_end) ||
+            FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
+                               tok::l_brace))) ||
+          (FormatTok->Tok.isAnyIdentifier() &&
+           std::binary_search(std::begin(FoundationIdentifiers),
+                              std::end(FoundationIdentifiers),
+                              FormatTok->TokenText)) ||
+          FormatTok->is(TT_ObjCStringLiteral) ||
+          FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
+                             TT_ObjCBlockLBrace, TT_ObjCBlockLParen,
+                             TT_ObjCDecl, TT_ObjCForIn, TT_ObjCMethodExpr,
+                             TT_ObjCMethodSpecifier, TT_ObjCProperty)) {
         return true;
-      for (auto ChildLine : Line->Children) {
-        if (LineContainsObjCCode(*ChildLine))
-          return true;
       }
+      for (auto ChildLine : Line.Children)
+        if (LineContainsObjCCode(*ChildLine, Keywords))
+          return true;
     }
     return false;
-  }
+  };
 
   bool IsObjC;
 };


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D44831.139802.patch
Type: text/x-patch
Size: 4330 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180326/6b46edbc/attachment-0001.bin>


More information about the cfe-commits mailing list