Move coroutines to kotlin.coroutines package: compiler

Generate continuation type as kotlin.coroutines.Continuaion. This code will
fail at runtime since there is no stdlib backing this change yet.
However, in order to generate compatible stdlib we need a compiler, which
generates continuation type as kotlin.coroutines.Continuation.
Thus, firstly we support the change in the compiler, make it bootstrap
compiler and only then change stdlib and tests accordingly.
 #KT-23362
This commit is contained in:
Ilmir Usmanov
2018-03-21 19:54:14 +03:00
parent f8c0c54a66
commit 2cfe387bab
67 changed files with 692 additions and 694 deletions
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 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.builtins
@@ -24,6 +13,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.impl.MutableClassDescriptor
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
@@ -31,25 +21,40 @@ import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.types.typeUtil.builtIns
val FAKE_CONTINUATION_CLASS_DESCRIPTOR_EXPERIMENTAL =
MutableClassDescriptor(
EmptyPackageFragmentDescriptor(ErrorUtils.getErrorModule(), DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL),
ClassKind.INTERFACE, /* isInner = */ false, /* isExternal = */ false,
DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL.shortName(), SourceElement.NO_SOURCE
).apply {
modality = Modality.ABSTRACT
visibility = Visibilities.PUBLIC
setTypeParameterDescriptors(
TypeParameterDescriptorImpl.createWithDefaultBound(
this, Annotations.EMPTY, false, Variance.IN_VARIANCE, Name.identifier("T"), 0
).let(::listOf)
)
createTypeConstructor()
}
val FAKE_CONTINUATION_CLASS_DESCRIPTOR =
MutableClassDescriptor(
EmptyPackageFragmentDescriptor(ErrorUtils.getErrorModule(), DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME),
ClassKind.INTERFACE, /* isInner = */ false, /* isExternal = */ false,
DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME.shortName(), SourceElement.NO_SOURCE
).apply {
modality = Modality.ABSTRACT
visibility = Visibilities.PUBLIC
setTypeParameterDescriptors(
TypeParameterDescriptorImpl.createWithDefaultBound(
this, Annotations.EMPTY, false, Variance.IN_VARIANCE, Name.identifier("T"), 0
).let(::listOf)
)
createTypeConstructor()
}
val FAKE_CONTINUATION_CLASS_DESCRIPTOR_RELEASE =
MutableClassDescriptor(
EmptyPackageFragmentDescriptor(ErrorUtils.getErrorModule(), DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_RELEASE),
ClassKind.INTERFACE, /* isInner = */ false, /* isExternal = */ false,
DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_RELEASE.shortName(), SourceElement.NO_SOURCE
).apply {
modality = Modality.ABSTRACT
visibility = Visibilities.PUBLIC
setTypeParameterDescriptors(
TypeParameterDescriptorImpl.createWithDefaultBound(
this, Annotations.EMPTY, false, Variance.IN_VARIANCE, Name.identifier("T"), 0
).let(::listOf)
)
createTypeConstructor()
}
fun transformSuspendFunctionToRuntimeFunctionType(suspendFunType: KotlinType): SimpleType {
fun transformSuspendFunctionToRuntimeFunctionType(suspendFunType: KotlinType, isReleaseCoroutines: Boolean): SimpleType {
assert(suspendFunType.isSuspendFunctionType) {
"This type should be suspend function type: $suspendFunType"
}
@@ -64,7 +69,8 @@ fun transformSuspendFunctionToRuntimeFunctionType(suspendFunType: KotlinType): S
// Continuation interface is not a part of built-ins anymore, it has been moved to stdlib.
// While it must be somewhere in the dependencies, but here we don't have a reference to the module,
// and it's rather complicated to inject it by now, so we just use a fake class descriptor.
FAKE_CONTINUATION_CLASS_DESCRIPTOR.typeConstructor,
if (isReleaseCoroutines) FAKE_CONTINUATION_CLASS_DESCRIPTOR_RELEASE.typeConstructor
else FAKE_CONTINUATION_CLASS_DESCRIPTOR_EXPERIMENTAL.typeConstructor,
listOf(suspendFunType.getReturnTypeFromFunctionType().asTypeProjection()), nullable = false
),
// TODO: names
@@ -73,14 +79,14 @@ fun transformSuspendFunctionToRuntimeFunctionType(suspendFunType: KotlinType): S
).makeNullableAsSpecified(suspendFunType.isMarkedNullable)
}
fun transformRuntimeFunctionTypeToSuspendFunction(funType: KotlinType): SimpleType? {
fun transformRuntimeFunctionTypeToSuspendFunction(funType: KotlinType, isReleaseCoroutines: Boolean): SimpleType? {
assert(funType.isFunctionType) {
"This type should be function type: $funType"
}
val continuationArgumentType = funType.getValueParameterTypesFromFunctionType().lastOrNull()?.type ?: return null
if (continuationArgumentType.constructor.declarationDescriptor?.fqNameSafe != DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME
|| continuationArgumentType.arguments.size != 1
if (!isContinuation(continuationArgumentType.constructor.declarationDescriptor?.fqNameSafe, isReleaseCoroutines) ||
continuationArgumentType.arguments.size != 1
) {
return null
}
@@ -97,4 +103,9 @@ fun transformRuntimeFunctionTypeToSuspendFunction(funType: KotlinType): SimpleTy
suspendReturnType,
suspendFunction = true
).makeNullableAsSpecified(funType.isMarkedNullable)
}
}
private fun isContinuation(name: FqName?, isReleaseCoroutines: Boolean): Boolean {
return if (isReleaseCoroutines) name == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_RELEASE
else name == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL
}
@@ -1,17 +1,6 @@
/*
* 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.
* 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.descriptors
@@ -32,8 +21,11 @@ fun ModuleDescriptor.resolveClassByFqName(fqName: FqName, lookupLocation: Lookup
?.getContributedClassifier(fqName.shortName(), lookupLocation) as? ClassDescriptor
}
fun ModuleDescriptor.findContinuationClassDescriptorOrNull(lookupLocation: LookupLocation) =
resolveClassByFqName(DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME, lookupLocation)
fun ModuleDescriptor.findContinuationClassDescriptorOrNull(lookupLocation: LookupLocation, releaseCoroutines: Boolean) =
if (releaseCoroutines)
resolveClassByFqName(DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_RELEASE, lookupLocation)
else
resolveClassByFqName(DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL, lookupLocation)
fun ModuleDescriptor.findContinuationClassDescriptor(lookupLocation: LookupLocation) =
findContinuationClassDescriptorOrNull(lookupLocation).sure { "Continuation interface is not found" }
fun ModuleDescriptor.findContinuationClassDescriptor(lookupLocation: LookupLocation, releaseCoroutines: Boolean) =
findContinuationClassDescriptorOrNull(lookupLocation, releaseCoroutines).sure { "Continuation interface is not found" }
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 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.resolve;
@@ -49,9 +38,15 @@ public class DescriptorUtils {
public static final FqName JVM_NAME = new FqName("kotlin.jvm.JvmName");
private static final FqName VOLATILE = new FqName("kotlin.jvm.Volatile");
private static final FqName SYNCHRONIZED = new FqName("kotlin.jvm.Synchronized");
public static final FqName COROUTINES_PACKAGE_FQ_NAME = new FqName("kotlin.coroutines.experimental");
public static final FqName COROUTINES_INTRINSICS_PACKAGE_FQ_NAME = COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("intrinsics"));
public static final FqName CONTINUATION_INTERFACE_FQ_NAME = COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("Continuation"));
public static final FqName COROUTINES_PACKAGE_FQ_NAME_RELEASE = new FqName("kotlin.coroutines");
public static final FqName COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL =
COROUTINES_PACKAGE_FQ_NAME_RELEASE.child(Name.identifier("experimental"));
public static final FqName COROUTINES_INTRINSICS_PACKAGE_FQ_NAME_EXPERIMENTAL =
COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.child(Name.identifier("intrinsics"));
public static final FqName CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL =
COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.child(Name.identifier("Continuation"));
public static final FqName CONTINUATION_INTERFACE_FQ_NAME_RELEASE =
COROUTINES_PACKAGE_FQ_NAME_RELEASE.child(Name.identifier("Continuation"));
private DescriptorUtils() {
}
@@ -1,30 +1,17 @@
/*
* 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.resolve.descriptorUtil
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.KotlinType
private val NO_INFER_ANNOTATION_FQ_NAME = FqName("kotlin.internal.NoInfer")
@@ -33,7 +20,6 @@ private val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME = FqName("kotlin.interna
private val HIDES_MEMBERS_ANNOTATION_FQ_NAME = FqName("kotlin.internal.HidesMembers")
private val ONLY_INPUT_TYPES_FQ_NAME = FqName("kotlin.internal.OnlyInputTypes")
private val DYNAMIC_EXTENSION_FQ_NAME = FqName("kotlin.internal.DynamicExtension")
private val RESTRICTS_SUSPENSION_FQ_NAME = DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("RestrictsSuspension"))
// @HidesMembers annotation only has effect for members with these names
val HIDES_MEMBERS_NAME_LIST = setOf(Name.identifier("forEach"))
@@ -51,7 +37,6 @@ fun CallableDescriptor.hasLowPriorityInOverloadResolution(): Boolean = annotatio
fun CallableDescriptor.hasHidesMembersAnnotation(): Boolean = annotations.hasAnnotation(HIDES_MEMBERS_ANNOTATION_FQ_NAME)
fun CallableDescriptor.hasDynamicExtensionAnnotation(): Boolean = annotations.hasAnnotation(DYNAMIC_EXTENSION_FQ_NAME)
fun ClassifierDescriptor.hasRestrictsSuspensionAnnotation(): Boolean = annotations.hasAnnotation(RESTRICTS_SUSPENSION_FQ_NAME)
fun TypeParameterDescriptor.hasOnlyInputTypesAnnotation(): Boolean = annotations.hasAnnotation(ONLY_INPUT_TYPES_FQ_NAME)