]> git.saurik.com Git - cycript.git/commitdiff
Allow type signatures to be specified on messages.
authorJay Freeman (saurik) <saurik@saurik.com>
Fri, 8 Jun 2012 09:13:15 +0000 (02:13 -0700)
committerJay Freeman (saurik) <saurik@saurik.com>
Fri, 8 Jun 2012 09:13:15 +0000 (02:13 -0700)
Cycript.yy.in
ObjectiveC/Replace.cpp
ObjectiveC/Syntax.hpp

index 8efb228815993ef3a6b98d02be95a39219b8252e..6a4f179eedf77604a11979f0069476ddf181c790 100644 (file)
@@ -1320,7 +1320,7 @@ MessageScope
 
 TypeOpt
     : "(" Expression ")" { $$ = $2; }
-    | "(" LexSetRegExp "void" ")" { $$ = NULL; }
+    | "(" LexSetRegExp "void" ")" { $$ = CYNew CYString("v"); }
     | { $$ = NULL; }
     ;
 
index f500bd8cda4381f73e4ca6c5e4b10de0cb9ab93e..fa8b003f23bc26eace897fe0ad3661269740f4bd 100644 (file)
 
 #include <sstream>
 
+static CYExpression *MessageType(CYContext &context, CYExpression *type, CYMessageParameter *next, CYExpression *extra = NULL) {
+    if (type == NULL)
+        return NULL;
+
+    CYExpression *left($C0($M(type, $S("toString"))));
+    if (extra != NULL)
+        left = $ CYAdd(left, extra);
+
+    if (next == NULL)
+        return left;
+
+    CYExpression *right(next->TypeSignature(context));
+    if (right == NULL)
+        return NULL;
+
+    return $ CYAdd(left, right);
+}
+
 CYStatement *CYCategory::Replace(CYContext &context) {
     CYVariable *cyc($V("$cyc")), *cys($V("$cys"));
 
@@ -74,10 +92,12 @@ CYStatement *CYMessage::Replace(CYContext &context, bool replace) const { $T(NUL
     CYVariable *self($V("self"));
     CYVariable *_class($V(instance_ ? "$cys" : "$cyp"));
 
+    CYExpression *type(TypeSignature(context) ?: $C1($M(cyn, $S("type")), _class));
+
     return $ CYBlock($$->*
         next_->Replace(context, replace)->*
         $E($ CYAssign(cyn, parameters_->Selector(context)))->*
-        $E($ CYAssign(cyt, $C1($M(cyn, $S("type")), _class)))->*
+        $E($ CYAssign(cyt, type))->*
         $E($C4($V(replace ? "class_replaceMethod" : "class_addMethod"),
             $V(instance_ ? "$cyc" : "$cym"),
             cyn,
@@ -90,6 +110,10 @@ CYStatement *CYMessage::Replace(CYContext &context, bool replace) const { $T(NUL
     );
 }
 
+CYExpression *CYMessage::TypeSignature(CYContext &context) const {
+    return MessageType(context, type_, parameters_, $S("@:"));
+}
+
 CYFunctionParameter *CYMessageParameter::Parameters(CYContext &context) const { $T(NULL)
     CYFunctionParameter *next(next_->Parameters(context));
     return name_ == NULL ? next : $ CYFunctionParameter($ CYDeclaration(name_), next);
@@ -104,6 +128,10 @@ CYSelectorPart *CYMessageParameter::SelectorPart(CYContext &context) const { $T(
     return tag_ == NULL ? next : $ CYSelectorPart(tag_, name_ != NULL, next);
 }
 
+CYExpression *CYMessageParameter::TypeSignature(CYContext &context) const {
+    return MessageType(context, type_, next_);
+}
+
 CYExpression *CYBox::Replace(CYContext &context) {
     return $C1($M($V("Instance"), $S("box")), value_);
 }
index d6787b44b9393181dea65b98e78e7242aa7daea6..a9a9798b649fd9df413cdf554d4f122dc32bbe5f 100644 (file)
@@ -98,6 +98,7 @@ struct CYMessageParameter :
     CYFunctionParameter *Parameters(CYContext &context) const;
     CYSelector *Selector(CYContext &context) const;
     CYSelectorPart *SelectorPart(CYContext &context) const;
+    CYExpression *TypeSignature(CYContext &context) const;
 };
 
 struct CYMessage :
@@ -118,6 +119,8 @@ struct CYMessage :
 
     CYStatement *Replace(CYContext &context, bool replace) const;
     void Output(CYOutput &out, bool replace) const;
+
+    CYExpression *TypeSignature(CYContext &context) const;
 };
 
 struct CYProtocol :