diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt index 02b2e0563b3..21c26a94662 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.ReflectionTypes import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil @@ -43,7 +44,6 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE -import org.jetbrains.kotlin.types.TypeUtils.makeConstantSubstitutor import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils @@ -324,4 +324,16 @@ fun getResolutionResultsCachedData(expression: KtExpression?, context: Resolutio val argumentCall = expression?.getCall(context.trace.getBindingContext()) ?: return null return context.resolutionResultsCache[argumentCall] -} \ No newline at end of file +} + +fun makeConstantSubstitutor(typeParameterDescriptors: Collection, type: KotlinType): TypeSubstitutor { + val constructors = typeParameterDescriptors.map { it.typeConstructor }.toSet() + val projection = TypeProjectionImpl(type) + + return TypeSubstitutor.create(object : TypeConstructorSubstitution() { + override operator fun get(key: TypeConstructor) = + if (key in constructors) projection else null + + override fun isEmpty() = false + }) +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/CommonSupertypes.java b/compiler/frontend/src/org/jetbrains/kotlin/types/CommonSupertypes.java index 4b0575fe5ca..f69df7300c6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/CommonSupertypes.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/CommonSupertypes.java @@ -29,10 +29,10 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; import org.jetbrains.kotlin.resolve.scopes.KtScope; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt; +import org.jetbrains.kotlin.utils.DFS; import java.util.*; -import static org.jetbrains.kotlin.types.TypeUtils.topologicallySortSuperclassesAndRecordAllInstances; import static org.jetbrains.kotlin.types.Variance.IN_VARIANCE; import static org.jetbrains.kotlin.types.Variance.OUT_VARIANCE; @@ -329,4 +329,57 @@ public class CommonSupertypes { markAll(type.getConstructor(), markerSet); } } + + @NotNull + public static List topologicallySortSuperclassesAndRecordAllInstances( + @NotNull KotlinType type, + @NotNull final Map> constructorToAllInstances, + @NotNull final Set visited + ) { + return DFS.dfs( + Collections.singletonList(type), + new DFS.Neighbors() { + @NotNull + @Override + public Iterable getNeighbors(KotlinType current) { + TypeSubstitutor substitutor = TypeSubstitutor.create(current); + Collection supertypes = current.getConstructor().getSupertypes(); + List result = new ArrayList(supertypes.size()); + for (KotlinType supertype : supertypes) { + if (visited.contains(supertype.getConstructor())) { + continue; + } + result.add(substitutor.safeSubstitute(supertype, Variance.INVARIANT)); + } + return result; + } + }, + new DFS.Visited() { + @Override + public boolean checkAndMarkVisited(KotlinType current) { + return visited.add(current.getConstructor()); + } + }, + new DFS.NodeHandlerWithListResult() { + @Override + public boolean beforeChildren(KotlinType current) { + TypeConstructor constructor = current.getConstructor(); + + Set instances = constructorToAllInstances.get(constructor); + if (instances == null) { + instances = new HashSet(); + constructorToAllInstances.put(constructor, instances); + } + instances.add(current); + + return true; + } + + @Override + public void afterChildren(KotlinType current) { + result.addFirst(current.getConstructor()); + } + } + ); + } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java index 08f8f974908..0107a312d03 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java @@ -28,14 +28,11 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor; import org.jetbrains.kotlin.resolve.scopes.KtScope; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; -import org.jetbrains.kotlin.utils.DFS; import java.util.*; public class TypeUtils { public static final KotlinType DONT_CARE = ErrorUtils.createErrorTypeWithCustomDebugName("DONT_CARE"); - public static final KotlinType PLACEHOLDER_FUNCTION_TYPE = ErrorUtils.createErrorTypeWithCustomDebugName("PLACEHOLDER_FUNCTION_TYPE"); - public static final KotlinType CANT_INFER_FUNCTION_PARAM_TYPE = ErrorUtils.createErrorType("Cannot be inferred"); public static class SpecialType implements KotlinType { @@ -331,10 +328,8 @@ public class TypeUtils { if (FlexibleTypesKt.isFlexible(type) && acceptsNullable(FlexibleTypesKt.flexibility(type).getUpperBound())) { return true; } - if (isTypeParameter(type)) { - return hasNullableLowerBound((TypeParameterDescriptor) type.getConstructor().getDeclarationDescriptor()); - } - return false; + TypeParameterDescriptor typeParameterDescriptor = getTypeParameterDescriptorOrNull(type); + return typeParameterDescriptor != null && hasNullableLowerBound(typeParameterDescriptor); } public static boolean hasNullableSuperType(@NotNull KotlinType type) { @@ -493,82 +488,6 @@ public class TypeUtils { return getDefaultPrimitiveNumberType(numberValueTypeConstructor); } - public static List topologicallySortSuperclassesAndRecordAllInstances( - @NotNull KotlinType type, - @NotNull final Map> constructorToAllInstances, - @NotNull final Set visited - ) { - return DFS.dfs( - Collections.singletonList(type), - new DFS.Neighbors() { - @NotNull - @Override - public Iterable getNeighbors(KotlinType current) { - TypeSubstitutor substitutor = TypeSubstitutor.create(current); - Collection supertypes = current.getConstructor().getSupertypes(); - List result = new ArrayList(supertypes.size()); - for (KotlinType supertype : supertypes) { - if (visited.contains(supertype.getConstructor())) { - continue; - } - result.add(substitutor.safeSubstitute(supertype, Variance.INVARIANT)); - } - return result; - } - }, - new DFS.Visited() { - @Override - public boolean checkAndMarkVisited(KotlinType current) { - return visited.add(current.getConstructor()); - } - }, - new DFS.NodeHandlerWithListResult() { - @Override - public boolean beforeChildren(KotlinType current) { - TypeConstructor constructor = current.getConstructor(); - - Set instances = constructorToAllInstances.get(constructor); - if (instances == null) { - instances = new HashSet(); - constructorToAllInstances.put(constructor, instances); - } - instances.add(current); - - return true; - } - - @Override - public void afterChildren(KotlinType current) { - result.addFirst(current.getConstructor()); - } - } - ); - } - - public static TypeSubstitutor makeConstantSubstitutor(Collection typeParameterDescriptors, KotlinType type) { - final Set constructors = org.jetbrains.kotlin.utils.CollectionsKt - .newHashSetWithExpectedSize(typeParameterDescriptors.size()); - for (TypeParameterDescriptor typeParameterDescriptor : typeParameterDescriptors) { - constructors.add(typeParameterDescriptor.getTypeConstructor()); - } - final TypeProjection projection = new TypeProjectionImpl(type); - - return TypeSubstitutor.create(new TypeConstructorSubstitution() { - @Override - public TypeProjection get(@NotNull TypeConstructor key) { - if (constructors.contains(key)) { - return projection; - } - return null; - } - - @Override - public boolean isEmpty() { - return false; - } - }); - } - public static boolean isTypeParameter(@NotNull KotlinType type) { return getTypeParameterDescriptorOrNull(type) != null; } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt index fc821f07365..d3af0a84fa4 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt @@ -48,9 +48,9 @@ import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.KtSecondaryConstructor import org.jetbrains.kotlin.resolve.BindingContextUtils import org.jetbrains.kotlin.resolve.DescriptorUtils.* +import org.jetbrains.kotlin.types.CommonSupertypes.topologicallySortSuperclassesAndRecordAllInstances import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeConstructor -import org.jetbrains.kotlin.types.TypeUtils.topologicallySortSuperclassesAndRecordAllInstances import org.jetbrains.kotlin.utils.identity import java.util.*