diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/InlineCallResolverExtension.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/InlineCallResolverExtension.java index 9d30f2a8a5b..673be10562e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/InlineCallResolverExtension.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/InlineCallResolverExtension.java @@ -25,9 +25,7 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext; -import org.jetbrains.jet.lang.resolve.calls.model.ExpressionValueArgument; -import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; -import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument; +import org.jetbrains.jet.lang.resolve.calls.model.*; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; @@ -55,7 +53,6 @@ public class InlineCallResolverExtension implements CallResolverExtension { ValueParameterDescriptor next = iterator.next(); JetType type = next.getType(); if (KotlinBuiltIns.getInstance().isExactFunctionOrExtensionFunctionType(type)) { - //TODO check annotations if (!InlineUtil.hasNoinlineAnnotation(next)) { inlinableParameters.add(next); } @@ -97,21 +94,28 @@ public class InlineCallResolverExtension implements CallResolverExtension { for (Map.Entry entry : resolvedCall.getValueArguments().entrySet()) { ResolvedValueArgument value = entry.getValue(); - if (value instanceof ExpressionValueArgument) { - JetExpression jetExpression = ((ExpressionValueArgument) value).getValueArgument().getArgumentExpression(); - - DeclarationDescriptor varDescriptor = getDescriptor(context, jetExpression); - - if (varDescriptor != null && inlinableParameters.contains(varDescriptor)) { - checkFunctionCall(context, targetDescriptor, jetExpression); + if (!(value instanceof DefaultValueArgument)) { + for (ValueArgument argument : value.getArguments()) { + checkValueParameter(context, targetDescriptor, argument, value instanceof VarargValueArgument); } } - //TODO default and vararg } checkVisibility(targetDescriptor, expression, context); } + private void checkValueParameter(BasicCallResolutionContext context, CallableDescriptor targetDescriptor, ValueArgument argument, boolean isVararg) { + JetExpression jetExpression = argument.getArgumentExpression(); + if (jetExpression == null) { + return; + } + CallableDescriptor varDescriptor = getDescriptor(context, jetExpression); + + if (varDescriptor != null && inlinableParameters.contains(varDescriptor)) { + checkFunctionCall(context, targetDescriptor, jetExpression, isVararg); + } + } + private void checkCallWithReceiver( @NotNull BasicCallResolutionContext context, @NotNull CallableDescriptor targetDescriptor, @@ -159,7 +163,17 @@ public class InlineCallResolverExtension implements CallResolverExtension { CallableDescriptor targetDescriptor, JetExpression receiverExpresssion ) { - if (!isInvokeOrInlineExtension(targetDescriptor)) { + checkFunctionCall(context, targetDescriptor, receiverExpresssion, false); + } + + private void checkFunctionCall( + BasicCallResolutionContext context, + CallableDescriptor targetDescriptor, + JetExpression receiverExpresssion, + boolean isVararg + ) { + boolean inlineCall = isInvokeOrInlineExtension(targetDescriptor); + if (!inlineCall || isVararg) { context.trace.report(Errors.USAGE_IS_NOT_INLINABLE.on(receiverExpresssion, receiverExpresssion, descriptor)); } } diff --git a/compiler/testData/diagnostics/tests/inline/vararg.kt b/compiler/testData/diagnostics/tests/inline/vararg.kt new file mode 100644 index 00000000000..014b20f1635 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inline/vararg.kt @@ -0,0 +1,16 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE + +inline fun inlineFun(s: (p: Int) -> Unit, noinline b: (p: Int) -> Unit) { + subInline(s, b) + subNoInline(s, b) +} + +inline fun Function1.inlineExt(s: (p: Int) -> Unit, noinline b: (p: Int) -> Unit) { + subInline(this, s, b) + subNoInline(this, s, b) +} + + +inline fun subInline(vararg s: (p: Int) -> Unit) {} + +fun subNoInline(vararg s: (p: Int) -> Unit) {} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index ee7f3801aa5..c13c400eb2c 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -3797,6 +3797,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/inline/unsupportedConstruction.kt"); } + @TestMetadata("vararg.kt") + public void testVararg() throws Exception { + doTest("compiler/testData/diagnostics/tests/inline/vararg.kt"); + } + @TestMetadata("wrongUsage.kt") public void testWrongUsage() throws Exception { doTest("compiler/testData/diagnostics/tests/inline/wrongUsage.kt");