Proper enhancement for type parameters
This commit is contained in:
committed by
Denis Zharkov
parent
04aee291b9
commit
8c78739983
+11
-6
@@ -17,6 +17,8 @@
|
|||||||
package org.jetbrains.kotlin.load.java.components
|
package org.jetbrains.kotlin.load.java.components
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.components.MutabilityQualifier.MUTABLE
|
import org.jetbrains.kotlin.load.java.components.MutabilityQualifier.MUTABLE
|
||||||
import org.jetbrains.kotlin.load.java.components.MutabilityQualifier.READ_ONLY
|
import org.jetbrains.kotlin.load.java.components.MutabilityQualifier.READ_ONLY
|
||||||
import org.jetbrains.kotlin.load.java.components.NullabilityQualifier.NOT_NULL
|
import org.jetbrains.kotlin.load.java.components.NullabilityQualifier.NOT_NULL
|
||||||
@@ -62,18 +64,18 @@ private fun JetType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers, i
|
|||||||
val shouldEnhance = position.shouldEnhance()
|
val shouldEnhance = position.shouldEnhance()
|
||||||
if (!shouldEnhance && getArguments().isEmpty()) return Result(this, 1)
|
if (!shouldEnhance && getArguments().isEmpty()) return Result(this, 1)
|
||||||
|
|
||||||
val originalClass = getConstructor().getDeclarationDescriptor() as? ClassDescriptor
|
val originalClass = getConstructor().getDeclarationDescriptor()
|
||||||
?: return Result(this, 1)
|
?: return Result(this, 1)
|
||||||
|
|
||||||
val effectiveQualifiers = qualifiers(index)
|
val effectiveQualifiers = qualifiers(index)
|
||||||
val enhancedClass = originalClass.enhanceMutability(effectiveQualifiers, position)
|
val enhancedClassifier = originalClass.enhanceMutability(effectiveQualifiers, position)
|
||||||
|
|
||||||
var globalArgIndex = index + 1
|
var globalArgIndex = index + 1
|
||||||
val enhancedArguments = getArguments().mapIndexed {
|
val enhancedArguments = getArguments().mapIndexed {
|
||||||
localArgIndex, arg ->
|
localArgIndex, arg ->
|
||||||
if (arg.isStarProjection()) {
|
if (arg.isStarProjection()) {
|
||||||
globalArgIndex++
|
globalArgIndex++
|
||||||
TypeUtils.makeStarProjection(enhancedClass.getTypeConstructor().getParameters()[localArgIndex])
|
TypeUtils.makeStarProjection(enhancedClassifier.getTypeConstructor().getParameters()[localArgIndex])
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val (enhancedType, subtreeSize) = arg.getType().enhancePossiblyFlexible(qualifiers, globalArgIndex)
|
val (enhancedType, subtreeSize) = arg.getType().enhancePossiblyFlexible(qualifiers, globalArgIndex)
|
||||||
@@ -87,18 +89,21 @@ private fun JetType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers, i
|
|||||||
|
|
||||||
val enhancedType = JetTypeImpl(
|
val enhancedType = JetTypeImpl(
|
||||||
getAnnotations(),
|
getAnnotations(),
|
||||||
enhancedClass.getTypeConstructor(),
|
enhancedClassifier.getTypeConstructor(),
|
||||||
this.getEnhancedNullability(effectiveQualifiers, position),
|
this.getEnhancedNullability(effectiveQualifiers, position),
|
||||||
enhancedArguments,
|
enhancedArguments,
|
||||||
enhancedClass.getMemberScope(enhancedArguments)
|
if (enhancedClassifier is ClassDescriptor)
|
||||||
|
enhancedClassifier.getMemberScope(enhancedArguments)
|
||||||
|
else enhancedClassifier.getDefaultType().getMemberScope()
|
||||||
)
|
)
|
||||||
return Result(enhancedType, globalArgIndex - index)
|
return Result(enhancedType, globalArgIndex - index)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TypeComponentPosition.shouldEnhance() = this != TypeComponentPosition.INFLEXIBLE
|
private fun TypeComponentPosition.shouldEnhance() = this != TypeComponentPosition.INFLEXIBLE
|
||||||
|
|
||||||
private fun ClassDescriptor.enhanceMutability(qualifiers: JavaTypeQualifiers, position: TypeComponentPosition): ClassDescriptor {
|
private fun ClassifierDescriptor.enhanceMutability(qualifiers: JavaTypeQualifiers, position: TypeComponentPosition): ClassifierDescriptor {
|
||||||
if (!position.shouldEnhance()) return this
|
if (!position.shouldEnhance()) return this
|
||||||
|
if (this !is ClassDescriptor) return this // mutability is not applicable for type parameters
|
||||||
|
|
||||||
val mapping = JavaToKotlinClassMap.INSTANCE
|
val mapping = JavaToKotlinClassMap.INSTANCE
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// FILE: k.kt
|
||||||
|
|
||||||
|
trait ML<T> {
|
||||||
|
public fun foo(): MutableList<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
class K : J<String>(), ML<String>
|
||||||
|
|
||||||
|
// FILE: J.java
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
class J<T> extends ML<T> {
|
||||||
|
public List<T> foo() { return null; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public/*package*/ open class J</*0*/ T> : ML<T!> {
|
||||||
|
public/*package*/ constructor J</*0*/ T>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ fun foo(): kotlin.MutableList<T!>
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final class K : J<kotlin.String>, ML<kotlin.String> {
|
||||||
|
public constructor K()
|
||||||
|
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*2*/ /*fake_override*/ fun foo(): kotlin.MutableList<kotlin.String>
|
||||||
|
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
internal trait ML</*0*/ T> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public abstract fun foo(): kotlin.MutableList<T>
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// FILE: k.kt
|
||||||
|
|
||||||
|
trait K {
|
||||||
|
fun <T> foo(t: T)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: J.java
|
||||||
|
|
||||||
|
interface J extends K {
|
||||||
|
<T> void foo(T t);
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public/*package*/ trait J : K {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public abstract override /*1*/ fun </*0*/ T> foo(/*0*/ t: T): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
internal trait K {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
internal abstract fun </*0*/ T> foo(/*0*/ t: T): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
Vendored
+1
-1
@@ -9,6 +9,6 @@ public interface TypeParamOfClass {
|
|||||||
|
|
||||||
public interface Super</*0*/ T> {
|
public interface Super</*0*/ T> {
|
||||||
public abstract fun dummy(): kotlin.Unit
|
public abstract fun dummy(): kotlin.Unit
|
||||||
org.jetbrains.annotations.NotNull() public abstract fun foo(): T!
|
org.jetbrains.annotations.NotNull() public abstract fun foo(): T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -9,6 +9,6 @@ public interface TypeParamOfClassSubstituted {
|
|||||||
|
|
||||||
public interface Super</*0*/ T> {
|
public interface Super</*0*/ T> {
|
||||||
public abstract fun dummy(): kotlin.Unit
|
public abstract fun dummy(): kotlin.Unit
|
||||||
org.jetbrains.annotations.NotNull() public abstract fun foo(): T!
|
org.jetbrains.annotations.NotNull() public abstract fun foo(): T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -4,11 +4,11 @@ public interface TypeParamOfFun {
|
|||||||
|
|
||||||
public interface Sub : test.TypeParamOfFun.Super {
|
public interface Sub : test.TypeParamOfFun.Super {
|
||||||
public abstract override /*1*/ /*fake_override*/ fun dummy(): kotlin.Unit
|
public abstract override /*1*/ /*fake_override*/ fun dummy(): kotlin.Unit
|
||||||
public abstract override /*1*/ fun </*0*/ E> foo(): E!
|
public abstract override /*1*/ fun </*0*/ E> foo(): E
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Super {
|
public interface Super {
|
||||||
public abstract fun dummy(): kotlin.Unit
|
public abstract fun dummy(): kotlin.Unit
|
||||||
org.jetbrains.annotations.NotNull() public abstract fun </*0*/ T> foo(): T!
|
org.jetbrains.annotations.NotNull() public abstract fun </*0*/ T> foo(): T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8192,6 +8192,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/types"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/types"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("arrayList.kt")
|
||||||
|
public void testArrayList() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/types/arrayList.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("returnCollection.kt")
|
@TestMetadata("returnCollection.kt")
|
||||||
public void testReturnCollection() throws Exception {
|
public void testReturnCollection() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/types/returnCollection.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/types/returnCollection.kt");
|
||||||
@@ -8209,6 +8215,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/types/shapeMismatchInCovariantPositionGeneric.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/types/shapeMismatchInCovariantPositionGeneric.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameter.kt")
|
||||||
|
public void testTypeParameter() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/types/typeParameter.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user