Refactoring. Create WrappedType.

This commit is contained in:
Stanislav Erokhin
2016-05-24 17:36:45 +03:00
parent 957bae18be
commit 7bc2c55d12
11 changed files with 128 additions and 128 deletions
@@ -99,9 +99,11 @@ class TypeResolver(
if (!c.allowBareTypes && !c.forceResolveLazyTypes && lazinessToken.isLazy()) { if (!c.allowBareTypes && !c.forceResolveLazyTypes && lazinessToken.isLazy()) {
// Bare types can be allowed only inside expressions; lazy type resolution is only relevant for declarations // Bare types can be allowed only inside expressions; lazy type resolution is only relevant for declarations
class LazyKotlinType : DelegatingType(), LazyEntity { class LazyKotlinType : WrappedType(), LazyEntity {
private val _delegate = storageManager.createLazyValue { doResolvePossiblyBareType(c, typeReference).getActualType() } private val _delegate = storageManager.createLazyValue { doResolvePossiblyBareType(c, typeReference).getActualType() }
override fun getDelegate() = _delegate()
override fun unwrap() = _delegate()
override fun isComputed() = _delegate.isComputed()
override fun forceResolveAllContents() { override fun forceResolveAllContents() {
ForceResolveUtil.forceResolveAllContents(constructor) ForceResolveUtil.forceResolveAllContents(constructor)
@@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.util.ReenteringLazyValueComputationException;
import static org.jetbrains.kotlin.resolve.BindingContext.DEFERRED_TYPE; import static org.jetbrains.kotlin.resolve.BindingContext.DEFERRED_TYPE;
public class DeferredType extends DelegatingType implements LazyType { public class DeferredType extends WrappedType implements LazyType {
private static final Function1 EMPTY_CONSUMER = new Function1<Object, Void>() { private static final Function1 EMPTY_CONSUMER = new Function1<Object, Void>() {
@Override @Override
@@ -81,15 +81,18 @@ public class DeferredType extends DelegatingType implements LazyType {
return lazyValue.isComputing(); return lazyValue.isComputing();
} }
@Override
public boolean isComputed() { public boolean isComputed() {
return lazyValue.isComputed(); return lazyValue.isComputed();
} }
@NotNull
@Override @Override
public KotlinType getDelegate() { public KotlinType unwrap() {
return lazyValue.invoke(); return lazyValue.invoke();
} }
@NotNull
@Override @Override
public String toString() { public String toString() {
try { try {
@@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -20,9 +20,7 @@ import org.jetbrains.kotlin.builtins.BuiltInsInitializer
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
import org.jetbrains.kotlin.descriptors.annotations.composeAnnotations
import org.jetbrains.kotlin.descriptors.annotations.createDeprecatedAnnotation import org.jetbrains.kotlin.descriptors.annotations.createDeprecatedAnnotation
import org.jetbrains.kotlin.descriptors.annotations.createUnsafeVarianceAnnotation
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
@@ -45,8 +43,8 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations import org.jetbrains.kotlin.types.WrappedType
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.SmartSet import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.kotlin.utils.addToStdlib.check import org.jetbrains.kotlin.utils.addToStdlib.check
@@ -79,10 +77,8 @@ open class JvmBuiltInsSettings(
} }
//NOTE: can't reference anyType right away, because this is sometimes called when JvmBuiltIns are initializing //NOTE: can't reference anyType right away, because this is sometimes called when JvmBuiltIns are initializing
val superTypes = listOf(object : DelegatingType() { val superTypes = listOf(object : WrappedType() {
override fun getDelegate(): KotlinType { override fun unwrap() = moduleDescriptor.builtIns.anyType
return moduleDescriptor.builtIns.anyType
}
}) })
val mockSerializableClass = ClassDescriptorImpl( val mockSerializableClass = ClassDescriptorImpl(
@@ -119,8 +119,8 @@ private fun TypeProjection.createCapturedIfNeeded(typeParameterDescriptor: TypeP
if (typeParameterDescriptor.variance == projectionKind) { if (typeParameterDescriptor.variance == projectionKind) {
// TODO: Make star projection type lazy // TODO: Make star projection type lazy
return if (isStarProjection) return if (isStarProjection)
TypeProjectionImpl(object : DelegatingType() { TypeProjectionImpl(object : WrappedType() {
override fun getDelegate() = this@createCapturedIfNeeded.type override fun unwrap(): KotlinType = this@createCapturedIfNeeded.type
}) })
else else
TypeProjectionImpl(this@createCapturedIfNeeded.type) TypeProjectionImpl(this@createCapturedIfNeeded.type)
@@ -17,6 +17,8 @@
package org.jetbrains.kotlin.types package org.jetbrains.kotlin.types
import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
@@ -43,6 +45,93 @@ interface KotlinType : Annotated {
} }
@Deprecated("Temporary marker method for refactoring") @Deprecated("Temporary marker method for refactoring")
fun KotlinType.asSimpleType(): SimpleType = this as SimpleType fun KotlinType.asSimpleType(): SimpleType {
return unwrap() as SimpleType
}
interface SimpleType : KotlinType fun KotlinType.unwrap(): KotlinType {
if (this is WrappedType) return unwrap().unwrap()
return this
}
interface SimpleType : KotlinType
abstract class WrappedType() : KotlinType, LazyType {
override val annotations: Annotations get() = delegate.annotations
override val constructor: TypeConstructor get() = delegate.constructor
override val arguments: List<TypeProjection> get() = delegate.arguments
override val isMarkedNullable: Boolean get() = delegate.isMarkedNullable
override val memberScope: MemberScope get() = delegate.memberScope
open fun isComputed(): Boolean = true
open val delegate: KotlinType
get() = unwrap()
abstract fun unwrap(): KotlinType
override fun toString(): String {
if (isComputed()) {
return delegate.toString()
}
else {
return "<Not computed yet>"
}
}
// todo: remove this later
override val isError: Boolean get() = delegate.isError
override val capabilities: TypeCapabilities get() = delegate.capabilities
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>): T? = delegate.getCapability(capabilityClass)
override fun equals(other: Any?): Boolean = unwrap().equals(other)
override fun hashCode(): Int = unwrap().hashCode()
}
fun SimpleType.lazyReplaceNullability(newNullable: Boolean): SimpleType {
if (this is WrappedSimpleType) {
return WrappedSimpleType(delegate, newAnnotations, newNullable)
}
else {
return WrappedSimpleType(this, newNullable = newNullable)
}
}
fun SimpleType.lazyReplaceAnnotations(newAnnotations: Annotations): SimpleType {
if (this is WrappedSimpleType) {
return WrappedSimpleType(delegate, newAnnotations, newNullable)
}
else {
return WrappedSimpleType(this, newAnnotations)
}
}
private class WrappedSimpleType(
override val delegate: SimpleType,
val newAnnotations: Annotations? = null,
val newNullable: Boolean? = null
): WrappedType(), SimpleType {
override val annotations: Annotations
get() = newAnnotations ?: delegate.annotations
override val isMarkedNullable: Boolean
get() = newNullable ?: delegate.isMarkedNullable
override fun unwrap(): KotlinType {
if (delegate.isError) return delegate // todo
return KotlinTypeImpl.create(annotations, constructor, isMarkedNullable, arguments, memberScope, capabilities)
}
override fun toString(): String {
if (isError) return delegate.toString()
return buildString {
for (annotation in annotations.getAllAnnotations()) {
append("[", DescriptorRenderer.DEBUG_TEXT.renderAnnotation(annotation.annotation, annotation.target), "] ")
}
append(constructor)
if (!arguments.isEmpty()) arguments.joinTo(this, separator = ", ", prefix = "<", postfix = ">")
if (isMarkedNullable) append("?")
}
}
}
@@ -139,22 +139,13 @@ public class TypeUtils {
if (flexibility != null) { if (flexibility != null) {
return flexibility.makeNullableAsSpecified(nullable); return flexibility.makeNullableAsSpecified(nullable);
} }
else {
SimpleType simpleType = KotlinTypeKt.asSimpleType(type);
// Wrapping serves two purposes here if (!(simpleType instanceof LazyType) && simpleType.isMarkedNullable() == nullable) return simpleType;
// 1. It's requires less memory than copying with a changed nullability flag: a copy has many fields, while a wrapper has only one
// 2. It preserves laziness of types
// Unwrap to avoid long delegation call chains return KotlinTypeKt.lazyReplaceNullability(simpleType, nullable);
if (type instanceof AbstractTypeWithKnownNullability) {
return makeNullableAsSpecified(((AbstractTypeWithKnownNullability) type).delegate, nullable);
} }
// checking to preserve laziness
if (!(type instanceof LazyType) && type.isMarkedNullable() == nullable) {
return type;
}
return nullable ? new NullableType(type) : new NotNullType(type);
} }
@NotNull @NotNull
@@ -528,81 +519,4 @@ public class TypeUtils {
} }
return null; return null;
} }
private static abstract class AbstractTypeWithKnownNullability extends AbstractKotlinType {
private final KotlinType delegate;
private AbstractTypeWithKnownNullability(@NotNull KotlinType delegate) {
this.delegate = delegate;
}
@Override
@NotNull
public TypeConstructor getConstructor() {
return delegate.getConstructor();
}
@Override
@NotNull
public List<TypeProjection> getArguments() {
return delegate.getArguments();
}
@Override
public abstract boolean isMarkedNullable();
@Override
@NotNull
public MemberScope getMemberScope() {
return delegate.getMemberScope();
}
@Override
public boolean isError() {
return delegate.isError();
}
@Override
@NotNull
public Annotations getAnnotations() {
return delegate.getAnnotations();
}
@Nullable
@Override
public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
return delegate.getCapability(capabilityClass);
}
@NotNull
@Override
public TypeCapabilities getCapabilities() {
return delegate.getCapabilities();
}
}
private static class NullableType extends AbstractTypeWithKnownNullability {
private NullableType(@NotNull KotlinType delegate) {
super(delegate);
}
@Override
public boolean isMarkedNullable() {
return true;
}
}
private static class NotNullType extends AbstractTypeWithKnownNullability {
private NotNullType(@NotNull KotlinType delegate) {
super(delegate);
}
@Override
public boolean isMarkedNullable() {
return false;
}
}
} }
@@ -77,8 +77,6 @@ fun KotlinType.isSubtypeOf(superType: KotlinType): Boolean = KotlinTypeChecker.D
fun KotlinType.cannotBeReified(): Boolean = fun KotlinType.cannotBeReified(): Boolean =
KotlinBuiltIns.isNothingOrNullableNothing(this) || this.isDynamic() || this.isCaptured() KotlinBuiltIns.isNothingOrNullableNothing(this) || this.isDynamic() || this.isCaptured()
fun KotlinType.unsafeAsReifiedArgument(): Boolean = arguments.any { !it.isStarProjection }
fun TypeProjection.substitute(doSubstitute: (KotlinType) -> KotlinType): TypeProjection { fun TypeProjection.substitute(doSubstitute: (KotlinType) -> KotlinType): TypeProjection {
return if (isStarProjection) return if (isStarProjection)
this this
@@ -87,11 +85,9 @@ fun TypeProjection.substitute(doSubstitute: (KotlinType) -> KotlinType): TypePro
fun KotlinType.replaceAnnotations(newAnnotations: Annotations): KotlinType { fun KotlinType.replaceAnnotations(newAnnotations: Annotations): KotlinType {
if (annotations.isEmpty() && newAnnotations.isEmpty()) return this if (annotations.isEmpty() && newAnnotations.isEmpty()) return this
return object : DelegatingType() { if (isFlexible()) return flexibility().replaceAnnotations(newAnnotations)
override fun getDelegate() = this@replaceAnnotations
override val annotations: Annotations get() = newAnnotations return asSimpleType().lazyReplaceAnnotations(newAnnotations)
}
} }
fun KotlinTypeChecker.equalTypesOrNulls(type1: KotlinType?, type2: KotlinType?): Boolean { fun KotlinTypeChecker.equalTypesOrNulls(type1: KotlinType?, type2: KotlinType?): Boolean {
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.types package org.jetbrains.kotlin.types
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.types.typeUtil.builtIns
@@ -32,9 +33,9 @@ class DynamicTypesAllowed: DynamicTypesSettings() {
fun KotlinType.isDynamic(): Boolean = this.getCapability(Flexibility::class.java)?.factory == DynamicTypeFactory fun KotlinType.isDynamic(): Boolean = this.getCapability(Flexibility::class.java)?.factory == DynamicTypeFactory
fun createDynamicType(builtIns: KotlinBuiltIns) = DynamicType(builtIns) fun createDynamicType(builtIns: KotlinBuiltIns) = DynamicType(builtIns, Annotations.EMPTY)
class DynamicType(builtIns: KotlinBuiltIns) : DelegatingFlexibleType(builtIns.nothingType, builtIns.nullableAnyType, DynamicTypeFactory) { class DynamicType(builtIns: KotlinBuiltIns, override val annotations: Annotations) : DelegatingFlexibleType(builtIns.nothingType, builtIns.nullableAnyType, DynamicTypeFactory) {
override val delegateType: KotlinType get() = upperBound override val delegateType: KotlinType get() = upperBound
override fun makeNullableAsSpecified(nullable: Boolean): KotlinType { override fun makeNullableAsSpecified(nullable: Boolean): KotlinType {
@@ -43,6 +44,8 @@ class DynamicType(builtIns: KotlinBuiltIns) : DelegatingFlexibleType(builtIns.no
} }
override val isMarkedNullable: Boolean get() = false override val isMarkedNullable: Boolean get() = false
override fun replaceAnnotations(newAnnotations: Annotations): KotlinType = DynamicType(delegateType.builtIns, annotations)
} }
object DynamicTypeFactory : FlexibleTypeFactory { object DynamicTypeFactory : FlexibleTypeFactory {
@@ -17,7 +17,9 @@
package org.jetbrains.kotlin.types package org.jetbrains.kotlin.types
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
interface FlexibleTypeFactory { interface FlexibleTypeFactory {
val id: String val id: String
@@ -50,6 +52,7 @@ interface Flexibility : TypeCapability, SubtypingRepresentatives {
fun makeNullableAsSpecified(nullable: Boolean): KotlinType fun makeNullableAsSpecified(nullable: Boolean): KotlinType
fun replaceAnnotations(newAnnotations: Annotations): KotlinType
} }
fun KotlinType.isFlexible(): Boolean = this.getCapability(Flexibility::class.java) != null fun KotlinType.isFlexible(): Boolean = this.getCapability(Flexibility::class.java) != null
@@ -173,6 +176,9 @@ class FlexibleTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) :
return KotlinTypeFactory.flexibleType(simpleType, TypeUtils.makeNullable(simpleType)) return KotlinTypeFactory.flexibleType(simpleType, TypeUtils.makeNullable(simpleType))
} }
} }
override fun replaceAnnotations(newAnnotations: Annotations): KotlinType
= KotlinTypeFactory.flexibleType(lowerBound.replaceAnnotations(newAnnotations).asSimpleType(), upperBound)
} }
// TODO: move Factory to descriptor.loader.java // TODO: move Factory to descriptor.loader.java
@@ -104,10 +104,7 @@ class SpecifyTypeExplicitlyIntention : SelfTargetingIntention<KtCallableDeclarat
} }
} }
object: DelegatingType() { KotlinTypeFactory.simpleType(it.asSimpleType(), arguments = newArguments)
override fun getDelegate() = it
override val arguments: List<TypeProjection> get() = newArguments
}
} }
.ifEmpty { return null } .ifEmpty { return null }
return object : ChooseValueExpression<KotlinType>(types, types.first()) { return object : ChooseValueExpression<KotlinType>(types, types.first()) {
@@ -54,9 +54,7 @@ private fun KotlinType.render(typeParameterNameMap: Map<TypeParameterDescriptor,
val typeParameter = it.key val typeParameter = it.key
var wrappingTypeParameter: TypeParameterDescriptor? = null var wrappingTypeParameter: TypeParameterDescriptor? = null
var wrappingTypeConstructor: TypeConstructor val wrappingTypeConstructor = object : TypeConstructor by typeParameter.typeConstructor {
wrappingTypeConstructor = object : TypeConstructor by typeParameter.typeConstructor {
override fun getDeclarationDescriptor() = wrappingTypeParameter override fun getDeclarationDescriptor() = wrappingTypeParameter
} }
@@ -65,11 +63,7 @@ private fun KotlinType.render(typeParameterNameMap: Map<TypeParameterDescriptor,
override fun getTypeConstructor() = wrappingTypeConstructor override fun getTypeConstructor() = wrappingTypeConstructor
} }
val wrappingType = object : DelegatingType() { val wrappingType = KotlinTypeFactory.simpleType(typeParameter.defaultType, constructor = wrappingTypeConstructor)
override fun getDelegate(): KotlinType? = typeParameter.defaultType
override val constructor: TypeConstructor get() = wrappingTypeConstructor
}
TypeProjectionImpl(wrappingType) TypeProjectionImpl(wrappingType)
} }
.mapKeys { it.key.typeConstructor } .mapKeys { it.key.typeConstructor }