public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
    if (this.expression != null) {
      flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
    }

    // compute the return sequence (running the finally blocks)
    FlowContext traversedContext = flowContext;
    int subCount = 0;
    boolean saveValueNeeded = false;
    boolean hasValueToSave =
        this.expression != null
            && this.expression.constant == Constant.NotAConstant
            && !(this.expression instanceof NullLiteral);
    do {
      SubRoutineStatement sub;
      if ((sub = traversedContext.subroutine()) != null) {
        if (this.subroutines == null) {
          this.subroutines = new SubRoutineStatement[5];
        }
        if (subCount == this.subroutines.length) {
          System.arraycopy(
              this.subroutines,
              0,
              (this.subroutines = new SubRoutineStatement[subCount * 2]),
              0,
              subCount); // grow
        }
        this.subroutines[subCount++] = sub;
        if (sub.isSubRoutineEscaping()) {
          saveValueNeeded = false;
          this.bits |= ASTNode.IsAnySubRoutineEscaping;
          break;
        }
      }
      traversedContext.recordReturnFrom(flowInfo.unconditionalInits());

      if (traversedContext instanceof InsideSubRoutineFlowContext) {
        ASTNode node = traversedContext.associatedNode;
        if (node instanceof TryStatement) {
          TryStatement tryStatement = (TryStatement) node;
          flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits
          if (hasValueToSave) {
            if (this.saveValueVariable == null) { // closest subroutine secret variable is used
              prepareSaveValueLocation(tryStatement);
            }
            saveValueNeeded = true;
          }
        }
      } else if (traversedContext instanceof InitializationFlowContext) {
        currentScope.problemReporter().cannotReturnOutsideFunction(this);
        return FlowInfo.DEAD_END;
      }
    } while ((traversedContext = traversedContext.parent) != null);

    // resize subroutines
    if ((this.subroutines != null) && (subCount != this.subroutines.length)) {
      System.arraycopy(
          this.subroutines, 0, (this.subroutines = new SubRoutineStatement[subCount]), 0, subCount);
    }

    // secret local variable for return value (note that this can only occur in a real method)
    if (saveValueNeeded) {
      if (this.saveValueVariable != null) {
        this.saveValueVariable.useFlag = LocalVariableBinding.USED;
      }
    } else {
      this.saveValueVariable = null;
      if (this.expression != null && this.expression.resolvedType == TypeBinding.BOOLEAN) {
        this.expression.bits |= ASTNode.IsReturnedValue;
      }
    }
    return FlowInfo.DEAD_END;
  }
Esempio n. 2
0
 public void exitAnyExceptionHandler() {
   if (this.subRoutineStartLabel == null) return;
   super.exitAnyExceptionHandler();
 }