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