diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/InternalFlexibleTypeTransformer.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/InternalFlexibleTypeTransformer.kt index bf26dc7affe..72873674616 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/InternalFlexibleTypeTransformer.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/InternalFlexibleTypeTransformer.kt @@ -16,12 +16,11 @@ package org.jetbrains.kotlin.load.java -import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeResolver.FlexibleJavaClassifierTypeFactory import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.TypeResolver.TypeTransformerForTests -import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.* object InternalFlexibleTypeTransformer : TypeTransformerForTests() { // This is a "magic" classifier: when type resolver sees it in the code, e.g. ft, instead of creating a normal type, @@ -35,7 +34,7 @@ object InternalFlexibleTypeTransformer : TypeTransformerForTests() { val descriptor = kotlinType.constructor.declarationDescriptor if (descriptor != null && FLEXIBLE_TYPE_CLASSIFIER.asSingleFqName().toUnsafe() == DescriptorUtils.getFqName(descriptor) && kotlinType.arguments.size == 2) { - return FlexibleJavaClassifierTypeFactory.create(kotlinType.arguments[0].type, kotlinType.arguments[1].type) + return KotlinTypeFactory.flexibleType(kotlinType.arguments[0].type.asSimpleType(), kotlinType.arguments[1].type.asSimpleType()) } return null } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SingleAbstractMethodUtils.java b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SingleAbstractMethodUtils.java index 44b25ba587f..33e160041b7 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SingleAbstractMethodUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SingleAbstractMethodUtils.java @@ -72,7 +72,8 @@ public class SingleAbstractMethodUtils { "' should not end with conflict"; if (FlexibleTypesKt.isNullabilityFlexible(samType)) { - return LazyJavaTypeResolver.FlexibleJavaClassifierTypeFactory.INSTANCE.create(type, TypeUtils.makeNullable(type)); + SimpleType simpleType = KotlinTypeKt.asSimpleType(type); + return KotlinTypeFactory.flexibleType(simpleType, TypeUtils.makeNullable(simpleType)); } return TypeUtils.makeNullableAsSpecified(type, samType.isMarkedNullable()); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/CommonSupertypes.java b/compiler/frontend/src/org/jetbrains/kotlin/types/CommonSupertypes.java index b804d3ebf19..c3a95829002 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/CommonSupertypes.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/CommonSupertypes.java @@ -83,9 +83,8 @@ public class CommonSupertypes { private static KotlinType findCommonSupertype(@NotNull Collection types, int recursionDepth, int maxDepth) { assert recursionDepth <= maxDepth : "Recursion depth exceeded: " + recursionDepth + " > " + maxDepth + " for types " + types; boolean hasFlexible = false; - List upper = new ArrayList(types.size()); - List lower = new ArrayList(types.size()); - Set factories = new LinkedHashSet(); + List upper = new ArrayList(types.size()); + List lower = new ArrayList(types.size()); for (KotlinType type : types) { if (FlexibleTypesKt.isFlexible(type)) { if (DynamicTypesKt.isDynamic(type)) { @@ -95,33 +94,33 @@ public class CommonSupertypes { Flexibility flexibility = FlexibleTypesKt.flexibility(type); upper.add(flexibility.getUpperBound()); lower.add(flexibility.getLowerBound()); - factories.add(flexibility.getFactory()); } else { - upper.add(type); - lower.add(type); + upper.add(KotlinTypeKt.asSimpleType(type)); + lower.add(KotlinTypeKt.asSimpleType(type)); } } - if (!hasFlexible) return commonSuperTypeForInflexible(types, recursionDepth, maxDepth); - return CollectionsKt.single(factories).create( // mixing different factories is not supported + if (!hasFlexible) return commonSuperTypeForInflexible(upper, recursionDepth, maxDepth); + return KotlinTypeFactory.flexibleType( // mixing different factories is not supported commonSuperTypeForInflexible(lower, recursionDepth, maxDepth), commonSuperTypeForInflexible(upper, recursionDepth, maxDepth) ); } @NotNull - private static KotlinType commonSuperTypeForInflexible(@NotNull Collection types, int recursionDepth, int maxDepth) { + private static SimpleType commonSuperTypeForInflexible(@NotNull Collection types, int recursionDepth, int maxDepth) { assert !types.isEmpty(); - Collection typeSet = new HashSet(types); + Collection typeSet = new HashSet(types); + // todo: dead code? KotlinType bestFit = FlexibleTypesKt.singleBestRepresentative(typeSet); - if (bestFit != null) return bestFit; + if (bestFit != null) return KotlinTypeKt.asSimpleType(bestFit); // If any of the types is nullable, the result must be nullable // This also removed Nothing and Nothing? because they are subtypes of everything else boolean nullable = false; - for (Iterator iterator = typeSet.iterator(); iterator.hasNext();) { + for (Iterator iterator = typeSet.iterator(); iterator.hasNext();) { KotlinType type = iterator.next(); assert type != null; assert !FlexibleTypesKt.isFlexible(type) : "Flexible type " + type + " passed to commonSuperTypeForInflexible"; @@ -146,10 +145,10 @@ public class CommonSupertypes { } // constructor of the supertype -> all of its instantiations occurring as supertypes - Map> commonSupertypes = computeCommonRawSupertypes(typeSet); + Map> commonSupertypes = computeCommonRawSupertypes(typeSet); while (commonSupertypes.size() > 1) { - Set merge = new HashSet(); - for (Set supertypes : commonSupertypes.values()) { + Set merge = new HashSet(); + for (Set supertypes : commonSupertypes.values()) { merge.addAll(supertypes); } commonSupertypes = computeCommonRawSupertypes(merge); @@ -157,24 +156,24 @@ public class CommonSupertypes { assert !commonSupertypes.isEmpty() : commonSupertypes + " <- " + types; // constructor of the supertype -> all of its instantiations occurring as supertypes - Map.Entry> entry = commonSupertypes.entrySet().iterator().next(); + Map.Entry> entry = commonSupertypes.entrySet().iterator().next(); // Reconstructing type arguments if possible - KotlinType result = computeSupertypeProjections(entry.getKey(), entry.getValue(), recursionDepth, maxDepth); + SimpleType result = computeSupertypeProjections(entry.getKey(), entry.getValue(), recursionDepth, maxDepth); return TypeUtils.makeNullableIfNeeded(result, nullable); } // Raw supertypes are superclasses w/o type arguments // @return TypeConstructor -> all instantiations of this constructor occurring as supertypes @NotNull - private static Map> computeCommonRawSupertypes(@NotNull Collection types) { + private static Map> computeCommonRawSupertypes(@NotNull Collection types) { assert !types.isEmpty(); - Map> constructorToAllInstances = new HashMap>(); + Map> constructorToAllInstances = new HashMap>(); Set commonSuperclasses = null; List order = null; - for (KotlinType type : types) { + for (SimpleType type : types) { Set visited = new HashSet(); order = topologicallySortSuperclassesAndRecordAllInstances(type, constructorToAllInstances, visited); @@ -188,7 +187,7 @@ public class CommonSupertypes { assert order != null; Set notSource = new HashSet(); - Map> result = new HashMap>(); + Map> result = new HashMap>(); for (TypeConstructor superConstructor : order) { if (!commonSuperclasses.contains(superConstructor)) { continue; @@ -206,7 +205,7 @@ public class CommonSupertypes { // constructor - type constructor of a supertype to be instantiated // types - instantiations of constructor occurring as supertypes of classes we are trying to intersect @NotNull - private static KotlinType computeSupertypeProjections(@NotNull TypeConstructor constructor, @NotNull Set types, int recursionDepth, int maxDepth) { + private static SimpleType computeSupertypeProjections(@NotNull TypeConstructor constructor, @NotNull Set types, int recursionDepth, int maxDepth) { // we assume that all the given types are applications of the same type constructor assert !types.isEmpty(); @@ -332,42 +331,42 @@ public class CommonSupertypes { @NotNull public static List topologicallySortSuperclassesAndRecordAllInstances( - @NotNull KotlinType type, - @NotNull final Map> constructorToAllInstances, + @NotNull SimpleType type, + @NotNull final Map> constructorToAllInstances, @NotNull final Set visited ) { return DFS.dfs( Collections.singletonList(type), - new DFS.Neighbors() { + new DFS.Neighbors() { @NotNull @Override - public Iterable getNeighbors(KotlinType current) { + public Iterable getNeighbors(SimpleType current) { TypeSubstitutor substitutor = TypeSubstitutor.create(current); Collection supertypes = current.getConstructor().getSupertypes(); - List result = new ArrayList(supertypes.size()); + List result = new ArrayList(supertypes.size()); for (KotlinType supertype : supertypes) { if (visited.contains(supertype.getConstructor())) { continue; } - result.add(substitutor.safeSubstitute(supertype, Variance.INVARIANT)); + result.add(KotlinTypeKt.asSimpleType(substitutor.safeSubstitute(supertype, Variance.INVARIANT))); } return result; } }, - new DFS.Visited() { + new DFS.Visited() { @Override - public boolean checkAndMarkVisited(KotlinType current) { + public boolean checkAndMarkVisited(SimpleType current) { return visited.add(current.getConstructor()); } }, - new DFS.NodeHandlerWithListResult() { + new DFS.NodeHandlerWithListResult() { @Override - public boolean beforeChildren(KotlinType current) { + public boolean beforeChildren(SimpleType current) { TypeConstructor constructor = current.getConstructor(); - Set instances = constructorToAllInstances.get(constructor); + Set instances = constructorToAllInstances.get(constructor); if (instances == null) { - instances = new HashSet(); + instances = new HashSet(); constructorToAllInstances.put(constructor, instances); } instances.add(current); @@ -376,7 +375,7 @@ public class CommonSupertypes { } @Override - public void afterChildren(KotlinType current) { + public void afterChildren(SimpleType current) { result.addFirst(current.getConstructor()); } } diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/FlexibleTypeAssertionsEnabledTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/FlexibleTypeAssertionsEnabledTest.kt index dd3a6c8f433..307bce216f5 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/FlexibleTypeAssertionsEnabledTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/FlexibleTypeAssertionsEnabledTest.kt @@ -17,8 +17,8 @@ package org.jetbrains.kotlin.jvm.compiler import org.jetbrains.kotlin.builtins.DefaultBuiltIns -import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeResolver import org.jetbrains.kotlin.test.KotlinTestWithEnvironmentManagement +import org.jetbrains.kotlin.types.KotlinTypeFactory class FlexibleTypeAssertionsEnabledTest : KotlinTestWithEnvironmentManagement() { @@ -26,8 +26,7 @@ class FlexibleTypeAssertionsEnabledTest : KotlinTestWithEnvironmentManagement() val builtIns = DefaultBuiltIns.Instance try { - LazyJavaTypeResolver.FlexibleJavaClassifierTypeFactory.create( - builtIns.intType, builtIns.stringType).arguments + KotlinTypeFactory.flexibleType(builtIns.intType, builtIns.stringType).arguments } catch (e: AssertionError) { assertEquals("Lower bound Int of a flexible type must be a subtype of the upper bound String", e.message) return diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaTypeParameterDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaTypeParameterDescriptor.kt index d1cd72d1012..48972057ae7 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaTypeParameterDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaTypeParameterDescriptor.kt @@ -22,10 +22,10 @@ import org.jetbrains.kotlin.descriptors.impl.AbstractLazyTypeParameterDescriptor import org.jetbrains.kotlin.load.java.components.TypeUsage import org.jetbrains.kotlin.load.java.lazy.LazyJavaAnnotations import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext -import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeResolver import org.jetbrains.kotlin.load.java.lazy.types.toAttributes import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.KotlinTypeFactory import org.jetbrains.kotlin.types.Variance class LazyJavaTypeParameterDescriptor( @@ -47,7 +47,7 @@ class LazyJavaTypeParameterDescriptor( override fun resolveUpperBounds(): List { val bounds = javaTypeParameter.upperBounds if (bounds.isEmpty()) { - return listOf(LazyJavaTypeResolver.FlexibleJavaClassifierTypeFactory.create( + return listOf(KotlinTypeFactory.flexibleType( c.module.builtIns.anyType, c.module.builtIns.nullableAnyType )) 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 2b96a2e5f9e..da53aa8edf9 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 @@ -56,7 +56,7 @@ class LazyJavaTypeResolver( } is JavaClassifierType -> if (attr.allowFlexible && attr.howThisTypeIsUsed != SUPERTYPE) - FlexibleJavaClassifierTypeFactory.create( + KotlinTypeFactory.flexibleType( LazyJavaClassifierType(javaType, attr.toFlexible(FLEXIBLE_LOWER_BOUND)), LazyJavaClassifierType(javaType, attr.toFlexible(FLEXIBLE_UPPER_BOUND)) ) @@ -75,7 +75,7 @@ class LazyJavaTypeResolver( if (primitiveType != null) { val jetType = c.module.builtIns.getPrimitiveArrayKotlinType(primitiveType) return@run if (attr.allowFlexible) - FlexibleJavaClassifierTypeFactory.create(jetType, TypeUtils.makeNullable(jetType)) + KotlinTypeFactory.flexibleType(jetType, TypeUtils.makeNullable(jetType)) else TypeUtils.makeNullableAsSpecified(jetType, !attr.isMarkedNotNull) } @@ -83,7 +83,7 @@ class LazyJavaTypeResolver( TYPE_ARGUMENT.toAttributes(attr.allowFlexible, attr.isForAnnotationParameter)) if (attr.allowFlexible) { - return@run FlexibleJavaClassifierTypeFactory.create( + return@run KotlinTypeFactory.flexibleType( c.module.builtIns.getArrayType(INVARIANT, componentType), TypeUtils.makeNullable(c.module.builtIns.getArrayType(OUT_VARIANCE, componentType))) } @@ -280,38 +280,6 @@ class LazyJavaTypeResolver( override val isMarkedNullable: Boolean get() = nullable() } - object FlexibleJavaClassifierTypeFactory : FlexibleTypeFactory { - override val id: String get() = "kotlin.jvm.PlatformType" - - override fun create(lowerBound: KotlinType, upperBound: KotlinType): KotlinType { - if (lowerBound == upperBound) return lowerBound - - return Impl(lowerBound, upperBound) - } - - private class Impl(lowerBound: KotlinType, upperBound: KotlinType) : - DelegatingFlexibleType(lowerBound, upperBound, FlexibleJavaClassifierTypeFactory), CustomTypeVariable { - - override val delegateType: KotlinType get() = lowerBound - - override fun getCapability(capabilityClass: Class): T? { - @Suppress("UNCHECKED_CAST") - if (capabilityClass == CustomTypeVariable::class.java) return this as T - - return super.getCapability(capabilityClass) - } - - override val isTypeVariable: Boolean get() = lowerBound.constructor.declarationDescriptor is TypeParameterDescriptor - && lowerBound.constructor == upperBound.constructor - - override fun substitutionResult(replacement: KotlinType): KotlinType { - return if (replacement.isFlexible()) replacement - else create(replacement, TypeUtils.makeNullable(replacement)) - } - - } - } - } internal fun makeStarProjection( diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt index c5cbf252122..0bfa3dfc4f3 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt @@ -91,7 +91,7 @@ internal object RawSubstitution : TypeSubstitution() { is ClassDescriptor -> { val lower = type.lowerIfFlexible() val upper = type.upperIfFlexible() - LazyJavaTypeResolver.FlexibleJavaClassifierTypeFactory.create( + KotlinTypeFactory.flexibleType( eraseInflexibleBasedOnClassDescriptor(lower, declaration, lowerTypeAttr), eraseInflexibleBasedOnClassDescriptor(upper, declaration, upperTypeAttr) ) @@ -100,7 +100,7 @@ internal object RawSubstitution : TypeSubstitution() { } } - private fun eraseInflexibleBasedOnClassDescriptor(type: KotlinType, declaration: ClassDescriptor, attr: JavaTypeAttributes): KotlinType { + private fun eraseInflexibleBasedOnClassDescriptor(type: KotlinType, declaration: ClassDescriptor, attr: JavaTypeAttributes): SimpleType { if (KotlinBuiltIns.isArray(type)) { val componentTypeProjection = type.arguments[0] val arguments = listOf( diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt index 254bed5c7dd..11f7d60a8b3 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt @@ -70,7 +70,7 @@ private fun KotlinType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQual val wereChanges = lowerResult.wereChanges || upperResult.wereChanges Result( if (wereChanges) - factory.create(lowerResult.type, upperResult.type) + KotlinTypeFactory.flexibleType(lowerResult.type.asSimpleType(), upperResult.type.asSimpleType()) else this@enhancePossiblyFlexible, lowerResult.subtreeSize, @@ -228,7 +228,7 @@ internal object NotNullTypeParameterTypeCapability : CustomTypeVariable { if (replacement.isFlexible()) { with(replacement.flexibility()) { - return factory.create(lowerBound.prepareReplacement(), upperBound.prepareReplacement()) + return KotlinTypeFactory.flexibleType(lowerBound.prepareReplacement().asSimpleType(), upperBound.prepareReplacement().asSimpleType()) } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt index b268dd7625f..dcda3223632 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt @@ -19,9 +19,9 @@ package org.jetbrains.kotlin.load.kotlin import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.load.java.lazy.LazyJavaPackageFragmentProvider -import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeResolver.FlexibleJavaClassifierTypeFactory import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.types.FlexibleJavaClassifierTypeFactory // This class is needed only for easier injection: exact types of needed components are specified in the constructor here. // Otherwise injector generator is not smart enough to deduce, for example, which package fragment provider DeserializationComponents needs diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/UnsafeVarianceTypeSubstitution.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/UnsafeVarianceTypeSubstitution.kt index dceb6684406..8facb39b1a0 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/UnsafeVarianceTypeSubstitution.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/UnsafeVarianceTypeSubstitution.kt @@ -45,9 +45,9 @@ internal class UnsafeVarianceTypeSubstitution(kotlinBuiltIns: KotlinBuiltIns) : if (unsafeVariancePaths.isEmpty()) return this if (isFlexible()) { - return flexibility().factory.create( - lowerIfFlexible().annotatePartsWithUnsafeVariance(subPathsWithIndex(unsafeVariancePaths, 0)), - upperIfFlexible().annotatePartsWithUnsafeVariance(subPathsWithIndex(unsafeVariancePaths, 1)) + return KotlinTypeFactory.flexibleType( + lowerIfFlexible().annotatePartsWithUnsafeVariance(subPathsWithIndex(unsafeVariancePaths, 0)).asSimpleType(), + upperIfFlexible().annotatePartsWithUnsafeVariance(subPathsWithIndex(unsafeVariancePaths, 1)).asSimpleType() ) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java index 590a8b8448f..b95c64fecc7 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java @@ -70,9 +70,9 @@ public abstract class KotlinBuiltIns { private final Set builtInsPackageFragments; - private final Map primitiveTypeToArrayKotlinType; - private final Map primitiveKotlinTypeToKotlinArrayType; - private final Map kotlinArrayTypeToPrimitiveKotlinType; + private final Map primitiveTypeToArrayKotlinType; + private final Map primitiveKotlinTypeToKotlinArrayType; + private final Map kotlinArrayTypeToPrimitiveKotlinType; private final StorageManager storageManager; public static final FqNames FQ_NAMES = new FqNames(); @@ -108,9 +108,9 @@ public abstract class KotlinBuiltIns { builtInsPackageFragments = new LinkedHashSet(packageNameToPackageFragment.values()); - primitiveTypeToArrayKotlinType = new EnumMap(PrimitiveType.class); - primitiveKotlinTypeToKotlinArrayType = new HashMap(); - kotlinArrayTypeToPrimitiveKotlinType = new HashMap(); + primitiveTypeToArrayKotlinType = new EnumMap(PrimitiveType.class); + primitiveKotlinTypeToKotlinArrayType = new HashMap(); + kotlinArrayTypeToPrimitiveKotlinType = new HashMap(); for (PrimitiveType primitive : PrimitiveType.values()) { makePrimitive(primitive); } @@ -127,8 +127,8 @@ public abstract class KotlinBuiltIns { } private void makePrimitive(@NotNull PrimitiveType primitiveType) { - KotlinType type = getBuiltInTypeByClassName(primitiveType.getTypeName().asString()); - KotlinType arrayType = getBuiltInTypeByClassName(primitiveType.getArrayTypeName().asString()); + SimpleType type = getBuiltInTypeByClassName(primitiveType.getTypeName().asString()); + SimpleType arrayType = getBuiltInTypeByClassName(primitiveType.getArrayTypeName().asString()); primitiveTypeToArrayKotlinType.put(primitiveType, arrayType); primitiveKotlinTypeToKotlinArrayType.put(type, arrayType); @@ -601,7 +601,7 @@ public abstract class KotlinBuiltIns { } @NotNull - private KotlinType getBuiltInTypeByClassName(@NotNull String classSimpleName) { + private SimpleType getBuiltInTypeByClassName(@NotNull String classSimpleName) { return getBuiltInClassByName(classSimpleName).getDefaultType(); } @@ -626,7 +626,7 @@ public abstract class KotlinBuiltIns { } @NotNull - public KotlinType getDefaultBound() { + public SimpleType getDefaultBound() { return getNullableAnyType(); } @@ -636,42 +636,42 @@ public abstract class KotlinBuiltIns { } @NotNull - public KotlinType getByteType() { + public SimpleType getByteType() { return getPrimitiveKotlinType(BYTE); } @NotNull - public KotlinType getShortType() { + public SimpleType getShortType() { return getPrimitiveKotlinType(SHORT); } @NotNull - public KotlinType getIntType() { + public SimpleType getIntType() { return getPrimitiveKotlinType(INT); } @NotNull - public KotlinType getLongType() { + public SimpleType getLongType() { return getPrimitiveKotlinType(LONG); } @NotNull - public KotlinType getFloatType() { + public SimpleType getFloatType() { return getPrimitiveKotlinType(FLOAT); } @NotNull - public KotlinType getDoubleType() { + public SimpleType getDoubleType() { return getPrimitiveKotlinType(DOUBLE); } @NotNull - public KotlinType getCharType() { + public SimpleType getCharType() { return getPrimitiveKotlinType(CHAR); } @NotNull - public KotlinType getBooleanType() { + public SimpleType getBooleanType() { return getPrimitiveKotlinType(BOOLEAN); } @@ -681,7 +681,7 @@ public abstract class KotlinBuiltIns { } @NotNull - public KotlinType getStringType() { + public SimpleType getStringType() { return getString().getDefaultType(); } @@ -701,7 +701,7 @@ public abstract class KotlinBuiltIns { } @NotNull - public KotlinType getPrimitiveArrayKotlinType(@NotNull PrimitiveType primitiveType) { + public SimpleType getPrimitiveArrayKotlinType(@NotNull PrimitiveType primitiveType) { return primitiveTypeToArrayKotlinType.get(primitiveType); } @@ -709,8 +709,8 @@ public abstract class KotlinBuiltIns { * @return {@code null} if not primitive */ @Nullable - public KotlinType getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(@NotNull KotlinType kotlinType) { - return primitiveKotlinTypeToKotlinArrayType.get(kotlinType); + public SimpleType getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(@NotNull KotlinType kotlinType) { + return primitiveKotlinTypeToKotlinArrayType.get(kotlinType); // todo unwrap } public static boolean isPrimitiveArray(@NotNull FqNameUnsafe arrayFqName) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/CapturedTypeApproximation.kt b/core/descriptors/src/org/jetbrains/kotlin/types/CapturedTypeApproximation.kt index 835424aad92..f6e3e30db32 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/CapturedTypeApproximation.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/CapturedTypeApproximation.kt @@ -97,10 +97,9 @@ fun approximateCapturedTypes(type: KotlinType): ApproximationBounds val boundsForFlexibleLower = approximateCapturedTypes(type.lowerIfFlexible()) val boundsForFlexibleUpper = approximateCapturedTypes(type.upperIfFlexible()) - val factory = type.flexibility().factory return ApproximationBounds( - factory.create(boundsForFlexibleLower.lower.lowerIfFlexible(), boundsForFlexibleUpper.lower.upperIfFlexible()), - factory.create(boundsForFlexibleLower.upper.lowerIfFlexible(), boundsForFlexibleUpper.upper.upperIfFlexible())) + KotlinTypeFactory.flexibleType(boundsForFlexibleLower.lower.lowerIfFlexible(), boundsForFlexibleUpper.lower.upperIfFlexible()), + KotlinTypeFactory.flexibleType(boundsForFlexibleLower.upper.lowerIfFlexible(), boundsForFlexibleUpper.upper.upperIfFlexible())) } val typeConstructor = type.constructor diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt index cab66c87f0a..2bc772662f4 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt @@ -47,4 +47,10 @@ object KotlinTypeFactory { nullable: Boolean = baseType.isMarkedNullable, memberScope: MemberScope = baseType.memberScope ): SimpleType = simpleType(annotations, constructor, arguments, nullable, memberScope) + + @JvmStatic + fun flexibleType(lowerBound: SimpleType, upperBound: SimpleType): KotlinType { + if (lowerBound == upperBound) return lowerBound + return FlexibleTypeImpl(lowerBound, upperBound) + } } \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java index 8c29574ae60..25c07157c8f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java @@ -133,6 +133,10 @@ public class TypeSubstitutor { // The type is within the substitution range, i.e. T or T? KotlinType type = originalProjection.getType(); + if (DynamicTypesKt.isDynamic(type)) { + return originalProjection; // todo investigate + } + TypeProjection replacement = substitution.get(type); Variance originalProjectionKind = originalProjection.getProjectionKind(); if (replacement == null && FlexibleTypesKt.isFlexible(type) && !TypeCapabilitiesKt.isCustomTypeVariable(type)) { @@ -147,8 +151,8 @@ public class TypeSubstitutor { originalProjectionKind == Variance.INVARIANT || originalProjectionKind == substitutedProjectionKind : "Unexpected substituted projection kind: " + substitutedProjectionKind + "; original: " + originalProjectionKind; - KotlinType substitutedFlexibleType = flexibility.getFactory().create( - substitutedLower.getType(), substitutedUpper.getType()); + KotlinType substitutedFlexibleType = KotlinTypeFactory.flexibleType( + KotlinTypeKt.asSimpleType(substitutedLower.getType()), KotlinTypeKt.asSimpleType(substitutedUpper.getType())); return new TypeProjectionImpl(substitutedProjectionKind, substitutedFlexibleType); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java index 42ff6c720fe..94f4790488e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.java @@ -157,6 +157,11 @@ public class TypeUtils { return nullable ? new NullableType(type) : new NotNullType(type); } + @NotNull + public static SimpleType makeNullableIfNeeded(@NotNull SimpleType type, boolean nullable) { + return KotlinTypeKt.asSimpleType(makeNullableIfNeeded((KotlinType) type, nullable)); + } + @NotNull public static KotlinType makeNullableIfNeeded(@NotNull KotlinType type, boolean nullable) { if (nullable) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/dynamicTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/dynamicTypes.kt index 68c2c013c3f..c3c1c863a07 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/dynamicTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/dynamicTypes.kt @@ -32,31 +32,30 @@ class DynamicTypesAllowed: DynamicTypesSettings() { fun KotlinType.isDynamic(): Boolean = this.getCapability(Flexibility::class.java)?.factory == DynamicTypeFactory -fun createDynamicType(builtIns: KotlinBuiltIns) = DynamicTypeFactory.create(builtIns.nothingType, builtIns.nullableAnyType) +fun createDynamicType(builtIns: KotlinBuiltIns) = DynamicType(builtIns) + +class DynamicType(builtIns: KotlinBuiltIns) : DelegatingFlexibleType(builtIns.nothingType, builtIns.nullableAnyType, DynamicTypeFactory) { + override val delegateType: KotlinType get() = upperBound + + override fun makeNullableAsSpecified(nullable: Boolean): KotlinType { + // Nullability has no effect on dynamics + return createDynamicType(delegateType.builtIns) + } + + override val isMarkedNullable: Boolean get() = false +} object DynamicTypeFactory : FlexibleTypeFactory { - override val id: String get() = "kotlin.DynamicType" - - override fun create(lowerBound: KotlinType, upperBound: KotlinType): KotlinType { + override fun create(lowerBound: SimpleType, upperBound: SimpleType): KotlinType { if (KotlinTypeChecker.FLEXIBLE_UNEQUAL_TO_INFLEXIBLE.equalTypes(lowerBound, lowerBound.builtIns.nothingType) && KotlinTypeChecker.FLEXIBLE_UNEQUAL_TO_INFLEXIBLE.equalTypes(upperBound, upperBound.builtIns.nullableAnyType)) { - return Impl(lowerBound, upperBound) + return createDynamicType(lowerBound.builtIns) } else { throw IllegalStateException("Illegal type range for dynamic type: $lowerBound..$upperBound") } } - private class Impl(lowerBound: KotlinType, upperBound: KotlinType) : - DelegatingFlexibleType(lowerBound, upperBound, DynamicTypeFactory) { - override val delegateType: KotlinType get() = upperBound - - override fun makeNullableAsSpecified(nullable: Boolean): KotlinType { - // Nullability has no effect on dynamics - return createDynamicType(delegateType.builtIns) - } - - override val isMarkedNullable: Boolean get() = false - } + override val id: String get() = "kotlin.DynamicType" } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt index e3930e7b341..fb5e841ca27 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt @@ -16,26 +16,27 @@ package org.jetbrains.kotlin.types +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.types.checker.KotlinTypeChecker interface FlexibleTypeFactory { val id: String - fun create(lowerBound: KotlinType, upperBound: KotlinType): KotlinType + fun create(lowerBound: SimpleType, upperBound: SimpleType): KotlinType object ThrowException : FlexibleTypeFactory { private fun error(): Nothing = throw IllegalArgumentException("This factory should not be used.") override val id: String get() = error() - override fun create(lowerBound: KotlinType, upperBound: KotlinType): KotlinType = error() + override fun create(lowerBound: SimpleType, upperBound: SimpleType): KotlinType = error() } } interface Flexibility : TypeCapability, SubtypingRepresentatives { // lowerBound is a subtype of upperBound - val lowerBound: KotlinType - val upperBound: KotlinType + val lowerBound: SimpleType + val upperBound: SimpleType val factory: FlexibleTypeFactory @@ -93,12 +94,12 @@ fun Collection.singleBestRepresentative(): TypeProjection? { return TypeProjectionImpl(projectionKinds.single(), bestType) } -fun KotlinType.lowerIfFlexible(): KotlinType = if (this.isFlexible()) this.flexibility().lowerBound else this -fun KotlinType.upperIfFlexible(): KotlinType = if (this.isFlexible()) this.flexibility().upperBound else this +fun KotlinType.lowerIfFlexible(): SimpleType = (if (this.isFlexible()) this.flexibility().lowerBound else this).asSimpleType() +fun KotlinType.upperIfFlexible(): SimpleType = (if (this.isFlexible()) this.flexibility().upperBound else this).asSimpleType() abstract class DelegatingFlexibleType protected constructor( - override val lowerBound: KotlinType, - override val upperBound: KotlinType, + override val lowerBound: SimpleType, + override val upperBound: SimpleType, override val factory: FlexibleTypeFactory ) : DelegatingType(), Flexibility { companion object { @@ -137,8 +138,7 @@ abstract class DelegatingFlexibleType protected constructor( } override fun makeNullableAsSpecified(nullable: Boolean): KotlinType { - return factory.create(TypeUtils.makeNullableAsSpecified(lowerBound, nullable), - TypeUtils.makeNullableAsSpecified(upperBound, nullable)) + return KotlinTypeFactory.flexibleType(TypeUtils.makeNullableAsSpecified(lowerBound, nullable), TypeUtils.makeNullableAsSpecified(upperBound, nullable)) } final override fun getDelegate(): KotlinType { @@ -148,3 +148,37 @@ abstract class DelegatingFlexibleType protected constructor( override fun toString() = "('$lowerBound'..'$upperBound')" } + +class FlexibleTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : + DelegatingFlexibleType(lowerBound, upperBound, FlexibleJavaClassifierTypeFactory), CustomTypeVariable { + + override val delegateType: KotlinType get() = lowerBound + + override fun getCapability(capabilityClass: Class): T? { + @Suppress("UNCHECKED_CAST") + if (capabilityClass == CustomTypeVariable::class.java) return this as T + + return super.getCapability(capabilityClass) + } + + override val isTypeVariable: Boolean get() = lowerBound.constructor.declarationDescriptor is TypeParameterDescriptor + && lowerBound.constructor == upperBound.constructor + + override fun substitutionResult(replacement: KotlinType): KotlinType { + if (replacement.isFlexible()) { + return replacement + } + else { + val simpleType = replacement.asSimpleType() + return KotlinTypeFactory.flexibleType(simpleType, TypeUtils.makeNullable(simpleType)) + } + } +} + +// TODO: move Factory to descriptor.loader.java +object FlexibleJavaClassifierTypeFactory : FlexibleTypeFactory { + override fun create(lowerBound: SimpleType, upperBound: SimpleType): KotlinType + = KotlinTypeFactory.flexibleType(lowerBound, upperBound) + + override val id: String get() = "kotlin.jvm.PlatformType" +} diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationDeserializer.kt index 27514f50fd5..67a9f17a28a 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationDeserializer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value import org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value.Type import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.SimpleType import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf @@ -143,7 +144,7 @@ class AnnotationDeserializer(private val module: ModuleDescriptor, private val n return factory.createErrorValue("Unresolved enum entry: $enumClassId.$enumEntryName") } - private fun resolveArrayElementType(value: Value, nameResolver: NameResolver): KotlinType = + private fun resolveArrayElementType(value: Value, nameResolver: NameResolver): SimpleType = with(builtIns) { when (value.type) { Type.BYTE -> getByteType() diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt index 5d818f76666..81e5a5760b7 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt @@ -34,6 +34,10 @@ import org.jetbrains.kotlin.types.typeUtil.* fun KotlinType.approximateFlexibleTypes(preferNotNull: Boolean = false): KotlinType { if (isDynamic()) return this + return approximateNonDynamicFlexibleTypes(preferNotNull) +} + +private fun KotlinType.approximateNonDynamicFlexibleTypes(preferNotNull: Boolean = false): SimpleType { if (isFlexible()) { val flexible = flexibility() val lowerClass = flexible.lowerBound.constructor.declarationDescriptor as? ClassDescriptor? @@ -48,12 +52,12 @@ fun KotlinType.approximateFlexibleTypes(preferNotNull: Boolean = false): KotlinT else if (preferNotNull) flexible.lowerBound else flexible.upperBound - approximation = approximation.approximateFlexibleTypes() + approximation = approximation.approximateNonDynamicFlexibleTypes() - approximation = if (isAnnotatedNotNull()) approximation.makeNotNullable() else approximation + approximation = if (isAnnotatedNotNull()) TypeUtils.makeNotNullable(approximation) else approximation if (approximation.isMarkedNullable && !flexible.lowerBound.isMarkedNullable && TypeUtils.isTypeParameter(approximation) && TypeUtils.hasNullableSuperType(approximation)) { - approximation = approximation.makeNotNullable() + approximation = TypeUtils.makeNotNullable(approximation) } return approximation diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/DeserializerForClassfileDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/DeserializerForClassfileDecompiler.kt index b14d63543a9..2d2ec5a46a8 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/DeserializerForClassfileDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/DeserializerForClassfileDecompiler.kt @@ -26,7 +26,6 @@ import org.jetbrains.kotlin.idea.decompiler.textBuilder.DeserializerForDecompile import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassifierResolver import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeResolver.FlexibleJavaClassifierTypeFactory import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.kotlin.* import org.jetbrains.kotlin.name.ClassId @@ -40,6 +39,7 @@ import org.jetbrains.kotlin.serialization.deserialization.DeserializationCompone import org.jetbrains.kotlin.serialization.deserialization.NotFoundClasses import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil +import org.jetbrains.kotlin.types.FlexibleJavaClassifierTypeFactory fun DeserializerForClassfileDecompiler(classFile: VirtualFile): DeserializerForClassfileDecompiler { val kotlinClassHeaderInfo = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(classFile) 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 127087e9262..2c8394d058d 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 @@ -45,7 +45,7 @@ import org.jetbrains.kotlin.resolve.BindingContextUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils.* import org.jetbrains.kotlin.types.CommonSupertypes.topologicallySortSuperclassesAndRecordAllInstances -import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.SimpleType import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.identity @@ -341,7 +341,7 @@ class ClassTranslator private constructor( } val sortedAllSuperTypes = topologicallySortSuperclassesAndRecordAllInstances( descriptor.defaultType, - mutableMapOf>(), + mutableMapOf>(), mutableSetOf() ) val supertypesRefs = mutableListOf() diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/res/syntheticDescriptorGeneration.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/res/syntheticDescriptorGeneration.kt index 60b4b7e5d59..de5efdf1d3a 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/res/syntheticDescriptorGeneration.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/res/syntheticDescriptorGeneration.kt @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinTypeFactory import org.jetbrains.kotlin.types.StarProjectionImpl +import org.jetbrains.kotlin.types.asSimpleType import org.jetbrains.kotlin.types.typeUtil.makeNullable private class XmlSourceElement(override val psi: PsiElement) : PsiSourceElement @@ -109,7 +110,7 @@ private fun genProperty( override val resourceId = id } - val flexibleType = LazyJavaTypeResolver.FlexibleJavaClassifierTypeFactory.create(type, type.makeNullable()) + val flexibleType = KotlinTypeFactory.flexibleType(type.asSimpleType(), type.makeNullable().asSimpleType()) property.setType( flexibleType, emptyList(),