public void resolve(BlockScope scope) {
    MethodScope methodScope = scope.methodScope();

    if (methodScope == null) {
      /* return statement outside of a method */
      scope.problemReporter().cannotReturnOutsideFunction(this);
      return;
    }

    MethodBinding methodBinding = null;
    TypeBinding methodType =
        (methodScope.referenceContext instanceof AbstractMethodDeclaration)
            ? ((methodBinding = ((AbstractMethodDeclaration) methodScope.referenceContext).binding)
                    == null
                ? null
                : methodBinding.returnType)
            : TypeBinding.ANY;
    TypeBinding expressionType;
    if (this.expression == null) {
      if (methodType != null && !methodType.isAnyType())
        scope.problemReporter().shouldReturn(methodType, this);
      return;
    }
    this.expression.setExpectedType(methodType); // needed in case of generic method invocation
    if ((expressionType = this.expression.resolveType(scope)) == null) return;
    if (methodType == null) return;

    if (methodType
        != expressionType) // must call before computeConversion() and typeMismatchError()
    scope.compilationUnitScope().recordTypeConversion(methodType, expressionType);
    if (this.expression.isConstantValueOfTypeAssignableToType(expressionType, methodType)
        || expressionType.isCompatibleWith(methodType)) {

      return;
    }
    if (methodBinding != null && !methodBinding.isConstructor())
      scope.problemReporter().typeMismatchError(expressionType, methodType, this.expression);
  }