Do not create redundant special variance when enhancing types

#KT-8538 Fixed
This commit is contained in:
Denis Zharkov
2015-08-03 12:50:13 +03:00
parent b2766bfb57
commit b7c042510d
7 changed files with 42 additions and 11 deletions
@@ -0,0 +1,10 @@
package test;
import org.jetbrains.annotations.*;
import java.util.*;
public interface ReadOnlyExtendsWildcard {
void bar(); // Non-SAM
void foo(@ReadOnly List<? extends CharSequence> x, @NotNull Comparable<? super String> y);
}
@@ -0,0 +1,6 @@
package test
public interface ReadOnlyExtendsWildcard {
public abstract fun bar(): kotlin.Unit
public abstract fun foo(/*0*/ org.jetbrains.annotations.ReadOnly() p0: kotlin.List<kotlin.CharSequence!>!, /*1*/ org.jetbrains.annotations.NotNull() p1: kotlin.Comparable<kotlin.String!>): kotlin.Unit
}
@@ -1382,6 +1382,12 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/mutability/LoadIterableWithPropagation.java");
doTestCompiledJava(fileName);
}
@TestMetadata("ReadOnlyExtendsWildcard.java")
public void testReadOnlyExtendsWildcard() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/mutability/ReadOnlyExtendsWildcard.java");
doTestCompiledJava(fileName);
}
}
@TestMetadata("compiler/testData/loadJava/compiledJava/notNull")
@@ -3977,6 +3977,12 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/mutability/LoadIterableWithPropagation.java");
doTest(fileName);
}
@TestMetadata("ReadOnlyExtendsWildcard.java")
public void testReadOnlyExtendsWildcard() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/mutability/ReadOnlyExtendsWildcard.java");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/loadJava/compiledJava/notNull")
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.types.Variance.INVARIANT
import org.jetbrains.kotlin.types.Variance.IN_VARIANCE
import org.jetbrains.kotlin.types.Variance.OUT_VARIANCE
import org.jetbrains.kotlin.types.checker.JetTypeChecker
import org.jetbrains.kotlin.types.typeUtil.createProjection
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
import org.jetbrains.kotlin.utils.sure
import java.util.HashSet
@@ -247,11 +248,11 @@ class LazyJavaTypeResolver(
if (bound == null)
makeStarProjection(typeParameter, attr)
else {
var projectionKind = if (javaType.isExtends()) OUT_VARIANCE else IN_VARIANCE
if (projectionKind == typeParameter.getVariance()) {
projectionKind = Variance.INVARIANT
}
TypeProjectionImpl(projectionKind, transformJavaType(bound, UPPER_BOUND.toAttributes()))
createProjection(
type = transformJavaType(bound, UPPER_BOUND.toAttributes()),
projectionKind = if (javaType.isExtends()) OUT_VARIANCE else IN_VARIANCE,
typeParameterDescriptor = typeParameter
)
}
}
else -> TypeProjectionImpl(INVARIANT, transformJavaType(javaType, attr))
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.load.java.typeEnhacement.NullabilityQualifier.NULLAB
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.createProjection
// The index in the lambda is the position of the type component:
// Example: for `A<B, C<D, E>>`, indices go as follows: `0 - A<...>, 1 - B, 2 - C<D, E>, 3 - D, 4 - E`,
@@ -74,6 +75,8 @@ private fun JetType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers, i
val effectiveQualifiers = qualifiers(index)
val (enhancedClassifier, enhancedMutabilityAnnotations) = originalClass.enhanceMutability(effectiveQualifiers, position)
val typeConstructor = enhancedClassifier.typeConstructor
var globalArgIndex = index + 1
val enhancedArguments = getArguments().mapIndexed {
localArgIndex, arg ->
@@ -84,10 +87,7 @@ private fun JetType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers, i
else {
val (enhancedType, subtreeSize) = arg.getType().enhancePossiblyFlexible(qualifiers, globalArgIndex)
globalArgIndex += subtreeSize
TypeProjectionImpl(
arg.getProjectionKind(),
enhancedType
)
createProjection(enhancedType, arg.projectionKind, typeParameterDescriptor = typeConstructor.parameters[localArgIndex])
}
}
@@ -99,12 +99,12 @@ private fun JetType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers, i
).filterNotNull().compositeAnnotationsOrSingle()
val (newSubstitution, substitutedEnhancedArgs) = computeNewSubstitutionAndArguments(
enhancedClassifier.typeConstructor.parameters, enhancedArguments
typeConstructor.parameters, enhancedArguments
)
val enhancedType = JetTypeImpl(
newAnnotations,
enhancedClassifier.getTypeConstructor(),
typeConstructor,
enhancedNullability,
substitutedEnhancedArgs,
newSubstitution,
@@ -136,3 +136,5 @@ public fun List<JetType>.defaultProjections(): List<TypeProjection> = map { Type
public fun JetType.isDefaultBound(): Boolean = KotlinBuiltIns.isDefaultBound(getSupertypeRepresentative())
public fun createProjection(type: JetType, projectionKind: Variance, typeParameterDescriptor: TypeParameterDescriptor?): TypeProjection =
TypeProjectionImpl(if (typeParameterDescriptor?.variance == projectionKind) Variance.INVARIANT else projectionKind, type)