Refactoring. Removed several usages of asSimpleType

This commit is contained in:
Stanislav Erokhin
2016-06-02 04:37:47 +03:00
parent 1d9ca06b96
commit f41c8dc045
12 changed files with 92 additions and 74 deletions
@@ -50,6 +50,7 @@ public class CommonSupertypes {
@NotNull
public static KotlinType commonSupertype(@NotNull Collection<KotlinType> types) {
if (types.size() == 1) return types.iterator().next();
// Recursion should not be significantly deeper than the deepest type in question
// It can be slightly deeper, though: e.g. when initial types are simple, but their supertypes are complex
return findCommonSupertype(types, 0, maxDepth(types) + 3);
@@ -86,18 +87,20 @@ public class CommonSupertypes {
List<SimpleType> upper = new ArrayList<SimpleType>(types.size());
List<SimpleType> lower = new ArrayList<SimpleType>(types.size());
for (KotlinType type : types) {
if (FlexibleTypesKt.isFlexible(type)) {
UnwrappedType unwrappedType = type.unwrap();
if (unwrappedType instanceof FlexibleType) {
if (DynamicTypesKt.isDynamic(type)) {
return type;
}
hasFlexible = true;
FlexibleType flexibleType = FlexibleTypesKt.asFlexibleType(type);
FlexibleType flexibleType = (FlexibleType) type;
upper.add(flexibleType.getUpperBound());
lower.add(flexibleType.getLowerBound());
}
else {
upper.add(KotlinTypeKt.asSimpleType(type));
lower.add(KotlinTypeKt.asSimpleType(type));
SimpleType simpleType = (SimpleType) unwrappedType;
upper.add(simpleType);
lower.add(simpleType);
}
}
@@ -113,10 +116,6 @@ public class CommonSupertypes {
assert !types.isEmpty();
Collection<SimpleType> typeSet = new HashSet<SimpleType>(types);
// todo: dead code?
KotlinType bestFit = FlexibleTypesKt.singleBestRepresentative(typeSet);
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;
@@ -348,7 +347,7 @@ public class CommonSupertypes {
if (visited.contains(supertype.getConstructor())) {
continue;
}
result.add(KotlinTypeKt.asSimpleType(substitutor.safeSubstitute(supertype, Variance.INVARIANT)));
result.add(FlexibleTypesKt.lowerIfFlexible(substitutor.safeSubstitute(supertype, Variance.INVARIANT)));
}
return result;
}
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.createProjection
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.utils.addToStdlib.check
import org.jetbrains.kotlin.utils.toReadOnlyList
@@ -41,7 +40,7 @@ import org.jetbrains.kotlin.utils.toReadOnlyList
// Example: for `A<B, C<D, E>>`, indices go as follows: `0 - A<...>, 1 - B, 2 - C<D, E>, 3 - D, 4 - E`,
// which corresponds to the left-to-right breadth-first walk of the tree representation of the type.
// For flexible types, both bounds are indexed in the same way: `(A<B>..C<D>)` gives `0 - (A<B>..C<D>), 1 - B and D`.
fun KotlinType.enhance(qualifiers: (Int) -> JavaTypeQualifiers) = this.enhancePossiblyFlexible(qualifiers, 0).typeIfChanged
fun KotlinType.enhance(qualifiers: (Int) -> JavaTypeQualifiers) = unwrap().enhancePossiblyFlexible(qualifiers, 0).typeIfChanged
fun KotlinType.hasEnhancedNullability()
= annotations.findAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION) != null
@@ -52,14 +51,16 @@ private enum class TypeComponentPosition {
INFLEXIBLE
}
private data class Result(val type: KotlinType, val subtreeSize: Int, val wereChanges: Boolean) {
private open class Result(open val type: KotlinType, val subtreeSize: Int, val wereChanges: Boolean) {
val typeIfChanged: KotlinType? get() = type.check { wereChanges }
}
private fun KotlinType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int): Result {
if (this.isError || unwrap() is RawTypeImpl) return Result(this, 1, false) // todo: Raw
return if (this.isFlexible()) {
with(this.asFlexibleType()) {
private class SimpleResult(override val type: SimpleType, subtreeSize: Int, wereChanges: Boolean): Result(type, subtreeSize, wereChanges)
private fun UnwrappedType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int): Result {
if (isError || this is RawTypeImpl) return Result(this, 1, false) // todo: Raw
return when(this) {
is FlexibleType -> {
val lowerResult = lowerBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_LOWER)
val upperResult = upperBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_UPPER)
assert(lowerResult.subtreeSize == upperResult.subtreeSize) {
@@ -71,23 +72,23 @@ private fun KotlinType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQual
val wereChanges = lowerResult.wereChanges || upperResult.wereChanges
Result(
if (wereChanges)
KotlinTypeFactory.flexibleType(lowerResult.type.asSimpleType(), upperResult.type.asSimpleType())
KotlinTypeFactory.flexibleType(lowerResult.type, upperResult.type)
else
this@enhancePossiblyFlexible,
lowerResult.subtreeSize,
wereChanges
)
}
is SimpleType -> enhanceInflexible(qualifiers, index, TypeComponentPosition.INFLEXIBLE)
}
else this.enhanceInflexible(qualifiers, index, TypeComponentPosition.INFLEXIBLE)
}
private fun KotlinType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int, position: TypeComponentPosition): Result {
private fun SimpleType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int, position: TypeComponentPosition): SimpleResult {
val shouldEnhance = position.shouldEnhance()
if (!shouldEnhance && arguments.isEmpty()) return Result(this, 1, false)
if (!shouldEnhance && arguments.isEmpty()) return SimpleResult(this, 1, false)
val originalClass = constructor.declarationDescriptor
?: return Result(this, 1, false)
?: return SimpleResult(this, 1, false)
val effectiveQualifiers = qualifiers(index)
val (enhancedClassifier, enhancedMutabilityAnnotations) = originalClass.enhanceMutability(effectiveQualifiers, position)
@@ -103,10 +104,10 @@ private fun KotlinType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers
TypeUtils.makeStarProjection(enhancedClassifier.typeConstructor.parameters[localArgIndex])
}
else {
val (enhancedType, subtreeSize, wasChangeInArgument) = arg.type.enhancePossiblyFlexible(qualifiers, globalArgIndex)
wereChanges = wereChanges || wasChangeInArgument
globalArgIndex += subtreeSize
createProjection(enhancedType, arg.projectionKind, typeParameterDescriptor = typeConstructor.parameters[localArgIndex])
val enhanced = arg.type.unwrap().enhancePossiblyFlexible(qualifiers, globalArgIndex)
wereChanges = wereChanges || enhanced.wereChanges
globalArgIndex += enhanced.subtreeSize
createProjection(enhanced.type, arg.projectionKind, typeParameterDescriptor = typeConstructor.parameters[localArgIndex])
}
}
@@ -114,7 +115,7 @@ private fun KotlinType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers
wereChanges = wereChanges || enhancedNullabilityAnnotations != null
val subtreeSize = globalArgIndex - index
if (!wereChanges) return Result(this, subtreeSize, wereChanges = false)
if (!wereChanges) return SimpleResult(this, subtreeSize, wereChanges = false)
val newAnnotations = listOf(
annotations,
@@ -135,7 +136,7 @@ private fun KotlinType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers
)
val result = if (effectiveQualifiers.isNotNullTypeParameter) NotNullTypeParameter(enhancedType) else enhancedType
return Result(result, subtreeSize, wereChanges = true)
return SimpleResult(result, subtreeSize, wereChanges = true)
}
private fun List<Annotations>.compositeAnnotationsOrSingle() = when (size) {
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
import org.jetbrains.kotlin.descriptors.annotations.composeAnnotations
import org.jetbrains.kotlin.descriptors.annotations.createUnsafeVarianceAnnotation
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
internal class UnsafeVarianceTypeSubstitution(kotlinBuiltIns: KotlinBuiltIns) : TypeSubstitution() {
private val unsafeVarianceAnnotations = AnnotationsImpl(listOf(kotlinBuiltIns.createUnsafeVarianceAnnotation()))
@@ -38,19 +37,22 @@ internal class UnsafeVarianceTypeSubstitution(kotlinBuiltIns: KotlinBuiltIns) :
},
customVariance = { null })
return topLevelType.annotatePartsWithUnsafeVariance(unsafeVariancePaths)
return topLevelType.unwrap().annotatePartsWithUnsafeVariance(unsafeVariancePaths)
}
private fun UnwrappedType.annotatePartsWithUnsafeVariance(unsafeVariancePaths: Collection<List<Int>>): UnwrappedType {
if (unsafeVariancePaths.isEmpty()) return this
return when (this) {
is FlexibleType ->
KotlinTypeFactory.flexibleType(
lowerBound.annotatePartsWithUnsafeVariance(subPathsWithIndex(unsafeVariancePaths, 0)),
upperBound.annotatePartsWithUnsafeVariance(subPathsWithIndex(unsafeVariancePaths, 1)))
is SimpleType -> annotatePartsWithUnsafeVariance(unsafeVariancePaths)
}
}
private fun KotlinType.annotatePartsWithUnsafeVariance(unsafeVariancePaths: Collection<List<Int>>): KotlinType {
private fun SimpleType.annotatePartsWithUnsafeVariance(unsafeVariancePaths: Collection<List<Int>>): SimpleType {
if (unsafeVariancePaths.isEmpty()) return this
if (isFlexible()) {
return KotlinTypeFactory.flexibleType(
lowerIfFlexible().annotatePartsWithUnsafeVariance(subPathsWithIndex(unsafeVariancePaths, 0)).asSimpleType(),
upperIfFlexible().annotatePartsWithUnsafeVariance(subPathsWithIndex(unsafeVariancePaths, 1)).asSimpleType()
)
}
// if root is unsafe
if (emptyList<Int>() in unsafeVariancePaths) {
return replaceAnnotations(composeAnnotations(annotations, unsafeVarianceAnnotations))
@@ -61,7 +63,7 @@ internal class UnsafeVarianceTypeSubstitution(kotlinBuiltIns: KotlinBuiltIns) :
if (argument.isStarProjection) return@map argument
TypeProjectionImpl(
argument.projectionKind,
argument.type.annotatePartsWithUnsafeVariance(subPathsWithIndex(unsafeVariancePaths, index)))
argument.type.unwrap().annotatePartsWithUnsafeVariance(subPathsWithIndex(unsafeVariancePaths, index)))
})
}
@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.serialization.deserialization.NotFoundClasses
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.ErrorUtils.UninferredParameterTypeConstructor
import org.jetbrains.kotlin.types.TypeUtils.CANT_INFER_FUNCTION_PARAM_TYPE
import org.jetbrains.kotlin.types.typeUtil.builtIns
import java.util.*
internal class DescriptorRendererImpl(
@@ -141,10 +140,10 @@ internal class DescriptorRendererImpl(
return type.toString()
}
val unwrappedType = type.unwrap()
if (unwrappedType is FlexibleType) {
return unwrappedType.render(this, this)
return when (unwrappedType) {
is FlexibleType -> unwrappedType.render(this, this)
is SimpleType -> renderSimpleType(unwrappedType)
}
return renderSimpleType(unwrappedType.asSimpleType())
}
private fun renderSimpleType(type: SimpleType): String {
@@ -64,6 +64,7 @@ abstract class WrappedType() : KotlinType(), LazyType {
override val arguments: List<TypeProjection> get() = delegate.arguments
override val isMarkedNullable: Boolean get() = delegate.isMarkedNullable
override val memberScope: MemberScope get() = delegate.memberScope
override val isError: Boolean get() = delegate.isError
override final fun unwrap(): UnwrappedType {
var result = delegate
@@ -81,9 +82,6 @@ abstract class WrappedType() : KotlinType(), LazyType {
return "<Not computed yet>"
}
}
// todo: remove this later
override val isError: Boolean get() = delegate.isError
}
sealed class UnwrappedType: KotlinType() {
@@ -120,6 +120,21 @@ fun KotlinType.replace(
): KotlinType {
if (newArguments.isEmpty() && newAnnotations === annotations) return this
val unwrapped = unwrap()
return when(unwrapped) {
is FlexibleType -> KotlinTypeFactory.flexibleType(unwrapped.lowerBound.replace(newArguments, newAnnotations),
unwrapped.upperBound.replace(newArguments, newAnnotations))
is SimpleType -> unwrapped.replace(newArguments, newAnnotations)
}
}
@JvmOverloads
fun SimpleType.replace(
newArguments: List<TypeProjection> = arguments,
newAnnotations: Annotations = annotations
): SimpleType {
if (newArguments.isEmpty() && newAnnotations === annotations) return this
if (newArguments.isEmpty()) {
return KotlinTypeFactory.simpleType(
newAnnotations,
@@ -171,5 +171,5 @@ private fun SimpleType.replaceArgumentsWithStarProjections(): SimpleType {
val newArguments = constructor.parameters.map(::StarProjectionImpl)
return replace(newArguments).asSimpleType()
return replace(newArguments)
}
@@ -60,14 +60,23 @@ fun Collection<TypeProjection>.singleBestRepresentative(): TypeProjection? {
val projectionKinds = this.map { it.projectionKind }.toSet()
if (projectionKinds.size != 1) return null
val bestType = this.map { it.type }.singleBestRepresentative()
if (bestType == null) return null
val bestType = this.map { it.type }.singleBestRepresentative() ?: return null
return TypeProjectionImpl(projectionKinds.single(), bestType)
}
fun KotlinType.lowerIfFlexible(): SimpleType = (if (this.isFlexible()) this.asFlexibleType().lowerBound else this).asSimpleType()
fun KotlinType.upperIfFlexible(): SimpleType = (if (this.isFlexible()) this.asFlexibleType().upperBound else this).asSimpleType()
fun KotlinType.lowerIfFlexible(): SimpleType = with(unwrap()) {
when (this) {
is FlexibleType -> lowerBound
is SimpleType -> this
}
}
fun KotlinType.upperIfFlexible(): SimpleType = with(unwrap()) {
when (this) {
is FlexibleType -> upperBound
is SimpleType -> this
}
}
class FlexibleTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : FlexibleType(lowerBound, upperBound), CustomTypeVariable {
companion object {
@@ -20,15 +20,16 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotationsWithPossibleTargets
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.AbstractLazyType
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.withAbbreviatedType
import org.jetbrains.kotlin.utils.toReadOnlyList
class DeserializedType private constructor(
private val c: DeserializationContext,
private val typeProto: ProtoBuf.Type,
private val additionalAnnotations: Annotations = Annotations.EMPTY
) : AbstractLazyType(c.storageManager), LazyType {
) : AbstractLazyType(c.storageManager) {
override fun computeTypeConstructor() = c.typeDeserializer.typeConstructor(typeProto)
override fun computeArguments() =
@@ -48,12 +49,6 @@ class DeserializedType private constructor(
override val isMarkedNullable: Boolean get() = typeProto.nullable
override val isError: Boolean
get() {
val descriptor = constructor.declarationDescriptor
return descriptor != null && ErrorUtils.isError(descriptor)
}
companion object {
fun create(
c: DeserializationContext,
@@ -104,7 +104,7 @@ class SpecifyTypeExplicitlyIntention : SelfTargetingIntention<KtCallableDeclarat
}
}
KotlinTypeFactory.simpleType(it.asSimpleType(), arguments = newArguments)
it.replace(newArguments)
}
.ifEmpty { return null }
return object : ChooseValueExpression<KotlinType>(types, types.first()) {
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleD
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.SimpleType
import java.util.*
class LazySyntheticElementResolveContext(private val module: ModuleDescriptor, storageManager: StorageManager) {
@@ -53,11 +54,11 @@ class LazySyntheticElementResolveContext(private val module: ModuleDescriptor, s
}
internal class SyntheticElementResolveContext(
val viewType: KotlinType,
val activityType: KotlinType,
val fragmentType: KotlinType?,
val supportActivityType: KotlinType?,
val supportFragmentType: KotlinType?) {
val viewType: SimpleType,
val activityType: SimpleType,
val fragmentType: SimpleType?,
val supportActivityType: SimpleType?,
val supportFragmentType: SimpleType?) {
companion object {
private fun errorType() = ErrorUtils.createErrorType("")
val ERROR_CONTEXT = SyntheticElementResolveContext(errorType(), errorType(), null, null, null)
@@ -71,12 +72,12 @@ internal class SyntheticElementResolveContext(
receivers
}
val fragmentTypes: List<Pair<KotlinType, KotlinType>> by lazy {
val fragmentTypes: List<Pair<SimpleType, SimpleType>> by lazy {
if (fragmentType == null) {
emptyList<Pair<KotlinType, KotlinType>>()
emptyList<Pair<SimpleType, SimpleType>>()
}
else {
val types = ArrayList<Pair<KotlinType, KotlinType>>(4)
val types = ArrayList<Pair<SimpleType, SimpleType>>(4)
types += Pair(activityType, fragmentType)
types += Pair(fragmentType, fragmentType)
if (supportActivityType != null && supportFragmentType != null) {
@@ -25,16 +25,14 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeResolver
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.SimpleType
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
@@ -76,7 +74,7 @@ internal fun genPropertyForWidget(
internal fun genPropertyForFragment(
packageFragmentDescriptor: AndroidSyntheticPackageFragmentDescriptor,
receiverType: KotlinType,
type: KotlinType,
type: SimpleType,
fragment: AndroidResource.Fragment
): PropertyDescriptor {
val sourceElement = fragment.sourceElement?.let { XmlSourceElement(it) } ?: SourceElement.NO_SOURCE
@@ -86,7 +84,7 @@ internal fun genPropertyForFragment(
private fun genProperty(
id: ResourceIdentifier,
receiverType: KotlinType,
type: KotlinType,
type: SimpleType,
containingDeclaration: AndroidSyntheticPackageFragmentDescriptor,
sourceElement: SourceElement,
errorType: String?
@@ -110,7 +108,8 @@ private fun genProperty(
override val resourceId = id
}
val flexibleType = KotlinTypeFactory.flexibleType(type.asSimpleType(), type.makeNullable().asSimpleType())
// todo support (Mutable)List
val flexibleType = KotlinTypeFactory.flexibleType(type, type.makeNullableAsSpecified(true))
property.setType(
flexibleType,
emptyList<TypeParameterDescriptor>(),