package org.eclipse.jdt.internal.compiler.flow;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.Reference;
import org.eclipse.jdt.internal.compiler.codegen.Label;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
Reference finalAssignments[];
VariableBinding finalVariables[];
int assignCount = 0;
+
+ Expression[] nullReferences;
+ int[] nullStatus;
+ int nullCount;
+
Scope associatedScope;
public LoopingFlowContext(
this.associatedScope = associatedScope;
}
- public void complainOnFinalAssignmentsInLoop(
- BlockScope scope,
- FlowInfo flowInfo) {
+ public void complainOnDeferredChecks(BlockScope scope, FlowInfo flowInfo) {
+
+ // complain on final assignments in loops
for (int i = 0; i < assignCount; i++) {
VariableBinding variable = finalVariables[i];
if (variable == null) continue;
}
}
}
+ // check inconsistent null checks
+ for (int i = 0; i < nullCount; i++) {
+ Expression expression = nullReferences[i];
+ if (expression == null) continue;
+ // final local variable
+ LocalVariableBinding local = expression.localVariableBinding();
+ switch (nullStatus[i]) {
+ case FlowInfo.NULL :
+ if (flowInfo.isDefinitelyNull(local)) {
+ nullReferences[i] = null;
+ this.parent.recordUsingNullReference(scope, local, expression, nullStatus[i], flowInfo);
+ }
+ break;
+ case FlowInfo.NON_NULL :
+ if (flowInfo.isDefinitelyNonNull(local)) {
+ nullReferences[i] = null;
+ this.parent.recordUsingNullReference(scope, local, expression, nullStatus[i], flowInfo);
+ }
+ break;
+ }
+ }
}
public Label continueLabel() {
public String individualToString() {
StringBuffer buffer = new StringBuffer("Looping flow context"); //$NON-NLS-1$
- buffer.append("[initsOnBreak -").append(initsOnBreak.toString()).append(']'); //$NON-NLS-1$
- buffer.append("[initsOnContinue -").append(initsOnContinue.toString()).append(']'); //$NON-NLS-1$
+ buffer.append("[initsOnBreak - ").append(initsOnBreak.toString()).append(']'); //$NON-NLS-1$
+ buffer.append("[initsOnContinue - ").append(initsOnContinue.toString()).append(']'); //$NON-NLS-1$
+ buffer.append("[finalAssignments count - ").append(assignCount).append(']'); //$NON-NLS-1$
+ buffer.append("[nullReferences count - ").append(nullCount).append(']'); //$NON-NLS-1$
return buffer.toString();
}
}
}
- boolean recordFinalAssignment(
+ protected boolean recordFinalAssignment(
VariableBinding binding,
Reference finalAssignment) {
return true;
}
+ protected boolean recordNullReference(Expression expression, int status) {
+ if (nullCount == 0) {
+ nullReferences = new Expression[5];
+ nullStatus = new int[5];
+ } else {
+ if (nullCount == nullReferences.length) {
+ System.arraycopy(nullReferences, 0, nullReferences = new Expression[nullCount * 2], 0, nullCount);
+ System.arraycopy(nullStatus, 0, nullStatus = new int[nullCount * 2], 0, nullCount);
+ }
+ }
+ nullReferences[nullCount] = expression;
+ nullStatus[nullCount++] = status;
+ return true;
+ }
+
void removeFinalAssignmentIfAny(Reference reference) {
for (int i = 0; i < assignCount; i++) {
if (finalAssignments[i] == reference) {