]>
git.saurik.com Git - cycript.git/blob - ObjectiveC/Replace.cpp
1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2013 Jay Freeman (saurik)
5 /* GNU General Public License, Version 3 {{{ */
7 * Cycript is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation, either version 3 of the License,
10 * or (at your option) any later version.
12 * Cycript is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Cycript. If not, see <http://www.gnu.org/licenses/>.
22 #include "Replace.hpp"
23 #include "ObjectiveC/Syntax.hpp"
27 static CYExpression
*MessageType(CYContext
&context
, CYExpression
*type
, CYMessageParameter
*next
, CYExpression
*extra
= NULL
) {
31 CYExpression
*left($
C0($
M(type
, $
S("toString"))));
33 left
= $
CYAdd(left
, extra
);
35 if (next
== NULL
|| next
->name_
== NULL
)
38 CYExpression
*right(next
->TypeSignature(context
));
42 return $
CYAdd(left
, right
);
45 CYStatement
*CYCategory::Replace(CYContext
&context
) {
46 CYVariable
*cyc($
V("$cyc")), *cys($
V("$cys"));
48 return $
E($
C1($
F(NULL
, $
P6($
L("$cys"), $
L("$cyp"), $
L("$cyc"), $
L("$cyn"), $
L("$cyt"), $
L("$cym")), $$
->*
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($
L("$cys"), $
L("$cyp"), $
L("$cyc"), $
L("$cyn"), $
L("$cyt"), $
L("$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 CYExpression
*CYTypeArrayOf::Replace(CYContext
&context
) {
82 return $
CYCall($
CYDirectMember(next_
->Replace(context
), $
CYString("arrayOf")), $
CYArgument(size_
));
85 CYExpression
*CYTypeConstant::Replace(CYContext
&context
) {
86 return $
CYCall($
CYDirectMember(next_
->Replace(context
), $
CYString("constant")));
89 CYExpression
*CYTypePointerTo::Replace(CYContext
&context
) {
90 return $
CYCall($
CYDirectMember(next_
->Replace(context
), $
CYString("pointerTo")));
93 CYExpression
*CYTypeVariable::Replace(CYContext
&context
) {
97 CYExpression
*CYEncodedType::Replace(CYContext
&context
) {
98 return type_
->Replace(context
);
101 CYStatement
*CYField::Replace(CYContext
&context
) const { $
T(NULL
)
102 CYVariable
*cyn($
V("$cyn"));
103 CYVariable
*cyt($
V("$cyt"));
105 CYExpression
*type($
C0($
M(type_
, $
S("toString"))));
107 return $
CYBlock($$
->*
108 next_
->Replace(context
)->*
109 $
E($
CYAssign(cyt
, type
))->*
110 $
E($
CYAssign(cyn
, $
N1($
V("Type"), cyt
)))->*
111 $
E($
C5($
V("class_addIvar"), $
V("$cyc"), $
S(name_
->Word()), $
M(cyn
, $
S("size")), $
M(cyn
, $
S("alignment")), cyt
))
115 CYStatement
*CYImport::Replace(CYContext
&context
) {
119 CYStatement
*CYMessage::Replace(CYContext
&context
, bool replace
) const { $
T(NULL
)
120 CYVariable
*cyn($
V("$cyn"));
121 CYVariable
*cyt($
V("$cyt"));
122 CYVariable
*self($
V("self"));
123 CYVariable
*_class($
V(instance_
? "$cys" : "$cyp"));
125 CYExpression
*type(TypeSignature(context
) ?: $
C1($
M(cyn
, $
S("type")), _class
));
127 return $
CYBlock($$
->*
128 next_
->Replace(context
, replace
)->*
129 $
E($
CYAssign(cyn
, parameters_
->Selector(context
)))->*
130 $
E($
CYAssign(cyt
, type
))->*
131 $
E($
C4($
V(replace
? "class_replaceMethod" : "class_addMethod"),
132 $
V(instance_
? "$cyc" : "$cym"),
134 $
N2($
V("Functor"), $
F(NULL
, $
P2($
L("self"), $
L("_cmd"), parameters_
->Parameters(context
)), $$
->*
135 $
CYVar($
L1($
L("$cyr", $
N2($
V("Super"), self
, _class
))))->*
136 $
CYReturn($
C1($
M($
F(NULL
, NULL
, code_
), $
S("call")), self
))
143 CYExpression
*CYMessage::TypeSignature(CYContext
&context
) const {
144 return MessageType(context
, type_
, parameters_
, $
S("@:"));
147 CYFunctionParameter
*CYMessageParameter::Parameters(CYContext
&context
) const { $
T(NULL
)
148 CYFunctionParameter
*next(next_
->Parameters(context
));
149 return name_
== NULL
? next
: $
CYFunctionParameter($
CYDeclaration(name_
), next
);
152 CYSelector
*CYMessageParameter::Selector(CYContext
&context
) const {
153 return $
CYSelector(SelectorPart(context
));
156 CYSelectorPart
*CYMessageParameter::SelectorPart(CYContext
&context
) const { $
T(NULL
)
157 CYSelectorPart
*next(next_
->SelectorPart(context
));
158 return tag_
== NULL
? next
: $
CYSelectorPart(tag_
, name_
!= NULL
, next
);
161 CYExpression
*CYMessageParameter::TypeSignature(CYContext
&context
) const {
162 return MessageType(context
, type_
, next_
);
165 CYExpression
*CYBox::Replace(CYContext
&context
) {
166 return $
C1($
M($
V("Instance"), $
S("box")), value_
);
169 CYExpression
*CYObjCBlock::Replace(CYContext
&context
) {
170 return $
N2($
V("Functor"), $
CYFunctionExpression(NULL
, $
CYFunctionParameter($
CYDeclaration($
CYIdentifier("$cyt")), parameters_
->Parameters(context
)), statements_
), parameters_
->TypeSignature(context
, $
CYAdd(type_
->Replace(context
), $
CYString("@"))));
173 CYStatement
*CYProtocol::Replace(CYContext
&context
) const { $
T(NULL
)
174 return $
CYBlock($$
->*
175 next_
->Replace(context
)->*
176 $
E($
C2($
V("class_addProtocol"),
182 CYExpression
*CYSelector::Replace(CYContext
&context
) {
183 return $
C1($
V("sel_registerName"), name_
->Replace(context
));
186 CYString
*CYSelectorPart::Replace(CYContext
&context
) {
187 std::ostringstream str
;
188 CYForEach (part
, this) {
189 if (part
->name_
!= NULL
)
190 str
<< part
->name_
->Word();
194 return $
S($pool
.strdup(str
.str().c_str()));
197 CYExpression
*CYSendDirect::Replace(CYContext
&context
) {
198 std::ostringstream name
;
199 CYArgument
**argument(&arguments_
);
200 CYSelectorPart
*selector(NULL
), *current(NULL
);
202 while (*argument
!= NULL
) {
203 if ((*argument
)->name_
!= NULL
) {
204 CYSelectorPart
*part($
CYSelectorPart((*argument
)->name_
, (*argument
)->value_
!= NULL
));
205 if (selector
== NULL
)
208 current
->SetNext(part
);
210 (*argument
)->name_
= NULL
;
213 if ((*argument
)->value_
== NULL
)
214 *argument
= (*argument
)->next_
;
216 argument
= &(*argument
)->next_
;
219 return $
C2($
V("objc_msgSend"), self_
, ($
CYSelector(selector
))->Replace(context
), arguments_
);
222 CYExpression
*CYSendSuper::Replace(CYContext
&context
) {
223 return $
CYSendDirect($
V("$cyr"), arguments_
);
226 CYFunctionParameter
*CYTypedParameter::Parameters(CYContext
&context
) { $
T(NULL
)
227 return $
CYFunctionParameter($
CYDeclaration(typed_
->identifier_
?: context
.Unique()), next_
->Parameters(context
));
230 CYExpression
*CYTypedParameter::TypeSignature(CYContext
&context
, CYExpression
*prefix
) { $
T(prefix
)
231 return next_
->TypeSignature(context
, $
CYAdd(prefix
, typed_
->type_
->Replace(context
)));