// process the action
LoopingFlowContext loopingContext =
new LoopingFlowContext(flowContext, flowInfo, this, this.breakLabel,
this.continueLabel, this.scope);
UnconditionalFlowInfo actionInfo =
condInfo.nullInfoLessUnconditionalCopy();
actionInfo.markAsDefinitelyUnknown(elementVarBinding);
if (currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
// this currently produces an unavoidable warning against all @NonNull element vars:
int nullStatus = this.elementVariable.checkAssignmentAgainstNullAnnotation(currentScope, flowContext,
elementVarBinding, FlowInfo.UNKNOWN, this.collection, this.collectionElementType);
// TODO (stephan): once we have JSR 308 fetch nullStatus from the collection element type
// and feed the result into the above check (instead of FlowInfo.UNKNOWN)
if ((elementVarBinding.type.tagBits & TagBits.IsBaseType) == 0) {
actionInfo.markNullStatus(elementVarBinding, nullStatus);
}
}
FlowInfo exitBranch;
if (!(this.action == null || (this.action.isEmptyBlock()
&& currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3))) {
if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) {
actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalCopy();
}
// code generation can be optimized when no need to continue in the loop
exitBranch = flowInfo.unconditionalCopy().
addInitializationsFrom(condInfo.initsWhenFalse());
// TODO (maxime) no need to test when false: can optimize (same for action being unreachable above)
if ((actionInfo.tagBits & loopingContext.initsOnContinue.tagBits &
FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
this.continueLabel = null;
} else {
actionInfo = actionInfo.mergedWith(loopingContext.initsOnContinue);
loopingContext.complainOnDeferredFinalChecks(this.scope, actionInfo);
exitBranch.addPotentialInitializationsFrom(actionInfo);
}
} else {
exitBranch = condInfo.initsWhenFalse();