diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 3f17fcb2d2a17c67172d2f0c602bba77b7eff2d7..cc0a20b79f325239a9b6544d72756cd048cc94c6 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -722,13 +722,17 @@ public class ExpressionCodegen extends JetVisitor { methodDescriptor.getDescriptor()); } else { - methodDescriptor = typeMapper.mapSignature((JetFunction) declarationPsiElement); - if (functionParent instanceof NamespaceDescriptorImpl && declarationPsiElement instanceof JetFunction) { + final JetFunction jetFunction = (JetFunction) declarationPsiElement; + methodDescriptor = typeMapper.mapSignature(jetFunction); + if (functionParent instanceof NamespaceDescriptorImpl) { + if (jetFunction.getReceiverTypeRef() != null) { + ensureReceiverOnStack(expression); + } pushMethodArguments(expression, methodDescriptor); final String owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(functionParent)); v.invokestatic(owner, methodDescriptor.getName(), methodDescriptor.getDescriptor()); } - else if (functionParent instanceof ClassDescriptor && declarationPsiElement instanceof JetFunction) { + else if (functionParent instanceof ClassDescriptor) { ensureReceiverOnStack(expression); pushMethodArguments(expression, methodDescriptor); final String owner = JetTypeMapper.jvmNameForInterface((ClassDescriptor) functionParent); diff --git a/idea/testData/codegen/extensionFunctions/whenFail.jet b/idea/testData/codegen/extensionFunctions/whenFail.jet new file mode 100644 index 0000000000000000000000000000000000000000..252fe893a86477c4eef1690676b10f6c2bd2d4a0 --- /dev/null +++ b/idea/testData/codegen/extensionFunctions/whenFail.jet @@ -0,0 +1,14 @@ +fun StringBuilder.takeFirst(): Char { + if (this.length() == 0) return '\0' + val c = this.charAt(0) + this.deleteCharAt(0) + return c +} + +fun foo(expr: StringBuilder): Int { + val c = expr.takeFirst() + when(c) { + '\0' => throw new Exception("zero") + else => throw new Exception("nonzero" + c) + } +} diff --git a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index 71453d139798a3e79278c17b73c08962232e17d4..b8d2823880c69f70754839de3c40126260735a4e 100644 --- a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -12,9 +12,8 @@ import org.jetbrains.jet.lang.psi.JetNamespace; import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.parsing.JetParsingTest; -import javax.swing.JComponent; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.nio.channels.NonWritableChannelException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -25,6 +24,17 @@ import java.util.Map; public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { private MyClassLoader myClassLoader; + protected static void assertThrows(Method foo, Class exceptionClass, Object instance, Object... args) throws IllegalAccessException { + boolean caught = false; + try { + foo.invoke(instance, args); + } + catch(InvocationTargetException ex) { + caught = exceptionClass.isInstance(ex.getTargetException()); + } + assertTrue(caught); + } + @Override protected void setUp() throws Exception { super.setUp(); @@ -128,14 +138,19 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { } protected Codegens generateClassesInFile() { - Codegens state = new Codegens(getProject(), false); - JetFile jetFile = (JetFile) myFixture.getFile(); - AnalyzingUtils.checkForSyntacticErrors(jetFile); - final JetNamespace namespace = jetFile.getRootNamespace(); - - NamespaceCodegen codegen = state.forNamespace(namespace); - codegen.generate(namespace); - return state; + try { + Codegens state = new Codegens(getProject(), false); + JetFile jetFile = (JetFile) myFixture.getFile(); + AnalyzingUtils.checkForSyntacticErrors(jetFile); + final JetNamespace namespace = jetFile.getRootNamespace(); + + NamespaceCodegen codegen = state.forNamespace(namespace); + codegen.generate(namespace); + return state; + } catch (RuntimeException e) { + System.out.println(generateToText()); + throw e; + } } protected Method generateFunction() { diff --git a/idea/tests/org/jetbrains/jet/codegen/ExtensionFunctionsTest.java b/idea/tests/org/jetbrains/jet/codegen/ExtensionFunctionsTest.java index 59d78daf88a79f27adb135bfafc06d65e66a8906..3305c6f551e57cd1a73c546ce7cc68f8cf5b512e 100644 --- a/idea/tests/org/jetbrains/jet/codegen/ExtensionFunctionsTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/ExtensionFunctionsTest.java @@ -17,4 +17,10 @@ public class ExtensionFunctionsTest extends CodegenTestCase { final Character c = (Character) foo.invoke(null); assertEquals('f', c.charValue()); } + + public void testWhenFail() throws Exception { + loadFile(); + Method foo = generateFunction("foo"); + assertThrows(foo, Exception.class, null, new StringBuilder()); + } } diff --git a/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java b/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java index 6f27ac9ebf689b59b774fb0072b9cd7f0b9ce710..5ac5d30fb4c6819d5e864ef6025c154af649c7c4 100644 --- a/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/PatternMatchingTest.java @@ -2,7 +2,6 @@ package org.jetbrains.jet.codegen; import jet.NoPatternMatchedException; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** @@ -25,14 +24,7 @@ public class PatternMatchingTest extends CodegenTestCase { loadFile(); Method foo = generateFunction(); assertTrue((Boolean) foo.invoke(null, 0)); - boolean caught = false; - try { - foo.invoke(null, 1); - } - catch(InvocationTargetException ex) { - caught = ex.getTargetException() instanceof NoPatternMatchedException; - } - assertTrue(caught); + assertThrows(foo, NoPatternMatchedException.class, null, 1); } public void testPattern() throws Exception {