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()) {
// 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() }
override fun getDelegate() = _delegate()
override fun unwrap() = _delegate()
override fun isComputed() = _delegate.isComputed()
override fun forceResolveAllContents() {
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");
* 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;
public class DeferredType extends DelegatingType implements LazyType {
public class DeferredType extends WrappedType implements LazyType {
private static final Function1 EMPTY_CONSUMER = new Function1<Object, Void>() {
@Override
@@ -81,15 +81,18 @@ public class DeferredType extends DelegatingType implements LazyType {
return lazyValue.isComputing();
}
@Override
public boolean isComputed() {
return lazyValue.isComputed();
}
@NotNull
@Override
public KotlinType getDelegate() {
public KotlinType unwrap() {
return lazyValue.invoke();
}
@NotNull
@Override
public String toString() {
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");
* 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.descriptors.*
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.createUnsafeVarianceAnnotation
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
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.StorageManager
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.WrappedType
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.SmartSet
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
val superTypes = listOf(object : DelegatingType() {
override fun getDelegate(): KotlinType {
return moduleDescriptor.builtIns.anyType
}
val superTypes = listOf(object : WrappedType() {
override fun unwrap() = moduleDescriptor.builtIns.anyType
})
val mockSerializableClass = ClassDescriptorImpl(
@@ -119,8 +119,8 @@ private fun TypeProjection.createCapturedIfNeeded(typeParameterDescriptor: TypeP
if (typeParameterDescriptor.variance == projectionKind) {
// TODO: Make star projection type lazy
return if (isStarProjection)
TypeProjectionImpl(object : DelegatingType() {
override fun getDelegate() = this@createCapturedIfNeeded.type
TypeProjectionImpl(object : WrappedType() {
override fun unwrap(): KotlinType = this@createCapturedIfNeeded.type
})
else
TypeProjectionImpl(this@createCapturedIfNeeded.type)
@@ -17,6 +17,8 @@
package org.jetbrains.kotlin.types
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.types.checker.KotlinTypeChecker
@@ -43,6 +45,93 @@ interface KotlinType : Annotated {
}
@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) {
return flexibility.makeNullableAsSpecified(nullable);
}
else {
SimpleType simpleType = KotlinTypeKt.asSimpleType(type);
// Wrapping serves two purposes here
// 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
if (!(simpleType instanceof LazyType) && simpleType.isMarkedNullable() == nullable) return simpleType;
// Unwrap to avoid long delegation call chains
if (type instanceof AbstractTypeWithKnownNullability) {
return makeNullableAsSpecified(((AbstractTypeWithKnownNullability) type).delegate, nullable);
return KotlinTypeKt.lazyReplaceNullability(simpleType, nullable);
}
// checking to preserve laziness
if (!(type instanceof LazyType) && type.isMarkedNullable() == nullable) {
return type;
}
return nullable ? new NullableType(type) : new NotNullType(type);
}
@NotNull
@@ -528,81 +519,4 @@ public class TypeUtils {
}
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 =
KotlinBuiltIns.isNothingOrNullableNothing(this) || this.isDynamic() || this.isCaptured()
fun KotlinType.unsafeAsReifiedArgument(): Boolean = arguments.any { !it.isStarProjection }
fun TypeProjection.substitute(doSubstitute: (KotlinType) -> KotlinType): TypeProjection {
return if (isStarProjection)
this
@@ -87,11 +85,9 @@ fun TypeProjection.substitute(doSubstitute: (KotlinType) -> KotlinType): TypePro
fun KotlinType.replaceAnnotations(newAnnotations: Annotations): KotlinType {
if (annotations.isEmpty() && newAnnotations.isEmpty()) return this
return object : DelegatingType() {
override fun getDelegate() = this@replaceAnnotations
if (isFlexible()) return flexibility().replaceAnnotations(newAnnotations)
override val annotations: Annotations get() = newAnnotations
}
return asSimpleType().lazyReplaceAnnotations(newAnnotations)
}
fun KotlinTypeChecker.equalTypesOrNulls(type1: KotlinType?, type2: KotlinType?): Boolean {
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.types
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.typeUtil.builtIns
@@ -32,9 +33,9 @@ class DynamicTypesAllowed: DynamicTypesSettings() {
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 fun makeNullableAsSpecified(nullable: Boolean): KotlinType {
@@ -43,6 +44,8 @@ class DynamicType(builtIns: KotlinBuiltIns) : DelegatingFlexibleType(builtIns.no
}
override val isMarkedNullable: Boolean get() = false
override fun replaceAnnotations(newAnnotations: Annotations): KotlinType = DynamicType(delegateType.builtIns, annotations)
}
object DynamicTypeFactory : FlexibleTypeFactory {
@@ -17,7 +17,9 @@
package org.jetbrains.kotlin.types
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.typeUtil.replaceAnnotations
interface FlexibleTypeFactory {
val id: String
@@ -50,6 +52,7 @@ interface Flexibility : TypeCapability, SubtypingRepresentatives {
fun makeNullableAsSpecified(nullable: Boolean): KotlinType
fun replaceAnnotations(newAnnotations: Annotations): KotlinType
}
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))
}
}
override fun replaceAnnotations(newAnnotations: Annotations): KotlinType
= KotlinTypeFactory.flexibleType(lowerBound.replaceAnnotations(newAnnotations).asSimpleType(), upperBound)
}
// TODO: move Factory to descriptor.loader.java
@@ -104,10 +104,7 @@ class SpecifyTypeExplicitlyIntention : SelfTargetingIntention<KtCallableDeclarat
}
}
object: DelegatingType() {
override fun getDelegate() = it
override val arguments: List<TypeProjection> get() = newArguments
}
KotlinTypeFactory.simpleType(it.asSimpleType(), arguments = newArguments)
}
.ifEmpty { return null }
return object : ChooseValueExpression<KotlinType>(types, types.first()) {
@@ -54,9 +54,7 @@ private fun KotlinType.render(typeParameterNameMap: Map<TypeParameterDescriptor,
val typeParameter = it.key
var wrappingTypeParameter: TypeParameterDescriptor? = null
var wrappingTypeConstructor: TypeConstructor
wrappingTypeConstructor = object : TypeConstructor by typeParameter.typeConstructor {
val wrappingTypeConstructor = object : TypeConstructor by typeParameter.typeConstructor {
override fun getDeclarationDescriptor() = wrappingTypeParameter
}
@@ -65,11 +63,7 @@ private fun KotlinType.render(typeParameterNameMap: Map<TypeParameterDescriptor,
override fun getTypeConstructor() = wrappingTypeConstructor
}
val wrappingType = object : DelegatingType() {
override fun getDelegate(): KotlinType? = typeParameter.defaultType
override val constructor: TypeConstructor get() = wrappingTypeConstructor
}
val wrappingType = KotlinTypeFactory.simpleType(typeParameter.defaultType, constructor = wrappingTypeConstructor)
TypeProjectionImpl(wrappingType)
}
.mapKeys { it.key.typeConstructor }