KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > flow > IfThenElseBlock


1 /* IfThenElseBlock Copyright (C) 1998-2002 Jochen Hoenicke.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU Lesser General Public License as published by
5  * the Free Software Foundation; either version 2, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; see the file COPYING.LESSER. If not, write to
15  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * $Id: IfThenElseBlock.java.in,v 4.3.2.1 2002/05/28 17:34:09 hoenicke Exp $
18  */

19
20 package jode.flow;
21 import jode.decompiler.LocalInfo;
22 import jode.decompiler.TabbedPrintWriter;
23 import jode.expr.Expression;
24 import jode.type.Type;
25 import jode.util.SimpleSet;
26
27 import java.util.Set JavaDoc;
28
29 /**
30  * An IfThenElseBlock is the structured block representing an if
31  * instruction. The else part may be null.
32  */

33 public class IfThenElseBlock extends StructuredBlock {
34
35     /**
36      * The condition. Must be of boolean type.
37      */

38     Expression cond;
39     /**
40      * The loads that are on the stack before cond is executed.
41      */

42     VariableStack condStack;
43     
44
45     /**
46      * The then part. This is always a valid block and not null
47      */

48     StructuredBlock thenBlock;
49
50     /**
51      * The else part, may be null, and mustn't be the then part.
52      */

53     StructuredBlock elseBlock;
54
55     /**
56      * Creates a new if then else block. The method setThenBlock must
57      * be called shortly after the creation.
58      */

59     public IfThenElseBlock(Expression cond) {
60         this.cond = cond;
61     }
62
63     /**
64      * Sets the then block.
65      * @param thenBlock the then block, must be non null.
66      */

67     public void setThenBlock(StructuredBlock thenBlock) {
68         this.thenBlock = thenBlock;
69         thenBlock.outer = this;
70         thenBlock.setFlowBlock(flowBlock);
71     }
72
73     /**
74      * Sets the else block.
75      * @param elseBlock the else block
76      */

77     public void setElseBlock(StructuredBlock elseBlock) {
78         this.elseBlock = elseBlock;
79         elseBlock.outer = this;
80         elseBlock.setFlowBlock(flowBlock);
81     }
82     
83     /* The implementation of getNext[Flow]Block is the standard
84      * implementation */

85
86     /**
87      * Replaces the given sub block with a new block.
88      * @param oldBlock the old sub block.
89      * @param newBlock the new sub block.
90      * @return false, if oldBlock wasn't a direct sub block.
91      */

92     public boolean replaceSubBlock(StructuredBlock oldBlock,
93                             StructuredBlock newBlock) {
94         if (thenBlock == oldBlock)
95             thenBlock = newBlock;
96         else if (elseBlock == oldBlock)
97             elseBlock = newBlock;
98         else
99             return false;
100         return true;
101     }
102
103     /**
104      * This does take the instr into account and modifies stack
105      * accordingly. It then calls super.mapStackToLocal.
106      * @param stack the stack before the instruction is called
107      * @return stack the stack afterwards.
108      */

109     public VariableStack mapStackToLocal(VariableStack stack) {
110     VariableStack newStack;
111     int params = cond.getFreeOperandCount();
112     if (params > 0) {
113         condStack = stack.peek(params);
114         newStack = stack.pop(params);
115     } else
116         newStack = stack;
117
118     VariableStack after
119         = VariableStack.merge(thenBlock.mapStackToLocal(newStack),
120                   elseBlock == null ? newStack
121                   : elseBlock.mapStackToLocal(newStack));
122     if (jump != null) {
123         jump.stackMap = after;
124         return null;
125     }
126     return after;
127     }
128     
129     public void removePush() {
130     if (condStack != null)
131         cond = condStack.mergeIntoExpression(cond);
132         thenBlock.removePush();
133     if (elseBlock != null)
134         elseBlock.removePush();
135     }
136
137     public Set getDeclarables() {
138     Set used = new SimpleSet();
139     cond.fillDeclarables(used);
140     return used;
141     }
142
143     /**
144      * Make the declarations, i.e. initialize the declare variable
145      * to correct values. This will declare every variable that
146      * is marked as used, but not done.<br>
147      *
148      * This will now also combine locals, that use the same slot, have
149      * compatible types and are declared in the same block. <br>
150      *
151      * @param done The set of the already declare variables.
152      */

153     public void makeDeclaration(Set done) {
154     cond.makeDeclaration(done);
155     super.makeDeclaration(done);
156     }
157
158     /**
159      * Print the source code for this structured block. This may be
160      * called only once, because it remembers which local variables
161      * were declared.
162      */

163     public void dumpInstruction(TabbedPrintWriter writer)
164         throws java.io.IOException JavaDoc
165     {
166         boolean needBrace = thenBlock.needsBraces();
167         writer.print("if (");
168     cond.dumpExpression(writer.EXPL_PAREN, writer);
169     writer.print(")");
170     if (needBrace)
171         writer.openBrace();
172     else
173         writer.println();
174         writer.tab();
175         thenBlock.dumpSource(writer);
176         writer.untab();
177         if (elseBlock != null) {
178         if (needBrace)
179         writer.closeBraceContinue();
180
181             if (elseBlock instanceof IfThenElseBlock
182                 && (elseBlock.declare == null
183                     || elseBlock.declare.isEmpty())) {
184                 needBrace = false;
185                 writer.print("else ");
186                 elseBlock.dumpSource(writer);
187             } else {
188                 needBrace = elseBlock.needsBraces();
189                 writer.print("else");
190         if (needBrace)
191             writer.openBrace();
192         else
193             writer.println();
194                 writer.tab();
195                 elseBlock.dumpSource(writer);
196                 writer.untab();
197             }
198         }
199         if (needBrace)
200         writer.closeBrace();
201     }
202
203     /**
204      * Returns all sub block of this structured block.
205      */

206     public StructuredBlock[] getSubBlocks() {
207         return (elseBlock == null)
208             ? new StructuredBlock[] { thenBlock }
209             : new StructuredBlock[] { thenBlock, elseBlock };
210     }
211
212     /**
213      * Determines if there is a sub block, that flows through to the end
214      * of this block. If this returns true, you know that jump is null.
215      * @return true, if the jump may be safely changed.
216      */

217     public boolean jumpMayBeChanged() {
218         return (thenBlock.jump != null || thenBlock.jumpMayBeChanged())
219             && elseBlock != null
220             && (elseBlock.jump != null || elseBlock.jumpMayBeChanged());
221     }
222
223     public void simplify() {
224     cond = cond.simplify();
225     super.simplify();
226     }
227
228     public boolean doTransformations() {
229         StructuredBlock last = flowBlock.lastModified;
230         return CreateCheckNull.transformJikes(this, last)
231         || CreateClassField.transform(this,last);
232     }
233 }
234
Popular Tags