diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index f47afb4ae47..2e9c4506b79 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -2550,24 +2550,40 @@ If finally block is present, its last expression is the value of try expression. } else { JetTypeReference typeReference = expression.getRight(); - JetType jetType = bindingContext.get(BindingContext.TYPE, typeReference); - assert jetType != null; - DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor(); + JetType rightType = bindingContext.get(BindingContext.TYPE, typeReference); + Type rightTypeAsm = boxType(asmType(rightType)); + assert rightType != null; + JetExpression left = expression.getLeft(); + JetType leftType = bindingContext.get(BindingContext.EXPRESSION_TYPE, left); + DeclarationDescriptor descriptor = rightType.getConstructor().getDeclarationDescriptor(); if (descriptor instanceof ClassDescriptor || descriptor instanceof TypeParameterDescriptor) { - Type type = boxType(asmType(jetType)); - generateInstanceOf(StackValue.expression(TYPE_OBJECT, expression.getLeft(), this), jetType, true); - Label isInstance = new Label(); - v.ifne(isInstance); - v.pop(); - if (opToken == JetTokens.AS_SAFE) { - v.aconst(null); + StackValue value = genQualified(receiver, left); + value.put(JetTypeMapper.boxType(value.type), v); + assert leftType != null; + + if (opToken != JetTokens.AS_SAFE) { + if(leftType.isNullable()) { + if (!rightType.isNullable()) { + v.dup(); + Label nonnull = new Label(); + v.ifnonnull(nonnull); + throwNewException(CLASS_TYPE_CAST_EXCEPTION); + v.mark(nonnull); + } + } } else { - throwNewException(CLASS_TYPE_CAST_EXCEPTION); + v.dup(); + v.instanceOf(rightTypeAsm); + Label ok = new Label(); + v.ifne(ok); + v.pop(); + v.aconst(null); + v.mark(ok); } - v.mark(isInstance); - v.checkcast(type); - return StackValue.onStack(type); + + v.checkcast(rightTypeAsm); + return StackValue.onStack(rightTypeAsm); } else { throw new UnsupportedOperationException("don't know how to handle non-class types in as/as?"); diff --git a/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java b/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java index fbb3d506d0a..06e2cb575b1 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java @@ -43,7 +43,7 @@ public class TypeInfoTest extends CodegenTestCase { Method foo = generateFunction(); Runnable r = newRunnable(); assertSame(r, foo.invoke(null, r)); - assertThrows(foo, TypeCastException.class, null, new Object()); + assertThrows(foo, ClassCastException.class, null, new Object()); } public void testIsOperator() throws Exception { diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/JetContentBasedFileSubstitutor.java b/idea/src/org/jetbrains/jet/plugin/libraries/JetContentBasedFileSubstitutor.java index 30c49172d5a..b7652072076 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/JetContentBasedFileSubstitutor.java +++ b/idea/src/org/jetbrains/jet/plugin/libraries/JetContentBasedFileSubstitutor.java @@ -61,7 +61,6 @@ public class JetContentBasedFileSubstitutor implements ContentBasedClassFileProc } @Nullable - @Override public PsiFile getDecompiledPsiFile(PsiFile psiFile) { return JetDecompiledData.getDecompiledData((ClsFileImpl) psiFile).getJetFile(); } diff --git a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java index e1e772f448b..2270039f2e6 100644 --- a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java +++ b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java @@ -21,6 +21,7 @@ import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.actions.ConfigurationContext; import com.intellij.execution.junit.RuntimeConfigurationProducer; import com.intellij.openapi.module.Module; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -56,19 +57,31 @@ public class JetRunConfigurationProducer extends RuntimeConfigurationProducer im return null; } + FqName startClassFQName = getStartClassFQName(location); + if (startClassFQName == null) { + return null; + } + + return createConfigurationByQName(module, configurationContext, startClassFQName); + } + + @Nullable + private FqName getStartClassFQName(Location location) { PsiFile psiFile = location.getPsiElement().getContainingFile(); if (psiFile instanceof JetFile) { JetFile jetFile = (JetFile) psiFile; if (JetMainDetector.hasMain(jetFile.getDeclarations())) { mySourceElement = jetFile; FqName fqName = JetPsiUtil.getFQName(jetFile); - FqName className = fqName.child(JvmAbi.PACKAGE_CLASS); - return createConfigurationByQName(module, configurationContext, className); + return fqName.child(JvmAbi.PACKAGE_CLASS); } } + return null; } + + @NotNull private RunnerAndConfigurationSettings createConfigurationByQName( @NotNull Module module, ConfigurationContext context, @@ -82,6 +95,30 @@ public class JetRunConfigurationProducer extends RuntimeConfigurationProducer im return settings; } + @Override + protected RunnerAndConfigurationSettings findExistingByElement( + Location location, + @NotNull RunnerAndConfigurationSettings[] existingConfigurations, + ConfigurationContext context + ) { + FqName startClassFQName = getStartClassFQName(location); + if (startClassFQName == null) { + return null; + } + + for (RunnerAndConfigurationSettings existingConfiguration : existingConfigurations) { + if (existingConfiguration.getType() instanceof JetRunConfigurationType) { + JetRunConfiguration jetConfiguration = (JetRunConfiguration)existingConfiguration.getConfiguration(); + if (Comparing.equal(jetConfiguration.settings().getMainClassName(), startClassFQName.getFqName())) { + if (Comparing.equal(location.getModule(), jetConfiguration.getConfigurationModule().getModule())) { + return existingConfiguration; + } + } + } + } + return null; + } + @Override public int compareTo(Object o) { return PREFERED;