Read old suspend functions in 1.3

This commit is contained in:
Ilmir Usmanov
2018-07-05 19:42:23 +03:00
parent 6b73e528ce
commit 5b7e099842
14 changed files with 147 additions and 16 deletions
@@ -302,17 +302,6 @@ fun <D : FunctionDescriptor> D.createCustomCopy(
private fun FunctionDescriptor.getContinuationParameterTypeOfSuspendFunction(isReleaseCoroutines: Boolean) =
module.getContinuationOfTypeOrAny(returnType!!, isReleaseCoroutines)
fun ModuleDescriptor.getContinuationOfTypeOrAny(kotlinType: KotlinType, isReleaseCoroutines: Boolean) =
module.findContinuationClassDescriptorOrNull(
NoLookupLocation.FROM_BACKEND,
isReleaseCoroutines
)?.defaultType?.let {
KotlinTypeFactory.simpleType(
it,
arguments = listOf(kotlinType.asTypeProjection())
)
} ?: module.builtIns.nullableAnyType
fun ModuleDescriptor.getSuccessOrFailure(kotlinType: KotlinType) =
module.resolveTopLevelClass(
DescriptorUtils.SUCCESS_OR_FAILURE_FQ_NAME,
@@ -312,7 +312,8 @@ class DescriptorSerializer private constructor(
if (requirement != null) {
builder.versionRequirement = requirement
} else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
builder.versionRequirement = writeVersionRequirement(LanguageFeature.Coroutines)
builder.versionRequirement =
writeVersionRequirement(if (this.extension.releaseCoroutines()) LanguageFeature.ReleaseCoroutines else LanguageFeature.Coroutines)
}
contractSerializer.serializeContractOfFunctionIfAny(descriptor, builder, this)
@@ -0,0 +1,19 @@
// FILE: A.kt
// LANGUAGE_VERSION: 1.2
suspend fun dummy() = "OK"
// FILE: B.kt
// LANGUAGE_VERSION: 1.3
import kotlin.coroutines.experimental.*
fun box(): String {
return dummy(object : Continuation<String> {
override val context = EmptyCoroutineContext
override fun resume(value: String) {
}
override fun resumeWithException(exception: Throwable) {
throw exception
}
}) as String
}
@@ -0,0 +1,8 @@
// !LANGUAGE: +ReleaseCoroutines
// SKIP_TXT
import kotlin.coroutines.experimental.coroutineContext
suspend fun test() {
coroutineContext
}
@@ -28,7 +28,7 @@ data class CompilerTestLanguageVersionSettings(
private val analysisFlags: Map<AnalysisFlag<*>, Any?> = emptyMap()
) : LanguageVersionSettings {
private val languageFeatures = specificFeaturesForTests() + initialLanguageFeatures
private val delegate = LanguageVersionSettingsImpl(languageVersion, apiVersion)
private val delegate = LanguageVersionSettingsImpl(languageVersion, apiVersion, emptyMap(), languageFeatures)
override fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State =
languageFeatures[feature] ?: delegate.getFeatureSupport(feature)
@@ -1855,6 +1855,24 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
}
}
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/release")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Release extends AbstractDiagnosticsTestWithStdLib {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInRelease() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/coroutines/release"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("coroutineContext.kt")
public void testCoroutineContext() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/release/coroutineContext.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/restrictSuspension")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -1855,6 +1855,24 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
}
}
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/release")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Release extends AbstractDiagnosticsTestWithStdLibUsingJavac {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInRelease() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/coroutines/release"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("coroutineContext.kt")
public void testCoroutineContext() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/release/coroutineContext.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/restrictSuspension")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -277,4 +277,22 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
public void testUnsignedTypesInAnnotations() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/unsignedTypesInAnnotations.kt");
}
@TestMetadata("compiler/testData/compileKotlinAgainstKotlin/coroutines")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Coroutines extends AbstractCompileKotlinAgainstKotlinTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInCoroutines() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/compileKotlinAgainstKotlin/coroutines"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/coroutines/simple.kt");
}
}
}
@@ -241,6 +241,12 @@ class LanguageVersionSettingsImpl @JvmOverloads constructor(
override fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State {
specificFeatures[feature]?.let { return it }
if (feature == LanguageFeature.Coroutines) {
if (getFeatureSupport(LanguageFeature.ReleaseCoroutines) == LanguageFeature.State.ENABLED) {
return LanguageFeature.State.ENABLED
}
}
val since = feature.sinceVersion
if (since != null && languageVersion >= since && apiVersion >= feature.sinceApiVersion) {
return feature.defaultState
@@ -6,8 +6,13 @@
package org.jetbrains.kotlin.descriptors
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.utils.sure
fun ModuleDescriptor.resolveClassByFqName(fqName: FqName, lookupLocation: LookupLocation): ClassDescriptor? {
@@ -29,3 +34,14 @@ fun ModuleDescriptor.findContinuationClassDescriptorOrNull(lookupLocation: Looku
fun ModuleDescriptor.findContinuationClassDescriptor(lookupLocation: LookupLocation, releaseCoroutines: Boolean) =
findContinuationClassDescriptorOrNull(lookupLocation, releaseCoroutines).sure { "Continuation interface is not found" }
fun ModuleDescriptor.getContinuationOfTypeOrAny(kotlinType: KotlinType, isReleaseCoroutines: Boolean) =
module.findContinuationClassDescriptorOrNull(
NoLookupLocation.FROM_BACKEND,
isReleaseCoroutines
)?.defaultType?.let {
KotlinTypeFactory.simpleType(
it,
arguments = listOf(kotlinType.asTypeProjection())
)
} ?: module.builtIns.nullableAnyType
@@ -26,9 +26,13 @@ import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.protobuf.MessageLite
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
import org.jetbrains.kotlin.types.KotlinType
class MemberDeserializer(private val c: DeserializationContext) {
private val annotationDeserializer = AnnotationDeserializer(c.components.moduleDescriptor, c.components.notFoundClasses)
@@ -159,12 +163,15 @@ class MemberDeserializer(private val c: DeserializationContext) {
)
val local = c.childContext(function, proto.typeParameterList)
val returnType = local.typeDeserializer.type(proto.returnType(c.typeTable))
val valueParameters = local.memberDeserializer.valueParameters(proto.valueParameterList, proto, AnnotatedCallableKind.FUNCTION)
val continuationParameter = createContinuationParameterIfNeeded(function, returnType, valueParameters, flags)
function.initialize(
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)),
valueParameters + listOfNotNull(continuationParameter),
if (continuationParameter == null) returnType else function.builtIns.nullableAnyType,
ProtoEnumFlags.modality(Flags.MODALITY.get(flags)),
ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)),
emptyMap<FunctionDescriptor.UserDataKey<*>, Any?>()
@@ -174,7 +181,7 @@ class MemberDeserializer(private val c: DeserializationContext) {
function.isExternal = Flags.IS_EXTERNAL_FUNCTION.get(flags)
function.isInline = Flags.IS_INLINE.get(flags)
function.isTailrec = Flags.IS_TAILREC.get(flags)
function.isSuspend = Flags.IS_SUSPEND.get(flags)
function.isSuspend = Flags.IS_SUSPEND.get(flags) && loadAsSuspend(function.versionRequirement)
function.isExpect = Flags.IS_EXPECT_FUNCTION.get(flags)
val mapValueForContract =
@@ -186,6 +193,30 @@ class MemberDeserializer(private val c: DeserializationContext) {
return function
}
private fun loadAsSuspend(versionRequirement: VersionRequirement?): Boolean =
if (c.components.configuration.releaseCoroutines) {
versionRequirement?.version == VersionRequirement.Version(1, 3)
} else true
private fun createContinuationParameterIfNeeded(
functionDescriptor: DeserializedSimpleFunctionDescriptor,
returnType: KotlinType,
valueParameters: List<ValueParameterDescriptor>,
flags: Int
): ValueParameterDescriptor? =
if (!Flags.IS_SUSPEND.get(flags) || loadAsSuspend(functionDescriptor.versionRequirement)) null
else ValueParameterDescriptorImpl(
containingDeclaration = functionDescriptor,
original = null,
index = valueParameters.size,
annotations = Annotations.EMPTY,
name = Name.identifier("continuation"),
outType = functionDescriptor.module.getContinuationOfTypeOrAny(returnType, isReleaseCoroutines = false),
declaresDefaultValue = false, isCrossinline = false,
isNoinline = false, varargElementType = null,
source = SourceElement.NO_SOURCE
)
fun loadTypeAlias(proto: ProtoBuf.TypeAlias): TypeAliasDescriptor {
val annotations = AnnotationsImpl(proto.annotationList.map { annotationDeserializer.deserializeAnnotation(it, c.nameResolver) })
@@ -138,6 +138,7 @@ public fun <R, T> (suspend R.() -> T).startCoroutine(
*/
@SinceKotlin("1.3")
@InlineOnly
@kotlin.internal.RequireKotlin("1.3")
public suspend inline fun <T> suspendCoroutine(crossinline block: (Continuation<T>) -> Unit): T =
suspendCoroutineUninterceptedOrReturn { c: Continuation<T> ->
val safe = SafeContinuation(c.intercepted())
@@ -37,6 +37,7 @@ import kotlin.internal.InlineOnly
*/
@SinceKotlin("1.3")
@InlineOnly
@kotlin.internal.RequireKotlin("1.3")
public suspend inline fun <T> suspendCoroutineUninterceptedOrReturn(crossinline block: (Continuation<T>) -> Any?): T =
throw NotImplementedError("Implementation of suspendCoroutineUninterceptedOrReturn is intrinsic")
@@ -3,6 +3,7 @@
* that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("SequenceBuilderKt")
@@ -54,6 +55,7 @@ public abstract class SequenceBuilder<in T> internal constructor() {
* @sample samples.collections.Sequences.Building.buildSequenceYieldAll
* @sample samples.collections.Sequences.Building.buildFibonacciSequence
*/
@kotlin.internal.RequireKotlin("1.3")
public abstract suspend fun yield(value: T)
/**
@@ -63,6 +65,7 @@ public abstract class SequenceBuilder<in T> internal constructor() {
*
* @sample samples.collections.Sequences.Building.buildSequenceYieldAll
*/
@kotlin.internal.RequireKotlin("1.3")
public abstract suspend fun yieldAll(iterator: Iterator<T>)
/**
@@ -70,6 +73,7 @@ public abstract class SequenceBuilder<in T> internal constructor() {
*
* @sample samples.collections.Sequences.Building.buildSequenceYieldAll
*/
@kotlin.internal.RequireKotlin("1.3")
public suspend fun yieldAll(elements: Iterable<T>) {
if (elements is Collection && elements.isEmpty()) return
return yieldAll(elements.iterator())
@@ -82,6 +86,7 @@ public abstract class SequenceBuilder<in T> internal constructor() {
*
* @sample samples.collections.Sequences.Building.buildSequenceYieldAll
*/
@kotlin.internal.RequireKotlin("1.3")
public suspend fun yieldAll(sequence: Sequence<T>) = yieldAll(sequence.iterator())
}