diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt index 344350ead9e..58dcae17585 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.serialization.deserialization +import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget @@ -60,12 +61,6 @@ class MemberDeserializer(private val c: DeserializationContext) { proto.receiverType(c.typeTable)?.let { local.typeDeserializer.type(it, receiverAnnotations) } ) - // Calculate isExperimentalCoroutineInReleaseEnvironment for type parameters - property.typeParameters.forEach { it.upperBounds } - - property.isExperimentalCoroutineInReleaseEnvironment = local.typeDeserializer.experimentalSuspendFunctionTypeEncountered && - c.components.configuration.releaseCoroutines && property.versionRequirement?.version != VersionRequirement.Version(1, 3) - val getter = if (hasGetter) { val getterFlags = proto.getterFlags val isNotDefault = proto.hasGetterFlags() && Flags.IS_NOT_DEFAULT.get(getterFlags) @@ -131,11 +126,20 @@ class MemberDeserializer(private val c: DeserializationContext) { ) } - property.initialize(getter, setter) + property.initialize(getter, setter, property.checkExperimentalCoroutine(local.typeDeserializer)) return property } + private fun DeserializedMemberDescriptor.checkExperimentalCoroutine(typeDeserializer: TypeDeserializer): Boolean { + // Calculate checkExperimentalCoroutine for type parameters + typeDeserializer.ownTypeParameters.forEach { it.upperBounds } + return typeDeserializer.experimentalSuspendFunctionTypeEncountered && versionAndReleaseCoroutinesMismatch() + } + + private fun DeserializedMemberDescriptor.versionAndReleaseCoroutinesMismatch(): Boolean = + c.components.configuration.releaseCoroutines && versionRequirement?.version != VersionRequirement.Version(1, 3) + private fun loadOldFlags(oldFlags: Int): Int { val lowSixBits = oldFlags and 0x3f val rest = (oldFlags shr 8) shl 6 @@ -155,16 +159,17 @@ class MemberDeserializer(private val c: DeserializationContext) { ) val local = c.childContext(function, proto.typeParameterList) - val receiverType = proto.receiverType(c.typeTable)?.let { local.typeDeserializer.type(it, receiverAnnotations) } function.initialize( - receiverType, + proto.receiverType(c.typeTable)?.let { local.typeDeserializer.type(it, receiverAnnotations) }, getDispatchReceiverParameter(), local.typeDeserializer.ownTypeParameters, local.memberDeserializer.valueParameters(proto.valueParameterList, proto, AnnotatedCallableKind.FUNCTION), local.typeDeserializer.type(proto.returnType(c.typeTable)), ProtoEnumFlags.modality(Flags.MODALITY.get(flags)), ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)), - emptyMap, Any?>() + emptyMap, Any?>(), + (Flags.IS_SUSPEND.get(flags) && function.versionAndReleaseCoroutinesMismatch()) || + function.checkExperimentalCoroutine(local.typeDeserializer) ) function.isOperator = Flags.IS_OPERATOR.get(flags) function.isInfix = Flags.IS_INFIX.get(flags) @@ -174,13 +179,6 @@ class MemberDeserializer(private val c: DeserializationContext) { function.isSuspend = Flags.IS_SUSPEND.get(flags) function.isExpect = Flags.IS_EXPECT_FUNCTION.get(flags) - // Calculate isExperimentalCoroutineInReleaseEnvironment for type parameters - function.typeParameters.forEach { it.upperBounds } - - function.isExperimentalCoroutineInReleaseEnvironment = local.typeDeserializer.experimentalSuspendFunctionTypeEncountered || - (c.components.configuration.releaseCoroutines && Flags.IS_SUSPEND.get(flags) && - function.versionRequirement?.version != VersionRequirement.Version(1, 3)) - val mapValueForContract = c.components.contractDeserializer.deserializeContractFromFunction(proto, function, c.typeTable, c.typeDeserializer) if (mapValueForContract != null) { @@ -203,14 +201,10 @@ class MemberDeserializer(private val c: DeserializationContext) { typeAlias.initialize( local.typeDeserializer.ownTypeParameters, local.typeDeserializer.simpleType(proto.underlyingType(c.typeTable)), - local.typeDeserializer.simpleType(proto.expandedType(c.typeTable)) + local.typeDeserializer.simpleType(proto.expandedType(c.typeTable)), + typeAlias.checkExperimentalCoroutine(local.typeDeserializer) ) - // Calculate isExperimentalCoroutineInReleaseEnvironment for type parameters - local.typeDeserializer.ownTypeParameters.forEach { it.upperBounds } - - typeAlias.isExperimentalCoroutineInReleaseEnvironment = local.typeDeserializer.experimentalSuspendFunctionTypeEncountered - return typeAlias } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberDescriptor.kt index aef92247256..c7561d817fe 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberDescriptor.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2015 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.serialization.deserialization.descriptors @@ -34,7 +23,7 @@ interface DeserializedMemberDescriptor : MemberDescriptor { val typeTable: TypeTable - var isExperimentalCoroutineInReleaseEnvironment: Boolean + val isExperimentalCoroutineInReleaseEnvironment: Boolean val versionRequirementTable: VersionRequirementTable @@ -70,14 +59,41 @@ class DeserializedSimpleFunctionDescriptor( override val typeTable: TypeTable, override val versionRequirementTable: VersionRequirementTable, override val containerSource: DeserializedContainerSource?, - source: SourceElement? = null, - override var isExperimentalCoroutineInReleaseEnvironment: Boolean = false + source: SourceElement? = null ) : DeserializedCallableMemberDescriptor, SimpleFunctionDescriptorImpl( containingDeclaration, original, annotations, name, kind, source ?: SourceElement.NO_SOURCE ) { + override var isExperimentalCoroutineInReleaseEnvironment: Boolean = false + private set + + fun initialize( + receiverParameterType: KotlinType?, + dispatchReceiverParameter: ReceiverParameterDescriptor?, + typeParameters: List, + unsubstitutedValueParameters: List, + unsubstitutedReturnType: KotlinType?, + modality: Modality?, + visibility: Visibility, + userDataMap: Map, *>, + isExperimentalCoroutineInReleaseEnvironment: Boolean + ): SimpleFunctionDescriptorImpl { + return super.initialize( + receiverParameterType, + dispatchReceiverParameter, + typeParameters, + unsubstitutedValueParameters, + unsubstitutedReturnType, + modality, + visibility, + userDataMap + ).also { + this.isExperimentalCoroutineInReleaseEnvironment = isExperimentalCoroutineInReleaseEnvironment + } + } + override fun createSubstitutedCopy( newOwner: DeclarationDescriptor, original: FunctionDescriptor?, @@ -88,7 +104,7 @@ class DeserializedSimpleFunctionDescriptor( ): FunctionDescriptorImpl { return DeserializedSimpleFunctionDescriptor( newOwner, original as SimpleFunctionDescriptor?, annotations, newName ?: name, kind, - proto, nameResolver, typeTable, versionRequirementTable, containerSource, source, isExperimentalCoroutineInReleaseEnvironment + proto, nameResolver, typeTable, versionRequirementTable, containerSource, source ) } } @@ -111,12 +127,23 @@ class DeserializedPropertyDescriptor( override val nameResolver: NameResolver, override val typeTable: TypeTable, override val versionRequirementTable: VersionRequirementTable, - override val containerSource: DeserializedContainerSource?, - override var isExperimentalCoroutineInReleaseEnvironment: Boolean = false + override val containerSource: DeserializedContainerSource? ) : DeserializedCallableMemberDescriptor, PropertyDescriptorImpl( containingDeclaration, original, annotations, modality, visibility, isVar, name, kind, SourceElement.NO_SOURCE, isLateInit, isConst, isExpect, false, isExternal, isDelegated ) { + override var isExperimentalCoroutineInReleaseEnvironment: Boolean = false + private set + + fun initialize( + getter: PropertyGetterDescriptorImpl?, + setter: PropertySetterDescriptor?, + isExperimentalCoroutineInReleaseEnvironment: Boolean + ) { + super.initialize(getter, setter) + .also { this.isExperimentalCoroutineInReleaseEnvironment = isExperimentalCoroutineInReleaseEnvironment } + } + override fun createSubstitutedCopy( newOwner: DeclarationDescriptor, newModality: Modality, @@ -127,8 +154,7 @@ class DeserializedPropertyDescriptor( ): PropertyDescriptorImpl { return DeserializedPropertyDescriptor( newOwner, original, annotations, newModality, newVisibility, isVar, newName, kind, isLateInit, isConst, isExternal, - @Suppress("DEPRECATION") isDelegated, isExpect, proto, nameResolver, typeTable, versionRequirementTable, containerSource, - isExperimentalCoroutineInReleaseEnvironment + @Suppress("DEPRECATION") isDelegated, isExpect, proto, nameResolver, typeTable, versionRequirementTable, containerSource ) } @@ -146,11 +172,13 @@ class DeserializedClassConstructorDescriptor( override val typeTable: TypeTable, override val versionRequirementTable: VersionRequirementTable, override val containerSource: DeserializedContainerSource?, - source: SourceElement? = null, - override var isExperimentalCoroutineInReleaseEnvironment: Boolean = false + source: SourceElement? = null ) : DeserializedCallableMemberDescriptor, ClassConstructorDescriptorImpl(containingDeclaration, original, annotations, isPrimary, kind, source ?: SourceElement.NO_SOURCE) { + override var isExperimentalCoroutineInReleaseEnvironment: Boolean = false + internal set + override fun createSubstitutedCopy( newOwner: DeclarationDescriptor, original: FunctionDescriptor?, @@ -162,7 +190,7 @@ class DeserializedClassConstructorDescriptor( return DeserializedClassConstructorDescriptor( newOwner as ClassDescriptor, original as ConstructorDescriptor?, annotations, isPrimary, kind, proto, nameResolver, typeTable, versionRequirementTable, containerSource, source - ) + ).also { it.isExperimentalCoroutineInReleaseEnvironment = isExperimentalCoroutineInReleaseEnvironment } } override fun isExternal(): Boolean = false @@ -184,8 +212,7 @@ class DeserializedTypeAliasDescriptor( override val nameResolver: NameResolver, override val typeTable: TypeTable, override val versionRequirementTable: VersionRequirementTable, - override val containerSource: DeserializedContainerSource?, - override var isExperimentalCoroutineInReleaseEnvironment: Boolean = false + override val containerSource: DeserializedContainerSource? ) : AbstractTypeAliasDescriptor(containingDeclaration, annotations, name, SourceElement.NO_SOURCE, visibility), DeserializedMemberDescriptor { override lateinit var constructors: Collection private set @@ -195,10 +222,14 @@ class DeserializedTypeAliasDescriptor( private lateinit var typeConstructorParameters: List private lateinit var defaultTypeImpl: SimpleType + override var isExperimentalCoroutineInReleaseEnvironment: Boolean = false + private set + fun initialize( declaredTypeParameters: List, underlyingType: SimpleType, - expandedType: SimpleType + expandedType: SimpleType, + isExperimentalCoroutineInReleaseEnvironment: Boolean ) { initialize(declaredTypeParameters) this.underlyingType = underlyingType @@ -206,6 +237,7 @@ class DeserializedTypeAliasDescriptor( typeConstructorParameters = computeConstructorTypeParameters() defaultTypeImpl = computeDefaultType() constructors = getTypeAliasConstructors() + this.isExperimentalCoroutineInReleaseEnvironment = isExperimentalCoroutineInReleaseEnvironment } override val classDescriptor: ClassDescriptor? @@ -217,13 +249,13 @@ class DeserializedTypeAliasDescriptor( if (substitutor.isEmpty) return this val substituted = DeserializedTypeAliasDescriptor( storageManager, containingDeclaration, annotations, name, visibility, - proto, nameResolver, typeTable, versionRequirementTable, containerSource, - isExperimentalCoroutineInReleaseEnvironment + proto, nameResolver, typeTable, versionRequirementTable, containerSource ) substituted.initialize( declaredTypeParameters, substitutor.safeSubstitute(underlyingType, Variance.INVARIANT).asSimpleType(), - substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType() + substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType(), + isExperimentalCoroutineInReleaseEnvironment ) return substituted