r174889 - Formatter: Detect ObjC message expressions after 'in' in loop

Nico Weber nicolasweber at gmx.de
Mon Feb 11 07:32:16 PST 2013


Author: nico
Date: Mon Feb 11 09:32:15 2013
New Revision: 174889

URL: http://llvm.org/viewvc/llvm-project?rev=174889&view=rev
Log:
Formatter: Detect ObjC message expressions after 'in' in loop

Before:
  for (id foo in[self getStuffFor : bla]) {
  }

Now:
  for (id foo in [self getStuffFor:bla]) {
  }

"in" is treated as loop keyword if the line starts with "for", and as a
regular identifier else. To check for "in", its IdentifierInfo is handed
through a few layers.


Modified:
    cfe/trunk/lib/Format/Format.cpp
    cfe/trunk/lib/Format/TokenAnnotator.cpp
    cfe/trunk/lib/Format/TokenAnnotator.h
    cfe/trunk/unittests/Format/FormatTest.cpp

Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=174889&r1=174888&r2=174889&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Mon Feb 11 09:32:15 2013
@@ -842,6 +842,8 @@ public:
     return FormatTok;
   }
 
+  IdentifierTable &getIdentTable() { return IdentTable; }
+
 private:
   FormatToken FormatTok;
   bool GreaterStashed;
@@ -909,7 +911,8 @@ public:
     UnwrappedLineParser Parser(Diag, Style, Tokens, *this);
     StructuralError = Parser.parse();
     unsigned PreviousEndOfLineColumn = 0;
-    TokenAnnotator Annotator(Style, SourceMgr, Lex);
+    TokenAnnotator Annotator(Style, SourceMgr, Lex,
+                             Tokens.getIdentTable().get("in"));
     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
       Annotator.annotate(AnnotatedLines[i]);
     }

Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=174889&r1=174888&r2=174889&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Mon Feb 11 09:32:15 2013
@@ -78,9 +78,10 @@ static const AnnotatedToken *getNextToke
 /// into template parameter lists.
 class AnnotatingParser {
 public:
-  AnnotatingParser(SourceManager &SourceMgr, Lexer &Lex, AnnotatedLine &Line)
+  AnnotatingParser(SourceManager &SourceMgr, Lexer &Lex, AnnotatedLine &Line,
+                   IdentifierInfo &Ident_in)
       : SourceMgr(SourceMgr), Lex(Lex), Line(Line), CurrentToken(&Line.First),
-        KeywordVirtualFound(false) {
+        KeywordVirtualFound(false), Ident_in(Ident_in) {
     Contexts.push_back(Context(1, /*IsExpression=*/ false));
     Contexts.back().LookForFunctionName = Line.MustBeDeclaration;
   }
@@ -195,6 +196,7 @@ public:
         !Parent || Parent->is(tok::colon) || Parent->is(tok::l_square) ||
         Parent->is(tok::l_paren) || Parent->is(tok::kw_return) ||
         Parent->is(tok::kw_throw) || isUnaryOperator(*Parent) ||
+        Parent->Type == TT_ObjCForIn ||
         getBinOpPrecedence(Parent->FormatTok.Tok.getKind(), true, true) >
         prec::Unknown;
     bool StartsObjCArrayLiteral = Parent && Parent->is(tok::at);
@@ -383,6 +385,11 @@ public:
     case tok::kw_template:
       parseTemplateDeclaration();
       break;
+    case tok::identifier:
+      if (Line.First.is(tok::kw_for) &&
+          Tok->FormatTok.Tok.getIdentifierInfo() == &Ident_in)
+        Tok->Type = TT_ObjCForIn;
+      break;
     default:
       break;
     }
@@ -684,6 +691,7 @@ private:
   AnnotatedLine &Line;
   AnnotatedToken *CurrentToken;
   bool KeywordVirtualFound;
+  IdentifierInfo &Ident_in;
 };
 
 /// \brief Parses binary expressions by inserting fake parenthesis based on
@@ -763,7 +771,7 @@ private:
 };
 
 void TokenAnnotator::annotate(AnnotatedLine &Line) {
-  AnnotatingParser Parser(SourceMgr, Lex, Line);
+  AnnotatingParser Parser(SourceMgr, Lex, Line, Ident_in);
   Line.Type = Parser.parseLine();
   if (Line.Type == LT_Invalid)
     return;

Modified: cfe/trunk/lib/Format/TokenAnnotator.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.h?rev=174889&r1=174888&r2=174889&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.h (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.h Mon Feb 11 09:32:15 2013
@@ -38,6 +38,7 @@ enum TokenType {
   TT_ObjCArrayLiteral,
   TT_ObjCBlockLParen,
   TT_ObjCDecl,
+  TT_ObjCForIn,
   TT_ObjCMethodExpr,
   TT_ObjCMethodSpecifier,
   TT_ObjCProperty,
@@ -178,8 +179,9 @@ inline prec::Level getPrecedence(const A
 /// \c UnwrappedLine.
 class TokenAnnotator {
 public:
-  TokenAnnotator(const FormatStyle &Style, SourceManager &SourceMgr, Lexer &Lex)
-      : Style(Style), SourceMgr(SourceMgr), Lex(Lex) {
+  TokenAnnotator(const FormatStyle &Style, SourceManager &SourceMgr, Lexer &Lex,
+                 IdentifierInfo &Ident_in)
+      : Style(Style), SourceMgr(SourceMgr), Lex(Lex), Ident_in(Ident_in) {
   }
 
   void annotate(AnnotatedLine &Line);
@@ -201,6 +203,9 @@ private:
   const FormatStyle &Style;
   SourceManager &SourceMgr;
   Lexer &Lex;
+
+  // Contextual keywords:
+  IdentifierInfo &Ident_in;
 };
 
 } // end namespace format

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=174889&r1=174888&r2=174889&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Mon Feb 11 09:32:15 2013
@@ -2427,6 +2427,10 @@ TEST_F(FormatTest, FormatObjCMethodExpr)
   verifyFormat("[foo bar:baz] % [foo bar:baz];");
   // Whew!
 
+  verifyFormat("return in[42];");
+  verifyFormat("for (id foo in [self getStuffFor:bla]) {\n"
+               "}");
+
   verifyFormat("[self stuffWithInt:(4 + 2) float:4.5];");
   verifyFormat("[self stuffWithInt:a ? b : c float:4.5];");
   verifyFormat("[self stuffWithInt:a ? [self foo:bar] : c];");





More information about the cfe-commits mailing list