public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { this.preAssertInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo); Constant cst = this.assertExpression.optimizedBooleanConstant(); if ((this.assertExpression.implicitConversion & TypeIds.UNBOXING) != 0) { this.assertExpression.checkNPE(currentScope, flowContext, flowInfo); } boolean isOptimizedTrueAssertion = cst != Constant.NotAConstant && cst.booleanValue() == true; boolean isOptimizedFalseAssertion = cst != Constant.NotAConstant && cst.booleanValue() == false; flowContext.tagBits |= FlowContext.HIDE_NULL_COMPARISON_WARNING; FlowInfo conditionFlowInfo = this.assertExpression.analyseCode(currentScope, flowContext, flowInfo.copy()); flowContext.extendTimeToLiveForNullCheckedField(1); // survive this assert as a Statement flowContext.tagBits &= ~FlowContext.HIDE_NULL_COMPARISON_WARNING; UnconditionalFlowInfo assertWhenTrueInfo = conditionFlowInfo.initsWhenTrue().unconditionalInits(); FlowInfo assertInfo = conditionFlowInfo.initsWhenFalse(); if (isOptimizedTrueAssertion) { assertInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD); } if (this.exceptionArgument != null) { // only gets evaluated when escaping - results are not taken into account FlowInfo exceptionInfo = this.exceptionArgument.analyseCode(currentScope, flowContext, assertInfo.copy()); if (isOptimizedTrueAssertion) { currentScope.problemReporter().fakeReachable(this.exceptionArgument); } else { flowContext.checkExceptionHandlers( currentScope.getJavaLangAssertionError(), this, exceptionInfo, currentScope); } } if (!isOptimizedTrueAssertion) { // add the assert support in the clinit manageSyntheticAccessIfNecessary(currentScope, flowInfo); } // account for potential AssertionError: flowContext.recordAbruptExit(); if (isOptimizedFalseAssertion) { return flowInfo; // if assertions are enabled, the following code will be unreachable // change this if we need to carry null analysis results of the assert // expression downstream } else { CompilerOptions compilerOptions = currentScope.compilerOptions(); if (!compilerOptions.includeNullInfoFromAsserts) { // keep just the initializations info, don't include assert's null info // merge initialization info's and then add back the null info from flowInfo to // make sure that the empty null info of assertInfo doesnt change flowInfo's null info. return ((flowInfo.nullInfoLessUnconditionalCopy()) .mergedWith(assertInfo.nullInfoLessUnconditionalCopy())) .addNullInfoFrom(flowInfo); } return flowInfo .mergedWith(assertInfo.nullInfoLessUnconditionalCopy()) .addInitializationsFrom(assertWhenTrueInfo.discardInitializationInfo()); // keep the merge from the initial code for the definite assignment // analysis, tweak the null part to influence nulls downstream } }