diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt index 57c48db362d..def8c1e84bc 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt @@ -456,7 +456,7 @@ private object ConstantStarSubstitution : TypeSubstitution() { val newProjections = key.constructor.parameters.map(::StarProjectionImpl) - val substitution = IndexedParametersSubstitution(key.constructor, newProjections) + val substitution = TypeConstructorSubstitution.create(key.constructor, newProjections) return TypeProjectionImpl( TypeSubstitutor.create(substitution).substitute(key.constructor.declarationDescriptor!!.defaultType, Variance.INVARIANT)!! diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhacement/typeEnhancement.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhacement/typeEnhancement.kt index 48926026eb4..f74da347354 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhacement/typeEnhancement.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhacement/typeEnhancement.kt @@ -101,7 +101,7 @@ private fun KotlinType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers ).filterNotNull().compositeAnnotationsOrSingle() val newSubstitution = computeNewSubstitution( - typeConstructor.parameters, enhancedArguments + typeConstructor, enhancedArguments ) val enhancedType = KotlinTypeImpl.create( diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java index 6a98d99afb4..4c67b8ab5d6 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java @@ -89,7 +89,7 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor { + " for " + getTypeConstructor() + " " + getTypeConstructor().getParameters(); if (typeArguments.isEmpty()) return getUnsubstitutedMemberScope(); - TypeSubstitutor substitutor = new IndexedParametersSubstitution(getTypeConstructor(), typeArguments).buildSubstitutor(); + TypeSubstitutor substitutor = TypeConstructorSubstitution.create(getTypeConstructor(), typeArguments).buildSubstitutor(); return new SubstitutingScope(getUnsubstitutedMemberScope(), substitutor); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/AbstractLazyType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/AbstractLazyType.kt index 2a4af142653..fdf31502d4f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/AbstractLazyType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/AbstractLazyType.kt @@ -34,7 +34,7 @@ public abstract class AbstractLazyType(storageManager: StorageManager) : Abstrac protected abstract fun computeArguments(): List - override fun getSubstitution() = computeCustomSubstitution() ?: IndexedParametersSubstitution(constructor, getArguments()) + override fun getSubstitution() = computeCustomSubstitution() ?: TypeConstructorSubstitution.create(constructor, getArguments()) protected open fun computeCustomSubstitution(): TypeSubstitution? = getCapability()?.substitution diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java index 6a3f90adf3c..0ebce7a7c8d 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java @@ -512,7 +512,7 @@ public class ErrorUtils { @NotNull @Override public TypeSubstitution getSubstitution() { - return new IndexedParametersSubstitution(constructor, arguments); + return TypeConstructorSubstitution.create(constructor, arguments); } @Override diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeImpl.kt index bc281f85e12..fa1b9cf72a8 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeImpl.kt @@ -88,7 +88,7 @@ private constructor( override fun getSubstitution(): TypeSubstitution { if (substitution == null) { - return IndexedParametersSubstitution(getConstructor(), getArguments()) + return TypeConstructorSubstitution.create(getConstructor(), getArguments()) } return substitution } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt index e00a1e008d4..98da0a7ea8e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.types +import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor 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 isEmpty() = map.isEmpty() } + + @JvmStatic + public fun create(typeConstructor: TypeConstructor, arguments: List): 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, private val arguments: Array ) : TypeSubstitution() { @@ -72,10 +84,6 @@ public class IndexedParametersSubstitution( } } - constructor( - typeConstructor: TypeConstructor, argumentsList: List - ) : this(typeConstructor.parameters, argumentsList) - constructor( parameters: List, argumentsList: List ) : this(parameters.toTypedArray(), argumentsList.toTypedArray()) @@ -95,20 +103,20 @@ public class IndexedParametersSubstitution( } public fun KotlinType.computeNewSubstitution( - newParameters: List, - newArguments: List + typeConstructor: TypeConstructor, + newArguments: List ): TypeSubstitution { val previousSubstitution = getSubstitution() 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 (previousSubstitution is IndexedParametersSubstitution || previousSubstitution.isEmpty()) { - return newIndexedSubstitution + return newSubstitution } - val composedSubstitution = CompositeTypeSubstitution(newIndexedSubstitution, previousSubstitution) + val composedSubstitution = CompositeTypeSubstitution(newSubstitution, previousSubstitution) return composedSubstitution } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java index 58ba9d4f0d5..14237c15fd2 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java @@ -64,7 +64,7 @@ public class TypeSubstitutor { @NotNull public static TypeSubstitutor create(@NotNull KotlinType context) { - return create(new IndexedParametersSubstitution(context.getConstructor(), context.getArguments())); + return create(TypeConstructorSubstitution.create(context.getConstructor(), context.getArguments())); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/HeuristicSignatures.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/HeuristicSignatures.kt index 9574611ed66..843791b193e 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/HeuristicSignatures.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/HeuristicSignatures.kt @@ -31,10 +31,7 @@ import org.jetbrains.kotlin.resolve.TypeResolver import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope -import org.jetbrains.kotlin.types.IndexedParametersSubstitution -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.SubstitutionUtils -import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.types.* import java.util.* public class HeuristicSignatures( @@ -70,7 +67,7 @@ public class HeuristicSignatures( 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) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/SuperClassNotInitialized.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/SuperClassNotInitialized.kt index 62fab84d1b0..19e6ddbcb22 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/SuperClassNotInitialized.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/SuperClassNotInitialized.kt @@ -39,8 +39,8 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.render import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.types.IndexedParametersSubstitution import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeConstructorSubstitution import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf import org.jetbrains.kotlin.utils.addIfNotNull import java.util.* @@ -68,7 +68,7 @@ public object SuperClassNotInitialized : KotlinIntentionActionsFactory() { if (classOrObjectDeclaration is KtClass) { val superType = classDescriptor.getTypeConstructor().getSupertypes().firstOrNull { it.getConstructor().getDeclarationDescriptor() == superClass } if (superType != null) { - val substitutor = IndexedParametersSubstitution(superClass.typeConstructor, superType.arguments).buildSubstitutor() + val substitutor = TypeConstructorSubstitution.create(superClass.typeConstructor, superType.arguments).buildSubstitutor() val substitutedConstructors = constructors .filter { it.getValueParameters().isNotEmpty() }