예제 #1
0
  @Override
  public <F extends CallableDescriptor> void check(
      @NotNull ResolvedCall<F> resolvedCall, @NotNull BasicCallResolutionContext context) {
    JetExpression expression = context.call.getCalleeExpression();
    if (expression == null) {
      return;
    }

    // checking that only invoke or inlinable extension called on function parameter
    CallableDescriptor targetDescriptor = resolvedCall.getResultingDescriptor();
    checkCallWithReceiver(
        context, targetDescriptor, resolvedCall.getDispatchReceiver(), expression);
    checkCallWithReceiver(
        context, targetDescriptor, resolvedCall.getExtensionReceiver(), expression);

    if (inlinableParameters.contains(targetDescriptor)) {
      if (!isInsideCall(expression)) {
        context.trace.report(Errors.USAGE_IS_NOT_INLINABLE.on(expression, expression, descriptor));
      }
    }

    for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry :
        resolvedCall.getValueArguments().entrySet()) {
      ResolvedValueArgument value = entry.getValue();
      ValueParameterDescriptor valueDescriptor = entry.getKey();
      if (!(value instanceof DefaultValueArgument)) {
        for (ValueArgument argument : value.getArguments()) {
          checkValueParameter(context, targetDescriptor, argument, valueDescriptor);
        }
      }
    }

    checkVisibility(targetDescriptor, expression, context);
    checkRecursion(context, targetDescriptor, expression);
  }
예제 #2
0
  private void checkValueParameter(
      @NotNull BasicCallResolutionContext context,
      @NotNull CallableDescriptor targetDescriptor,
      @NotNull ValueArgument targetArgument,
      @NotNull ValueParameterDescriptor targetParameterDescriptor) {
    JetExpression argumentExpression = targetArgument.getArgumentExpression();
    if (argumentExpression == null) {
      return;
    }
    CallableDescriptor argumentCallee = getCalleeDescriptor(context, argumentExpression, false);

    if (argumentCallee != null && inlinableParameters.contains(argumentCallee)) {
      boolean isTargetInlineFunction =
          targetDescriptor instanceof SimpleFunctionDescriptor
              && ((SimpleFunctionDescriptor) targetDescriptor).getInlineStrategy().isInline();

      if (!isTargetInlineFunction || !isInlinableParameter(targetParameterDescriptor)) {
        context.trace.report(
            Errors.USAGE_IS_NOT_INLINABLE.on(argumentExpression, argumentExpression, descriptor));
      } else {
        if (allowsNonLocalReturns(argumentCallee)
            && !allowsNonLocalReturns(targetParameterDescriptor)) {
          context.trace.report(
              Errors.NON_LOCAL_RETURN_NOT_ALLOWED.on(
                  argumentExpression, argumentExpression, argumentCallee, descriptor));
        } else {
          checkNonLocalReturn(context, argumentCallee, argumentExpression);
        }
      }
    }
  }
예제 #3
0
 private void checkLambdaInvokeOrExtensionCall(
     @NotNull BasicCallResolutionContext context,
     @NotNull CallableDescriptor lambdaDescriptor,
     @NotNull CallableDescriptor callDescriptor,
     @NotNull JetExpression receiverExpresssion) {
   boolean inlinableCall = isInvokeOrInlineExtension(callDescriptor);
   if (!inlinableCall) {
     context.trace.report(
         Errors.USAGE_IS_NOT_INLINABLE.on(receiverExpresssion, receiverExpresssion, descriptor));
   } else {
     checkNonLocalReturn(context, lambdaDescriptor, receiverExpresssion);
   }
 }