KT-3307 Compiler exception trying to call Java method

#KT-3307 Fixed
This commit is contained in:
Andrey Breslav
2013-02-07 15:40:12 +04:00
parent 091399aa4b
commit 0b4b87fc3a
7 changed files with 81 additions and 6 deletions
@@ -95,7 +95,8 @@ public class RawTypesCheck {
}
for (HierarchicalMethodSignature superSignature : method.getHierarchicalMethodSignature().getSuperSignatures()) {
if (superSignature.isRaw() || hasRawTypesInSignature(superSignature.getMethod())) {
PsiMethod superMethod = superSignature.getMethod();
if (superSignature.isRaw() || typeParameterIsErased(method, superMethod) || hasRawTypesInSignature(superMethod)) {
return true;
}
}
@@ -103,6 +104,14 @@ public class RawTypesCheck {
return false;
}
private static boolean typeParameterIsErased(@NotNull PsiMethod a, @NotNull PsiMethod b) {
// Java allows you to write
// <T extends Foo> T foo(), in the superclass and then
// Foo foo(), in the subclass
// this is a valid Java override, but in fact it is an erasure
return a.getTypeParameters().length != b.getTypeParameters().length;
}
private RawTypesCheck() {
}
}
@@ -22,6 +22,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
@@ -222,6 +223,7 @@ public class OverridingUtil {
public static boolean isReturnTypeOkForOverride(@NotNull JetTypeChecker typeChecker, @NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) {
TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor);
if (typeSubstitutor == null) return false;
JetType superReturnType = superDescriptor.getReturnType();
assert superReturnType != null;
@@ -235,11 +237,14 @@ public class OverridingUtil {
return typeChecker.isSubtypeOf(subReturnType, substitutedSuperReturnType);
}
@Nullable
private static TypeSubstitutor prepareTypeSubstitutor(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) {
List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();
if (subTypeParameters.size() != superTypeParameters.size()) return null;
Map<TypeConstructor, TypeProjection> substitutionContext = Maps.newHashMap();
for (int i = 0, typeParametersSize = superTypeParameters.size(); i < typeParametersSize; i++) {
for (int i = 0; i < superTypeParameters.size(); i++) {
TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i);
TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i);
substitutionContext.put(
@@ -0,0 +1,21 @@
// FILE: Bug.java
public interface Bug {
<RET extends Bug> RET save();
}
// FILE: SubBug.java
public class SubBug implements Bug {
public SubBug save() {
return this;
}
}
// FILE: Bug.kt
fun TestBug() {
SubBug().save() // can resolve on subtype
val bug: Bug = SubBug()
bug.save<Bug>() // can resolve on supertype
}
@@ -0,0 +1,19 @@
package test;
public interface MethodTypeParameterErased {
public interface Bug<T> {
<RET extends Bug<T>> RET save();
void foo();
}
public abstract class SubBug implements Bug<Object> {
public SubBug save() {
return this;
}
public void foo() {}
}
}
@@ -0,0 +1,13 @@
package test
public trait MethodTypeParameterErased : java.lang.Object {
public trait Bug</*0*/ T> : java.lang.Object {
public abstract fun </*0*/ RET : test.MethodTypeParameterErased.Bug<T>?> save() : RET?
}
public open class SubBug : test.MethodTypeParameterErased.Bug<jet.Any> {
public constructor SubBug()
public open fun save() : test.MethodTypeParameterErased.SubBug?
}
}
@@ -16,16 +16,13 @@
package org.jetbrains.jet.checkers;
import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestSuite;
import java.io.File;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.test.InnerTestClasses;
import org.jetbrains.jet.test.TestMetadata;
import org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve;
import java.io.File;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@@ -2629,6 +2626,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/j+k/kt2890.kt");
}
@TestMetadata("kt3307.kt")
public void testKt3307() throws Exception {
doTest("compiler/testData/diagnostics/tests/j+k/kt3307.kt");
}
@TestMetadata("mutableIterator.kt")
public void testMutableIterator() throws Exception {
doTest("compiler/testData/diagnostics/tests/j+k/mutableIterator.kt");
@@ -161,6 +161,12 @@ public final class LoadJavaCustomTest extends KotlinTestWithEnvironment {
dir + "SubclassWithRawType.java");
}
public void testMethodTypeParameterErased() throws Exception {
String dir = PATH + "/methodTypeParameterErased/";
doTest(dir + "MethodTypeParameterErased.txt",
dir + "MethodTypeParameterErased.java");
}
public static class SubclassingKotlinInJavaTest extends KotlinTestWithEnvironmentManagement {
public void testSubclassingKotlinInJava() throws Exception {
doTest(PATH + "/" + getTestName(true));