r219424 - Objective-C SDK modernization. convert message expression

Fariborz Jahanian fjahanian at apple.com
Thu Oct 9 11:30:56 PDT 2014


Author: fjahanian
Date: Thu Oct  9 13:30:56 2014
New Revision: 219424

URL: http://llvm.org/viewvc/llvm-project?rev=219424&view=rev
Log:
Objective-C SDK modernization. convert message expression 
to Objective-C dot-syntax. rdar://18498572

Added:
    cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m
    cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m.result
Modified:
    cfe/trunk/lib/ARCMigrate/ObjCMT.cpp

Modified: cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=219424&r1=219423&r2=219424&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/ObjCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ObjCMT.cpp Thu Oct  9 13:30:56 2014
@@ -211,6 +211,104 @@ bool ObjCMigrateAction::BeginInvocation(
 }
 
 namespace {
+  // FIXME. This duplicates one in RewriteObjCFoundationAPI.cpp
+  bool subscriptOperatorNeedsParens(const Expr *FullExpr) {
+    const Expr* Expr = FullExpr->IgnoreImpCasts();
+    if (isa<ArraySubscriptExpr>(Expr) ||
+        isa<CallExpr>(Expr) ||
+        isa<DeclRefExpr>(Expr) ||
+        isa<CXXNamedCastExpr>(Expr) ||
+        isa<CXXConstructExpr>(Expr) ||
+        isa<CXXThisExpr>(Expr) ||
+        isa<CXXTypeidExpr>(Expr) ||
+        isa<CXXUnresolvedConstructExpr>(Expr) ||
+        isa<ObjCMessageExpr>(Expr) ||
+        isa<ObjCPropertyRefExpr>(Expr) ||
+        isa<ObjCProtocolExpr>(Expr) ||
+        isa<MemberExpr>(Expr) ||
+        isa<ObjCIvarRefExpr>(Expr) ||
+        isa<ParenExpr>(FullExpr) ||
+        isa<ParenListExpr>(Expr) ||
+        isa<SizeOfPackExpr>(Expr))
+      return false;
+    
+    return true;
+  }
+  
+  /// \brief - Rewrite message expression for Objective-C setter and getters into
+  /// property-dot syntax.
+  bool rewriteToPropertyDotSyntax(const ObjCMessageExpr *Msg,
+                                  Preprocessor &PP,
+                                  const NSAPI &NS, edit::Commit &commit,
+                                  const ParentMap *PMap) {
+    if (!Msg || Msg->isImplicit() ||
+        Msg->getReceiverKind() != ObjCMessageExpr::Instance)
+      return false;
+    const ObjCMethodDecl *Method = Msg->getMethodDecl();
+    if (!Method)
+      return false;
+    if (!Method->isPropertyAccessor())
+      return false;
+    
+    const ObjCInterfaceDecl *IFace =
+      NS.getASTContext().getObjContainingInterface(Method);
+    if (!IFace)
+      return false;
+    
+    const ObjCPropertyDecl *Prop = Method->findPropertyDecl();
+    if (!Prop)
+      return false;
+    
+    SourceRange MsgRange = Msg->getSourceRange();
+    const Expr *receiver = Msg->getInstanceReceiver();
+    bool NeedsParen = subscriptOperatorNeedsParens(receiver);
+    bool IsGetter = (Msg->getNumArgs() == 0);
+    if (IsGetter) {
+      // Find space location range between receiver expression and getter method.
+      SourceLocation BegLoc = receiver->getLocEnd();
+      BegLoc = PP.getLocForEndOfToken(BegLoc);
+      SourceLocation EndLoc = Msg->getSelectorLoc(0);
+      SourceRange SpaceRange(BegLoc, EndLoc);
+      std::string PropertyDotString;
+      // rewrite getter method expression into: receiver.property or
+      // (receiver).property
+      if (NeedsParen) {
+        commit.insertBefore(receiver->getLocStart(), "(");
+        PropertyDotString = ").";
+      }
+      else
+        PropertyDotString = ".";
+      PropertyDotString += Prop->getName();
+      commit.replace(SpaceRange, PropertyDotString);
+      
+      // remove '[' ']'
+      commit.replace(SourceRange(MsgRange.getBegin(), MsgRange.getBegin()), "");
+      commit.replace(SourceRange(MsgRange.getEnd(), MsgRange.getEnd()), "");
+    } else {
+      SourceRange ReceiverRange = receiver->getSourceRange();
+      if (NeedsParen)
+        commit.insertWrap("(", ReceiverRange, ")");
+      std::string PropertyDotString = ".";
+      PropertyDotString += Prop->getName();
+      PropertyDotString += " =";
+      const Expr*const* Args = Msg->getArgs();
+      const Expr *RHS = Args[0];
+      if (!RHS)
+        return false;
+      SourceLocation BegLoc = ReceiverRange.getEnd();
+      BegLoc = PP.getLocForEndOfToken(BegLoc);
+      SourceLocation EndLoc = RHS->getLocStart();
+      EndLoc = EndLoc.getLocWithOffset(-1);
+      SourceRange Range(BegLoc, EndLoc);
+      commit.replace(Range, PropertyDotString);
+      // remove '[' ']'
+      commit.replace(SourceRange(MsgRange.getBegin(), MsgRange.getBegin()), "");
+      commit.replace(SourceRange(MsgRange.getEnd(), MsgRange.getEnd()), "");
+    }
+    return true;
+  }
+  
+
 class ObjCMigrator : public RecursiveASTVisitor<ObjCMigrator> {
   ObjCMigrateASTConsumer &Consumer;
   ParentMap &PMap;
@@ -235,6 +333,13 @@ public:
       Consumer.Editor->commit(commit);
     }
 
+    if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Property) {
+      edit::Commit commit(*Consumer.Editor);
+      rewriteToPropertyDotSyntax(E, Consumer.PP, *Consumer.NSAPIObj,
+                                 commit, &PMap);
+      Consumer.Editor->commit(commit);
+    }
+
     return true;
   }
 

Added: cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m?rev=219424&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m (added)
+++ cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m Thu Oct  9 13:30:56 2014
@@ -0,0 +1,39 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result
+
+// rdar://18498572
+ at interface NSObject @end
+
+ at interface P : NSObject
+{
+  P* obj;
+  int i1, i2, i3;
+}
+ at property int count;
+ at property (copy) P* PropertyReturnsPObj;
+- (P*) MethodReturnsPObj;
+ at end
+
+P* fun();
+
+ at implementation P
+- (int) Meth : (P*)array {
+  [obj setCount : 100];
+
+  [(P*)0 setCount : [array count]];
+
+  [[obj PropertyReturnsPObj] setCount : [array count]];
+
+  [obj setCount : (i1+i2*i3 - 100)];
+
+  return [obj count] -
+         [(P*)0 count] + [array count] +
+         [fun() count] - 
+         [[obj PropertyReturnsPObj] count] +
+         [self->obj count];
+}
+
+- (P*) MethodReturnsPObj { return 0; }
+ at end

Added: cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m.result?rev=219424&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m.result (added)
+++ cfe/trunk/test/ARCMT/objcmt-property-dot-syntax.m.result Thu Oct  9 13:30:56 2014
@@ -0,0 +1,39 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result
+
+// rdar://18498572
+ at interface NSObject @end
+
+ at interface P : NSObject
+{
+  P* obj;
+  int i1, i2, i3;
+}
+ at property int count;
+ at property (copy) P* PropertyReturnsPObj;
+ at property (nonatomic, readonly, strong) P *MethodReturnsPObj;
+ at end
+
+P* fun();
+
+ at implementation P
+- (int) Meth : (P*)array {
+  obj.count = 100;
+
+  ((P*)0).count = array.count;
+
+  obj.PropertyReturnsPObj.count = array.count;
+
+  obj.count = (i1+i2*i3 - 100);
+
+  return obj.count -
+         ((P*)0).count + array.count +
+         fun().count - 
+         obj.PropertyReturnsPObj.count +
+         self->obj.count;
+}
+
+- (P*) MethodReturnsPObj { return 0; }
+ at end





More information about the cfe-commits mailing list