Switching off propagation of types and KotlinSignatures for platform types

This commit is contained in:
Andrey Breslav
2014-06-24 17:54:32 +04:00
parent fefadaa171
commit c3c72fc528
7 changed files with 145 additions and 10 deletions
@@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.java.JavaPackage;
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils; import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.resolver.ExternalAnnotationResolver; import org.jetbrains.jet.lang.resolve.java.resolver.ExternalAnnotationResolver;
import org.jetbrains.jet.lang.resolve.java.structure.JavaMember; import org.jetbrains.jet.lang.resolve.java.structure.JavaMember;
@@ -64,7 +65,7 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD
@NotNull List<TypeParameterDescriptor> methodTypeParameters, @NotNull List<TypeParameterDescriptor> methodTypeParameters,
boolean hasSuperMethods boolean hasSuperMethods
) { ) {
String signature = SignaturesUtil.getKotlinSignature(externalAnnotationResolver, methodOrConstructor); String signature = JavaPackage.getPLATFORM_TYPES() ? null : SignaturesUtil.getKotlinSignature(externalAnnotationResolver, methodOrConstructor);
if (signature == null) { if (signature == null) {
setAnnotated(false); setAnnotated(false);
@@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JavaPackage;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaMethodDescriptor; import org.jetbrains.jet.lang.resolve.java.descriptor.JavaMethodDescriptor;
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature; import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmSignaturePackage; import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmSignaturePackage;
@@ -150,6 +151,8 @@ public class SignaturesPropagationData {
private JetType modifyReturnTypeAccordingToSuperMethods( private JetType modifyReturnTypeAccordingToSuperMethods(
@NotNull JetType autoType // type built by JavaTypeTransformer @NotNull JetType autoType // type built by JavaTypeTransformer
) { ) {
if (JavaPackage.getPLATFORM_TYPES()) return autoType;
List<TypeAndVariance> typesFromSuperMethods = ContainerUtil.map(superFunctions, List<TypeAndVariance> typesFromSuperMethods = ContainerUtil.map(superFunctions,
new Function<FunctionDescriptor, TypeAndVariance>() { new Function<FunctionDescriptor, TypeAndVariance>() {
@Override @Override
@@ -162,6 +165,8 @@ public class SignaturesPropagationData {
} }
private List<TypeParameterDescriptor> modifyTypeParametersAccordingToSuperMethods(List<TypeParameterDescriptor> autoTypeParameters) { private List<TypeParameterDescriptor> modifyTypeParametersAccordingToSuperMethods(List<TypeParameterDescriptor> autoTypeParameters) {
if (JavaPackage.getPLATFORM_TYPES()) return autoTypeParameters;
List<TypeParameterDescriptor> result = Lists.newArrayList(); List<TypeParameterDescriptor> result = Lists.newArrayList();
for (TypeParameterDescriptor autoParameter : autoTypeParameters) { for (TypeParameterDescriptor autoParameter : autoTypeParameters) {
@@ -399,9 +404,9 @@ public class SignaturesPropagationData {
@NotNull List<TypeAndVariance> typesFromSuper, @NotNull List<TypeAndVariance> typesFromSuper,
@NotNull TypeUsage howThisTypeIsUsed @NotNull TypeUsage howThisTypeIsUsed
) { ) {
if (autoType.isError()) { if (autoType.isError()) return autoType;
return autoType;
} if (JavaPackage.getPLATFORM_TYPES()) return autoType;
boolean resultNullable = typeMustBeNullable(autoType, typesFromSuper, howThisTypeIsUsed); boolean resultNullable = typeMustBeNullable(autoType, typesFromSuper, howThisTypeIsUsed);
ClassifierDescriptor resultClassifier = modifyTypeClassifier(autoType, typesFromSuper); ClassifierDescriptor resultClassifier = modifyTypeClassifier(autoType, typesFromSuper);
@@ -430,6 +435,8 @@ public class SignaturesPropagationData {
@NotNull ClassifierDescriptor classifier, @NotNull ClassifierDescriptor classifier,
@NotNull List<TypeAndVariance> typesFromSuper @NotNull List<TypeAndVariance> typesFromSuper
) { ) {
if (typesFromSuper.isEmpty()) return autoType.getArguments();
List<TypeProjection> autoArguments = autoType.getArguments(); List<TypeProjection> autoArguments = autoType.getArguments();
if (!(classifier instanceof ClassDescriptor)) { if (!(classifier instanceof ClassDescriptor)) {
@@ -462,6 +469,8 @@ public class SignaturesPropagationData {
@NotNull TypeProjection argument, @NotNull TypeProjection argument,
@NotNull List<TypeProjectionAndVariance> projectionsFromSuper @NotNull List<TypeProjectionAndVariance> projectionsFromSuper
) { ) {
if (projectionsFromSuper.isEmpty()) return argument.getProjectionKind();
Set<Variance> projectionKindsInSuper = Sets.newLinkedHashSet(); Set<Variance> projectionKindsInSuper = Sets.newLinkedHashSet();
for (TypeProjectionAndVariance projectionAndVariance : projectionsFromSuper) { for (TypeProjectionAndVariance projectionAndVariance : projectionsFromSuper) {
projectionKindsInSuper.add(projectionAndVariance.typeProjection.getProjectionKind()); projectionKindsInSuper.add(projectionAndVariance.typeProjection.getProjectionKind());
@@ -575,7 +584,7 @@ public class SignaturesPropagationData {
boolean someSupersCovariantNullable = false; boolean someSupersCovariantNullable = false;
boolean someSupersNotNull = false; boolean someSupersNotNull = false;
for (TypeAndVariance typeFromSuper : typesFromSuper) { for (TypeAndVariance typeFromSuper : typesFromSuper) {
if (!typeFromSuper.type.isNullable()) { if (!TypeUtils.isNullableType(typeFromSuper.type)) {
someSupersNotNull = true; someSupersNotNull = true;
} }
else { else {
@@ -590,13 +599,13 @@ public class SignaturesPropagationData {
if (someSupersNotNull && someSupersNotCovariantNullable) { if (someSupersNotNull && someSupersNotCovariantNullable) {
reportError("Incompatible types in superclasses: " + typesFromSuper); reportError("Incompatible types in superclasses: " + typesFromSuper);
return autoType.isNullable(); return TypeUtils.isNullableType(autoType);
} }
else if (someSupersNotNull) { else if (someSupersNotNull) {
return false; return false;
} }
else if (someSupersNotCovariantNullable || someSupersCovariantNullable) { else if (someSupersNotCovariantNullable || someSupersCovariantNullable) {
boolean annotatedAsNotNull = howThisTypeIsUsed != TYPE_ARGUMENT && !autoType.isNullable(); boolean annotatedAsNotNull = howThisTypeIsUsed != TYPE_ARGUMENT && !TypeUtils.isNullableType(autoType);
if (annotatedAsNotNull && someSupersNotCovariantNullable) { if (annotatedAsNotNull && someSupersNotCovariantNullable) {
DescriptorRenderer renderer = DescriptorRenderer.SOURCE_CODE_SHORT_NAMES_IN_TYPES; DescriptorRenderer renderer = DescriptorRenderer.SOURCE_CODE_SHORT_NAMES_IN_TYPES;
@@ -606,7 +615,7 @@ public class SignaturesPropagationData {
return !annotatedAsNotNull; return !annotatedAsNotNull;
} }
return autoType.isNullable(); return TypeUtils.isNullableType(autoType);
} }
@NotNull @NotNull
@@ -0,0 +1,48 @@
// FILE: p/G.java
package p;
public interface G<TG> {
}
// FILE: p/A.kt
package p;
public trait A<TA> {
fun foo(p: A<TA>)
}
// FILE: p/B.java
package p;
public class B<TB> implements A<TB> {
void foo(A<TB> p) {}
}
// FILE: p/C.java
package p;
public class C<TC> extends B<TC> implements A<TC> {
}
// FILE: p/P.java
package p;
public class P {
}
// FILE: k.kt
import p.*
abstract class K: C<P>() {
}
abstract class AL: java.util.ArrayList<P>() {
}
@@ -0,0 +1,30 @@
// FILE: p/A.java
package p;
public interface A {
<TA> void foo(TA p);
}
// FILE: p/B.java
package p;
public class B implements A {
<TB> void foo(TB p) {}
}
// FILE: p/C.java
package p;
public class C extends B implements A {
}
// FILE: k.kt
import p.*
abstract class K: C() {
}
@@ -0,0 +1,26 @@
// FILE: p/I.java
package p;
import p.J.Param
public interface I {
String s();
}
// FILE: p/J.java
package p;
public class J implements I {
public String s() { return null; }
}
// FILE: k.kt
import p.*
fun test() {
val s = J().s()
s.get(0)
s!!.get(0)
}
@@ -6155,12 +6155,22 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("GenericsInSupertypes.kt")
public void testGenericsInSupertypes() throws Exception {
doTest("compiler/testData/diagnostics/tests/j+k/GenericsInSupertypes.kt");
}
@TestMetadata("inheritAbstractSamAdapter.kt") @TestMetadata("inheritAbstractSamAdapter.kt")
public void testInheritAbstractSamAdapter() throws Exception { public void testInheritAbstractSamAdapter() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/inheritAbstractSamAdapter.kt"); String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/inheritAbstractSamAdapter.kt");
doTest(fileName); doTest(fileName);
} }
@TestMetadata("InheritedGenericFunction.kt")
public void testInheritedGenericFunction() throws Exception {
doTest("compiler/testData/diagnostics/tests/j+k/InheritedGenericFunction.kt");
}
@TestMetadata("innerNestedClassFromJava.kt") @TestMetadata("innerNestedClassFromJava.kt")
public void testInnerNestedClassFromJava() throws Exception { public void testInnerNestedClassFromJava() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/innerNestedClassFromJava.kt"); String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/innerNestedClassFromJava.kt");
@@ -7719,6 +7729,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("override.kt")
public void testOverride() throws Exception {
doTest("compiler/testData/diagnostics/tests/platformTypes/override.kt");
}
@TestMetadata("compiler/testData/diagnostics/tests/platformTypes/methodCall") @TestMetadata("compiler/testData/diagnostics/tests/platformTypes/methodCall")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class) @RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
@@ -76,11 +76,11 @@ public class TypeCheckingProcedure {
return equalTypes(flexibleType1.getLowerBound(), flexibleType2.getLowerBound()) return equalTypes(flexibleType1.getLowerBound(), flexibleType2.getLowerBound())
&& equalTypes(flexibleType1.getUpperBound(), flexibleType2.getUpperBound()); && equalTypes(flexibleType1.getUpperBound(), flexibleType2.getUpperBound());
} }
return equalTypes(flexibleType1.getLowerBound(), type2) || equalTypes(flexibleType1.getUpperBound(), type2); return heterogeneousEquivalence(type2, flexibleType1);
} }
else if (type2 instanceof FlexibleType) { else if (type2 instanceof FlexibleType) {
FlexibleType flexibleType2 = (FlexibleType) type2; FlexibleType flexibleType2 = (FlexibleType) type2;
return equalTypes(type1, flexibleType2.getLowerBound()) || equalTypes(type1, flexibleType2.getUpperBound()); return heterogeneousEquivalence(type1, flexibleType2);
} }
if (type1.isNullable() != type2.isNullable()) { if (type1.isNullable() != type2.isNullable()) {
@@ -121,6 +121,12 @@ public class TypeCheckingProcedure {
return true; return true;
} }
private boolean heterogeneousEquivalence(JetType inflexibleType, FlexibleType flexibleType) {
// This is to account for the case when we have Collection<X> vs (Mutable)Collection<X>! or K(java.util.Collection<? extends X>)
assert !TypesPackage.isFlexible(inflexibleType) : "Only inflexible types are allowed here: " + inflexibleType;
return isSubtypeOf(flexibleType.getLowerBound(), inflexibleType) && isSubtypeOf(inflexibleType, flexibleType.getUpperBound());
}
public enum EnrichedProjectionKind { public enum EnrichedProjectionKind {
IN, OUT, INV, STAR; IN, OUT, INV, STAR;