blob: 21d5f14bc8e5618563b7fceabbc15f6ddfdd08e0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.flow;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
public abstract class FlowInfo {
public final static int REACHABLE = 0;
public final static int UNREACHABLE = 1;
public final static int UNKNOWN = 0;
public final static int NULL = 1;
public final static int NON_NULL = -1;
public static final UnconditionalFlowInfo DEAD_END; // Represents a dead branch status of initialization
static {
DEAD_END = new UnconditionalFlowInfo();
DEAD_END.reachMode = UNREACHABLE;
}
abstract public FlowInfo addInitializationsFrom(FlowInfo otherInits);
abstract public FlowInfo addPotentialInitializationsFrom(FlowInfo otherInits);
public FlowInfo asNegatedCondition() {
return this;
}
public static FlowInfo conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){
// if (initsWhenTrue.equals(initsWhenFalse)) return initsWhenTrue; -- could optimize if #equals is defined
return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse);
}
abstract public FlowInfo copy();
public static UnconditionalFlowInfo initial(int maxFieldCount) {
UnconditionalFlowInfo info = new UnconditionalFlowInfo();
info.maxFieldCount = maxFieldCount;
return info;
}
abstract public FlowInfo initsWhenFalse();
abstract public FlowInfo initsWhenTrue();
/**
* Check status of definite assignment for a field.
*/
abstract public boolean isDefinitelyAssigned(FieldBinding field);
/**
* Check status of definite assignment for a local.
*/
public abstract boolean isDefinitelyAssigned(LocalVariableBinding local);
/**
* Check status of definite null assignment for a field.
*/
abstract public boolean isDefinitelyNonNull(FieldBinding field);
/**
* Check status of definite null assignment for a local.
*/
public abstract boolean isDefinitelyNonNull(LocalVariableBinding local);
/**
* Check status of definite null assignment for a field.
*/
abstract public boolean isDefinitelyNull(FieldBinding field);
/**
* Check status of definite null assignment for a local.
*/
public abstract boolean isDefinitelyNull(LocalVariableBinding local);
/**
* Check status of potential assignment for a field.
*/
abstract public boolean isPotentiallyAssigned(FieldBinding field);
/**
* Check status of potential assignment for a local variable.
*/
abstract public boolean isPotentiallyAssigned(LocalVariableBinding field);
abstract public boolean isReachable();
/**
* Record a field got definitely assigned.
*/
abstract public void markAsDefinitelyAssigned(FieldBinding field);
/**
* Record a local got definitely assigned to a non-null value.
*/
abstract public void markAsDefinitelyNonNull(LocalVariableBinding local);
/**
* Record a field got definitely assigned to a non-null value.
*/
abstract public void markAsDefinitelyNonNull(FieldBinding field);
/**
* Record a local got definitely assigned to null.
*/
abstract public void markAsDefinitelyNull(LocalVariableBinding local);
/**
* Record a field got definitely assigned.
*/
abstract public void markAsDefinitelyNull(FieldBinding field);
/**
* Record a local got definitely assigned.
*/
abstract public void markAsDefinitelyAssigned(LocalVariableBinding local);
/**
* Clear the initialization info for a field
*/
abstract public void markAsDefinitelyNotAssigned(FieldBinding field);
/**
* Clear the initialization info for a local variable
*/
abstract public void markAsDefinitelyNotAssigned(LocalVariableBinding local);
/**
* Merge branches using optimized boolean conditions
*/
public static FlowInfo mergedOptimizedBranches(FlowInfo initsWhenTrue, boolean isOptimizedTrue, FlowInfo initsWhenFalse, boolean isOptimizedFalse, boolean allowFakeDeadBranch) {
FlowInfo mergedInfo;
if (isOptimizedTrue){
if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE);
} else {
mergedInfo = initsWhenTrue.addPotentialInitializationsFrom(initsWhenFalse);
}
} else if (isOptimizedFalse) {
if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE);
} else {
mergedInfo = initsWhenFalse.addPotentialInitializationsFrom(initsWhenTrue);
}
} else {
mergedInfo = initsWhenTrue.unconditionalInits().mergedWith(initsWhenFalse.unconditionalInits());
}
return mergedInfo;
}
abstract public int reachMode();
abstract public FlowInfo setReachMode(int reachMode);
/**
* Returns the receiver updated in the following way: <ul>
* <li> intersection of definitely assigned variables,
* <li> union of potentially assigned variables.
* </ul>
*/
abstract public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits);
public String toString(){
if (this == DEAD_END){
return "FlowInfo.DEAD_END"; //$NON-NLS-1$
}
return super.toString();
}
abstract public UnconditionalFlowInfo unconditionalInits();
}