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)); } } }
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); } }
@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); }