Introduce TypeConstructorSubstitution.create
After latest changes type constructors of inner classes contains
additional type parameters that are copies of ones from outer class.
Their indices are correct, but they used only for subtyping check,
all entries within inner classes are still refers to original
descriptors having different indices.
Example:
class Outer<E> {
inner class Inner<F> { // Inner's type constructor looks like Inner<F, E>
fun foo(): E // refers to E in outer having index 0
}
}
Indexed substitution does not work here because of intersecting indices,
so we replace it with common map substituion in such cases.
This commit is contained in:
+1
-1
@@ -456,7 +456,7 @@ private object ConstantStarSubstitution : TypeSubstitution() {
|
|||||||
|
|
||||||
val newProjections = key.constructor.parameters.map(::StarProjectionImpl)
|
val newProjections = key.constructor.parameters.map(::StarProjectionImpl)
|
||||||
|
|
||||||
val substitution = IndexedParametersSubstitution(key.constructor, newProjections)
|
val substitution = TypeConstructorSubstitution.create(key.constructor, newProjections)
|
||||||
|
|
||||||
return TypeProjectionImpl(
|
return TypeProjectionImpl(
|
||||||
TypeSubstitutor.create(substitution).substitute(key.constructor.declarationDescriptor!!.defaultType, Variance.INVARIANT)!!
|
TypeSubstitutor.create(substitution).substitute(key.constructor.declarationDescriptor!!.defaultType, Variance.INVARIANT)!!
|
||||||
|
|||||||
+1
-1
@@ -101,7 +101,7 @@ private fun KotlinType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers
|
|||||||
).filterNotNull().compositeAnnotationsOrSingle()
|
).filterNotNull().compositeAnnotationsOrSingle()
|
||||||
|
|
||||||
val newSubstitution = computeNewSubstitution(
|
val newSubstitution = computeNewSubstitution(
|
||||||
typeConstructor.parameters, enhancedArguments
|
typeConstructor, enhancedArguments
|
||||||
)
|
)
|
||||||
|
|
||||||
val enhancedType = KotlinTypeImpl.create(
|
val enhancedType = KotlinTypeImpl.create(
|
||||||
|
|||||||
+1
-1
@@ -89,7 +89,7 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor {
|
|||||||
+ " for " + getTypeConstructor() + " " + getTypeConstructor().getParameters();
|
+ " for " + getTypeConstructor() + " " + getTypeConstructor().getParameters();
|
||||||
if (typeArguments.isEmpty()) return getUnsubstitutedMemberScope();
|
if (typeArguments.isEmpty()) return getUnsubstitutedMemberScope();
|
||||||
|
|
||||||
TypeSubstitutor substitutor = new IndexedParametersSubstitution(getTypeConstructor(), typeArguments).buildSubstitutor();
|
TypeSubstitutor substitutor = TypeConstructorSubstitution.create(getTypeConstructor(), typeArguments).buildSubstitutor();
|
||||||
return new SubstitutingScope(getUnsubstitutedMemberScope(), substitutor);
|
return new SubstitutingScope(getUnsubstitutedMemberScope(), substitutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public abstract class AbstractLazyType(storageManager: StorageManager) : Abstrac
|
|||||||
|
|
||||||
protected abstract fun computeArguments(): List<TypeProjection>
|
protected abstract fun computeArguments(): List<TypeProjection>
|
||||||
|
|
||||||
override fun getSubstitution() = computeCustomSubstitution() ?: IndexedParametersSubstitution(constructor, getArguments())
|
override fun getSubstitution() = computeCustomSubstitution() ?: TypeConstructorSubstitution.create(constructor, getArguments())
|
||||||
|
|
||||||
protected open fun computeCustomSubstitution(): TypeSubstitution? = getCapability<CustomSubstitutionCapability>()?.substitution
|
protected open fun computeCustomSubstitution(): TypeSubstitution? = getCapability<CustomSubstitutionCapability>()?.substitution
|
||||||
|
|
||||||
|
|||||||
@@ -512,7 +512,7 @@ public class ErrorUtils {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public TypeSubstitution getSubstitution() {
|
public TypeSubstitution getSubstitution() {
|
||||||
return new IndexedParametersSubstitution(constructor, arguments);
|
return TypeConstructorSubstitution.create(constructor, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ private constructor(
|
|||||||
|
|
||||||
override fun getSubstitution(): TypeSubstitution {
|
override fun getSubstitution(): TypeSubstitution {
|
||||||
if (substitution == null) {
|
if (substitution == null) {
|
||||||
return IndexedParametersSubstitution(getConstructor(), getArguments())
|
return TypeConstructorSubstitution.create(getConstructor(), getArguments())
|
||||||
}
|
}
|
||||||
return substitution
|
return substitution
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.types
|
package org.jetbrains.kotlin.types
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
|
||||||
@@ -59,10 +60,21 @@ public abstract class TypeConstructorSubstitution : TypeSubstitution() {
|
|||||||
override fun get(key: TypeConstructor) = map[key.declarationDescriptor]
|
override fun get(key: TypeConstructor) = map[key.declarationDescriptor]
|
||||||
override fun isEmpty() = map.isEmpty()
|
override fun isEmpty() = map.isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
public fun create(typeConstructor: TypeConstructor, arguments: List<TypeProjection>): TypeSubstitution {
|
||||||
|
val parameters = typeConstructor.parameters
|
||||||
|
|
||||||
|
if (parameters.lastOrNull()?.isCapturedFromOuterDeclaration ?: false) {
|
||||||
|
return createByConstructorsMap(typeConstructor.parameters.map { it.typeConstructor }.zip(arguments).toMap())
|
||||||
|
}
|
||||||
|
|
||||||
|
return IndexedParametersSubstitution(parameters, arguments)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IndexedParametersSubstitution(
|
public class IndexedParametersSubstitution private constructor(
|
||||||
private val parameters: Array<TypeParameterDescriptor>,
|
private val parameters: Array<TypeParameterDescriptor>,
|
||||||
private val arguments: Array<TypeProjection>
|
private val arguments: Array<TypeProjection>
|
||||||
) : TypeSubstitution() {
|
) : TypeSubstitution() {
|
||||||
@@ -72,10 +84,6 @@ public class IndexedParametersSubstitution(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
|
||||||
typeConstructor: TypeConstructor, argumentsList: List<TypeProjection>
|
|
||||||
) : this(typeConstructor.parameters, argumentsList)
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
parameters: List<TypeParameterDescriptor>, argumentsList: List<TypeProjection>
|
parameters: List<TypeParameterDescriptor>, argumentsList: List<TypeProjection>
|
||||||
) : this(parameters.toTypedArray(), argumentsList.toTypedArray())
|
) : this(parameters.toTypedArray(), argumentsList.toTypedArray())
|
||||||
@@ -95,20 +103,20 @@ public class IndexedParametersSubstitution(
|
|||||||
}
|
}
|
||||||
|
|
||||||
public fun KotlinType.computeNewSubstitution(
|
public fun KotlinType.computeNewSubstitution(
|
||||||
newParameters: List<TypeParameterDescriptor>,
|
typeConstructor: TypeConstructor,
|
||||||
newArguments: List<TypeProjection>
|
newArguments: List<TypeProjection>
|
||||||
): TypeSubstitution {
|
): TypeSubstitution {
|
||||||
val previousSubstitution = getSubstitution()
|
val previousSubstitution = getSubstitution()
|
||||||
if (newArguments.isEmpty()) return previousSubstitution
|
if (newArguments.isEmpty()) return previousSubstitution
|
||||||
|
|
||||||
val newIndexedSubstitution = IndexedParametersSubstitution(newParameters, newArguments)
|
val newSubstitution = TypeConstructorSubstitution.create(typeConstructor, newArguments)
|
||||||
|
|
||||||
// If previous substitution was trivial just replace it with indexed one
|
// If previous substitution was trivial just replace it with indexed one
|
||||||
if (previousSubstitution is IndexedParametersSubstitution || previousSubstitution.isEmpty()) {
|
if (previousSubstitution is IndexedParametersSubstitution || previousSubstitution.isEmpty()) {
|
||||||
return newIndexedSubstitution
|
return newSubstitution
|
||||||
}
|
}
|
||||||
|
|
||||||
val composedSubstitution = CompositeTypeSubstitution(newIndexedSubstitution, previousSubstitution)
|
val composedSubstitution = CompositeTypeSubstitution(newSubstitution, previousSubstitution)
|
||||||
|
|
||||||
return composedSubstitution
|
return composedSubstitution
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class TypeSubstitutor {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static TypeSubstitutor create(@NotNull KotlinType context) {
|
public static TypeSubstitutor create(@NotNull KotlinType context) {
|
||||||
return create(new IndexedParametersSubstitution(context.getConstructor(), context.getArguments()));
|
return create(TypeConstructorSubstitution.create(context.getConstructor(), context.getArguments()));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
+2
-5
@@ -31,10 +31,7 @@ import org.jetbrains.kotlin.resolve.TypeResolver
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl
|
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
|
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
|
||||||
import org.jetbrains.kotlin.types.IndexedParametersSubstitution
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.types.SubstitutionUtils
|
|
||||||
import org.jetbrains.kotlin.types.Variance
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
public class HeuristicSignatures(
|
public class HeuristicSignatures(
|
||||||
@@ -70,7 +67,7 @@ public class HeuristicSignatures(
|
|||||||
|
|
||||||
val type = typeFromText(typeStr, typeParameters)
|
val type = typeFromText(typeStr, typeParameters)
|
||||||
|
|
||||||
val substitutor = IndexedParametersSubstitution(ownerClass.typeConstructor, ownerType.arguments).buildSubstitutor()
|
val substitutor = TypeConstructorSubstitution.create(ownerClass.typeConstructor, ownerType.arguments).buildSubstitutor()
|
||||||
return substitutor.substitute(type, Variance.INVARIANT)
|
return substitutor.substitute(type, Variance.INVARIANT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
|||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.renderer.render
|
import org.jetbrains.kotlin.renderer.render
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.types.IndexedParametersSubstitution
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.TypeConstructorSubstitution
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -68,7 +68,7 @@ public object SuperClassNotInitialized : KotlinIntentionActionsFactory() {
|
|||||||
if (classOrObjectDeclaration is KtClass) {
|
if (classOrObjectDeclaration is KtClass) {
|
||||||
val superType = classDescriptor.getTypeConstructor().getSupertypes().firstOrNull { it.getConstructor().getDeclarationDescriptor() == superClass }
|
val superType = classDescriptor.getTypeConstructor().getSupertypes().firstOrNull { it.getConstructor().getDeclarationDescriptor() == superClass }
|
||||||
if (superType != null) {
|
if (superType != null) {
|
||||||
val substitutor = IndexedParametersSubstitution(superClass.typeConstructor, superType.arguments).buildSubstitutor()
|
val substitutor = TypeConstructorSubstitution.create(superClass.typeConstructor, superType.arguments).buildSubstitutor()
|
||||||
|
|
||||||
val substitutedConstructors = constructors
|
val substitutedConstructors = constructors
|
||||||
.filter { it.getValueParameters().isNotEmpty() }
|
.filter { it.getValueParameters().isNotEmpty() }
|
||||||
|
|||||||
Reference in New Issue
Block a user