KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > flow > CaseBlock


1 /* CaseBlock 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: CaseBlock.java,v 4.15.4.2 2002/05/28 17:34:08 hoenicke Exp $
18  */

19
20 package jode.flow;
21 import jode.expr.ConstOperator;
22 import jode.type.Type;
23
24 /**
25  * This block represents a case instruction. A case instruction is a
26  * part of a switch construction and may have a subpart or not (for
27  * multiple case directly after each other.
28  *
29  * @author Jochen Hoenicke */

30 public class CaseBlock extends StructuredBlock {
31     /**
32      * The inner block that jumps to the subroutine, or null
33      * if this is a value only.
34      */

35     StructuredBlock subBlock;
36
37     /**
38      * The value of this case.
39      */

40     int value;
41
42     /**
43      * True, if this is the default case
44      */

45     boolean isDefault = false;
46
47     /**
48      * True, if the previous case falls through to this case
49      */

50     boolean isFallThrough = false;
51
52     /**
53      * True, if this is the last case in a switch
54      */

55     boolean isLastBlock = false;
56
57     public CaseBlock(int value) {
58     this.value = value;
59     subBlock = null;
60     }
61
62     public CaseBlock(int value, Jump dest) {
63     this.value = value;
64     subBlock = new EmptyBlock(dest);
65     subBlock.outer = this;
66     }
67
68     public void checkConsistent() {
69         if (!(outer instanceof SwitchBlock))
70             throw new jode.AssertError("Inconsistency");
71         super.checkConsistent();
72     }
73
74     /**
75      * Replaces the given sub block with a new block.
76      * @param oldBlock the old sub block.
77      * @param newBlock the new sub block.
78      * @return false, if oldBlock wasn't a direct sub block.
79      */

80     public boolean replaceSubBlock(StructuredBlock oldBlock,
81                    StructuredBlock newBlock) {
82         if (subBlock == oldBlock)
83             subBlock = newBlock;
84         else
85             return false;
86         return true;
87     }
88
89     /**
90      * Tells if we want braces around this case. We only need braces
91      * if there is a declaration on the first level (list of
92      * sequential blocks).
93      */

94     protected boolean wantBraces() {
95     StructuredBlock block = subBlock;
96     if (block == null)
97         return false;
98     for (;;) {
99         if (block.declare != null && !block.declare.isEmpty()) {
100         /* A declaration; we need braces. */
101         return true;
102         }
103
104         if (!(block instanceof SequentialBlock)) {
105         /* This was the last block on the first level.
106          * Finally check if that is an declaring InstructionBlock.
107          */

108         if (block instanceof InstructionBlock
109             && ((InstructionBlock)block).isDeclaration)
110             return true;
111
112
113         /* If we get here, we need no braces.
114          */

115         return false;
116         }
117         
118         StructuredBlock[] subBlocks = block.getSubBlocks();
119         if (subBlocks[0] instanceof InstructionBlock
120         && ((InstructionBlock)subBlocks[0]).isDeclaration) {
121         /* An instruction block declares on the same level as
122          * the surrounding SequentialBlock.
123          */

124         return true;
125         }
126
127         /* continue with the second sub block. */
128         block = subBlocks[1];
129     }
130     }
131
132     /**
133      * Returns all sub block of this structured block.
134      */

135     public StructuredBlock[] getSubBlocks() {
136         return (subBlock != null)
137             ? new StructuredBlock[] { subBlock }
138             : new StructuredBlock[0];
139     }
140
141     public void dumpInstruction(jode.decompiler.TabbedPrintWriter writer)
142         throws java.io.IOException JavaDoc
143     {
144     if (isDefault) {
145         /* If this is the default case and does nothing, we can
146          * skip this.
147          * We have to make sure, that nothing flows into the default
148          * block though. XXX remove if sure.
149          */

150         if (isLastBlock
151         && subBlock instanceof EmptyBlock
152         && subBlock.jump == null)
153         return;
154         if (subBlock instanceof BreakBlock
155         && ((BreakBlock) subBlock).breaksBlock == this) {
156         /* make sure that the previous block is correctly breaked */
157         if (isFallThrough) {
158             writer.tab();
159             subBlock.dumpSource(writer);
160             writer.untab();
161         }
162         return;
163         }
164         if (isFallThrough) {
165         writer.tab();
166         writer.println("/* fall through */");
167         writer.untab();
168         }
169         writer.print("default:");
170     } else {
171         if (isFallThrough) {
172         writer.tab();
173         writer.println("/* fall through */");
174         writer.untab();
175         }
176             ConstOperator constOp = new ConstOperator(new Integer JavaDoc(value));
177         Type type = ((SwitchBlock)outer).getInstruction().getType();
178         constOp.setType(type);
179             constOp.makeInitializer(type);
180         writer.print("case " + constOp.toString() + ":");
181         }
182     if (subBlock != null) {
183         boolean needBraces = wantBraces();
184         if (needBraces)
185         writer.openBrace();
186         else
187         writer.println();
188         if (subBlock != null) {
189         writer.tab();
190         subBlock.dumpSource(writer);
191         writer.untab();
192         }
193         if (needBraces)
194         writer.closeBrace();
195     } else
196         writer.println();
197     }
198
199     /**
200      * Determines if there is a sub block, that flows through to the end
201      * of this block. If this returns true, you know that jump is null.
202      * @return true, if the jump may be safely changed.
203      */

204     public boolean jumpMayBeChanged() {
205         return subBlock.jump != null || subBlock.jumpMayBeChanged();
206     }
207 }
208
Popular Tags