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