001: /*
002: * $Id: JavacClassGenerator.java 2223 2005-05-27 10:13:49Z russel $
003: *
004: * Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005: *
006: * Redistribution and use of this software and associated documentation
007: * ("Software"), with or without modification, are permitted provided that the
008: * following conditions are met: 1. Redistributions of source code must retain
009: * copyright statements and notices. Redistributions must also contain a copy
010: * of this document. 2. Redistributions in binary form must reproduce the above
011: * copyright notice, this list of conditions and the following disclaimer in
012: * the documentation and/or other materials provided with the distribution. 3.
013: * The name "groovy" must not be used to endorse or promote products derived
014: * from this Software without prior written permission of The Codehaus. For
015: * written permission, please contact info@codehaus.org. 4. Products derived
016: * from this Software may not be called "groovy" nor may "groovy" appear in
017: * their names without prior written permission of The Codehaus. "groovy" is a
018: * registered trademark of The Codehaus. 5. Due credit should be given to The
019: * Codehaus - http://groovy.codehaus.org/
020: *
021: * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY
022: * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
023: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
024: * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR
025: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
026: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
027: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
028: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
029: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
030: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
031: * DAMAGE.
032: *
033: */
034: package org.codehaus.groovy.classgen;
035:
036: import groovy.lang.Closure;
037: import groovy.lang.GString;
038: import groovy.lang.GroovyRuntimeException;
039: import groovy.lang.MissingClassException;
040: import groovy.lang.Reference;
041:
042: import java.math.BigDecimal;
043: import java.math.BigInteger;
044: import java.security.AccessControlException;
045: import java.util.ArrayList;
046: import java.util.HashMap;
047: import java.util.HashSet;
048: import java.util.Iterator;
049: import java.util.LinkedList;
050: import java.util.Map;
051: import java.util.Set;
052: import java.util.logging.Logger;
053:
054: import org.codehaus.groovy.ast.ASTNode;
055: import org.codehaus.groovy.ast.ClassNode; //import org.codehaus.groovy.ast.CodeVisitorSupport;
056: import org.codehaus.groovy.ast.CompileUnit;
057: import org.codehaus.groovy.ast.ConstructorNode;
058: import org.codehaus.groovy.ast.FieldNode; //import org.codehaus.groovy.ast.GroovyClassVisitor;
059: //import org.codehaus.groovy.ast.GroovyCodeVisitor;
060: import org.codehaus.groovy.ast.InnerClassNode;
061: import org.codehaus.groovy.ast.MethodNode;
062: import org.codehaus.groovy.ast.Parameter;
063: import org.codehaus.groovy.ast.PropertyNode;
064: import org.codehaus.groovy.ast.Type;
065: import org.codehaus.groovy.ast.VariableScope;
066: import org.codehaus.groovy.ast.expr.ArgumentListExpression;
067: import org.codehaus.groovy.ast.expr.ArrayExpression;
068: import org.codehaus.groovy.ast.expr.BinaryExpression;
069: import org.codehaus.groovy.ast.expr.BooleanExpression;
070: import org.codehaus.groovy.ast.expr.CastExpression;
071: import org.codehaus.groovy.ast.expr.ClassExpression;
072: import org.codehaus.groovy.ast.expr.ClosureExpression;
073: import org.codehaus.groovy.ast.expr.ConstantExpression;
074: import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
075: import org.codehaus.groovy.ast.expr.Expression;
076: import org.codehaus.groovy.ast.expr.ExpressionTransformer;
077: import org.codehaus.groovy.ast.expr.FieldExpression;
078: import org.codehaus.groovy.ast.expr.GStringExpression;
079: import org.codehaus.groovy.ast.expr.ListExpression;
080: import org.codehaus.groovy.ast.expr.MapEntryExpression;
081: import org.codehaus.groovy.ast.expr.MapExpression;
082: import org.codehaus.groovy.ast.expr.MethodCallExpression;
083: import org.codehaus.groovy.ast.expr.NegationExpression;
084: import org.codehaus.groovy.ast.expr.NotExpression;
085: import org.codehaus.groovy.ast.expr.PostfixExpression;
086: import org.codehaus.groovy.ast.expr.PrefixExpression;
087: import org.codehaus.groovy.ast.expr.PropertyExpression;
088: import org.codehaus.groovy.ast.expr.RangeExpression;
089: import org.codehaus.groovy.ast.expr.RegexExpression;
090: import org.codehaus.groovy.ast.expr.StaticMethodCallExpression;
091: import org.codehaus.groovy.ast.expr.TernaryExpression;
092: import org.codehaus.groovy.ast.expr.TupleExpression;
093: import org.codehaus.groovy.ast.expr.VariableExpression;
094: import org.codehaus.groovy.ast.stmt.AssertStatement;
095: import org.codehaus.groovy.ast.stmt.BlockStatement;
096: import org.codehaus.groovy.ast.stmt.BreakStatement;
097: import org.codehaus.groovy.ast.stmt.CaseStatement;
098: import org.codehaus.groovy.ast.stmt.CatchStatement;
099: import org.codehaus.groovy.ast.stmt.ContinueStatement;
100: import org.codehaus.groovy.ast.stmt.DoWhileStatement;
101: import org.codehaus.groovy.ast.stmt.ExpressionStatement;
102: import org.codehaus.groovy.ast.stmt.ForStatement;
103: import org.codehaus.groovy.ast.stmt.IfStatement;
104: import org.codehaus.groovy.ast.stmt.ReturnStatement;
105: import org.codehaus.groovy.ast.stmt.Statement;
106: import org.codehaus.groovy.ast.stmt.SwitchStatement;
107: import org.codehaus.groovy.ast.stmt.SynchronizedStatement;
108: import org.codehaus.groovy.ast.stmt.ThrowStatement;
109: import org.codehaus.groovy.ast.stmt.TryCatchStatement;
110: import org.codehaus.groovy.ast.stmt.WhileStatement;
111: import org.codehaus.groovy.runtime.InvokerHelper;
112: import org.codehaus.groovy.syntax.Token;
113: import org.codehaus.groovy.syntax.Types;
114: import org.codehaus.groovy.syntax.parser.RuntimeParserException; //import org.objectweb.asm.ClassVisitor;
115: //import org.objectweb.asm.MethodVisitor;
116: //import org.objectweb.asm.Opcodes;
117: import org.objectweb.asm.Label;
118: import com.sun.tools.javac.v8.tree.Tree;
119: import com.sun.tools.javac.v8.tree.TreeMaker;
120: import com.sun.tools.javac.v8.util.Name;
121: import com.sun.tools.javac.v8.util.List;
122: import com.sun.tools.javac.v8.code.Symbol;
123: import com.sun.tools.javac.v8.code.Scope;
124:
125: /**
126: * Generates Java class versions of Groovy classes using Sun's Javac Java AST model
127: *
128: * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
129: * @version $Revision: 2223 $
130: */
131: public abstract class JavacClassGenerator extends ClassGenerator {
132:
133: private Logger log = Logger.getLogger(getClass().getName());
134:
135: private Tree.Factory factory;
136: private Tree.TopLevel topLevel;
137: private Name.Table nameTable = new Name.Table();
138: private Name sourceFileName;
139:
140: public JavacClassGenerator(GeneratorContext context,
141: ClassLoader classLoader, String sourceFile) {
142: super (classLoader);
143: sourceFileName = nameTable.fromString(sourceFile);
144: }
145:
146: // GroovyClassVisitor interface
147: //-------------------------------------------------------------------------
148: //
149: // public void visitClass(ClassNode classNode) {
150: //
151: // //className = nameTable.fromString(classNode.getName());
152: //
153: // Tree pid = null;
154: // List defs = new List();
155: // Symbol.PackageSymbol packageSymbol = null;
156: //
157: // Symbol owner = null; /// new Symbol.ClassSymbol()
158: // Scope namedImportScope = new Scope(owner);
159: // Scope starImportScope = new Scope(owner);
160: //
161: // topLevel = new Tree.TopLevel(pid, defs, sourceFileName, packageSymbol, namedImportScope, starImportScope);
162: // factory = new TreeMaker(topLevel);
163: //
164: //
165: //
166: // try {
167: // syntheticStaticFields.clear();
168: // this.classNode = classNode;
169: // this.outermostClass = null;
170: //
171: // //System.out.println("Generating class: " + classNode.getName());
172: //
173: // // lets check that the classes are all valid
174: // classNode.setSuperClass(checkValidType(classNode.getSuperClass(), classNode, "Must be a valid base class"));
175: // String[] interfaces = classNode.getInterfaces();
176: // for (int i = 0; i < interfaces.length; i++ ) {
177: // interfaces[i] = checkValidType(interfaces[i], classNode, "Must be a valid interface name");
178: // }
179: //
180: //
181: // classNode.visitContents(this);
182: //
183: // createSyntheticStaticFields();
184: //
185: //
186: // factory.ClassDef();
187: //
188: // for (Iterator iter = innerClasses.iterator(); iter.hasNext();) {
189: // ClassNode innerClass = (ClassNode) iter.next();
190: //
191: // /** TODO process innner classes */
192: // }
193: // }
194: // catch (GroovyRuntimeException e) {
195: // e.setModule(classNode.getModule());
196: // throw e;
197: // }
198: // }
199: //
200: // public void visitConstructor(ConstructorNode node) {
201: // this.constructorNode = node;
202: // this.methodNode = null;
203: // this.variableScope = null;
204: //
205: // visitParameters(node, node.getParameters());
206: //
207: // findMutableVariables();
208: // resetVariableStack(node.getParameters());
209: //
210: // Statement code = node.getCode();
211: // if (code != null) {
212: // code.visit(this);
213: // }
214: // factory.MethodDef();
215: // }
216: //
217: // public void visitMethod(MethodNode node) {
218: // this.constructorNode = null;
219: // this.methodNode = node;
220: // this.variableScope = null;
221: //
222: // visitParameters(node, node.getParameters());
223: //
224: // node.setReturnType(checkValidType(node.getReturnType(), node, "Must be a valid return type"));
225: //
226: // findMutableVariables();
227: // resetVariableStack(node.getParameters());
228: //
229: // node.getCode().visit(this);
230: // factory.MethodDef();
231: // }
232: //
233: // protected void visitParameters(ASTNode node, Parameter[] parameters) {
234: // for (int i = 0, size = parameters.length; i < size; i++ ) {
235: // visitParameter(node, parameters[i]);
236: // }
237: // }
238: //
239: // protected void visitParameter(ASTNode node, Parameter parameter) {
240: // if (! parameter.isDynamicType()) {
241: // parameter.setType(checkValidType(parameter.getType(), node, "Must be a valid parameter class"));
242: // }
243: // }
244: //
245: // public void visitField(FieldNode fieldNode) {
246: // onLineNumber(fieldNode);
247: //
248: // // lets check that the classes are all valid
249: // fieldNode.setType(checkValidType(fieldNode.getType(), fieldNode, "Must be a valid field class for field: " + fieldNode.getName()));
250: //
251: // //System.out.println("Visiting field: " + fieldNode.getName() + " on
252: // // class: " + classNode.getName());
253: //
254: // Object fieldValue = null;
255: // Expression expression = fieldNode.getInitialValueExpression();
256: // if (expression instanceof ConstantExpression) {
257: // ConstantExpression constantExp = (ConstantExpression) expression;
258: // Object value = constantExp.getValue();
259: // if (isPrimitiveFieldType(fieldNode.getType())) {
260: // // lets convert any primitive types
261: // Class type = null;
262: // try {
263: // type = loadClass(fieldNode.getType());
264: // fieldValue = InvokerHelper.asType(value, type);
265: // }
266: // catch (Exception e) {
267: // log.warning("Caught unexpected: " + e);
268: // }
269: // }
270: // }
271: //
272: // }
273: //
274: // /**
275: // * Creates a getter, setter and field
276: // */
277: // public void visitProperty(PropertyNode statement) {
278: // onLineNumber(statement);
279: // //this.propertyNode = statement;
280: // this.methodNode = null;
281: // }
282: //
283: // // GroovyCodeVisitor interface
284: // //-------------------------------------------------------------------------
285: //
286: // // Statements
287: // //-------------------------------------------------------------------------
288: //
289: // public void visitForLoop(ForStatement loop) {
290: // onLineNumber(loop);
291: //
292: //
293: // factory.ForLoop()
294: //
295: // //
296: // // Declare the loop counter.
297: //
298: // Type variableType = checkValidType(loop.getVariableType(), loop, "for loop variable");
299: // Variable variable = defineVariable(loop.getVariable(), variableType, true);
300: //
301: // if( isInScriptBody() ) {
302: // variable.setProperty( true );
303: // }
304: //
305: //
306: // //
307: // // Then initialize the iterator and generate the loop control
308: //
309: // loop.getCollectionExpression().visit(this);
310: //
311: // asIteratorMethod.call(cv);
312: //
313: // final int iteratorIdx = defineVariable(createVariableName("iterator"), "java.util.Iterator", false).getIndex();
314: // cv.visitVarInsn(ASTORE, iteratorIdx);
315: //
316: // pushBlockScope();
317: //
318: // Label continueLabel = scope.getContinueLabel();
319: // cv.visitJumpInsn(GOTO, continueLabel);
320: // Label label2 = new Label();
321: // cv.visitLabel(label2);
322: //
323: // BytecodeExpression expression = new BytecodeExpression() {
324: // public void visit(GroovyCodeVisitor visitor) {
325: // cv.visitVarInsn(ALOAD, iteratorIdx);
326: //
327: // iteratorNextMethod.call(cv);
328: // }
329: // };
330: //
331: // evaluateEqual( BinaryExpression.newAssignmentExpression(loop.getVariable(), expression) );
332: //
333: //
334: // //
335: // // Generate the loop body
336: //
337: // loop.getLoopBlock().visit(this);
338: //
339: //
340: // //
341: // // Generate the loop tail
342: //
343: // cv.visitLabel(continueLabel);
344: // cv.visitVarInsn(ALOAD, iteratorIdx);
345: //
346: // iteratorHasNextMethod.call(cv);
347: //
348: // cv.visitJumpInsn(IFNE, label2);
349: //
350: // cv.visitLabel(scope.getBreakLabel());
351: // popScope();
352: // }
353: //
354: // public void visitWhileLoop(WhileStatement loop) {
355: // onLineNumber(loop);
356: //
357: // /*
358: // * // quick hack if (!methodNode.isStatic()) { cv.visitVarInsn(ALOAD,
359: // * 0); }
360: // */
361: //
362: // pushBlockScope();
363: //
364: // Label continueLabel = scope.getContinueLabel();
365: //
366: // cv.visitJumpInsn(GOTO, continueLabel);
367: // Label l1 = new Label();
368: // cv.visitLabel(l1);
369: //
370: // loop.getLoopBlock().visit(this);
371: //
372: // cv.visitLabel(continueLabel);
373: // //cv.visitVarInsn(ALOAD, 0);
374: //
375: // loop.getBooleanExpression().visit(this);
376: //
377: // cv.visitJumpInsn(IFNE, l1);
378: //
379: // cv.visitLabel(scope.getBreakLabel());
380: // popScope();
381: // }
382: //
383: // public void visitDoWhileLoop(DoWhileStatement loop) {
384: // onLineNumber(loop);
385: //
386: // pushBlockScope();
387: //
388: // Label breakLabel = scope.getBreakLabel();
389: //
390: // Label continueLabel = scope.getContinueLabel();
391: // cv.visitLabel(continueLabel);
392: // Label l1 = new Label();
393: //
394: // loop.getLoopBlock().visit(this);
395: //
396: // cv.visitLabel(l1);
397: //
398: // loop.getBooleanExpression().visit(this);
399: //
400: // cv.visitJumpInsn(IFNE, continueLabel);
401: //
402: // cv.visitLabel(breakLabel);
403: // popScope();
404: // }
405: //
406: // public void visitIfElse(IfStatement ifElse) {
407: // onLineNumber(ifElse);
408: //
409: // ifElse.getBooleanExpression().visit(this);
410: //
411: // Label l0 = new Label();
412: // cv.visitJumpInsn(IFEQ, l0);
413: // ifElse.getIfBlock().visit(this);
414: //
415: // Label l1 = new Label();
416: // cv.visitJumpInsn(GOTO, l1);
417: // cv.visitLabel(l0);
418: //
419: // ifElse.getElseBlock().visit(this);
420: // cv.visitLabel(l1);
421: // }
422: //
423: // public void visitTernaryExpression(TernaryExpression expression) {
424: // onLineNumber(expression);
425: //
426: // expression.getBooleanExpression().visit(this);
427: //
428: // Label l0 = new Label();
429: // cv.visitJumpInsn(IFEQ, l0);
430: // expression.getTrueExpression().visit(this);
431: //
432: // Label l1 = new Label();
433: // cv.visitJumpInsn(GOTO, l1);
434: // cv.visitLabel(l0);
435: //
436: // expression.getFalseExpression().visit(this);
437: // cv.visitLabel(l1);
438: // }
439: //
440: // public void visitAssertStatement(AssertStatement statement) {
441: // onLineNumber(statement);
442: //
443: // //System.out.println("Assert: " + statement.getLineNumber() + " for: "
444: // // + statement.getText());
445: //
446: // BooleanExpression booleanExpression = statement.getBooleanExpression();
447: // booleanExpression.visit(this);
448: //
449: // Label l0 = new Label();
450: // cv.visitJumpInsn(IFEQ, l0);
451: //
452: // // do nothing
453: //
454: // Label l1 = new Label();
455: // cv.visitJumpInsn(GOTO, l1);
456: // cv.visitLabel(l0);
457: //
458: // // push expression string onto stack
459: // String expressionText = booleanExpression.getText();
460: // List list = new ArrayList();
461: // addVariableNames(booleanExpression, list);
462: // if (list.isEmpty()) {
463: // cv.visitLdcInsn(expressionText);
464: // }
465: // else {
466: // boolean first = true;
467: //
468: // // lets create a new expression
469: // cv.visitTypeInsn(NEW, "java/lang/StringBuffer");
470: // cv.visitInsn(DUP);
471: // cv.visitLdcInsn(expressionText + ". Values: ");
472: //
473: // cv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "(Ljava/lang/String;)V");
474: //
475: // int tempIndex = defineVariable(createVariableName("assert"), "java.lang.Object", false).getIndex();
476: //
477: // cv.visitVarInsn(ASTORE, tempIndex);
478: //
479: // for (Iterator iter = list.iterator(); iter.hasNext();) {
480: // String name = (String) iter.next();
481: // String text = name + " = ";
482: // if (first) {
483: // first = false;
484: // }
485: // else {
486: // text = ", " + text;
487: // }
488: //
489: // cv.visitVarInsn(ALOAD, tempIndex);
490: // cv.visitLdcInsn(text);
491: // cv.visitMethodInsn(
492: // INVOKEVIRTUAL,
493: // "java/lang/StringBuffer",
494: // "append",
495: // "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
496: // cv.visitInsn(POP);
497: //
498: // cv.visitVarInsn(ALOAD, tempIndex);
499: // new VariableExpression(name).visit(this);
500: // cv.visitMethodInsn(
501: // INVOKEVIRTUAL,
502: // "java/lang/StringBuffer",
503: // "append",
504: // "(Ljava/lang/Object;)Ljava/lang/StringBuffer;");
505: // cv.visitInsn(POP);
506: //
507: // }
508: // cv.visitVarInsn(ALOAD, tempIndex);
509: // }
510: //
511: // // now the optional exception expression
512: // statement.getMessageExpression().visit(this);
513: //
514: // assertFailedMethod.call(cv);
515: // cv.visitLabel(l1);
516: // }
517: //
518: // public void visitTryCatchFinally(TryCatchStatement statement) {
519: // onLineNumber(statement);
520: //
521: // CatchStatement catchStatement = statement.getCatchStatement(0);
522: //
523: // Statement tryStatement = statement.getTryStatement();
524: //
525: // if (tryStatement.isEmpty() || catchStatement == null) {
526: // final Label l0 = new Label();
527: // cv.visitLabel(l0);
528: //
529: // tryStatement.visit(this);
530: //
531: // int index1 = defineVariable(this.createVariableName("exception"), "java.lang.Object").getIndex();
532: // int index2 = defineVariable(this.createVariableName("exception"), "java.lang.Object").getIndex();
533: //
534: // final Label l1 = new Label();
535: // cv.visitJumpInsn(JSR, l1);
536: // final Label l2 = new Label();
537: // cv.visitLabel(l2);
538: // final Label l3 = new Label();
539: // cv.visitJumpInsn(GOTO, l3);
540: // final Label l4 = new Label();
541: // cv.visitLabel(l4);
542: // cv.visitVarInsn(ASTORE, index1);
543: // cv.visitJumpInsn(JSR, l1);
544: // final Label l5 = new Label();
545: // cv.visitLabel(l5);
546: // cv.visitVarInsn(ALOAD, index1);
547: // cv.visitInsn(ATHROW);
548: // cv.visitLabel(l1);
549: // cv.visitVarInsn(ASTORE, index2);
550: //
551: // statement.getFinallyStatement().visit(this);
552: //
553: // cv.visitVarInsn(RET, index2);
554: // cv.visitLabel(l3);
555: //
556: // exceptionBlocks.add(new Runnable() {
557: // public void run() {
558: // cv.visitTryCatchBlock(l0, l2, l4, null);
559: // cv.visitTryCatchBlock(l4, l5, l4, null);
560: // }
561: // });
562: //
563: // }
564: // else {
565: // String exceptionVar = catchStatement.getVariable();
566: // String exceptionType =
567: // checkValidType(catchStatement.getExceptionType(), catchStatement, "in catch statement");
568: //
569: // int exceptionIndex = defineVariable(exceptionVar, exceptionType, false).getIndex();
570: // int index2 = defineVariable(this.createVariableName("exception"), "java.lang.Object").getIndex();
571: // int index3 = defineVariable(this.createVariableName("exception"), "java.lang.Object").getIndex();
572: //
573: // final Label l0 = new Label();
574: // cv.visitLabel(l0);
575: //
576: // tryStatement.visit(this);
577: //
578: // final Label l1 = new Label();
579: // cv.visitLabel(l1);
580: // Label l2 = new Label();
581: // cv.visitJumpInsn(JSR, l2);
582: // final Label l3 = new Label();
583: // cv.visitLabel(l3);
584: // Label l4 = new Label();
585: // cv.visitJumpInsn(GOTO, l4);
586: // final Label l5 = new Label();
587: // cv.visitLabel(l5);
588: //
589: // cv.visitVarInsn(ASTORE, exceptionIndex);
590: //
591: // if (catchStatement != null) {
592: // catchStatement.visit(this);
593: // }
594: //
595: // cv.visitJumpInsn(JSR, l2);
596: // final Label l6 = new Label();
597: // cv.visitLabel(l6);
598: // cv.visitJumpInsn(GOTO, l4);
599: //
600: // final Label l7 = new Label();
601: // cv.visitLabel(l7);
602: // cv.visitVarInsn(ASTORE, index2);
603: // cv.visitJumpInsn(JSR, l2);
604: //
605: // final Label l8 = new Label();
606: // cv.visitLabel(l8);
607: // cv.visitVarInsn(ALOAD, index2);
608: // cv.visitInsn(ATHROW);
609: // cv.visitLabel(l2);
610: // cv.visitVarInsn(ASTORE, index3);
611: //
612: // statement.getFinallyStatement().visit(this);
613: //
614: // cv.visitVarInsn(RET, index3);
615: // cv.visitLabel(l4);
616: //
617: // // rest of code goes here...
618: //
619: // //final String exceptionTypeInternalName = (catchStatement !=
620: // // null) ?
621: // // getTypeDescription(exceptionType) : null;
622: // final String exceptionTypeInternalName =
623: // (catchStatement != null) ? BytecodeHelper.getClassInternalName(exceptionType) : null;
624: //
625: // exceptionBlocks.add(new Runnable() {
626: // public void run() {
627: // cv.visitTryCatchBlock(l0, l1, l5, exceptionTypeInternalName);
628: // cv.visitTryCatchBlock(l0, l3, l7, null);
629: // cv.visitTryCatchBlock(l5, l6, l7, null);
630: // cv.visitTryCatchBlock(l7, l8, l7, null);
631: // }
632: // });
633: // }
634: // }
635: //
636: // public void visitSwitch(SwitchStatement statement) {
637: // onLineNumber(statement);
638: //
639: // statement.getExpression().visit(this);
640: //
641: // pushBlockScope();
642: //
643: // int switchVariableIndex = defineVariable(createVariableName("switch"), "java.lang.Object").getIndex();
644: // cv.visitVarInsn(ASTORE, switchVariableIndex);
645: //
646: // List caseStatements = statement.getCaseStatements();
647: // int caseCount = caseStatements.size();
648: // Label[] labels = new Label[caseCount + 1];
649: // for (int i = 0; i < caseCount; i++) {
650: // labels[i] = new Label();
651: // }
652: //
653: // int i = 0;
654: // for (Iterator iter = caseStatements.iterator(); iter.hasNext(); i++) {
655: // CaseStatement caseStatement = (CaseStatement) iter.next();
656: // visitCaseStatement(caseStatement, switchVariableIndex, labels[i], labels[i + 1]);
657: // }
658: //
659: // statement.getDefaultStatement().visit(this);
660: //
661: // cv.visitLabel(scope.getBreakLabel());
662: //
663: // popScope();
664: // }
665: //
666: // public void visitCaseStatement(CaseStatement statement) {
667: // }
668: //
669: // public void visitCaseStatement(
670: // CaseStatement statement,
671: // int switchVariableIndex,
672: // Label thisLabel,
673: // Label nextLabel) {
674: //
675: // onLineNumber(statement);
676: //
677: // cv.visitVarInsn(ALOAD, switchVariableIndex);
678: // statement.getExpression().visit(this);
679: //
680: // isCaseMethod.call(cv);
681: //
682: // Label l0 = new Label();
683: // cv.visitJumpInsn(IFEQ, l0);
684: //
685: // cv.visitLabel(thisLabel);
686: //
687: // statement.getCode().visit(this);
688: //
689: // // now if we don't finish with a break we need to jump past
690: // // the next comparison
691: // if (nextLabel != null) {
692: // cv.visitJumpInsn(GOTO, nextLabel);
693: // }
694: //
695: // cv.visitLabel(l0);
696: // }
697: //
698: // public void visitBreakStatement(BreakStatement statement) {
699: // onLineNumber(statement);
700: //
701: // cv.visitJumpInsn(GOTO, scope.getBreakLabel());
702: // }
703: //
704: // public void visitContinueStatement(ContinueStatement statement) {
705: // onLineNumber(statement);
706: //
707: // cv.visitJumpInsn(GOTO, scope.getContinueLabel());
708: // }
709: //
710: // public void visitSynchronizedStatement(SynchronizedStatement statement) {
711: // onLineNumber(statement);
712: //
713: // statement.getExpression().visit(this);
714: //
715: // int index = defineVariable(createVariableName("synchronized"), "java.lang.Integer").getIndex();
716: //
717: // cv.visitVarInsn(ASTORE, index);
718: // cv.visitInsn(MONITORENTER);
719: // final Label l0 = new Label();
720: // cv.visitLabel(l0);
721: //
722: // statement.getCode().visit(this);
723: //
724: // cv.visitVarInsn(ALOAD, index);
725: // cv.visitInsn(MONITOREXIT);
726: // final Label l1 = new Label();
727: // cv.visitJumpInsn(GOTO, l1);
728: // final Label l2 = new Label();
729: // cv.visitLabel(l2);
730: // cv.visitVarInsn(ALOAD, index);
731: // cv.visitInsn(MONITOREXIT);
732: // cv.visitInsn(ATHROW);
733: // cv.visitLabel(l1);
734: //
735: // exceptionBlocks.add(new Runnable() {
736: // public void run() {
737: // cv.visitTryCatchBlock(l0, l2, l2, null);
738: // }
739: // });
740: // }
741: //
742: // public void visitThrowStatement(ThrowStatement statement) {
743: // statement.getExpression().visit(this);
744: //
745: // // we should infer the type of the exception from the expression
746: // cv.visitTypeInsn(CHECKCAST, "java/lang/Throwable");
747: //
748: // cv.visitInsn(ATHROW);
749: // }
750: //
751: // public void visitReturnStatement(ReturnStatement statement) {
752: // onLineNumber(statement);
753: //
754: // Expression expression = statement.getExpression();
755: // evaluateExpression(expression);
756: //
757: // //return is based on class type
758: // //TODO: make work with arrays
759: // // we may need to cast
760: // String returnType = methodNode.getReturnType();
761: // helper.unbox(returnType);
762: // if (returnType.equals("double")) {
763: // cv.visitInsn(DRETURN);
764: // }
765: // else if (returnType.equals("float")) {
766: // cv.visitInsn(FRETURN);
767: // }
768: // else if (returnType.equals("long")) {
769: // cv.visitInsn(LRETURN);
770: // }
771: // else if (returnType.equals("boolean")) {
772: // cv.visitInsn(IRETURN);
773: // }
774: // else if (
775: // returnType.equals("char")
776: // || returnType.equals("byte")
777: // || returnType.equals("int")
778: // || returnType.equals("short")) { //byte,short,boolean,int are
779: // // all IRETURN
780: // cv.visitInsn(IRETURN);
781: // }
782: // else {
783: // doConvertAndCast(returnType, expression);
784: // cv.visitInsn(ARETURN);
785: //
786: // /*
787: // if (c == Boolean.class) {
788: // Label l0 = new Label();
789: // cv.visitJumpInsn(IFEQ, l0);
790: // cv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TRUE", "Ljava/lang/Boolean;");
791: // cv.visitInsn(ARETURN);
792: // cv.visitLabel(l0);
793: // cv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "FALSE", "Ljava/lang/Boolean;");
794: // cv.visitInsn(ARETURN);
795: // }
796: // else {
797: // if (isValidTypeForCast(returnType) && !returnType.equals(c.getName())) {
798: // doConvertAndCast(returnType, expression);
799: // }
800: // cv.visitInsn(ARETURN);
801: // }
802: // */
803: // }
804: //
805: // outputReturn = true;
806: // }
807:
808: }
|