Build type enhancement properly, by taking into account both bounds of the original flexible type
^KT-44420 Fixed
This commit is contained in:
+6
@@ -20852,6 +20852,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/platformTypes/typeEnhancement"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/platformTypes/typeEnhancement"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("buildFlexibleEnhancement.kt")
|
||||||
|
public void testBuildFlexibleEnhancement() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/platformTypes/typeEnhancement/buildFlexibleEnhancement.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("overriddenExtensions.kt")
|
@TestMetadata("overriddenExtensions.kt")
|
||||||
public void testOverriddenExtensions() throws Exception {
|
public void testOverriddenExtensions() throws Exception {
|
||||||
|
|||||||
Vendored
+35
@@ -0,0 +1,35 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// FULL_JDK
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
// FILE: NonNullApi.java
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target({ElementType.TYPE, ElementType.PACKAGE})
|
||||||
|
@javax.annotation.Nonnull
|
||||||
|
@javax.annotation.meta.TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER})
|
||||||
|
@Documented
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface NonNullApi { }
|
||||||
|
|
||||||
|
// FILE: Foo.java
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
@NonNullApi
|
||||||
|
public class Foo<E> {
|
||||||
|
public Foo(Collection<? extends E> c) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val collection: Collection<Int> = listOf(1, 2, 3)
|
||||||
|
Foo(collection)
|
||||||
|
}
|
||||||
+1
-1
@@ -77,7 +77,7 @@ fun main(a: A) {
|
|||||||
a.field?.length
|
a.field?.length
|
||||||
a.field.length
|
a.field.length
|
||||||
|
|
||||||
<!RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS("MutableList<String!>?")!>a.baz()<!>.get(0)
|
<!RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS("(Mutable)List<String!>?")!>a.baz()<!>.get(0)
|
||||||
a.baz()!!.get(0).get(0)
|
a.baz()!!.get(0).get(0)
|
||||||
a.baz()!!.get(0)?.get(0)
|
a.baz()!!.get(0)?.get(0)
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+6
@@ -20858,6 +20858,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/platformTypes/typeEnhancement"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/platformTypes/typeEnhancement"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("buildFlexibleEnhancement.kt")
|
||||||
|
public void testBuildFlexibleEnhancement() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/platformTypes/typeEnhancement/buildFlexibleEnhancement.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("overriddenExtensions.kt")
|
@TestMetadata("overriddenExtensions.kt")
|
||||||
public void testOverriddenExtensions() throws Exception {
|
public void testOverriddenExtensions() throws Exception {
|
||||||
|
|||||||
+16
-6
@@ -58,6 +58,15 @@ class JavaTypeEnhancement(private val javaResolverSettings: JavaResolverSettings
|
|||||||
// For flexible types, both bounds are indexed in the same way: `(A<B>..C<D>)` gives `0 - (A<B>..C<D>), 1 - B and D`.
|
// For flexible types, both bounds are indexed in the same way: `(A<B>..C<D>)` gives `0 - (A<B>..C<D>), 1 - B and D`.
|
||||||
fun KotlinType.enhance(qualifiers: (Int) -> JavaTypeQualifiers) = unwrap().enhancePossiblyFlexible(qualifiers, 0).typeIfChanged
|
fun KotlinType.enhance(qualifiers: (Int) -> JavaTypeQualifiers) = unwrap().enhancePossiblyFlexible(qualifiers, 0).typeIfChanged
|
||||||
|
|
||||||
|
private fun buildEnhancementByFlexibleTypeBounds(lowerBound: KotlinType, upperBound: KotlinType): KotlinType? {
|
||||||
|
val upperEnhancement = upperBound.getEnhancement()
|
||||||
|
val lowerEnhancement = lowerBound.getEnhancement() ?: upperEnhancement ?: return null
|
||||||
|
|
||||||
|
if (upperEnhancement == null) return lowerEnhancement
|
||||||
|
|
||||||
|
return KotlinTypeFactory.flexibleType(lowerEnhancement.lowerIfFlexible(), upperEnhancement.upperIfFlexible())
|
||||||
|
}
|
||||||
|
|
||||||
private fun UnwrappedType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int): Result {
|
private fun UnwrappedType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int): Result {
|
||||||
if (isError) return Result(this, 1, false)
|
if (isError) return Result(this, 1, false)
|
||||||
return when (this) {
|
return when (this) {
|
||||||
@@ -72,12 +81,13 @@ class JavaTypeEnhancement(private val javaResolverSettings: JavaResolverSettings
|
|||||||
}
|
}
|
||||||
|
|
||||||
val wereChanges = lowerResult.wereChanges || upperResult.wereChanges
|
val wereChanges = lowerResult.wereChanges || upperResult.wereChanges
|
||||||
val enhancement = lowerResult.type.getEnhancement() ?: upperResult.type.getEnhancement()
|
val enhancement = buildEnhancementByFlexibleTypeBounds(lowerResult.type, upperResult.type)
|
||||||
val type = if (!wereChanges) this@enhancePossiblyFlexible
|
val type = if (wereChanges) {
|
||||||
else when {
|
when (this) {
|
||||||
this is RawTypeImpl -> RawTypeImpl(lowerResult.type, upperResult.type)
|
is RawTypeImpl -> RawTypeImpl(lowerResult.type, upperResult.type)
|
||||||
else -> KotlinTypeFactory.flexibleType(lowerResult.type, upperResult.type)
|
else -> KotlinTypeFactory.flexibleType(lowerResult.type, upperResult.type)
|
||||||
}.wrapEnhancement(enhancement)
|
}.wrapEnhancement(enhancement)
|
||||||
|
} else this@enhancePossiblyFlexible
|
||||||
|
|
||||||
Result(
|
Result(
|
||||||
type,
|
type,
|
||||||
|
|||||||
Reference in New Issue
Block a user