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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.flow;
13 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
14 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
16 public abstract class FlowInfo {
18 public final static int REACHABLE = 0;
19 public final static int UNREACHABLE = 1;
21 public final static int UNKNOWN = 0;
22 public final static int NULL = 1;
23 public final static int NON_NULL = -1;
25 public static final UnconditionalFlowInfo DEAD_END; // Represents a dead branch status of initialization
27 DEAD_END = new UnconditionalFlowInfo();
28 DEAD_END.reachMode = UNREACHABLE;
30 abstract public FlowInfo addInitializationsFrom(FlowInfo otherInits);
32 abstract public FlowInfo addPotentialInitializationsFrom(FlowInfo otherInits);
34 public FlowInfo asNegatedCondition() {
39 public static FlowInfo conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){
41 // if (initsWhenTrue.equals(initsWhenFalse)) return initsWhenTrue; -- could optimize if #equals is defined
42 return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse);
45 abstract public FlowInfo copy();
47 public static UnconditionalFlowInfo initial(int maxFieldCount) {
48 UnconditionalFlowInfo info = new UnconditionalFlowInfo();
49 info.maxFieldCount = maxFieldCount;
53 abstract public FlowInfo initsWhenFalse();
55 abstract public FlowInfo initsWhenTrue();
58 * Check status of definite assignment for a field.
60 abstract public boolean isDefinitelyAssigned(FieldBinding field);
63 * Check status of definite assignment for a local.
65 public abstract boolean isDefinitelyAssigned(LocalVariableBinding local);
68 * Check status of definite null assignment for a field.
70 abstract public boolean isDefinitelyNonNull(FieldBinding field);
73 * Check status of definite null assignment for a local.
75 public abstract boolean isDefinitelyNonNull(LocalVariableBinding local);
78 * Check status of definite null assignment for a field.
80 abstract public boolean isDefinitelyNull(FieldBinding field);
83 * Check status of definite null assignment for a local.
85 public abstract boolean isDefinitelyNull(LocalVariableBinding local);
88 * Check status of potential assignment for a field.
90 abstract public boolean isPotentiallyAssigned(FieldBinding field);
93 * Check status of potential assignment for a local variable.
96 abstract public boolean isPotentiallyAssigned(LocalVariableBinding field);
98 abstract public boolean isReachable();
101 * Record a field got definitely assigned.
103 abstract public void markAsDefinitelyAssigned(FieldBinding field);
106 * Record a local got definitely assigned to a non-null value.
108 abstract public void markAsDefinitelyNonNull(LocalVariableBinding local);
111 * Record a field got definitely assigned to a non-null value.
113 abstract public void markAsDefinitelyNonNull(FieldBinding field);
116 * Record a local got definitely assigned to null.
118 abstract public void markAsDefinitelyNull(LocalVariableBinding local);
121 * Record a field got definitely assigned.
123 abstract public void markAsDefinitelyNull(FieldBinding field);
126 * Record a local got definitely assigned.
128 abstract public void markAsDefinitelyAssigned(LocalVariableBinding local);
131 * Clear the initialization info for a field
133 abstract public void markAsDefinitelyNotAssigned(FieldBinding field);
136 * Clear the initialization info for a local variable
138 abstract public void markAsDefinitelyNotAssigned(LocalVariableBinding local);
141 * Merge branches using optimized boolean conditions
143 public static FlowInfo mergedOptimizedBranches(FlowInfo initsWhenTrue, boolean isOptimizedTrue, FlowInfo initsWhenFalse, boolean isOptimizedFalse, boolean allowFakeDeadBranch) {
145 if (isOptimizedTrue){
146 if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
147 mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE);
149 mergedInfo = initsWhenTrue.addPotentialInitializationsFrom(initsWhenFalse);
152 } else if (isOptimizedFalse) {
153 if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
154 mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE);
156 mergedInfo = initsWhenFalse.addPotentialInitializationsFrom(initsWhenTrue);
160 mergedInfo = initsWhenTrue.unconditionalInits().mergedWith(initsWhenFalse.unconditionalInits());
165 abstract public int reachMode();
167 abstract public FlowInfo setReachMode(int reachMode);
170 * Returns the receiver updated in the following way: <ul>
171 * <li> intersection of definitely assigned variables,
172 * <li> union of potentially assigned variables.
175 abstract public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits);
177 public String toString(){
179 if (this == DEAD_END){
180 return "FlowInfo.DEAD_END"; //$NON-NLS-1$
182 return super.toString();
185 abstract public UnconditionalFlowInfo unconditionalInits();