]> git.saurik.com Git - cycript.git/blobdiff - ObjectiveC/Replace.mm
Implemented initial support for Ruby Blocks.
[cycript.git] / ObjectiveC / Replace.mm
index e25ff8625ac4eb9090c5d439ae51dafb4027b41d..fbd99343065c170b4786c271cf1d481e4d5d5bd4 100644 (file)
@@ -40,7 +40,7 @@
 #include "Replace.hpp"
 #include "ObjectiveC/Syntax.hpp"
 
-#include <objc/runtime.h>
+#include <Foundation/Foundation.h>
 #include <sstream>
 
 CYStatement *CYCategory::Replace(CYContext &context) {
@@ -49,6 +49,7 @@ CYStatement *CYCategory::Replace(CYContext &context) {
     return $E($C1($F(NULL, $P5("$cys", "$cyp", "$cyc", "$cyn", "$cyt"), $$->*
         $E($ CYAssign($V("$cyp"), $C1($V("object_getClass"), cys)))->*
         $E($ CYAssign(cyc, cys))->*
+        $E($ CYAssign($V("$cym"), $C1($V("object_getClass"), cyc)))->*
         messages_->Replace(context, true)
     ), name_->ClassName(context, true)));
 }
@@ -62,6 +63,7 @@ CYExpression *CYClass::Replace_(CYContext &context) {
         $E($ CYAssign($V("$cyp"), $C1($V("object_getClass"), cys)))->*
         $E($ CYAssign(cyc, $C3($V("objc_allocateClassPair"), cys, name, $D(0))))->*
         $E($ CYAssign($V("$cym"), $C1($V("object_getClass"), cyc)))->*
+        protocols_->Replace(context)->*
         fields_->Replace(context)->*
         messages_->Replace(context, false)->*
         $E($C1($V("objc_registerClassPair"), cyc))->*
@@ -117,6 +119,15 @@ CYSelectorPart *CYMessageParameter::SelectorPart(CYContext &context) const { $T(
     return tag_ == NULL ? next : $ CYSelectorPart(tag_, name_ != NULL, next);
 }
 
+CYStatement *CYProtocol::Replace(CYContext &context) const { $T(NULL)
+    return $ CYBlock($$->*
+        next_->Replace(context)->*
+        $E($C2($V("class_addProtocol"),
+            $V("$cyc"), name_
+        ))
+    );
+}
+
 CYExpression *CYSelector::Replace(CYContext &context) {
     return $N1($V("Selector"), name_->Replace(context));
 }
@@ -125,7 +136,7 @@ CYString *CYSelectorPart::Replace(CYContext &context) {
     std::ostringstream str;
     for (const CYSelectorPart *part(this); part != NULL; part = part->next_) {
         if (part->name_ != NULL)
-            str << part->name_->Value();
+            str << part->name_->Word();
         if (part->value_)
             str << ':';
     }
@@ -135,13 +146,17 @@ CYString *CYSelectorPart::Replace(CYContext &context) {
 CYExpression *CYSendDirect::Replace(CYContext &context) {
     std::ostringstream name;
     CYArgument **argument(&arguments_);
+    CYSelectorPart *selector(NULL), *current(NULL);
 
     while (*argument != NULL) {
         if ((*argument)->name_ != NULL) {
-            name << *(*argument)->name_;
+            CYSelectorPart *part($ CYSelectorPart((*argument)->name_, (*argument)->value_ != NULL));
+            if (selector == NULL)
+                selector = part;
+            if (current != NULL)
+                current->SetNext(part);
+            current = part;
             (*argument)->name_ = NULL;
-            if ((*argument)->value_ != NULL)
-                name << ':';
         }
 
         if ((*argument)->value_ == NULL)
@@ -150,10 +165,7 @@ CYExpression *CYSendDirect::Replace(CYContext &context) {
             argument = &(*argument)->next_;
     }
 
-    SEL sel(sel_registerName(name.str().c_str()));
-    double address(static_cast<double>(reinterpret_cast<uintptr_t>(sel)));
-
-    return $C2($V("objc_msgSend"), self_, $D(address), arguments_);
+    return $C2($V("objc_msgSend"), self_, ($ CYSelector(selector))->Replace(context), arguments_);
 }
 
 CYExpression *CYSendSuper::Replace(CYContext &context) {