KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > es > parser > CallExpr


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.es.parser;
30
31 import com.caucho.es.ESException;
32 import com.caucho.es.ESId;
33 import com.caucho.es.wrapper.ESMethodDescriptor;
34
35 import java.io.IOException JavaDoc;
36 import java.util.ArrayList JavaDoc;
37
38 /**
39  * Represents a method call. Both Java calls and JavaScript calls are
40  * handled here.
41  */

42 class CallExpr extends Expr {
43   protected Expr term;
44   private Expr field;
45   private boolean isNew;
46   protected boolean isTop;
47   protected ArrayList JavaDoc args = new ArrayList JavaDoc();
48
49   protected TypeExpr typeExpr;
50   protected boolean isCalculated;
51   
52   // The Java method if we can determine direct Java call.
53
protected ESMethodDescriptor method;
54
55   CallExpr(Block block, Expr term, Expr field, boolean isNew)
56     throws ESException
57   {
58     super(block);
59     
60     this.term = term;
61     this.field = field;
62     this.isNew = isNew;
63
64     if (term != null)
65       term.setUsed();
66     if (field != null)
67       field.setUsed();
68
69     if (term == null || ! (term.getTypeExpr() instanceof JavaTypeExpr))
70       block.function.setCall();
71   }
72
73   void exprStatement(Function fun) throws ESException
74   {
75     isTop = true;
76     noValue = true;
77
78     fun.addExpr(this);
79   }
80
81   /**
82    * Returns the javascript type for the expression
83    *
84    * @return a javascript type.
85    */

86   int getType()
87   {
88     calculateType();
89     
90     return type;
91   }
92
93   /**
94    * Returns the type expression of the call.
95    *
96    * @return a type expression.
97    */

98   Expr getTypeExpr()
99   {
100     calculateType();
101
102     return typeExpr;
103   }
104
105   /**
106    * Calculate the return type of the expression.
107    */

108   private void calculateType()
109   {
110     boolean isStatic = false;
111
112     if (isCalculated)
113       return;
114     
115     isCalculated = true;
116
117     Class JavaDoc javaClass = term.getJavaClass();
118     if (term instanceof JavaClassExpr) {
119       isStatic = true;
120       javaClass = ((JavaClassExpr) term).getJavaClass();
121     }
122
123     if (javaClass == null || field == null ||
124         ! (field instanceof LiteralExpr) ||
125         term.getType() != TYPE_JAVA && ! isStatic) {
126       return;
127     }
128     
129     LiteralExpr lit = (LiteralExpr) field;
130     String JavaDoc name = lit.getLiteral().toString();
131
132     method = JavaMethod.bestMethod(javaClass, name, isStatic, args);
133
134     // exception if can't find method
135
if (method != null) {
136       Class JavaDoc returnType = method.getReturnType();
137
138       if (returnType.equals(void.class))
139         type = TYPE_VOID;
140       else if (returnType.equals(int.class))
141         type = TYPE_INTEGER;
142       else if (returnType.equals(double.class))
143         type = TYPE_NUMBER;
144       else if (returnType.equals(boolean.class))
145         type = TYPE_BOOLEAN;
146       else {
147         type = TYPE_JAVA;
148         this.javaType = returnType;
149       }
150       
151       typeExpr = new JavaTypeExpr(block, returnType);
152     }
153   }
154
155   void printBooleanImpl() throws IOException JavaDoc
156   {
157     printJavaImpl();
158   }
159
160   void printInt32Impl() throws IOException JavaDoc
161   {
162     printJavaImpl();
163   }
164
165   void printNumImpl() throws IOException JavaDoc
166   {
167     printJavaImpl();
168   }
169
170   /**
171    * Generates code for the call, producing a JavaScript result.
172    */

173   void printImpl() throws IOException JavaDoc
174   {
175     if (term instanceof IdExpr && field == null &&
176         ! ((IdExpr) term).isJavaLocal()) {
177       ESId id = ((IdExpr) term).getId();
178
179       field = new LiteralExpr(block, id);
180       term = null;
181     }
182
183     if (term != null) {
184       if (isNew)
185         cl.print("_call.doNew(");
186       else
187         cl.print("_call.call(");
188
189       term.print();
190
191       if (field != null) {
192         cl.print(", ");
193         field.printStr();
194       }
195     }
196     else if (function.isGlobalScope() && withDepth == 0) {
197       if (isNew)
198         cl.print("_call.doNew(_env.global, ");
199       else
200         cl.print("_call.call(_env.global, ");
201
202       field.printStr();
203     }
204     else {
205       if (isNew)
206         cl.print("_call.newScope(");
207       else
208         cl.print("_call.callScope(");
209       
210       field.printStr();
211     }
212
213     int argCount = function.cl.getCallDepth();
214     
215     cl.print(", " + argCount);
216     
217     for (int i = 0; i < args.size() && i < 3; i++) {
218       Expr expr = (Expr) args.get(i);
219       cl.print(", ");
220       function.cl.pushCall();
221       expr.print();
222     }
223     if (args.size() >= 3)
224       cl.print(", 3");
225     for (int i = 3; i < args.size(); i++) {
226       Expr expr = (Expr) args.get(i);
227       cl.print("+ _call.arg(" + (i + argCount) + ", ");
228       function.cl.pushCall();
229       expr.print();
230       cl.print(")");
231     }
232     function.cl.popCall(args.size());
233     cl.print(")");
234     if (isTop)
235       cl.println(";");
236   }
237
238   void printStringImpl()
239     throws IOException JavaDoc
240   {
241     if (String JavaDoc.class.equals(getJavaClass()))
242       printJavaImpl();
243     else {
244       cl.print("String.valueOf(");
245       printJavaImpl();
246       cl.print(")");
247     }
248   }
249
250   /**
251    * Generates code for the call, producing a Java result.
252    */

253   void printJavaImpl()
254     throws IOException JavaDoc
255   {
256     if (method.isStaticVirtual()) {
257       cl.print(method.getMethodClassName());
258     }
259     else {
260       if (term instanceof JavaClassExpr)
261         cl.print(method.getMethodClassName());
262       else {
263         term.printJava();
264       }
265     }
266     
267     cl.print('.');
268     cl.print(method.getName());
269     cl.print("(");
270
271     boolean isFirst = true;
272     if (method.isStaticVirtual()) {
273       cl.print("(");
274       printJavaClass(method.getDeclaringClass());
275       cl.print(")");
276       isFirst = false;
277       term.printJava();
278     }
279
280     Class JavaDoc []params = null;
281     if (method != null)
282       params = method.getParameterTypes();
283       
284     for (int i = 0; i < args.size(); i++) {
285       Expr expr = (Expr) args.get(i);
286       
287       if (! isFirst)
288         cl.print(", ");
289       isFirst = false;
290
291       if (params == null)
292         expr.printJava();
293       else if (params[i].equals(String JavaDoc.class)) {
294         expr.printJavaString();
295       }
296       else if (! params[i].isPrimitive()) {
297         cl.print("(");
298         printJavaClass(params[i]);
299         cl.print(")");
300
301         expr.printJava();
302       }
303       else if (params[i].equals(int.class))
304         expr.printInt32();
305       else if (params[i].equals(long.class))
306         expr.printInt64();
307       else if (params[i].equals(boolean.class))
308         expr.printBoolean();
309       else if (params[i].equals(double.class))
310         expr.printNum();
311       else
312         expr.printJava();
313     }
314     cl.print(")");
315     if (isTop)
316       cl.println(";");
317   }
318   
319   /**
320    * adds a new call parameter
321    */

322   void addCallParam(Expr param)
323   {
324     param.setUsed();
325     args.add(param);
326   }
327 }
328
Popular Tags