KT-3307 Compiler exception trying to call Java method
#KT-3307 Fixed
This commit is contained in:
+10
-1
@@ -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
|
||||
}
|
||||
+19
@@ -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() {}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user