added -J option to preserve unmodified files in preexisting jarfile
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / flow / FlowInfo.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.flow;
12
13 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
14 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
15
16 public abstract class FlowInfo {
17
18         public final static int REACHABLE = 0;
19         public final static int UNREACHABLE = 1;
20         
21         public final static int UNKNOWN = 0;
22         public final static int NULL = 1;
23         public final static int NON_NULL = -1;
24         
25         public static final UnconditionalFlowInfo DEAD_END; // Represents a dead branch status of initialization
26         static {
27                 DEAD_END = new UnconditionalFlowInfo();
28                 DEAD_END.reachMode = UNREACHABLE;
29         }
30         abstract public FlowInfo addInitializationsFrom(FlowInfo otherInits);
31
32         abstract public FlowInfo addPotentialInitializationsFrom(FlowInfo otherInits);
33
34         public FlowInfo asNegatedCondition() {
35
36                 return this;
37         }
38
39         public static FlowInfo conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){
40
41                 // if (initsWhenTrue.equals(initsWhenFalse)) return initsWhenTrue; -- could optimize if #equals is defined
42                 return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse);
43         }
44
45         abstract public FlowInfo copy();
46
47         public static UnconditionalFlowInfo initial(int maxFieldCount) {
48                 UnconditionalFlowInfo info = new UnconditionalFlowInfo();
49                 info.maxFieldCount = maxFieldCount;
50                 return info;
51         }
52
53         abstract public FlowInfo initsWhenFalse();
54
55         abstract public FlowInfo initsWhenTrue();
56
57         /**
58          * Check status of definite assignment for a field.
59          */
60          abstract public boolean isDefinitelyAssigned(FieldBinding field);   
61
62         /**
63          * Check status of definite assignment for a local.
64          */
65         public abstract boolean isDefinitelyAssigned(LocalVariableBinding local);
66
67         /**
68          * Check status of definite null assignment for a field.
69          */
70          abstract public boolean isDefinitelyNonNull(FieldBinding field);   
71
72         /**
73          * Check status of definite null assignment for a local.
74          */
75         public abstract boolean isDefinitelyNonNull(LocalVariableBinding local);
76
77         /**
78          * Check status of definite null assignment for a field.
79          */
80          abstract public boolean isDefinitelyNull(FieldBinding field);   
81
82         /**
83          * Check status of definite null assignment for a local.
84          */
85         public abstract boolean isDefinitelyNull(LocalVariableBinding local);
86
87         /**
88          * Check status of potential assignment for a field.
89          */
90          abstract public boolean isPotentiallyAssigned(FieldBinding field);   
91
92         /**
93          * Check status of potential assignment for a local variable.
94          */
95
96          abstract public boolean isPotentiallyAssigned(LocalVariableBinding field);   
97
98         abstract public boolean isReachable();
99         
100         /**
101          * Record a field got definitely assigned.
102          */
103         abstract public void markAsDefinitelyAssigned(FieldBinding field);
104
105         /**
106          * Record a local got definitely assigned to a non-null value.
107          */
108         abstract public void markAsDefinitelyNonNull(LocalVariableBinding local);
109
110         /**
111          * Record a field got definitely assigned to a non-null value.
112          */
113         abstract public void markAsDefinitelyNonNull(FieldBinding field);
114
115         /**
116          * Record a local got definitely assigned to null.
117          */
118         abstract public void markAsDefinitelyNull(LocalVariableBinding local);
119
120         /**
121          * Record a field got definitely assigned.
122          */
123         abstract public void markAsDefinitelyNull(FieldBinding field);
124
125         /**
126          * Record a local got definitely assigned.
127          */
128         abstract public void markAsDefinitelyAssigned(LocalVariableBinding local);
129
130         /**
131          * Clear the initialization info for a field
132          */
133         abstract public void markAsDefinitelyNotAssigned(FieldBinding field);
134
135         /**
136          * Clear the initialization info for a local variable
137          */
138         abstract public void markAsDefinitelyNotAssigned(LocalVariableBinding local);
139
140         /**
141          * Merge branches using optimized boolean conditions
142          */
143         public static FlowInfo mergedOptimizedBranches(FlowInfo initsWhenTrue, boolean isOptimizedTrue, FlowInfo initsWhenFalse, boolean isOptimizedFalse, boolean allowFakeDeadBranch) {
144                 FlowInfo mergedInfo;
145                 if (isOptimizedTrue){
146                         if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
147                                 mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE);
148                         } else {
149                                 mergedInfo = initsWhenTrue.addPotentialInitializationsFrom(initsWhenFalse);
150                         }
151
152                 } else if (isOptimizedFalse) {
153                         if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
154                                 mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE);
155                         } else {
156                                 mergedInfo = initsWhenFalse.addPotentialInitializationsFrom(initsWhenTrue);
157                         }
158
159                 } else {
160                         mergedInfo = initsWhenTrue.unconditionalInits().mergedWith(initsWhenFalse.unconditionalInits());
161                 }
162                 return mergedInfo;
163         }
164         
165         abstract public int reachMode();
166
167         abstract public FlowInfo setReachMode(int reachMode);
168
169         /**
170          * Returns the receiver updated in the following way: <ul>
171          * <li> intersection of definitely assigned variables, 
172          * <li> union of potentially assigned variables.
173          * </ul>
174          */
175         abstract public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits);
176
177         public String toString(){
178
179                 if (this == DEAD_END){
180                         return "FlowInfo.DEAD_END"; //$NON-NLS-1$
181                 }
182                 return super.toString();
183         }
184
185         abstract public UnconditionalFlowInfo unconditionalInits();
186 }