Deserialize constructors and properties with version requirement 1.3
if they have suspend function type in their descriptors. Also, review fixes. #KT-25256: Fixed
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 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.
|
||||
*/
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
|
||||
import org.jetbrains.kotlin.psi.KtModifierList
|
||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.checkCoroutinesFeature
|
||||
import java.util.*
|
||||
|
||||
object ModifierCheckerCore {
|
||||
@@ -338,9 +339,6 @@ object ModifierCheckerCore {
|
||||
|
||||
val dependencies = featureDependencies[modifier] ?: return true
|
||||
for (dependency in dependencies) {
|
||||
if (dependency == LanguageFeature.Coroutines && languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) {
|
||||
continue
|
||||
}
|
||||
val restrictedTargets = featureDependenciesTargets[dependency]
|
||||
if (restrictedTargets != null && actualTargets.intersect(restrictedTargets).isEmpty()) {
|
||||
continue
|
||||
@@ -348,6 +346,11 @@ object ModifierCheckerCore {
|
||||
|
||||
val featureSupport = languageVersionSettings.getFeatureSupport(dependency)
|
||||
|
||||
if (dependency == LanguageFeature.Coroutines) {
|
||||
checkCoroutinesFeature(languageVersionSettings, trace, node.psi)
|
||||
continue
|
||||
}
|
||||
|
||||
val diagnosticData = dependency to languageVersionSettings
|
||||
when (featureSupport) {
|
||||
LanguageFeature.State.ENABLED_WITH_WARNING -> {
|
||||
|
||||
+6
-5
@@ -61,10 +61,6 @@ object CoroutineSuspendCallChecker : CallChecker {
|
||||
else -> return
|
||||
}
|
||||
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) && context.languageVersionSettings.apiVersion < ApiVersion.KOTLIN_1_3) {
|
||||
context.trace.report(Errors.UNSUPPORTED.on(reportOn, "cannot use release coroutines API version less than 1.3"))
|
||||
}
|
||||
|
||||
val enclosingSuspendFunction = context.scope
|
||||
.parentsWithSelf.firstOrNull {
|
||||
it is LexicalScope && it.kind in ALLOWED_SCOPE_KINDS &&
|
||||
@@ -136,7 +132,12 @@ object BuilderFunctionsCallChecker : CallChecker {
|
||||
}
|
||||
|
||||
fun checkCoroutinesFeature(languageVersionSettings: LanguageVersionSettings, diagnosticHolder: DiagnosticSink, reportOn: PsiElement) {
|
||||
if (languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) return
|
||||
if (languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) {
|
||||
if (languageVersionSettings.apiVersion < ApiVersion.KOTLIN_1_3) {
|
||||
diagnosticHolder.report(Errors.UNSUPPORTED.on(reportOn, "cannot use release coroutines with api version less than 1.3"))
|
||||
}
|
||||
return
|
||||
}
|
||||
val diagnosticData = LanguageFeature.Coroutines to languageVersionSettings
|
||||
when (languageVersionSettings.getFeatureSupport(LanguageFeature.Coroutines)) {
|
||||
LanguageFeature.State.ENABLED -> {
|
||||
|
||||
+8
-8
@@ -240,9 +240,8 @@ class DescriptorSerializer private constructor(
|
||||
val requirement = serializeVersionRequirement(descriptor)
|
||||
if (requirement != null) {
|
||||
builder.versionRequirement = requirement
|
||||
}
|
||||
else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||
builder.versionRequirement = writeVersionRequirement(LanguageFeature.Coroutines)
|
||||
} else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||
builder.versionRequirement = writeVersionRequirementDependingOnCoroutinesVersion()
|
||||
}
|
||||
|
||||
extension.serializeProperty(descriptor, builder)
|
||||
@@ -312,8 +311,7 @@ class DescriptorSerializer private constructor(
|
||||
if (requirement != null) {
|
||||
builder.versionRequirement = requirement
|
||||
} else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||
builder.versionRequirement =
|
||||
writeVersionRequirement(if (this.extension.releaseCoroutines()) LanguageFeature.ReleaseCoroutines else LanguageFeature.Coroutines)
|
||||
builder.versionRequirement = writeVersionRequirementDependingOnCoroutinesVersion()
|
||||
}
|
||||
|
||||
contractSerializer.serializeContractOfFunctionIfAny(descriptor, builder, this)
|
||||
@@ -342,9 +340,8 @@ class DescriptorSerializer private constructor(
|
||||
val requirement = serializeVersionRequirement(descriptor)
|
||||
if (requirement != null) {
|
||||
builder.versionRequirement = requirement
|
||||
}
|
||||
else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||
builder.versionRequirement = writeVersionRequirement(LanguageFeature.Coroutines)
|
||||
} else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||
builder.versionRequirement = writeVersionRequirementDependingOnCoroutinesVersion()
|
||||
}
|
||||
|
||||
extension.serializeConstructor(descriptor, builder)
|
||||
@@ -352,6 +349,9 @@ class DescriptorSerializer private constructor(
|
||||
return builder
|
||||
}
|
||||
|
||||
private fun writeVersionRequirementDependingOnCoroutinesVersion(): Int =
|
||||
writeVersionRequirement(if (this.extension.releaseCoroutines()) LanguageFeature.ReleaseCoroutines else LanguageFeature.Coroutines)
|
||||
|
||||
private fun CallableMemberDescriptor.isSuspendOrHasSuspendTypesInSignature(): Boolean {
|
||||
if (this is FunctionDescriptor && isSuspend) return true
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
$TESTDATA_DIR$/releaseCoroutinesApiVersion1.2.kt
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
-language-version
|
||||
1.3
|
||||
-api-version
|
||||
1.2
|
||||
@@ -0,0 +1,13 @@
|
||||
suspend fun dummy() {}
|
||||
|
||||
val c: suspend () -> Unit = {}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {}
|
||||
|
||||
val d = suspend {}
|
||||
|
||||
suspend fun check() {
|
||||
dummy()
|
||||
c()
|
||||
builder {}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
warning: language version 1.3 is experimental, there are no backwards compatibility guarantees for new language and library features
|
||||
compiler/testData/cli/jvm/releaseCoroutinesApiVersion1.2.kt:1:1: error: unsupported [cannot use release coroutines with api version less than 1.3]
|
||||
suspend fun dummy() {}
|
||||
^
|
||||
compiler/testData/cli/jvm/releaseCoroutinesApiVersion1.2.kt:3:8: error: unsupported [cannot use release coroutines with api version less than 1.3]
|
||||
val c: suspend () -> Unit = {}
|
||||
^
|
||||
compiler/testData/cli/jvm/releaseCoroutinesApiVersion1.2.kt:5:16: error: unsupported [cannot use release coroutines with api version less than 1.3]
|
||||
fun builder(c: suspend () -> Unit) {}
|
||||
^
|
||||
compiler/testData/cli/jvm/releaseCoroutinesApiVersion1.2.kt:7:9: error: unsupported [cannot use release coroutines with api version less than 1.3]
|
||||
val d = suspend {}
|
||||
^
|
||||
compiler/testData/cli/jvm/releaseCoroutinesApiVersion1.2.kt:9:1: error: unsupported [cannot use release coroutines with api version less than 1.3]
|
||||
suspend fun check() {
|
||||
^
|
||||
compiler/testData/cli/jvm/releaseCoroutinesApiVersion1.2.kt:12:5: error: unsupported [cannot use release coroutines with api version less than 1.3]
|
||||
builder {}
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
@@ -1,11 +0,0 @@
|
||||
// !API_VERSION: 1.3
|
||||
// LANGUAGE_VERSION: 1.3
|
||||
|
||||
suspend fun named() {}
|
||||
|
||||
suspend fun withStateMachine() {
|
||||
named()
|
||||
named()
|
||||
}
|
||||
|
||||
val l: suspend() -> Unit = {}
|
||||
+8
@@ -1,3 +1,11 @@
|
||||
suspend fun callRelease() {
|
||||
dummy()
|
||||
|
||||
C().dummy()
|
||||
|
||||
// TODO: This should be error
|
||||
WithNested.Nested().dummy()
|
||||
|
||||
// TODO: This should be error
|
||||
WithInner().Inner().dummy()
|
||||
}
|
||||
+17
-1
@@ -1 +1,17 @@
|
||||
suspend fun dummy() {}
|
||||
suspend fun dummy() {}
|
||||
|
||||
class C {
|
||||
suspend fun dummy() = "OK"
|
||||
}
|
||||
|
||||
class WithNested {
|
||||
class Nested {
|
||||
suspend fun dummy() = "OK"
|
||||
}
|
||||
}
|
||||
|
||||
class WithInner {
|
||||
inner class Inner {
|
||||
suspend fun dummy() = "OK"
|
||||
}
|
||||
}
|
||||
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/releaseCoroutineCallFromExperimental/output.txt
Vendored
+3
@@ -1,4 +1,7 @@
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/releaseCoroutineCallFromExperimental/experimental.kt:2:5: error: 'dummy(): Unit' is only available since Kotlin 1.3 and cannot be used in Kotlin 1.2
|
||||
dummy()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/releaseCoroutineCallFromExperimental/experimental.kt:4:9: error: 'dummy(): String' is only available since Kotlin 1.3 and cannot be used in Kotlin 1.2
|
||||
C().dummy()
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
|
||||
@@ -27,6 +27,6 @@ fun ok(continuation: Continuation<String>): Any? {
|
||||
fun box(): String {
|
||||
if ((::ok).builder() != "OK") return "FAIL 1"
|
||||
if (({ cont: Continuation<String> -> "OK" }).builder() != "OK") return "FAIL 2"
|
||||
if ((fun (cont: Continuation<String>): Any? = "OK").builder() != "OK") return "FAIL 2"
|
||||
if ((fun (cont: Continuation<String>): Any? = "OK").builder() != "OK") return "FAIL 3"
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,23 @@ suspend fun String.dummy() = this + "K"
|
||||
|
||||
suspend fun String.dummy(s: String) = this + s
|
||||
|
||||
class C {
|
||||
suspend fun dummy() = "OK"
|
||||
}
|
||||
|
||||
class WithNested {
|
||||
class Nested {
|
||||
suspend fun dummy() = "OK"
|
||||
}
|
||||
}
|
||||
|
||||
class WithInner {
|
||||
inner class Inner {
|
||||
suspend fun dummy() = "OK"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// FILE: B.kt
|
||||
// LANGUAGE_VERSION: 1.3
|
||||
import kotlin.coroutines.experimental.*
|
||||
@@ -23,5 +40,8 @@ fun box(): String {
|
||||
if (dummy(continuation) != "OK") return "FAIL 1"
|
||||
if ("O".dummy(continuation) != "OK") return "FAIL 2"
|
||||
if ("O".dummy("K", continuation) != "OK") return "FAIL 3"
|
||||
if (C().dummy(continuation) != "OK") return "FAIL 4"
|
||||
if (WithNested.Nested().dummy(continuation) != "OK") return "FAIL 5"
|
||||
if (WithInner().Inner().dummy(continuation) != "OK") return "FAIL 6"
|
||||
return "OK"
|
||||
}
|
||||
|
||||
+15
-10
@@ -1,21 +1,26 @@
|
||||
// !API_VERSION: 1.2
|
||||
// !DIAGNOSTICS: -PRE_RELEASE_CLASS
|
||||
// !DIAGNOSTICS: -PRE_RELEASE_CLASS, -UNUSED_PARAMETER
|
||||
// !LANGUAGE: +ReleaseCoroutines
|
||||
// SKIP_TXT
|
||||
|
||||
suspend fun dummy() {}
|
||||
<!UNSUPPORTED!>suspend<!> fun dummy() {}
|
||||
|
||||
suspend fun test1() {
|
||||
// TODO: Forbid
|
||||
fun builder(c: <!UNSUPPORTED!>suspend<!> () -> Unit) {}
|
||||
|
||||
<!UNSUPPORTED!>suspend<!> fun test1() {
|
||||
kotlin.coroutines.<!UNRESOLVED_REFERENCE!>coroutineContext<!>
|
||||
|
||||
kotlin.coroutines.experimental.<!UNSUPPORTED, UNSUPPORTED!>coroutineContext<!>
|
||||
kotlin.coroutines.experimental.<!UNSUPPORTED!>coroutineContext<!>
|
||||
|
||||
<!UNSUPPORTED!>suspend {}()<!>
|
||||
<!UNSUPPORTED!>suspend<!> {}()
|
||||
|
||||
<!UNSUPPORTED!>dummy<!>()
|
||||
dummy()
|
||||
|
||||
val c: suspend () -> Unit = {}
|
||||
<!UNSUPPORTED!>c<!>()
|
||||
val c: <!UNSUPPORTED!>suspend<!> () -> Unit = {}
|
||||
c()
|
||||
|
||||
<!UNSUPPORTED!>builder<!> {}
|
||||
}
|
||||
|
||||
fun test2() {
|
||||
@@ -27,6 +32,6 @@ fun test2() {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun test3(): Unit = <!TYPE_MISMATCH!>kotlin.coroutines.experimental.<!NO_VALUE_FOR_PARAMETER, TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>suspendCoroutine<!> <!TYPE_MISMATCH!>{ <!CANNOT_INFER_PARAMETER_TYPE!>_<!> -> Unit }<!><!>
|
||||
<!UNSUPPORTED!>suspend<!> fun test3(): Unit = <!TYPE_MISMATCH!>kotlin.coroutines.experimental.<!NO_VALUE_FOR_PARAMETER, TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>suspendCoroutine<!> <!TYPE_MISMATCH!>{ <!CANNOT_INFER_PARAMETER_TYPE!>_<!> -> Unit }<!><!>
|
||||
|
||||
suspend fun test4(): Unit = kotlin.coroutines.<!UNRESOLVED_REFERENCE!>suspendCoroutine<!> { <!CANNOT_INFER_PARAMETER_TYPE!>_<!> -> Unit }
|
||||
<!UNSUPPORTED!>suspend<!> fun test4(): Unit = kotlin.coroutines.<!UNRESOLVED_REFERENCE!>suspendCoroutine<!> { <!CANNOT_INFER_PARAMETER_TYPE!>_<!> -> Unit }
|
||||
+4
-4
@@ -7,7 +7,7 @@ import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
class Controller {
|
||||
<!EXPERIMENTAL_FEATURE_WARNING!>suspend<!> fun noParams(): Unit = suspendCoroutineUninterceptedOrReturn {
|
||||
suspend fun noParams(): Unit = suspendCoroutineUninterceptedOrReturn {
|
||||
if (hashCode() % 2 == 0) {
|
||||
it.resume(Unit)
|
||||
COROUTINE_SUSPENDED
|
||||
@@ -16,7 +16,7 @@ class Controller {
|
||||
Unit
|
||||
}
|
||||
}
|
||||
<!EXPERIMENTAL_FEATURE_WARNING!>suspend<!> fun yieldString(value: String) = suspendCoroutineUninterceptedOrReturn<Int> {
|
||||
suspend fun yieldString(value: String) = suspendCoroutineUninterceptedOrReturn<Int> {
|
||||
it.resume(1)
|
||||
it checkType { _<Continuation<Int>>() }
|
||||
it.<!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>resume<!>("")
|
||||
@@ -27,10 +27,10 @@ class Controller {
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(c: <!EXPERIMENTAL_FEATURE_WARNING!>suspend<!> Controller.() -> Unit) {}
|
||||
fun builder(c: suspend Controller.() -> Unit) {}
|
||||
|
||||
fun test() {
|
||||
<!EXPERIMENTAL_FEATURE_WARNING!>builder<!> {
|
||||
builder {
|
||||
noParams() checkType { _<Unit>() }
|
||||
yieldString("abc") checkType { _<Int>() }
|
||||
}
|
||||
|
||||
@@ -61,7 +61,10 @@ import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -660,19 +663,6 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
classpath.add(ForTestCompileRuntime.androidAnnotationsForTests());
|
||||
}
|
||||
|
||||
ApiVersion av = ApiVersion.LATEST_STABLE;
|
||||
boolean explicitApiVersion = false;
|
||||
|
||||
for (TestFile tf : files) {
|
||||
Map<String, String> directives = KotlinTestUtils.parseDirectives(tf.content);
|
||||
if (directives.containsKey(API_VERSION_DIRECTIVE)) {
|
||||
assert !explicitApiVersion : "multiple API_VERSIONs";
|
||||
explicitApiVersion = true;
|
||||
av = ApiVersion.Companion.parse(directives.get(API_VERSION_DIRECTIVE));
|
||||
assert av != null : "incorrect API_VERSION";
|
||||
}
|
||||
}
|
||||
|
||||
CompilerConfiguration configuration = createConfiguration(
|
||||
configurationKind, getJdkKind(files),
|
||||
classpath,
|
||||
@@ -680,14 +670,6 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
files
|
||||
);
|
||||
|
||||
if (explicitApiVersion) {
|
||||
CommonConfigurationKeysKt.setLanguageVersionSettings(configuration, new LanguageVersionSettingsImpl(
|
||||
CommonConfigurationKeysKt.getLanguageVersionSettings(configuration).getLanguageVersion(), av,
|
||||
new HashMap<AnalysisFlag<?>, Object>() {{
|
||||
put(AnalysisFlag.getExplicitApiVersion(), true);
|
||||
}}));
|
||||
}
|
||||
|
||||
myEnvironment = KotlinCoreEnvironment.createForTests(
|
||||
getTestRootDisposable(), configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||
);
|
||||
|
||||
@@ -461,6 +461,11 @@ public class CliTestGenerated extends AbstractCliTest {
|
||||
runTest("compiler/testData/cli/jvm/progressiveModeOn.args");
|
||||
}
|
||||
|
||||
@TestMetadata("releaseCoroutinesApiVersion1.2.args")
|
||||
public void testReleaseCoroutinesApiVersion1_2() throws Exception {
|
||||
runTest("compiler/testData/cli/jvm/releaseCoroutinesApiVersion1.2.args");
|
||||
}
|
||||
|
||||
@TestMetadata("returnAsWhenKey.args")
|
||||
public void testReturnAsWhenKey() throws Exception {
|
||||
runTest("compiler/testData/cli/jvm/returnAsWhenKey.args");
|
||||
|
||||
-5
@@ -153,11 +153,6 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/privateSuspendFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("releaseCoroutines.kt")
|
||||
public void testReleaseCoroutines() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/releaseCoroutines.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samAdapterAndInlinedOne.kt")
|
||||
public void testSamAdapterAndInlinedOne() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/samAdapterAndInlinedOne.kt");
|
||||
|
||||
+5
-1
@@ -433,7 +433,11 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
|
||||
}
|
||||
|
||||
fun testReleaseCoroutineCallFromExperimental() {
|
||||
val library = compileLibrary("library", additionalOptions = listOf("-language-version", "1.3"), checkKotlinOutput = {})
|
||||
val library = compileLibrary(
|
||||
"library",
|
||||
additionalOptions = listOf("-language-version", "1.3", "-api-version", "1.3"),
|
||||
checkKotlinOutput = {}
|
||||
)
|
||||
compileKotlin(
|
||||
"experimental.kt",
|
||||
tmpdir,
|
||||
|
||||
@@ -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.serialization
|
||||
@@ -40,12 +29,13 @@ import java.io.File
|
||||
|
||||
class VersionRequirementTest : TestCaseWithTmpdir() {
|
||||
fun doTest(
|
||||
expectedVersionRequirement: VersionRequirement.Version,
|
||||
expectedLevel: DeprecationLevel,
|
||||
expectedMessage: String?,
|
||||
expectedVersionKind: ProtoBuf.VersionRequirement.VersionKind,
|
||||
expectedErrorCode: Int?,
|
||||
vararg fqNames: String
|
||||
expectedVersionRequirement: VersionRequirement.Version,
|
||||
expectedLevel: DeprecationLevel,
|
||||
expectedMessage: String?,
|
||||
expectedVersionKind: ProtoBuf.VersionRequirement.VersionKind,
|
||||
expectedErrorCode: Int?,
|
||||
customLanguageVersion: LanguageVersion = LanguageVersionSettingsImpl.DEFAULT.languageVersion,
|
||||
fqNames: List<String>
|
||||
) {
|
||||
LoadDescriptorUtil.compileKotlinToDirAndGetModule(
|
||||
listOf(File("compiler/testData/versionRequirement/${getTestName(true)}.kt")), tmpdir,
|
||||
@@ -54,8 +44,8 @@ class VersionRequirementTest : TestCaseWithTmpdir() {
|
||||
KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, tmpdir).apply {
|
||||
put(JVMConfigurationKeys.JVM_TARGET, JvmTarget.JVM_1_8)
|
||||
languageVersionSettings = LanguageVersionSettingsImpl(
|
||||
LanguageVersionSettingsImpl.DEFAULT.languageVersion,
|
||||
LanguageVersionSettingsImpl.DEFAULT.apiVersion,
|
||||
customLanguageVersion,
|
||||
ApiVersion.createByLanguageVersion(customLanguageVersion),
|
||||
mapOf(AnalysisFlag.jvmDefaultMode to JvmDefaultMode.ENABLE),
|
||||
emptyMap()
|
||||
)
|
||||
@@ -113,59 +103,89 @@ class VersionRequirementTest : TestCaseWithTmpdir() {
|
||||
}
|
||||
|
||||
fun testSuspendFun() {
|
||||
doTest(VersionRequirement.Version(1, 1), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null,
|
||||
"test.topLevel",
|
||||
"test.Foo.member",
|
||||
"test.Foo.<init>",
|
||||
"test.async1",
|
||||
"test.async2",
|
||||
"test.async3",
|
||||
"test.async4",
|
||||
"test.asyncVal"
|
||||
)
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 1), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null,
|
||||
fqNames = listOf(
|
||||
"test.topLevel",
|
||||
"test.Foo.member",
|
||||
"test.Foo.<init>",
|
||||
"test.async1",
|
||||
"test.async2",
|
||||
"test.async3",
|
||||
"test.async4",
|
||||
"test.asyncVal"
|
||||
)
|
||||
)
|
||||
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 3), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null,
|
||||
customLanguageVersion = LanguageVersion.KOTLIN_1_3,
|
||||
fqNames = listOf(
|
||||
"test.topLevel",
|
||||
"test.Foo.member",
|
||||
"test.Foo.<init>",
|
||||
"test.async1",
|
||||
"test.async2",
|
||||
"test.async3",
|
||||
"test.async4",
|
||||
"test.asyncVal"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun testLanguageVersionViaAnnotation() {
|
||||
doTest(VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message", LANGUAGE_VERSION, 42,
|
||||
"test.Klass",
|
||||
"test.Konstructor.<init>",
|
||||
"test.Typealias",
|
||||
"test.function",
|
||||
"test.property"
|
||||
)
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message", LANGUAGE_VERSION, 42,
|
||||
fqNames = listOf(
|
||||
"test.Klass",
|
||||
"test.Konstructor.<init>",
|
||||
"test.Typealias",
|
||||
"test.function",
|
||||
"test.property"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun testApiVersionViaAnnotation() {
|
||||
doTest(VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message", API_VERSION, 42,
|
||||
"test.Klass",
|
||||
"test.Konstructor.<init>",
|
||||
"test.Typealias",
|
||||
"test.function",
|
||||
"test.property"
|
||||
)
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message", API_VERSION, 42,
|
||||
fqNames = listOf(
|
||||
"test.Klass",
|
||||
"test.Konstructor.<init>",
|
||||
"test.Typealias",
|
||||
"test.function",
|
||||
"test.property"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun testCompilerVersionViaAnnotation() {
|
||||
doTest(VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message", COMPILER_VERSION, 42,
|
||||
"test.Klass",
|
||||
"test.Konstructor.<init>",
|
||||
"test.Typealias",
|
||||
"test.function",
|
||||
"test.property"
|
||||
)
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message", COMPILER_VERSION, 42,
|
||||
fqNames = listOf(
|
||||
"test.Klass",
|
||||
"test.Konstructor.<init>",
|
||||
"test.Typealias",
|
||||
"test.function",
|
||||
"test.property"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun testPatchVersion() {
|
||||
doTest(VersionRequirement.Version(1, 1, 50), DeprecationLevel.HIDDEN, null, LANGUAGE_VERSION, null,
|
||||
"test.Klass"
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 1, 50), DeprecationLevel.HIDDEN, null, LANGUAGE_VERSION, null,
|
||||
fqNames = listOf("test.Klass")
|
||||
)
|
||||
}
|
||||
|
||||
fun testJvmDefault() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 2, 40), DeprecationLevel.ERROR, null, COMPILER_VERSION, null,
|
||||
"test.Base",
|
||||
"test.Derived"
|
||||
fqNames = listOf(
|
||||
"test.Base",
|
||||
"test.Derived"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ fun ModuleDescriptor.findContinuationClassDescriptor(lookupLocation: LookupLocat
|
||||
|
||||
fun ModuleDescriptor.getContinuationOfTypeOrAny(kotlinType: KotlinType, isReleaseCoroutines: Boolean) =
|
||||
module.findContinuationClassDescriptorOrNull(
|
||||
NoLookupLocation.FROM_BACKEND,
|
||||
NoLookupLocation.FROM_DESERIALIZATION,
|
||||
isReleaseCoroutines
|
||||
)?.defaultType?.let {
|
||||
KotlinTypeFactory.simpleType(
|
||||
|
||||
+8
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.serialization.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.builtins.transformRuntimeFunctionTypeToSuspendFunction
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||
@@ -170,7 +171,13 @@ class TypeDeserializer(
|
||||
// kotlin.suspend is still built with LV=1.2, thus it references old Continuation
|
||||
// And otherwise, once stdlib is compiled with 1.3 one may want to stay at LV=1.2
|
||||
if (c.containingDeclaration.safeAs<CallableDescriptor>()?.fqNameOrNull() == KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME) {
|
||||
transformRuntimeFunctionTypeToSuspendFunction(functionType, false)?.let { return it }
|
||||
transformRuntimeFunctionTypeToSuspendFunction(functionType, false)?.let {
|
||||
if (!it.isSuspendFunctionType) {
|
||||
transformRuntimeFunctionTypeToSuspendFunction(functionType, true)?.let { return it }
|
||||
} else {
|
||||
return it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transformRuntimeFunctionTypeToSuspendFunction(functionType, isReleaseCoroutines)?.let { return it }
|
||||
|
||||
@@ -138,7 +138,7 @@ public fun <R, T> (suspend R.() -> T).startCoroutine(
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
@InlineOnly
|
||||
@kotlin.internal.RequireKotlin("1.3")
|
||||
@kotlin.internal.RequireKotlin("1.3") // TODO: This is needed for tests only and can be safely removed after 1.3 is released
|
||||
public suspend inline fun <T> suspendCoroutine(crossinline block: (Continuation<T>) -> Unit): T =
|
||||
suspendCoroutineUninterceptedOrReturn { c: Continuation<T> ->
|
||||
val safe = SafeContinuation(c.intercepted())
|
||||
|
||||
@@ -37,7 +37,7 @@ import kotlin.internal.InlineOnly
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
@InlineOnly
|
||||
@kotlin.internal.RequireKotlin("1.3")
|
||||
@kotlin.internal.RequireKotlin("1.3") // TODO: This is needed for tests only and can be safely removed after 1.3 is released
|
||||
public suspend inline fun <T> suspendCoroutineUninterceptedOrReturn(crossinline block: (Continuation<T>) -> Any?): T =
|
||||
throw NotImplementedError("Implementation of suspendCoroutineUninterceptedOrReturn is intrinsic")
|
||||
|
||||
|
||||
@@ -55,7 +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")
|
||||
@kotlin.internal.RequireKotlin("1.3") // TODO: This is needed for tests only and can be safely removed after 1.3 is released
|
||||
public abstract suspend fun yield(value: T)
|
||||
|
||||
/**
|
||||
@@ -65,7 +65,7 @@ public abstract class SequenceBuilder<in T> internal constructor() {
|
||||
*
|
||||
* @sample samples.collections.Sequences.Building.buildSequenceYieldAll
|
||||
*/
|
||||
@kotlin.internal.RequireKotlin("1.3")
|
||||
@kotlin.internal.RequireKotlin("1.3") // TODO: This is needed for tests only and can be safely removed after 1.3 is released
|
||||
public abstract suspend fun yieldAll(iterator: Iterator<T>)
|
||||
|
||||
/**
|
||||
@@ -73,7 +73,7 @@ public abstract class SequenceBuilder<in T> internal constructor() {
|
||||
*
|
||||
* @sample samples.collections.Sequences.Building.buildSequenceYieldAll
|
||||
*/
|
||||
@kotlin.internal.RequireKotlin("1.3")
|
||||
@kotlin.internal.RequireKotlin("1.3") // TODO: This is needed for tests only and can be safely removed after 1.3 is released
|
||||
public suspend fun yieldAll(elements: Iterable<T>) {
|
||||
if (elements is Collection && elements.isEmpty()) return
|
||||
return yieldAll(elements.iterator())
|
||||
@@ -86,7 +86,7 @@ public abstract class SequenceBuilder<in T> internal constructor() {
|
||||
*
|
||||
* @sample samples.collections.Sequences.Building.buildSequenceYieldAll
|
||||
*/
|
||||
@kotlin.internal.RequireKotlin("1.3")
|
||||
@kotlin.internal.RequireKotlin("1.3") // TODO: This is needed for tests only and can be safely removed after 1.3 is released
|
||||
public suspend fun yieldAll(sequence: Sequence<T>) = yieldAll(sequence.iterator())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user