]>
git.saurik.com Git - cycript.git/blob - ObjectiveC/Replace.cpp
85b7c9d61e73e216198f7da4a5c6ea82be8f0552
1 /* Cycript - Inlining/Optimizing JavaScript Compiler
2 * Copyright (C) 2009 Jay Freeman (saurik)
5 /* Modified BSD License {{{ */
7 * Redistribution and use in source and binary
8 * forms, with or without modification, are permitted
9 * provided that the following conditions are met:
11 * 1. Redistributions of source code must retain the
12 * above copyright notice, this list of conditions
13 * and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the
15 * above copyright notice, this list of conditions
16 * and the following disclaimer in the documentation
17 * and/or other materials provided with the
19 * 3. The name of the author may not be used to endorse
20 * or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
25 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 #include "Replace.hpp"
41 #include "ObjectiveC/Syntax.hpp"
45 CYStatement
*CYCategory::Replace(CYContext
&context
) {
46 CYVariable
*cyc($
V("$cyc")), *cys($
V("$cys"));
48 return $
E($
C1($
F(NULL
, $
P5("$cys", "$cyp", "$cyc", "$cyn", "$cyt"), $$
->*
49 $
E($
CYAssign($
V("$cyp"), $
C1($
V("object_getClass"), cys
)))->*
50 $
E($
CYAssign(cyc
, cys
))->*
51 $
E($
CYAssign($
V("$cym"), $
C1($
V("object_getClass"), cyc
)))->*
52 messages_
->Replace(context
, true)
53 ), name_
->ClassName(context
, true)));
56 CYExpression
*CYClass::Replace_(CYContext
&context
) {
57 CYVariable
*cyc($
V("$cyc")), *cys($
V("$cys"));
59 CYExpression
*name(name_
!= NULL
? name_
->ClassName(context
, false) : $
C1($
V("$cyq"), $
S("CY$")));
61 return $
C1($
F(NULL
, $
P6("$cys", "$cyp", "$cyc", "$cyn", "$cyt", "$cym"), $$
->*
62 $
E($
CYAssign($
V("$cyp"), $
C1($
V("object_getClass"), cys
)))->*
63 $
E($
CYAssign(cyc
, $
C3($
V("objc_allocateClassPair"), cys
, name
, $
D(0))))->*
64 $
E($
CYAssign($
V("$cym"), $
C1($
V("object_getClass"), cyc
)))->*
65 protocols_
->Replace(context
)->*
66 fields_
->Replace(context
)->*
67 messages_
->Replace(context
, false)->*
68 $
E($
C1($
V("objc_registerClassPair"), cyc
))->*
70 ), super_
== NULL
? $
CYNull() : super_
);
73 CYExpression
*CYClassExpression::Replace(CYContext
&context
) {
74 return Replace_(context
);
77 CYStatement
*CYClassStatement::Replace(CYContext
&context
) {
78 return $
E(Replace_(context
));
81 CYStatement
*CYField::Replace(CYContext
&context
) const {
85 CYStatement
*CYImport::Replace(CYContext
&context
) {
89 CYStatement
*CYMessage::Replace(CYContext
&context
, bool replace
) const { $
T(NULL
)
90 CYVariable
*cyn($
V("$cyn"));
91 CYVariable
*cyt($
V("$cyt"));
92 CYVariable
*self($
V("self"));
93 CYVariable
*_class($
V(instance_
? "$cys" : "$cyp"));
95 return $
CYBlock($$
->*
96 next_
->Replace(context
, replace
)->*
97 $
E($
CYAssign(cyn
, parameters_
->Selector(context
)))->*
98 $
E($
CYAssign(cyt
, $
C1($
M(cyn
, $
S("type")), _class
)))->*
99 $
E($
C4($
V(replace
? "class_replaceMethod" : "class_addMethod"),
100 $
V(instance_
? "$cyc" : "$cym"),
102 $
N2($
V("Functor"), $
F(NULL
, $
P2("self", "_cmd", parameters_
->Parameters(context
)), $$
->*
103 $
CYVar($
L1($
L($
I("$cyr"), $
N2($
V("Super"), self
, _class
))))->*
104 $
CYReturn($
C1($
M($
F(NULL
, NULL
, code_
), $
S("call")), self
))
111 CYFunctionParameter
*CYMessageParameter::Parameters(CYContext
&context
) const { $
T(NULL
)
112 CYFunctionParameter
*next(next_
->Parameters(context
));
113 return name_
== NULL
? next
: $
CYFunctionParameter(name_
, next
);
116 CYSelector
*CYMessageParameter::Selector(CYContext
&context
) const {
117 return $
CYSelector(SelectorPart(context
));
120 CYSelectorPart
*CYMessageParameter::SelectorPart(CYContext
&context
) const { $
T(NULL
)
121 CYSelectorPart
*next(next_
->SelectorPart(context
));
122 return tag_
== NULL
? next
: $
CYSelectorPart(tag_
, name_
!= NULL
, next
);
125 CYStatement
*CYProtocol::Replace(CYContext
&context
) const { $
T(NULL
)
126 return $
CYBlock($$
->*
127 next_
->Replace(context
)->*
128 $
E($
C2($
V("class_addProtocol"),
134 CYExpression
*CYSelector::Replace(CYContext
&context
) {
135 return $
N1($
V("Selector"), name_
->Replace(context
));
138 CYString
*CYSelectorPart::Replace(CYContext
&context
) {
139 std::ostringstream str
;
140 for (const CYSelectorPart
*part(this); part
!= NULL
; part
= part
->next_
) {
141 if (part
->name_
!= NULL
)
142 str
<< part
->name_
->Word();
146 return $
S(apr_pstrdup($pool
, str
.str().c_str()));
149 CYExpression
*CYSendDirect::Replace(CYContext
&context
) {
150 std::ostringstream name
;
151 CYArgument
**argument(&arguments_
);
152 CYSelectorPart
*selector(NULL
), *current(NULL
);
154 while (*argument
!= NULL
) {
155 if ((*argument
)->name_
!= NULL
) {
156 CYSelectorPart
*part($
CYSelectorPart((*argument
)->name_
, (*argument
)->value_
!= NULL
));
157 if (selector
== NULL
)
160 current
->SetNext(part
);
162 (*argument
)->name_
= NULL
;
165 if ((*argument
)->value_
== NULL
)
166 *argument
= (*argument
)->next_
;
168 argument
= &(*argument
)->next_
;
171 return $
C2($
V("objc_msgSend"), self_
, ($
CYSelector(selector
))->Replace(context
), arguments_
);
174 CYExpression
*CYSendSuper::Replace(CYContext
&context
) {
175 return $
CYSendDirect($
V("cyr"), arguments_
);