001: /* IfThenElseOperator Copyright (C) 1998-2002 Jochen Hoenicke.
002: *
003: * This program is free software; you can redistribute it and/or modify
004: * it under the terms of the GNU Lesser General Public License as published by
005: * the Free Software Foundation; either version 2, or (at your option)
006: * any later version.
007: *
008: * This program is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
011: * GNU General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public License
014: * along with this program; see the file COPYING.LESSER. If not, write to
015: * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
016: *
017: * $Id: IfThenElseOperator.java,v 2.17.2.3 2002/05/28 17:34:06 hoenicke Exp $
018: */
019:
020: package jode.expr;
021:
022: import jode.type.Type;
023: import jode.decompiler.FieldAnalyzer;
024: import jode.decompiler.TabbedPrintWriter;
025:
026: public class IfThenElseOperator extends Operator {
027: public IfThenElseOperator(Type type) {
028: super (type, 0);
029: initOperands(3);
030: }
031:
032: public int getPriority() {
033: return 200;
034: }
035:
036: public void updateSubTypes() {
037: subExpressions[0].setType(Type.tBoolean);
038: subExpressions[1].setType(Type.tSubType(type));
039: subExpressions[2].setType(Type.tSubType(type));
040: }
041:
042: public void updateType() {
043: Type commonType = Type.tSuperType(subExpressions[1].getType())
044: .intersection(
045: Type.tSuperType(subExpressions[2].getType()));
046: updateParentType(commonType);
047: }
048:
049: public Expression simplify() {
050: if (getType().isOfType(Type.tBoolean)) {
051: if (subExpressions[1] instanceof ConstOperator
052: && subExpressions[2] instanceof ConstOperator) {
053: ConstOperator c1 = (ConstOperator) subExpressions[1];
054: ConstOperator c2 = (ConstOperator) subExpressions[2];
055: if (c1.getValue().equals(new Integer(1))
056: && c2.getValue().equals(new Integer(0)))
057: return subExpressions[0].simplify();
058: if (c2.getValue().equals(new Integer(1))
059: && c1.getValue().equals(new Integer(0)))
060: return subExpressions[0].negate().simplify();
061: }
062: }
063: if (subExpressions[0] instanceof CompareUnaryOperator
064: && ((((CompareUnaryOperator) subExpressions[0])
065: .getOperatorIndex() & ~1) == Operator.COMPARE_OP)) {
066: CompareUnaryOperator cmp = (CompareUnaryOperator) subExpressions[0];
067: int cmpType = cmp.getOperatorIndex() & 1;
068: if ((subExpressions[2 - cmpType] instanceof GetFieldOperator)
069: && (subExpressions[1 + cmpType] instanceof StoreInstruction)) {
070: // Check for
071: // class$classname != null ? class$classname :
072: // (class$classname = class$("classname"))
073: // and replace with
074: // classname.class
075: GetFieldOperator get = (GetFieldOperator) subExpressions[2 - cmpType];
076: StoreInstruction put = (StoreInstruction) subExpressions[1 + cmpType];
077: int opIndex = cmp.getOperatorIndex();
078: FieldAnalyzer field;
079: if (put.getLValue() instanceof PutFieldOperator
080: && ((field = ((PutFieldOperator) put
081: .getLValue()).getField()) != null)
082: && field.isSynthetic()
083: && put.lvalueMatches(get)
084: && (cmp.subExpressions[0] instanceof GetFieldOperator)
085: && put
086: .lvalueMatches((GetFieldOperator) cmp.subExpressions[0])
087: && put.subExpressions[1] instanceof InvokeOperator) {
088: InvokeOperator invoke = (InvokeOperator) put.subExpressions[1];
089: if (invoke.isGetClass()
090: && invoke.subExpressions[0] instanceof ConstOperator
091: && (invoke.subExpressions[0].getType()
092: .equals(Type.tString))) {
093: String clazz = (String) ((ConstOperator) invoke.subExpressions[0])
094: .getValue();
095: if (field.setClassConstant(clazz))
096: return new ClassFieldOperator(clazz
097: .charAt(0) == '[' ? Type
098: .tType(clazz) : Type.tClass(clazz));
099: }
100: }
101: }
102: }
103: return super .simplify();
104: }
105:
106: public boolean opEquals(Operator o) {
107: return (o instanceof IfThenElseOperator);
108: }
109:
110: public void dumpExpression(TabbedPrintWriter writer)
111: throws java.io.IOException {
112: subExpressions[0].dumpExpression(writer, 201);
113: writer.breakOp();
114: writer.print(" ? ");
115: int subPriority = 0;
116: if (!subExpressions[1].getType().getHint().isOfType(
117: subExpressions[2].getType())) {
118: writer.startOp(writer.IMPL_PAREN, 2);
119: /* We need a cast here */
120: writer.print("(");
121: writer.printType(getType().getHint());
122: writer.print(") ");
123: subPriority = 700;
124: }
125: subExpressions[1].dumpExpression(writer, subPriority);
126: if (subPriority == 700)
127: writer.endOp();
128: writer.breakOp();
129: writer.print(" : ");
130: subExpressions[2].dumpExpression(writer, 200);
131: }
132: }
|