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 static final UnconditionalFlowInfo DEAD_END; // Represents a dead branch status of initialization
22 	static {
23 		DEAD_END = new UnconditionalFlowInfo();
24 		DEAD_END.reachMode = UNREACHABLE;
25 	}
addInitializationsFrom(FlowInfo otherInits)26 	abstract public FlowInfo addInitializationsFrom(FlowInfo otherInits);
27 
addPotentialInitializationsFrom(FlowInfo otherInits)28 	abstract public FlowInfo addPotentialInitializationsFrom(FlowInfo otherInits);
29 
asNegatedCondition()30 	public FlowInfo asNegatedCondition() {
31 
32 		return this;
33 	}
34 
conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse)35 	public static FlowInfo conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){
36 
37 		// if (initsWhenTrue.equals(initsWhenFalse)) return initsWhenTrue; -- could optimize if #equals is defined
38 		return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse);
39 	}
40 
copy()41 	abstract public FlowInfo copy();
42 
initial(int maxFieldCount)43 	public static UnconditionalFlowInfo initial(int maxFieldCount) {
44 		UnconditionalFlowInfo info = new UnconditionalFlowInfo();
45 		info.maxFieldCount = maxFieldCount;
46 		return info;
47 	}
48 
initsWhenFalse()49 	abstract public FlowInfo initsWhenFalse();
50 
initsWhenTrue()51 	abstract public FlowInfo initsWhenTrue();
52 
53 	/**
54 	 * Check status of definite assignment for a field.
55 	 */
isDefinitelyAssigned(FieldBinding field)56 	 abstract public boolean isDefinitelyAssigned(FieldBinding field);
57 
58 	/**
59 	 * Check status of definite assignment for a local.
60 	 */
isDefinitelyAssigned(LocalVariableBinding local)61 	public abstract boolean isDefinitelyAssigned(LocalVariableBinding local);
62 
63 	//abstract public int reachMode();
64 
65 	/**
66 	 * Check status of potential assignment for a field.
67 	 */
isPotentiallyAssigned(FieldBinding field)68 	 abstract public boolean isPotentiallyAssigned(FieldBinding field);
69 
70 	/**
71 	 * Check status of potential assignment for a local variable.
72 	 */
73 
isPotentiallyAssigned(LocalVariableBinding field)74 	 abstract public boolean isPotentiallyAssigned(LocalVariableBinding field);
75 
isReachable()76 	abstract public boolean isReachable();
77 
78 	/**
79 	 * Record a field got definitely assigned.
80 	 */
markAsDefinitelyAssigned(FieldBinding field)81 	abstract public void markAsDefinitelyAssigned(FieldBinding field);
82 
83 	/**
84 	 * Record a local got definitely assigned.
85 	 */
markAsDefinitelyAssigned(LocalVariableBinding local)86 	abstract public void markAsDefinitelyAssigned(LocalVariableBinding local);
87 
88 	/**
89 	 * Clear the initialization info for a field
90 	 */
markAsDefinitelyNotAssigned(FieldBinding field)91 	abstract public void markAsDefinitelyNotAssigned(FieldBinding field);
92 
93 	/**
94 	 * Clear the initialization info for a local variable
95 	 */
markAsDefinitelyNotAssigned(LocalVariableBinding local)96 	abstract public void markAsDefinitelyNotAssigned(LocalVariableBinding local);
97 
98 	/**
99 	 * Merge branches using optimized boolean conditions
100 	 */
mergedOptimizedBranches(FlowInfo initsWhenTrue, boolean isOptimizedTrue, FlowInfo initsWhenFalse, boolean isOptimizedFalse, boolean allowFakeDeadBranch)101 	public static FlowInfo mergedOptimizedBranches(FlowInfo initsWhenTrue, boolean isOptimizedTrue, FlowInfo initsWhenFalse, boolean isOptimizedFalse, boolean allowFakeDeadBranch) {
102 		FlowInfo mergedInfo;
103 		if (isOptimizedTrue){
104 			if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
105 				mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE);
106 			} else {
107 				mergedInfo = initsWhenTrue.addPotentialInitializationsFrom(initsWhenFalse);
108 			}
109 
110 		} else if (isOptimizedFalse) {
111 			if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
112 				mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE);
113 			} else {
114 				mergedInfo = initsWhenFalse.addPotentialInitializationsFrom(initsWhenTrue);
115 			}
116 
117 		} else {
118 			mergedInfo = initsWhenTrue.unconditionalInits().mergedWith(initsWhenFalse.unconditionalInits());
119 		}
120 		return mergedInfo;
121 	}
122 
reachMode()123 	abstract public int reachMode();
124 
setReachMode(int reachMode)125 	abstract public FlowInfo setReachMode(int reachMode);
126 
127 	/**
128 	 * Returns the receiver updated in the following way: <ul>
129 	 * <li> intersection of definitely assigned variables,
130 	 * <li> union of potentially assigned variables.
131 	 * </ul>
132 	 */
mergedWith(UnconditionalFlowInfo otherInits)133 	abstract public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits);
134 
toString()135 	public String toString(){
136 
137 		if (this == DEAD_END){
138 			return "FlowInfo.DEAD_END"; //$NON-NLS-1$
139 		}
140 		return super.toString();
141 	}
142 
unconditionalInits()143 	abstract public UnconditionalFlowInfo unconditionalInits();
144 }
145