diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index e64c72523cb..ad84469d387 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -819,10 +819,14 @@ public class ExpressionCodegen extends JetVisitor { } private void invokeMethodWithArguments(CallableMethod callableMethod, JetCallExpression expression) { + invokeMethodWithArguments(callableMethod, expression, false); + } + + private void invokeMethodWithArguments(CallableMethod callableMethod, JetCallExpression expression, final boolean haveReceiver) { if (callableMethod.isOwnerFromCall()) { setOwnerFromCall(callableMethod, expression); } - if (callableMethod.needsReceiverOnStack()) { + if (callableMethod.needsReceiverOnStack() && !haveReceiver) { ensureReceiverOnStack(expression, callableMethod.getReceiverClass()); } pushMethodArguments(expression, callableMethod.getValueParameterTypes()); @@ -1793,6 +1797,23 @@ public class ExpressionCodegen extends JetVisitor { conditionValue = generatePatternMatch(pattern, patternCondition.isNegated(), StackValue.local(subjectLocal, subjectType)); } + else if (condition instanceof JetWhenConditionCall) { + final JetExpression call = ((JetWhenConditionCall) condition).getCallSuffixExpression(); + if (call instanceof JetCallExpression) { + v.load(subjectLocal, subjectType); + final DeclarationDescriptor declarationDescriptor = resolveCalleeDescriptor((JetCallExpression) call); + final PsiElement declaration = resolveCalleeToDeclaration(declarationDescriptor); + final CallableMethod callableMethod = typeMapper.mapToCallableMethod((PsiNamedElement) declaration); + if (callableMethod.getSignature().getReturnType() != Type.BOOLEAN_TYPE) { + throw new UnsupportedOperationException("calls in pattern matching must return boolean"); + } + invokeMethodWithArguments(callableMethod, (JetCallExpression) call, true); + conditionValue = StackValue.onStack(Type.BOOLEAN_TYPE); + } + else { + throw new UnsupportedOperationException("unsupported kind of call suffix"); + } + } else { throw new UnsupportedOperationException("unsupported kind of when condition"); } diff --git a/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java b/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java index 9c31be0dde8..18ca2c4e064 100644 --- a/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java @@ -69,4 +69,11 @@ public class PatternMatchingTest extends CodegenTestCase { assertEquals("one,two", foo.invoke(null, new Tuple2(1, 2))); assertEquals("something", foo.invoke(null, new Tuple2("not", "tuple"))); } + + public void testCall() throws Exception { + loadText("fun foo(s: String) = when(s) { .startsWith(\"J\") => \"JetBrains\"; else => \"something\" }"); + Method foo = generateFunction(); + assertEquals("JetBrains", foo.invoke(null, "Java")); + assertEquals("something", foo.invoke(null, "C#")); + } }