]> granicus.if.org Git - clang/commitdiff
[clang-format] Refine ObjC guesser to handle child lines of child lines
authorBen Hamilton <benhamilton@google.com>
Tue, 27 Mar 2018 15:01:21 +0000 (15:01 +0000)
committerBen Hamilton <benhamilton@google.com>
Tue, 27 Mar 2018 15:01:21 +0000 (15:01 +0000)
Summary:
This fixes an issue brought up by djasper@ in his review of D44790. We
handled top-level child lines, but if those child lines themselves
had child lines, we didn't handle them.

Rather than use recursion (which could blow out the stack), I use a
DenseSet to hold the set of lines we haven't yet checked (since order
doesn't matter), and update the set to add the children of each
line as we check it.

Test Plan: New tests added. Confirmed tests failed before fix
  and passed after fix.

Reviewers: djasper

Reviewed By: djasper

Subscribers: klimek, cfe-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@328628 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Format/Format.cpp
unittests/Format/FormatTest.cpp

index ac22d6b4501b541ce5f8c19af794af0efd5c9d33..f7e74abab37b4fdef096c7be87b8c4a713b2385c 100644 (file)
@@ -1514,8 +1514,8 @@ private:
         "UIView",
     };
 
-    auto LineContainsObjCCode = [&Keywords](const AnnotatedLine &Line) {
-      for (const FormatToken *FormatTok = Line.First; FormatTok;
+    for (auto Line : AnnotatedLines) {
+      for (const FormatToken *FormatTok = Line->First; FormatTok;
            FormatTok = FormatTok->Next) {
         if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
              (FormatTok->isObjCAtKeyword(tok::objc_interface) ||
@@ -1535,14 +1535,7 @@ private:
                                TT_ObjCMethodSpecifier, TT_ObjCProperty)) {
           return true;
         }
-      }
-      return false;
-    };
-    for (auto Line : AnnotatedLines) {
-      if (LineContainsObjCCode(*Line))
-        return true;
-      for (auto ChildLine : Line->Children) {
-        if (LineContainsObjCCode(*ChildLine))
+        if (guessIsObjC(Line->Children, Keywords))
           return true;
       }
     }
index c1250283a131ab2c3cac189c07ffaf2acd3cd0e6..819ab3c44a5b21b9db75db2ceced59dfcc192316 100644 (file)
@@ -12159,6 +12159,12 @@ TEST_F(FormatTest, GuessLanguageWithChildLines) {
             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