Beispiel #1
0
  private void checkValueParameter(
      @NotNull CallCheckerContext context,
      @NotNull CallableDescriptor targetDescriptor,
      @NotNull ValueArgument targetArgument,
      @NotNull ValueParameterDescriptor targetParameterDescriptor) {
    KtExpression argumentExpression = targetArgument.getArgumentExpression();
    if (argumentExpression == null) {
      return;
    }
    CallableDescriptor argumentCallee = getCalleeDescriptor(context, argumentExpression, false);

    if (argumentCallee != null && inlinableParameters.contains(argumentCallee)) {
      if (InlineUtil.isInline(targetDescriptor)
          && isInlinableParameter(targetParameterDescriptor)) {
        if (allowsNonLocalReturns(argumentCallee)
            && !allowsNonLocalReturns(targetParameterDescriptor)) {
          context
              .getTrace()
              .report(NON_LOCAL_RETURN_NOT_ALLOWED.on(argumentExpression, argumentExpression));
        } else {
          checkNonLocalReturn(context, argumentCallee, argumentExpression);
        }
      } else {
        context
            .getTrace()
            .report(USAGE_IS_NOT_INLINABLE.on(argumentExpression, argumentExpression, descriptor));
      }
    }
  }
Beispiel #2
0
 private void checkLambdaInvokeOrExtensionCall(
     @NotNull CallCheckerContext context,
     @NotNull CallableDescriptor lambdaDescriptor,
     @NotNull CallableDescriptor callDescriptor,
     @NotNull KtExpression receiverExpression) {
   boolean inlinableCall = isInvokeOrInlineExtension(callDescriptor);
   if (!inlinableCall) {
     context
         .getTrace()
         .report(USAGE_IS_NOT_INLINABLE.on(receiverExpression, receiverExpression, descriptor));
   } else {
     checkNonLocalReturn(context, lambdaDescriptor, receiverExpression);
   }
 }
Beispiel #3
0
  @Override
  public void check(
      @NotNull ResolvedCall<?> resolvedCall,
      @NotNull PsiElement reportOn,
      @NotNull CallCheckerContext context) {
    KtExpression expression = resolvedCall.getCall().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.getTrace().report(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);
        }
      }
    }

    checkVisibilityAndAccess(targetDescriptor, expression, context);
    checkRecursion(context, targetDescriptor, expression);
  }