0001: /*
0002: $Header: /cvsroot/xorm/xorm/src/org/xorm/query/CodeParser.java,v 1.4 2003/04/27 00:00:23 wbiggs Exp $
0003:
0004: This file is part of XORM.
0005:
0006: XORM is free software; you can redistribute it and/or modify
0007: it under the terms of the GNU General Public License as published by
0008: the Free Software Foundation; either version 2 of the License, or
0009: (at your option) any later version.
0010:
0011: XORM is distributed in the hope that it will be useful,
0012: but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0014: GNU General Public License for more details.
0015:
0016: You should have received a copy of the GNU General Public License
0017: along with XORM; if not, write to the Free Software
0018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0019: */
0020: package org.xorm.query;
0021:
0022: import java.beans.Introspector;
0023:
0024: import java.io.InputStream;
0025: import java.io.IOException;
0026:
0027: import java.util.ArrayList;
0028: import java.util.Iterator;
0029: import java.util.Stack;
0030:
0031: import org.apache.bcel.classfile.*;
0032: import org.apache.bcel.generic.*;
0033:
0034: public class CodeParser implements org.apache.bcel.generic.Visitor,
0035: QueryLanguage {
0036: private static final int EQUAL = 1, NOT_EQUAL = -1, LT = 2,
0037: GTE = -2, GT = 3, LTE = -3, AND = 4, OR = 5, ANDL = 6,
0038: ORL = 7, STARTS_WITH = 8, ENDS_WITH = 9, CONTAINS = 10;
0039:
0040: private static final String[] OP_NAMES = { "<=", ">=", "!=", null,
0041: "==", "<", ">", "&&", "||", "&", "|", "startsWith",
0042: "endsWith", "contains" };
0043:
0044: private static String opName(int op) {
0045: return OP_NAMES[op + 3];
0046: }
0047:
0048: private static class Stack2 {
0049: private Stack expressions = new Stack();
0050: private Stack types = new Stack();
0051:
0052: public void push(Object expression, Type type) {
0053: System.out.println("Pushing: " + expression);
0054: expressions.push(expression);
0055: types.push(type);
0056: }
0057:
0058: public void push(Object expression) {
0059: push(expression, null);
0060: }
0061:
0062: public Expression pop() {
0063: types.pop();
0064: return (Expression) expressions.pop();
0065: }
0066:
0067: public Type peekType() {
0068: return (Type) types.peek();
0069: }
0070:
0071: public Expression firstElement() {
0072: return (Expression) expressions.firstElement();
0073: }
0074:
0075: public int size() {
0076: return expressions.size();
0077: }
0078: }
0079:
0080: // Instance variables
0081: private Stack2 stack = new Stack2();
0082: private int lastOp;
0083: private boolean done;
0084: private InstructionHandle currentHandle;
0085: private boolean consume;
0086: private boolean sawNumeric;
0087: private Method method;
0088: private ConstantPoolGen cpg;
0089: private ArrayList variableNames;
0090: private Class candidateClass;
0091: private Class clazz;
0092:
0093: // JDOQL representation of parameters
0094: private String parameters;
0095:
0096: // JDOQL representation of variables
0097: private String variables;
0098:
0099: public CodeParser(Class clazz) throws QuerySyntaxException {
0100: this .clazz = clazz;
0101: compile();
0102: }
0103:
0104: public void compile() throws QuerySyntaxException {
0105: if (candidateClass != null)
0106: return; // already compiled
0107: try {
0108: // Use BCEL to decompile the class file
0109: String filename = clazz.getName().replace('.', '/')
0110: + ".class";
0111: InputStream in = clazz.getClassLoader()
0112: .getResourceAsStream(filename);
0113: JavaClass jclass = new ClassParser(in, filename).parse();
0114:
0115: // Find superclass or interface that is persistent
0116: // by convention: use the superclass, or if none, use
0117: // the first interface implemented. TODO make more robust.
0118: candidateClass = clazz.getSuperclass();
0119: if (candidateClass.equals(Object.class)) {
0120: candidateClass = clazz.getInterfaces()[0];
0121: }
0122:
0123: // Find Variables
0124: StringBuffer sb = new StringBuffer();
0125: Field[] fields = jclass.getFields();
0126: variableNames = new ArrayList();
0127: for (int i = 0; i < fields.length; i++) {
0128: org.apache.bcel.classfile.Field field = fields[i];
0129: variableNames.add(field.getName());
0130: if (i > 0) {
0131: sb.append("; ");
0132: }
0133: sb
0134: .append(
0135: Utility.signatureToString(field
0136: .getSignature())).append(' ')
0137: .append(field.getName());
0138: }
0139: if (sb.length() > 0) {
0140: variables = sb.toString();
0141: }
0142:
0143: // Look for the evaluate method
0144: Method[] methods = jclass.getMethods();
0145: for (int i = 0; i < methods.length; i++) {
0146: method = methods[i];
0147: if (method.getName().equals("evaluate")) {
0148: InstructionList il = new InstructionList(method
0149: .getCode().getCode());
0150:
0151: Iterator it = il.iterator();
0152: currentHandle = (InstructionHandle) it.next();
0153: cpg = new ConstantPoolGen(method.getConstantPool());
0154: parse();
0155:
0156: LocalVariable[] lva = method
0157: .getLocalVariableTable()
0158: .getLocalVariableTable();
0159: sb = new StringBuffer();
0160: for (int j = 1; j < lva.length; j++) {
0161: LocalVariable lv = lva[j];
0162: if (j > 1) {
0163: sb.append(", ");
0164: }
0165: sb.append(
0166: Utility.signatureToString(lv
0167: .getSignature())).append(' ')
0168: .append(lv.getName());
0169: }
0170: if (sb.length() > 0) {
0171: parameters = sb.toString();
0172: }
0173: break;
0174: }
0175: }
0176: } catch (Throwable e) {
0177: throw new QuerySyntaxException(e);
0178: }
0179: }
0180:
0181: private CodeParser(Method method, InstructionHandle handle,
0182: ArrayList variableNames) {
0183: this .method = method;
0184: this .cpg = new ConstantPoolGen(method.getConstantPool());
0185: this .currentHandle = handle;
0186: this .variableNames = variableNames;
0187: }
0188:
0189: public Class getCandidateClass() {
0190: return candidateClass;
0191: }
0192:
0193: private void parse() {
0194: while (!done && currentHandle != null) {
0195: consume = true;
0196: System.out.println(currentHandle);
0197: currentHandle.accept(this );
0198: if (consume) {
0199: currentHandle = currentHandle.getNext();
0200: }
0201: }
0202: }
0203:
0204: public Expression getExpression() {
0205: return stack.firstElement();
0206: }
0207:
0208: /** Returns the JDOQL filter equivalent of the code. */
0209: public String getFilter() {
0210: return stack.firstElement().toString();
0211: }
0212:
0213: /** Returns the JDOQL parameters for the code, or null. */
0214: public String getParameters() {
0215: return parameters;
0216: }
0217:
0218: /** Returns the JDOQL variable declarations for the code, or null. */
0219: public String getVariables() {
0220: return variables;
0221: }
0222:
0223: public String toString() {
0224: return stack.firstElement().toString();
0225: }
0226:
0227: /**
0228: * If there are two items on the stack and a value for lastOp,
0229: * combine them.
0230: */
0231: public void collapse() {
0232: while (stack.size() > 1) {
0233: Expression rhs = stack.pop();
0234: Expression origRHS = rhs;
0235: Type lhsType = stack.peekType();
0236: if (lhsType == Type.BOOLEAN) {
0237: if ("1".equals(rhs.toString())) {
0238: rhs = Expression.Constant.TRUE;
0239: } else if ("0".equals(rhs.toString())) {
0240: rhs = Expression.Constant.FALSE;
0241: }
0242: }
0243: Expression lhs = stack.pop();
0244: if (lastOp == 0) {
0245: stack.push(new Expression.ConditionalAnd(lhs, rhs));
0246: return;
0247: }
0248: if (lastOp == AND && "1".equals(origRHS.toString())) {
0249: stack.push(lhs);
0250: } else if (lastOp == AND && "0".equals(origRHS.toString())) {
0251: stack.push(Expression.Constant.FALSE);
0252: } else if (lastOp == OR && "1".equals(origRHS.toString())) {
0253: stack.push(Expression.Constant.TRUE);
0254: } else if (lastOp == OR && "0".equals(origRHS.toString())) {
0255: stack.push(lhs);
0256: } else if (lastOp == AND && "1".equals(lhs.toString())) {
0257: stack.push(rhs);
0258: } else if (lastOp == AND && "0".equals(lhs.toString())) {
0259: stack.push(Expression.Constant.FALSE);
0260: } else if (lastOp == OR && "1".equals(lhs.toString())) {
0261: stack.push(Expression.Constant.TRUE);
0262: } else if (lastOp == OR && "0".equals(lhs.toString())) {
0263: stack.push(rhs);
0264: } else {
0265: String exp;
0266: switch (lastOp) {
0267: case EQUAL:
0268: stack.push(new Expression.Equal(lhs, rhs));
0269: break;
0270: case NOT_EQUAL:
0271: stack.push(new Expression.NotEqual(lhs, rhs));
0272: break;
0273: case LT:
0274: stack.push(new Expression.LessThan(lhs, rhs));
0275: break;
0276: case GTE:
0277: stack
0278: .push(new Expression.GreaterThanEqual(lhs,
0279: rhs));
0280: break;
0281: case GT:
0282: stack.push(new Expression.GreaterThan(lhs, rhs));
0283: break;
0284: case LTE:
0285: stack.push(new Expression.LessThanEqual(lhs, rhs));
0286: break;
0287: case AND:
0288: stack.push(new Expression.ConditionalAnd(lhs, rhs));
0289: break;
0290: case OR:
0291: stack.push(new Expression.ConditionalOr(lhs, rhs));
0292: break;
0293: case ANDL:
0294: stack.push(new Expression.And(lhs, rhs));
0295: break;
0296: case ORL:
0297: stack.push(new Expression.InclusiveOr(lhs, rhs));
0298: break;
0299: case STARTS_WITH:
0300: case ENDS_WITH:
0301: case CONTAINS:
0302: stack.push(new Expression.MethodCall(lhs,
0303: opName(lastOp), new Expression[] { rhs },
0304: Boolean.class));
0305: break;
0306: }
0307: }
0308: lastOp = 0;
0309: }
0310: }
0311:
0312: // Unimplemented high level visitors
0313: public void visitAllocationInstruction(AllocationInstruction ins) {
0314: }
0315:
0316: public void visitArithmeticInstruction(ArithmeticInstruction ins) {
0317: }
0318:
0319: public void visitArrayInstruction(ArrayInstruction ins) {
0320: }
0321:
0322: public void visitBranchInstruction(BranchInstruction ins) {
0323: }
0324:
0325: public void visitCPInstruction(CPInstruction ins) {
0326: }
0327:
0328: public void visitConversionInstruction(ConversionInstruction ins) {
0329: }
0330:
0331: public void visitExceptionThrower(ExceptionThrower ins) {
0332: }
0333:
0334: public void visitFieldInstruction(FieldInstruction ins) {
0335: }
0336:
0337: public void visitFieldOrMethod(
0338: org.apache.bcel.generic.FieldOrMethod ins) {
0339: }
0340:
0341: public void visitIfInstruction(IfInstruction ins) {
0342: }
0343:
0344: public void visitInvokeInstruction(InvokeInstruction ins) {
0345: }
0346:
0347: public void visitJsrInstruction(JsrInstruction ins) {
0348: }
0349:
0350: public void visitLoadClass(LoadClass ins) {
0351: }
0352:
0353: public void visitLocalVariableInstruction(
0354: LocalVariableInstruction ins) {
0355: }
0356:
0357: public void visitPopInstruction(PopInstruction ins) {
0358: }
0359:
0360: public void visitPushInstruction(PushInstruction ins) {
0361: }
0362:
0363: public void visitReturnInstruction(ReturnInstruction ins) {
0364: }
0365:
0366: public void visitSelect(Select ins) {
0367: }
0368:
0369: public void visitStackConsumer(StackConsumer ins) {
0370: }
0371:
0372: public void visitStackInstruction(StackInstruction ins) {
0373: }
0374:
0375: public void visitStackProducer(StackProducer ins) {
0376: }
0377:
0378: public void visitStoreInstruction(StoreInstruction ins) {
0379: }
0380:
0381: public void visitTypedInstruction(TypedInstruction ins) {
0382: }
0383:
0384: public void visitUnconditionalBranch(UnconditionalBranch ins) {
0385: }
0386:
0387: public void visitVariableLengthInstruction(
0388: VariableLengthInstruction ins) {
0389: }
0390:
0391: // Constants and variables
0392: public void visitConstantPushInstruction(ConstantPushInstruction ins) {
0393: stack.push(new Expression.Constant(ins.getValue()));
0394: }
0395:
0396: public void visitLDC(LDC ins) {
0397: stack.push(new Expression.Constant(ins.getValue(cpg)));
0398: }
0399:
0400: // Implemented by visitConstantPushInstruction
0401: public void visitDCONST(DCONST ins) {
0402: }
0403:
0404: public void visitFCONST(FCONST ins) {
0405: }
0406:
0407: public void visitICONST(ICONST ins) {
0408: }
0409:
0410: public void visitLCONST(LCONST ins) {
0411: }
0412:
0413: public void visitBIPUSH(BIPUSH ins) {
0414: }
0415:
0416: public void visitSIPUSH(SIPUSH ins) {
0417: }
0418:
0419: public void visitACONST_NULL(ACONST_NULL ins) {
0420: stack.push(Expression.Constant.NULL);
0421: }
0422:
0423: public void visitLoadInstruction(LoadInstruction ins) {
0424: int index = ins.getIndex();
0425: if (index == 0) {
0426: stack.push(Expression.FieldAccess.THIS, ins.getType(cpg));
0427: } else {
0428: String name = method.getLocalVariableTable()
0429: .getLocalVariable(index).getName();
0430: stack.push(new Expression.Parameter(name, typeToClass(ins
0431: .getType(cpg))), ins.getType(cpg));
0432: }
0433: }
0434:
0435: // Implemented by visitLoadInstruction
0436: public void visitALOAD(ALOAD ins) {
0437: }
0438:
0439: public void visitDLOAD(DLOAD ins) {
0440: }
0441:
0442: public void visitFLOAD(FLOAD ins) {
0443: }
0444:
0445: public void visitILOAD(ILOAD ins) {
0446: }
0447:
0448: public void visitLLOAD(LLOAD ins) {
0449: }
0450:
0451: // Goto
0452: public void visitGotoInstruction(GotoInstruction ins) {
0453: currentHandle = ins.getTarget();
0454: consume = false;
0455: }
0456:
0457: // Implemented by visitGotoInstruction
0458: public void visitGOTO(GOTO ins) {
0459: }
0460:
0461: public void visitGOTO_W(GOTO_W ins) {
0462: }
0463:
0464: // Conditionals that consume the stack
0465: public void visitIF_ICMPEQ(IF_ICMPEQ ins) {
0466: lastOp = EQUAL;
0467: doCondition(ins);
0468: }
0469:
0470: public void visitIF_ICMPNE(IF_ICMPNE ins) {
0471: lastOp = NOT_EQUAL;
0472: doCondition(ins);
0473: }
0474:
0475: public void visitIF_ICMPLT(IF_ICMPLT ins) {
0476: lastOp = LT;
0477: doCondition(ins);
0478: }
0479:
0480: public void visitIF_ICMPLE(IF_ICMPLE ins) {
0481: lastOp = LTE;
0482: doCondition(ins);
0483: }
0484:
0485: public void visitIF_ICMPGE(IF_ICMPGE ins) {
0486: lastOp = GTE;
0487: doCondition(ins);
0488: }
0489:
0490: public void visitIF_ICMPGT(IF_ICMPGT ins) {
0491: lastOp = GT;
0492: doCondition(ins);
0493: }
0494:
0495: public void visitIF_ACMPEQ(IF_ACMPEQ ins) {
0496: lastOp = EQUAL;
0497: doCondition(ins);
0498: }
0499:
0500: public void visitIF_ACMPNE(IF_ACMPNE ins) {
0501: lastOp = NOT_EQUAL;
0502: doCondition(ins);
0503: }
0504:
0505: // Conditionals that do not consume the stack
0506: public void visitIFEQ(IFEQ ins) {
0507: lastOp = NOT_EQUAL;
0508: if (sawNumeric) {
0509: lastOp = EQUAL;
0510: sawNumeric = false;
0511: }
0512: doCondition(ins);
0513: }
0514:
0515: public void visitIFNE(IFNE ins) {
0516: lastOp = EQUAL;
0517: if (sawNumeric) {
0518: lastOp = NOT_EQUAL;
0519: sawNumeric = false;
0520: }
0521: doCondition(ins);
0522: }
0523:
0524: public void visitIFLT(IFLT ins) {
0525: lastOp = LT;
0526: doCondition(ins);
0527: }
0528:
0529: public void visitIFLE(IFLE ins) {
0530: lastOp = LTE;
0531: doCondition(ins);
0532: }
0533:
0534: public void visitIFGE(IFGE ins) {
0535: lastOp = GT;
0536: doCondition(ins);
0537: }
0538:
0539: public void visitIFGT(IFGT ins) {
0540: lastOp = GT;
0541: doCondition(ins);
0542: }
0543:
0544: public void visitIFNULL(IFNULL ins) {
0545: lastOp = EQUAL;
0546: stack.push(Expression.Constant.NULL);
0547: doCondition(ins);
0548: }
0549:
0550: public void visitIFNONNULL(IFNONNULL ins) {
0551: lastOp = NOT_EQUAL;
0552: stack.push(Expression.Constant.NULL);
0553: doCondition(ins);
0554: }
0555:
0556: // Numeric comparisons
0557: public void visitFCMPG(FCMPG ins) {
0558: sawNumeric = true;
0559: }
0560:
0561: public void visitDCMPL(DCMPL ins) {
0562: sawNumeric = true;
0563: }
0564:
0565: public void visitLCMP(LCMP ins) {
0566: sawNumeric = true;
0567: }
0568:
0569: public void visitDCMPG(DCMPG ins) {
0570: sawNumeric = true;
0571: }
0572:
0573: public void visitFCMPL(FCMPL ins) {
0574: sawNumeric = true;
0575: }
0576:
0577: // Logical operators
0578: public void visitIAND(IAND ins) {
0579: collapse();
0580: lastOp = ANDL;
0581: collapse();
0582: }
0583:
0584: public void visitIOR(IOR ins) {
0585: collapse();
0586: lastOp = ORL;
0587: collapse();
0588: }
0589:
0590: // Method and field traversal
0591: public void visitINVOKEVIRTUAL(INVOKEVIRTUAL ins) {
0592: String name = ins.getMethodName(cpg);
0593: if ("equals".equals(name)) {
0594: lastOp = EQUAL;
0595: } else if ("startsWith".equals(name)) {
0596: lastOp = STARTS_WITH;
0597: collapse();
0598: } else if ("endsWith".equals(name)) {
0599: lastOp = ENDS_WITH;
0600: collapse();
0601: } else if (name.startsWith("get")) {
0602: name = Introspector.decapitalize(name.substring(3));
0603: stack.push(new Expression.FieldAccess(stack.pop(), name,
0604: typeToClass(ins.getReturnType(cpg))), ins
0605: .getReturnType(cpg));
0606: }
0607: }
0608:
0609: public void visitINVOKEINTERFACE(INVOKEINTERFACE ins) {
0610: String name = ins.getMethodName(cpg);
0611: if ("contains".equals(name)) {
0612: lastOp = CONTAINS;
0613: collapse();
0614: } else if (name.startsWith("get")) {
0615: name = Introspector.decapitalize(name.substring(3));
0616: stack.push(new Expression.FieldAccess(stack.pop(), name,
0617: typeToClass(ins.getReturnType(cpg))), ins
0618: .getReturnType(cpg));
0619: }
0620: }
0621:
0622: public void visitGETFIELD(GETFIELD ins) {
0623: Expression owner = stack.pop();
0624: String name = ins.getName(cpg);
0625: if (variableNames.contains(name)) {
0626: stack.push(new Expression.Variable(name, typeToClass(ins
0627: .getType(cpg))), ins.getType(cpg));
0628: } else {
0629: stack.push(new Expression.FieldAccess(owner, name,
0630: typeToClass(ins.getType(cpg))), ins.getType(cpg));
0631: }
0632: }
0633:
0634: // Return from method
0635: public void visitIRETURN(IRETURN ins) {
0636: collapse();
0637: done = true;
0638: }
0639:
0640: // Negate numbers
0641: public void visitDNEG(DNEG ins) {
0642: doNegate();
0643: }
0644:
0645: public void visitFNEG(FNEG ins) {
0646: doNegate();
0647: }
0648:
0649: public void visitINEG(INEG ins) {
0650: doNegate();
0651: }
0652:
0653: public void visitLNEG(LNEG ins) {
0654: doNegate();
0655: }
0656:
0657: // Unimplemented bytecodes (throw exceptions if used)
0658: public void visitAALOAD(AALOAD ins) {
0659: throw new UnsupportedOperationException(ins.toString());
0660: }
0661:
0662: public void visitAASTORE(AASTORE ins) {
0663: throw new UnsupportedOperationException(ins.toString());
0664: }
0665:
0666: public void visitANEWARRAY(ANEWARRAY ins) {
0667: throw new UnsupportedOperationException(ins.toString());
0668: }
0669:
0670: public void visitARETURN(ARETURN ins) {
0671: throw new UnsupportedOperationException(ins.toString());
0672: }
0673:
0674: public void visitARRAYLENGTH(ARRAYLENGTH ins) {
0675: throw new UnsupportedOperationException(ins.toString());
0676: }
0677:
0678: public void visitASTORE(ASTORE ins) {
0679: throw new UnsupportedOperationException(ins.toString());
0680: }
0681:
0682: public void visitATHROW(ATHROW ins) {
0683: throw new UnsupportedOperationException(ins.toString());
0684: }
0685:
0686: public void visitBALOAD(BALOAD ins) {
0687: throw new UnsupportedOperationException(ins.toString());
0688: }
0689:
0690: public void visitBASTORE(BASTORE ins) {
0691: throw new UnsupportedOperationException(ins.toString());
0692: }
0693:
0694: public void visitBREAKPOINT(BREAKPOINT ins) {
0695: throw new UnsupportedOperationException(ins.toString());
0696: }
0697:
0698: public void visitCALOAD(CALOAD ins) {
0699: throw new UnsupportedOperationException(ins.toString());
0700: }
0701:
0702: public void visitCASTORE(CASTORE ins) {
0703: throw new UnsupportedOperationException(ins.toString());
0704: }
0705:
0706: public void visitCHECKCAST(CHECKCAST ins) {
0707: throw new UnsupportedOperationException(ins.toString());
0708: }
0709:
0710: public void visitDADD(DADD ins) {
0711: throw new UnsupportedOperationException(ins.toString());
0712: }
0713:
0714: public void visitDALOAD(DALOAD ins) {
0715: throw new UnsupportedOperationException(ins.toString());
0716: }
0717:
0718: public void visitDASTORE(DASTORE ins) {
0719: throw new UnsupportedOperationException(ins.toString());
0720: }
0721:
0722: public void visitDDIV(DDIV ins) {
0723: throw new UnsupportedOperationException(ins.toString());
0724: }
0725:
0726: public void visitDMUL(DMUL ins) {
0727: throw new UnsupportedOperationException(ins.toString());
0728: }
0729:
0730: public void visitDREM(DREM ins) {
0731: throw new UnsupportedOperationException(ins.toString());
0732: }
0733:
0734: public void visitDRETURN(DRETURN ins) {
0735: throw new UnsupportedOperationException(ins.toString());
0736: }
0737:
0738: public void visitDSTORE(DSTORE ins) {
0739: throw new UnsupportedOperationException(ins.toString());
0740: }
0741:
0742: public void visitDSUB(DSUB ins) {
0743: throw new UnsupportedOperationException(ins.toString());
0744: }
0745:
0746: public void visitDUP(DUP ins) {
0747: throw new UnsupportedOperationException(ins.toString());
0748: }
0749:
0750: public void visitDUP2(DUP2 ins) {
0751: throw new UnsupportedOperationException(ins.toString());
0752: }
0753:
0754: public void visitDUP2_X1(DUP2_X1 ins) {
0755: throw new UnsupportedOperationException(ins.toString());
0756: }
0757:
0758: public void visitDUP2_X2(DUP2_X2 ins) {
0759: throw new UnsupportedOperationException(ins.toString());
0760: }
0761:
0762: public void visitDUP_X1(DUP_X1 ins) {
0763: throw new UnsupportedOperationException(ins.toString());
0764: }
0765:
0766: public void visitDUP_X2(DUP_X2 ins) {
0767: throw new UnsupportedOperationException(ins.toString());
0768: }
0769:
0770: public void visitFADD(FADD ins) {
0771: throw new UnsupportedOperationException(ins.toString());
0772: }
0773:
0774: public void visitFALOAD(FALOAD ins) {
0775: throw new UnsupportedOperationException(ins.toString());
0776: }
0777:
0778: public void visitFASTORE(FASTORE ins) {
0779: throw new UnsupportedOperationException(ins.toString());
0780: }
0781:
0782: public void visitFDIV(FDIV ins) {
0783: throw new UnsupportedOperationException(ins.toString());
0784: }
0785:
0786: public void visitFMUL(FMUL ins) {
0787: throw new UnsupportedOperationException(ins.toString());
0788: }
0789:
0790: public void visitFREM(FREM ins) {
0791: throw new UnsupportedOperationException(ins.toString());
0792: }
0793:
0794: public void visitFRETURN(FRETURN ins) {
0795: throw new UnsupportedOperationException(ins.toString());
0796: }
0797:
0798: public void visitFSTORE(FSTORE ins) {
0799: throw new UnsupportedOperationException(ins.toString());
0800: }
0801:
0802: public void visitFSUB(FSUB ins) {
0803: throw new UnsupportedOperationException(ins.toString());
0804: }
0805:
0806: public void visitGETSTATIC(GETSTATIC ins) {
0807: throw new UnsupportedOperationException(ins.toString());
0808: }
0809:
0810: public void visitIADD(IADD ins) {
0811: throw new UnsupportedOperationException(ins.toString());
0812: }
0813:
0814: public void visitIALOAD(IALOAD ins) {
0815: throw new UnsupportedOperationException(ins.toString());
0816: }
0817:
0818: public void visitIASTORE(IASTORE ins) {
0819: throw new UnsupportedOperationException(ins.toString());
0820: }
0821:
0822: public void visitIDIV(IDIV ins) {
0823: throw new UnsupportedOperationException(ins.toString());
0824: }
0825:
0826: public void visitIINC(IINC ins) {
0827: throw new UnsupportedOperationException(ins.toString());
0828: }
0829:
0830: public void visitIMPDEP1(IMPDEP1 ins) {
0831: throw new UnsupportedOperationException(ins.toString());
0832: }
0833:
0834: public void visitIMPDEP2(IMPDEP2 ins) {
0835: throw new UnsupportedOperationException(ins.toString());
0836: }
0837:
0838: public void visitIMUL(IMUL ins) {
0839: throw new UnsupportedOperationException(ins.toString());
0840: }
0841:
0842: public void visitINSTANCEOF(INSTANCEOF ins) {
0843: throw new UnsupportedOperationException(ins.toString());
0844: }
0845:
0846: public void visitINVOKESPECIAL(INVOKESPECIAL ins) {
0847: throw new UnsupportedOperationException(ins.toString());
0848: }
0849:
0850: public void visitINVOKESTATIC(INVOKESTATIC ins) {
0851: throw new UnsupportedOperationException(ins.toString());
0852: }
0853:
0854: public void visitIREM(IREM ins) {
0855: throw new UnsupportedOperationException(ins.toString());
0856: }
0857:
0858: public void visitISHL(ISHL ins) {
0859: throw new UnsupportedOperationException(ins.toString());
0860: }
0861:
0862: public void visitISHR(ISHR ins) {
0863: throw new UnsupportedOperationException(ins.toString());
0864: }
0865:
0866: public void visitISTORE(ISTORE ins) {
0867: throw new UnsupportedOperationException(ins.toString());
0868: }
0869:
0870: public void visitISUB(ISUB ins) {
0871: throw new UnsupportedOperationException(ins.toString());
0872: }
0873:
0874: public void visitIUSHR(IUSHR ins) {
0875: throw new UnsupportedOperationException(ins.toString());
0876: }
0877:
0878: public void visitIXOR(IXOR ins) {
0879: throw new UnsupportedOperationException(ins.toString());
0880: }
0881:
0882: public void visitJSR(JSR ins) {
0883: throw new UnsupportedOperationException(ins.toString());
0884: }
0885:
0886: public void visitJSR_W(JSR_W ins) {
0887: throw new UnsupportedOperationException(ins.toString());
0888: }
0889:
0890: public void visitLADD(LADD ins) {
0891: throw new UnsupportedOperationException(ins.toString());
0892: }
0893:
0894: public void visitLALOAD(LALOAD ins) {
0895: throw new UnsupportedOperationException(ins.toString());
0896: }
0897:
0898: public void visitLAND(LAND ins) {
0899: throw new UnsupportedOperationException(ins.toString());
0900: }
0901:
0902: public void visitLASTORE(LASTORE ins) {
0903: throw new UnsupportedOperationException(ins.toString());
0904: }
0905:
0906: public void visitLDC2_W(LDC2_W ins) {
0907: throw new UnsupportedOperationException(ins.toString());
0908: }
0909:
0910: public void visitLDIV(LDIV ins) {
0911: throw new UnsupportedOperationException(ins.toString());
0912: }
0913:
0914: public void visitLMUL(LMUL ins) {
0915: throw new UnsupportedOperationException(ins.toString());
0916: }
0917:
0918: public void visitLOOKUPSWITCH(LOOKUPSWITCH ins) {
0919: throw new UnsupportedOperationException(ins.toString());
0920: }
0921:
0922: public void visitLOR(LOR ins) {
0923: throw new UnsupportedOperationException(ins.toString());
0924: }
0925:
0926: public void visitLREM(LREM ins) {
0927: throw new UnsupportedOperationException(ins.toString());
0928: }
0929:
0930: public void visitLRETURN(LRETURN ins) {
0931: throw new UnsupportedOperationException(ins.toString());
0932: }
0933:
0934: public void visitLSHL(LSHL ins) {
0935: throw new UnsupportedOperationException(ins.toString());
0936: }
0937:
0938: public void visitLSHR(LSHR ins) {
0939: throw new UnsupportedOperationException(ins.toString());
0940: }
0941:
0942: public void visitLSTORE(LSTORE ins) {
0943: throw new UnsupportedOperationException(ins.toString());
0944: }
0945:
0946: public void visitLSUB(LSUB ins) {
0947: throw new UnsupportedOperationException(ins.toString());
0948: }
0949:
0950: public void visitLUSHR(LUSHR ins) {
0951: throw new UnsupportedOperationException(ins.toString());
0952: }
0953:
0954: public void visitLXOR(LXOR ins) {
0955: throw new UnsupportedOperationException(ins.toString());
0956: }
0957:
0958: public void visitMONITORENTER(MONITORENTER ins) {
0959: throw new UnsupportedOperationException(ins.toString());
0960: }
0961:
0962: public void visitMONITOREXIT(MONITOREXIT ins) {
0963: throw new UnsupportedOperationException(ins.toString());
0964: }
0965:
0966: public void visitMULTIANEWARRAY(MULTIANEWARRAY ins) {
0967: throw new UnsupportedOperationException(ins.toString());
0968: }
0969:
0970: public void visitNEW(NEW ins) {
0971: throw new UnsupportedOperationException(ins.toString());
0972: }
0973:
0974: public void visitNEWARRAY(NEWARRAY ins) {
0975: throw new UnsupportedOperationException(ins.toString());
0976: }
0977:
0978: public void visitPOP(POP ins) {
0979: throw new UnsupportedOperationException(ins.toString());
0980: }
0981:
0982: public void visitPOP2(POP2 ins) {
0983: throw new UnsupportedOperationException(ins.toString());
0984: }
0985:
0986: public void visitPUTFIELD(PUTFIELD ins) {
0987: throw new UnsupportedOperationException(ins.toString());
0988: }
0989:
0990: public void visitPUTSTATIC(PUTSTATIC ins) {
0991: throw new UnsupportedOperationException(ins.toString());
0992: }
0993:
0994: public void visitRET(RET ins) {
0995: throw new UnsupportedOperationException(ins.toString());
0996: }
0997:
0998: public void visitRETURN(RETURN ins) {
0999: throw new UnsupportedOperationException(ins.toString());
1000: }
1001:
1002: public void visitSALOAD(SALOAD ins) {
1003: throw new UnsupportedOperationException(ins.toString());
1004: }
1005:
1006: public void visitSASTORE(SASTORE ins) {
1007: throw new UnsupportedOperationException(ins.toString());
1008: }
1009:
1010: public void visitSWAP(SWAP ins) {
1011: throw new UnsupportedOperationException(ins.toString());
1012: }
1013:
1014: public void visitTABLESWITCH(TABLESWITCH ins) {
1015: throw new UnsupportedOperationException(ins.toString());
1016: }
1017:
1018: // Type conversions, not handled here
1019: public void visitD2I(D2I ins) {
1020: }
1021:
1022: public void visitD2L(D2L ins) {
1023: }
1024:
1025: public void visitD2F(D2F ins) {
1026: }
1027:
1028: public void visitF2D(F2D ins) {
1029: }
1030:
1031: public void visitF2I(F2I ins) {
1032: }
1033:
1034: public void visitF2L(F2L ins) {
1035: }
1036:
1037: public void visitI2B(I2B ins) {
1038: }
1039:
1040: public void visitI2C(I2C ins) {
1041: }
1042:
1043: public void visitI2D(I2D ins) {
1044: }
1045:
1046: public void visitI2F(I2F ins) {
1047: }
1048:
1049: public void visitI2L(I2L ins) {
1050: }
1051:
1052: public void visitI2S(I2S ins) {
1053: }
1054:
1055: public void visitL2D(L2D ins) {
1056: }
1057:
1058: public void visitL2F(L2F ins) {
1059: }
1060:
1061: public void visitL2I(L2I ins) {
1062: }
1063:
1064: // NOP, everyone's favorite opcode.
1065: public void visitNOP(NOP ins) {
1066: /* Why are we created only to suffer and die? */
1067: }
1068:
1069: private void doNegate() {
1070: Expression num = stack.pop();
1071: stack.push(new Expression.UnaryMinus(num));
1072: }
1073:
1074: private void doCondition(IfInstruction ins) {
1075: InstructionHandle handle = ins.getTarget();
1076: System.out.println("BRANCH BEGIN");
1077: CodeParser branch = new CodeParser(method, handle,
1078: variableNames);
1079: System.out.println("BRANCH RETURN value: " + branch);
1080: System.out.println("CONTINUE BEGIN");
1081: CodeParser contd = new CodeParser(method, currentHandle
1082: .getNext(), variableNames);
1083: System.out.println("CONTINUE RETURN value: " + contd);
1084:
1085: boolean value = "1".equals(branch.getExpression().toString());
1086: boolean value2 = "0".equals(contd.getExpression().toString());
1087: if (!value && !value2) {
1088: lastOp = -lastOp;
1089: }
1090: collapse();
1091: stack.push(contd.getExpression());
1092: if (value) {
1093: lastOp = OR;
1094: } else {
1095: lastOp = AND;
1096: }
1097: collapse();
1098: if (contd.lastOp != 0) {
1099: lastOp = contd.lastOp;
1100: collapse();
1101: }
1102: done = true;
1103: }
1104:
1105: private static Class typeToClass(Type type) {
1106: if (type == Type.BOOLEAN) {
1107: return Boolean.class;
1108: }
1109: if (type == Type.INT) {
1110: return Integer.class;
1111: }
1112: if (type == Type.SHORT) {
1113: return Short.class;
1114: }
1115: if (type == Type.BYTE) {
1116: return Byte.class;
1117: }
1118: if (type == Type.LONG) {
1119: return Long.class;
1120: }
1121: if (type == Type.DOUBLE) {
1122: return Double.class;
1123: }
1124: if (type == Type.FLOAT) {
1125: return Float.class;
1126: }
1127: if (type == Type.CHAR) {
1128: return Character.class;
1129: }
1130: if (type instanceof ObjectType) {
1131: try {
1132: return Class
1133: .forName(((ObjectType) type).getClassName());
1134: } catch (ClassNotFoundException e) {
1135: }
1136: }
1137: throw new IllegalArgumentException(type.toString());
1138: }
1139:
1140: public QueryOrdering[] getOrdering() {
1141: return null;
1142: }
1143:
1144: }
|