From 2cfe387bab0f5cdf5a1c097aaa9dbe70b09b29f3 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Wed, 21 Mar 2018 19:54:14 +0300 Subject: [PATCH] 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 --- .../common/commonCoroutineCodegenUtil.kt | 38 ++-- .../kotlin/codegen/ClosureCodegen.java | 4 +- .../kotlin/codegen/ExpressionCodegen.java | 15 +- .../kotlin/codegen/FunctionCodegen.java | 12 +- .../kotlin/codegen/JvmRuntimeTypes.kt | 31 +-- .../binding/CodegenAnnotatingVisitor.java | 11 +- .../codegen/coroutines/CoroutineCodegen.kt | 66 +++--- .../CoroutineTransformerMethodVisitor.kt | 39 ++-- ...ndantLocalsEliminationMethodTransformer.kt | 11 +- .../SuspendFunctionGenerationStrategy.kt | 30 ++- .../coroutines/coroutineCodegenUtil.kt | 190 ++++++++++-------- .../inline/AnonymousObjectTransformer.kt | 22 +- .../kotlin/codegen/inline/InlineCodegen.kt | 31 +-- .../kotlin/codegen/inline/MethodInliner.kt | 7 +- .../serialization/JvmSerializerExtension.java | 23 +-- .../KotlinToJvmSignatureMapperImpl.kt | 18 +- ...FactoryForDuplicateSignatureDiagnostics.kt | 28 +-- .../kotlin/codegen/state/GenerationState.kt | 26 +-- .../codegen/state/KotlinTypeMapper.java | 26 ++- .../CompilerDeserializationConfiguration.kt | 17 +- .../calls/checkers/coroutineCallChecker.kt | 41 ++-- .../serialization/DescriptorSerializer.kt | 4 +- .../serialization/SerializerExtension.kt | 17 +- .../bytecodeListing/releaseCoroutines.kt | 10 + .../bytecodeListing/releaseCoroutines.txt | 30 +++ .../codegen/BytecodeListingTestGenerated.java | 6 + .../CoroutineLanguageVersionSettingsUtil.kt | 37 ++++ .../kotlin/config/LanguageVersionSettings.kt | 3 +- .../load/kotlin/methodSignatureMapping.kt | 17 +- .../load/kotlin/typeSignatureMapping.kt | 33 +-- .../kotlin/builtins/suspendFunctionTypes.kt | 79 ++++---- .../kotlin/descriptors/descriptorUtil.kt | 26 +-- .../kotlin/resolve/DescriptorUtils.java | 27 +-- .../kotlin/resolve/annotationsForResolve.kt | 19 +- .../DeserializationConfiguration.kt | 18 +- .../deserialization/TypeDeserializer.kt | 29 +-- .../stubBuilder/TypeClsStubBuilder.kt | 25 +-- .../kotlin/idea/debugger/debuggerUtil.kt | 25 +-- .../KotlinSuspendCallLineMarkerProvider.kt | 11 +- .../AbstractUselessCallInspection.kt | 8 +- .../jetbrains/kotlin/js/config/JsConfig.java | 4 +- ...utinesDisabledLanguageVersionSettings.java | 52 +++++ .../jetbrains/kotlin/js/inline/JsInliner.java | 29 ++- .../callTranslator/CallTranslator.kt | 6 +- .../callTranslator/FunctionCallCases.kt | 2 +- .../callTranslator/VariableCallCases.kt | 2 +- .../translate/context/TranslationContext.java | 25 +-- .../js/translate/intrinsic/Intrinsics.kt | 4 +- .../intrinsic/functions/FunctionIntrinsics.kt | 5 +- .../functions/factories/CompositeFIF.java | 3 +- .../factories/CoroutineContextFIF.kt | 4 +- .../ExceptionPropertyIntrinsicFactory.kt | 2 +- .../factories/FunctionIntrinsicFactory.java | 3 +- .../functions/factories/InterceptedFIF.kt | 19 +- .../functions/factories/LongOperationFIF.kt | 2 +- .../PrimitiveBinaryOperationFIF.java | 2 +- .../factories/PrimitiveUnaryOperationFIF.java | 2 +- .../functions/factories/StringPlusCharFIF.kt | 2 +- ...uspendCoroutineUninterceptedOrReturnFIF.kt | 19 +- .../ThrowableConstructorIntrinsicFactory.kt | 2 +- .../IntrinsicIncrementTranslator.java | 2 +- .../reference/CallArgumentTranslator.kt | 19 +- .../js/translate/utils/TranslationUtils.java | 21 +- .../kotlin/js/translate/utils/utils.kt | 20 +- .../parcel/ParcelableDeclarationChecker.kt | 19 +- ...KotlinUastBindingContextProviderService.kt | 3 +- ...KotlinUastBindingContextProviderService.kt | 3 +- 67 files changed, 692 insertions(+), 694 deletions(-) create mode 100644 compiler/testData/codegen/bytecodeListing/releaseCoroutines.kt create mode 100644 compiler/testData/codegen/bytecodeListing/releaseCoroutines.txt create mode 100644 compiler/util/src/org/jetbrains/kotlin/config/CoroutineLanguageVersionSettingsUtil.kt create mode 100644 js/js.frontend/src/org/jetbrains/kotlin/js/config/ReleaseCoroutinesDisabledLanguageVersionSettings.java diff --git a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/commonCoroutineCodegenUtil.kt b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/commonCoroutineCodegenUtil.kt index ddc581db9f4..57bd84ee578 100644 --- a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/commonCoroutineCodegenUtil.kt +++ b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/commonCoroutineCodegenUtil.kt @@ -1,32 +1,18 @@ /* - * 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.backend.common +import org.jetbrains.kotlin.config.coroutinesIntrinsicsPackageFqName import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorEquivalenceForOverrides -import org.jetbrains.kotlin.resolve.DescriptorUtils.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME -import org.jetbrains.kotlin.resolve.calls.checkers.COROUTINE_CONTEXT_1_2_20_FQ_NAME -import org.jetbrains.kotlin.resolve.calls.checkers.COROUTINE_CONTEXT_FQ_NAME -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.module +import org.jetbrains.kotlin.config.LanguageVersionSettings val SUSPEND_COROUTINE_OR_RETURN_NAME = Name.identifier("suspendCoroutineOrReturn") val INTERCEPTED_NAME = Name.identifier("intercepted") @@ -34,33 +20,33 @@ val COROUTINE_SUSPENDED_NAME = Name.identifier("COROUTINE_SUSPENDED") val SUSPEND_COROUTINE_UNINTERCEPTED_OR_RETURN_NAME = Name.identifier("suspendCoroutineUninterceptedOrReturn") -fun FunctionDescriptor.isBuiltInIntercepted(): Boolean { +fun FunctionDescriptor.isBuiltInIntercepted(languageVersionSettings: LanguageVersionSettings): Boolean { if (name != INTERCEPTED_NAME) return false val original = - module.getPackage(COROUTINES_INTRINSICS_PACKAGE_FQ_NAME).memberScope + module.getPackage(languageVersionSettings.coroutinesIntrinsicsPackageFqName()).memberScope .getContributedFunctions(INTERCEPTED_NAME, NoLookupLocation.FROM_BACKEND) .singleOrNull() as CallableDescriptor return DescriptorEquivalenceForOverrides.areEquivalent(original, this) } -fun FunctionDescriptor.isBuiltInSuspendCoroutineOrReturn(): Boolean { +fun FunctionDescriptor.isBuiltInSuspendCoroutineOrReturn(languageVersionSettings: LanguageVersionSettings): Boolean { if (name != SUSPEND_COROUTINE_OR_RETURN_NAME) return false - val originalDeclaration = getBuiltInSuspendCoroutineOrReturn() ?: return false + val originalDeclaration = getBuiltInSuspendCoroutineOrReturn(languageVersionSettings) ?: return false return DescriptorEquivalenceForOverrides.areEquivalent( originalDeclaration, this ) } -fun FunctionDescriptor.getBuiltInSuspendCoroutineOrReturn() = - module.getPackage(COROUTINES_INTRINSICS_PACKAGE_FQ_NAME).memberScope +fun FunctionDescriptor.getBuiltInSuspendCoroutineOrReturn(languageVersionSettings: LanguageVersionSettings) = + module.getPackage(languageVersionSettings.coroutinesIntrinsicsPackageFqName()).memberScope .getContributedFunctions(SUSPEND_COROUTINE_OR_RETURN_NAME, NoLookupLocation.FROM_BACKEND) .singleOrNull() -fun FunctionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(): Boolean { +fun FunctionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings: LanguageVersionSettings): Boolean { if (name != SUSPEND_COROUTINE_UNINTERCEPTED_OR_RETURN_NAME) return false - val original = module.getPackage(COROUTINES_INTRINSICS_PACKAGE_FQ_NAME).memberScope + val original = module.getPackage(languageVersionSettings.coroutinesIntrinsicsPackageFqName()).memberScope .getContributedFunctions(SUSPEND_COROUTINE_UNINTERCEPTED_OR_RETURN_NAME, NoLookupLocation.FROM_BACKEND) .singleOrNull() as CallableDescriptor return DescriptorEquivalenceForOverrides.areEquivalent(original, this) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java index ea35b36c3dd..57a7531292e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java @@ -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. */ @@ -422,7 +422,7 @@ public class ClosureCodegen extends MemberCodegen { String superClassConstructorDescriptor; if (superClassAsmType.equals(LAMBDA) || superClassAsmType.equals(FUNCTION_REFERENCE) || - superClassAsmType.equals(CoroutineCodegenUtilKt.COROUTINE_IMPL_ASM_TYPE)) { + superClassAsmType.equals(CoroutineCodegenUtilKt.coroutineImplAsmType(state.getLanguageVersionSettings()))) { int arity = calculateArity(); iv.iconst(arity); if (shouldHaveBoundReferenceReceiver) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 230ae1a8e0a..bf8a9d3bf76 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -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. */ @@ -2237,9 +2237,7 @@ public class ExpressionCodegen extends KtVisitor impleme @NotNull public StackValue invokeFunction(@NotNull Call call, @NotNull ResolvedCall resolvedCall, @NotNull StackValue receiver) { ResolvedCallWithRealDescriptor callWithRealDescriptor = - CoroutineCodegenUtilKt.replaceSuspensionFunctionWithRealDescriptor( - resolvedCall, state.getProject(), state.getBindingContext() - ); + CoroutineCodegenUtilKt.replaceSuspensionFunctionWithRealDescriptor(resolvedCall, state); if (callWithRealDescriptor != null) { prepareCoroutineArgumentForSuspendCall(resolvedCall, callWithRealDescriptor.getFakeContinuationExpression()); return invokeFunction(callWithRealDescriptor.getResolvedCall(), receiver); @@ -2352,7 +2350,8 @@ public class ExpressionCodegen extends KtVisitor impleme @NotNull CallGenerator callGenerator, @NotNull ArgumentGenerator argumentGenerator ) { - boolean isSuspendNoInlineCall = CoroutineCodegenUtilKt.isSuspendNoInlineCall(resolvedCall, this); + boolean isSuspendNoInlineCall = + CoroutineCodegenUtilKt.isSuspendNoInlineCall(resolvedCall, this, state.getLanguageVersionSettings()); boolean isConstructor = resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor; if (!(callableMethod instanceof IntrinsicWithSpecialReceiver)) { putReceiverAndInlineMarkerIfNeeded(callableMethod, resolvedCall, receiver, isSuspendNoInlineCall, isConstructor); @@ -2503,7 +2502,7 @@ public class ExpressionCodegen extends KtVisitor impleme FunctionDescriptor original = CoroutineCodegenUtilKt.getOriginalSuspendFunctionView( unwrapInitialSignatureDescriptor(DescriptorUtils.unwrapFakeOverride((FunctionDescriptor) descriptor.getOriginal())), - bindingContext + bindingContext, state ); if (isDefaultCompilation) { return new InlineCodegenForDefaultBody(original, this, state, new PsiSourceCompilerForInline(this, callElement)); @@ -3583,9 +3582,7 @@ public class ExpressionCodegen extends KtVisitor impleme ResolvedCall resolvedCall = CallUtilKt.getResolvedCallWithAssert(expression, bindingContext); ResolvedCallWithRealDescriptor callWithRealDescriptor = - CoroutineCodegenUtilKt.replaceSuspensionFunctionWithRealDescriptor( - resolvedCall, state.getProject(), state.getBindingContext() - ); + CoroutineCodegenUtilKt.replaceSuspensionFunctionWithRealDescriptor(resolvedCall, state); if (callWithRealDescriptor != null) { prepareCoroutineArgumentForSuspendCall(resolvedCall, callWithRealDescriptor.getFakeContinuationExpression()); resolvedCall = callWithRealDescriptor.getResolvedCall(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 08fb924e721..f7d4da5a340 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -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. */ @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.codegen.coroutines.SuspendFunctionGenerationStrategy import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.config.JvmTarget; +import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.Annotated; import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; @@ -161,7 +162,8 @@ public class FunctionCodegen { @NotNull FunctionGenerationStrategy strategy ) { if (CoroutineCodegenUtilKt.isSuspendFunctionNotSuspensionView(descriptor)) { - generateMethod(origin, CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(descriptor, bindingContext), strategy); + generateMethod(origin, CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(descriptor, state.getLanguageVersionSettings() + .supportsFeature(LanguageFeature.ReleaseCoroutines), bindingContext), strategy); return; } @@ -625,7 +627,11 @@ public class FunctionCodegen { Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper); if (functionDescriptor instanceof AnonymousFunctionDescriptor && functionDescriptor.isSuspend()) { - functionDescriptor = CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(functionDescriptor, typeMapper.getBindingContext()); + functionDescriptor = CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView( + functionDescriptor, + parentCodegen.state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines), + typeMapper.getBindingContext() + ); } generateLocalVariableTable( mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, context.getContextKind(), typeMapper, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.kt index 6aa3d2cfe66..90ca64536b0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.kt @@ -1,24 +1,15 @@ /* - * 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.codegen import org.jetbrains.kotlin.builtins.createFunctionType -import org.jetbrains.kotlin.codegen.coroutines.COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME +import org.jetbrains.kotlin.codegen.coroutines.coroutinesJvmInternalPackageFqName import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.coroutines.isSuspendLambda import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations @@ -31,10 +22,10 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.types.KotlinType -class JvmRuntimeTypes(module: ModuleDescriptor) { +class JvmRuntimeTypes(module: ModuleDescriptor, private val languageVersionSettings: LanguageVersionSettings) { private val kotlinJvmInternalPackage = MutablePackageFragmentDescriptor(module, FqName("kotlin.jvm.internal")) private val kotlinCoroutinesJvmInternalPackage = - MutablePackageFragmentDescriptor(module, COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME) + MutablePackageFragmentDescriptor(module, languageVersionSettings.coroutinesJvmInternalPackageFqName()) private fun klass(name: String) = lazy { createClass(kotlinJvmInternalPackage, name) } @@ -68,10 +59,10 @@ class JvmRuntimeTypes(module: ModuleDescriptor) { fun getSupertypesForClosure(descriptor: FunctionDescriptor): Collection { val actualFunctionDescriptor = - if (descriptor.isSuspend) - getOrCreateJvmSuspendFunctionView(descriptor) - else - descriptor + if (descriptor.isSuspend) + getOrCreateJvmSuspendFunctionView(descriptor, languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) + else + descriptor val functionType = createFunctionType( descriptor.builtIns, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java index 3e169aecf49..247ea05d1b3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java @@ -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. */ @@ -14,13 +14,13 @@ import kotlin.collections.CollectionsKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.ReflectionTypes; -import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor; import org.jetbrains.kotlin.cfg.WhenChecker; import org.jetbrains.kotlin.codegen.*; import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.when.SwitchCodegenProvider; import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping; +import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.config.LanguageVersionSettings; import org.jetbrains.kotlin.coroutines.CoroutineUtilKt; import org.jetbrains.kotlin.descriptors.*; @@ -308,7 +308,8 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { if (CoroutineUtilKt.isSuspendLambda(functionDescriptor)) { SimpleFunctionDescriptor jvmSuspendFunctionView = CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView( - (SimpleFunctionDescriptor) functionDescriptor + (SimpleFunctionDescriptor) functionDescriptor, + languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) ); bindingTrace.record( @@ -510,7 +511,8 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { !functionDescriptor.getVisibility().equals(Visibilities.LOCAL)) { SimpleFunctionDescriptor jvmSuspendFunctionView = CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView( - (SimpleFunctionDescriptor) functionDescriptor + (SimpleFunctionDescriptor) functionDescriptor, + languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) ); // This is a very subtle place (hack). @@ -573,6 +575,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { SimpleFunctionDescriptor jvmSuspendFunctionView = CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView( (SimpleFunctionDescriptor) functionDescriptor, + languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines), /*bindingContext*/ null, /*dropSuspend*/ true ); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt index c42887df808..3385e3028ad 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt @@ -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. */ @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding.CAPTURES_CROSSINLINE_ import org.jetbrains.kotlin.codegen.context.ClosureContext import org.jetbrains.kotlin.codegen.context.MethodContext import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension -import org.jetbrains.kotlin.coroutines.isSuspendLambda +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl @@ -53,6 +53,7 @@ abstract class AbstractCoroutineCodegen( outerExpressionCodegen.parentCodegen, classBuilder ) { protected val classDescriptor = closureContext.contextDescriptor + protected val languageVersionSettings = outerExpressionCodegen.state.languageVersionSettings protected val doResumeDescriptor = SimpleFunctionDescriptorImpl.create( @@ -85,7 +86,7 @@ abstract class AbstractCoroutineCodegen( override fun generateConstructor(): Method { val args = calculateConstructorParameters(typeMapper, closure, asmType) - val argTypes = args.map { it.fieldType }.plus(CONTINUATION_ASM_TYPE).toTypedArray() + val argTypes = args.map { it.fieldType }.plus(languageVersionSettings.continuationAsmType()).toTypedArray() val constructor = Method("", Type.VOID_TYPE, argTypes) val mv = v.newMethod( @@ -104,9 +105,9 @@ abstract class AbstractCoroutineCodegen( iv.load(argTypes.map { it.size }.sum(), AsmTypes.OBJECT_TYPE) val superClassConstructorDescriptor = Type.getMethodDescriptor( - Type.VOID_TYPE, - Type.INT_TYPE, - CONTINUATION_ASM_TYPE + Type.VOID_TYPE, + Type.INT_TYPE, + languageVersionSettings.continuationAsmType() ) iv.invokespecial(superClassAsmType.internalName, "", superClassConstructorDescriptor, false) @@ -142,7 +143,10 @@ class CoroutineCodegenForLambda private constructor( funDescriptor.createCustomCopy { setName(Name.identifier(SUSPEND_FUNCTION_CREATE_METHOD_NAME)) setReturnType( - funDescriptor.module.getContinuationOfTypeOrAny(builtIns.unitType) + funDescriptor.module.getContinuationOfTypeOrAny( + builtIns.unitType, + state.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) + ) ) // 'create' method should not inherit initial descriptor for suspend function from original descriptor putUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION, null) @@ -205,8 +209,8 @@ class CoroutineCodegenForLambda private constructor( v.thisName, createCoroutineDescriptor.name.identifier, Type.getMethodDescriptor( - CONTINUATION_ASM_TYPE, - *parameterTypes.toTypedArray() + languageVersionSettings.continuationAsmType(), + *parameterTypes.toTypedArray() ), false ) @@ -307,7 +311,8 @@ class CoroutineCodegenForLambda private constructor( lineNumber = CodegenUtil.getLineNumberForElement(element, false) ?: 0, shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization, containingClassInternalName = v.thisName, - isForNamedFunction = false + isForNamedFunction = false, + languageVersionSettings = languageVersionSettings ) } @@ -333,8 +338,12 @@ class CoroutineCodegenForLambda private constructor( expressionCodegen, declaration, expressionCodegen.context.intoCoroutineClosure( - getOrCreateJvmSuspendFunctionView(originalSuspendLambdaDescriptor, expressionCodegen.state.bindingContext), - originalSuspendLambdaDescriptor, expressionCodegen, expressionCodegen.state.typeMapper + getOrCreateJvmSuspendFunctionView( + originalSuspendLambdaDescriptor, + expressionCodegen.state.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines), + expressionCodegen.state.bindingContext + ), + originalSuspendLambdaDescriptor, expressionCodegen, expressionCodegen.state.typeMapper ), classBuilder, originalSuspendLambdaDescriptor, @@ -352,6 +361,14 @@ class CoroutineCodegenForNamedFunction private constructor( classBuilder: ClassBuilder, originalSuspendFunctionDescriptor: FunctionDescriptor ) : AbstractCoroutineCodegen(outerExpressionCodegen, element, closureContext, classBuilder) { + private val labelFieldStackValue = StackValue.field( + FieldInfo.createForHiddenField( + outerExpressionCodegen.state.languageVersionSettings.coroutineImplAsmType(), + Type.INT_TYPE, + COROUTINE_LABEL_FIELD_NAME + ), + StackValue.LOCAL_0 + ) private val suspendFunctionJvmView = bindingContext[CodegenBinding.SUSPEND_FUNCTION_TO_JVM_VIEW, originalSuspendFunctionDescriptor]!! @@ -393,13 +410,13 @@ class CoroutineCodegenForNamedFunction private constructor( StackValue.LOCAL_0 ).store(StackValue.local(2, AsmTypes.JAVA_THROWABLE_TYPE), codegen.v) - LABEL_FIELD_STACK_VALUE.store( - StackValue.operation(Type.INT_TYPE) { - LABEL_FIELD_STACK_VALUE.put(Type.INT_TYPE, it) - it.iconst(1 shl 31) - it.or(Type.INT_TYPE) - }, - codegen.v + labelFieldStackValue.store( + StackValue.operation(Type.INT_TYPE) { + labelFieldStackValue.put(Type.INT_TYPE, it) + it.iconst(1 shl 31) + it.or(Type.INT_TYPE) + }, + codegen.v ) val captureThisType = closure.captureThis?.let(typeMapper::mapType) @@ -450,7 +467,7 @@ class CoroutineCodegenForNamedFunction private constructor( ) mv.visitCode() - LABEL_FIELD_STACK_VALUE.put(Type.INT_TYPE, InstructionAdapter(mv)) + labelFieldStackValue.put(Type.INT_TYPE, InstructionAdapter(mv)) mv.visitInsn(Opcodes.IRETURN) mv.visitEnd() } @@ -466,7 +483,7 @@ class CoroutineCodegenForNamedFunction private constructor( ) mv.visitCode() - LABEL_FIELD_STACK_VALUE.store(StackValue.local(1, Type.INT_TYPE), InstructionAdapter(mv)) + labelFieldStackValue.store(StackValue.local(1, Type.INT_TYPE), InstructionAdapter(mv)) mv.visitInsn(Opcodes.RETURN) mv.visitEnd() } @@ -478,14 +495,7 @@ class CoroutineCodegenForNamedFunction private constructor( AsmUtil.writeAnnotationData(av, serializer, functionProto) } } - companion object { - private val LABEL_FIELD_STACK_VALUE = - StackValue.field( - FieldInfo.createForHiddenField(COROUTINE_IMPL_ASM_TYPE, Type.INT_TYPE, COROUTINE_LABEL_FIELD_NAME), - StackValue.LOCAL_0 - ) - fun create( cv: ClassBuilder, expressionCodegen: ExpressionCodegen, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt index 3b47f19b376..2dd375eb3f7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt @@ -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.codegen.coroutines @@ -27,6 +16,7 @@ import org.jetbrains.kotlin.codegen.optimization.common.* import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer import org.jetbrains.kotlin.codegen.optimization.fixStack.top import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.utils.sure @@ -52,6 +42,7 @@ class CoroutineTransformerMethodVisitor( private val isForNamedFunction: Boolean, private val shouldPreserveClassInitialization: Boolean, private val lineNumber: Int, + private val languageVersionSettings: LanguageVersionSettings, // It's only matters for named functions, may differ from '!isStatic(access)' in case of DefaultImpls private val needDispatchReceiver: Boolean = false, // May differ from containingClassInternalName in case of DefaultImpls @@ -73,7 +64,7 @@ class CoroutineTransformerMethodVisitor( ) FixStackMethodTransformer().transform(containingClassInternalName, methodNode) - RedundantLocalsEliminationMethodTransformer().transform(containingClassInternalName, methodNode) + RedundantLocalsEliminationMethodTransformer(languageVersionSettings).transform(containingClassInternalName, methodNode) updateMaxStack(methodNode) val suspensionPoints = collectSuspensionPoints(methodNode) @@ -128,7 +119,7 @@ class CoroutineTransformerMethodVisitor( insertBefore( actualCoroutineStart, insnListOf( - *withInstructionAdapter { loadCoroutineSuspendedMarker() }.toArray(), + *withInstructionAdapter { loadCoroutineSuspendedMarker(languageVersionSettings) }.toArray(), tableSwitchLabel, // Allow debugger to stop on enter into suspend function LineNumberNode(lineNumber, tableSwitchLabel), @@ -181,7 +172,7 @@ class CoroutineTransformerMethodVisitor( else FieldInsnNode( Opcodes.GETFIELD, - COROUTINE_IMPL_ASM_TYPE.internalName, + languageVersionSettings.coroutineImplAsmType().internalName, COROUTINE_LABEL_FIELD_NAME, Type.INT_TYPE.descriptor ) @@ -197,7 +188,7 @@ class CoroutineTransformerMethodVisitor( else FieldInsnNode( Opcodes.PUTFIELD, - COROUTINE_IMPL_ASM_TYPE.internalName, + languageVersionSettings.coroutineImplAsmType().internalName, COROUTINE_LABEL_FIELD_NAME, Type.INT_TYPE.descriptor ) @@ -291,7 +282,8 @@ class CoroutineTransformerMethodVisitor( needDispatchReceiver, internalNameForDispatchReceiver, containingClassInternalName, - classBuilderForCoroutineState + classBuilderForCoroutineState, + languageVersionSettings ) visitVarInsn(Opcodes.ASTORE, continuationIndex) @@ -605,7 +597,8 @@ internal fun InstructionAdapter.generateContinuationConstructorCall( needDispatchReceiver: Boolean, internalNameForDispatchReceiver: String?, containingClassInternalName: String, - classBuilderForCoroutineState: ClassBuilder + classBuilderForCoroutineState: ClassBuilder, + languageVersionSettings: LanguageVersionSettings ) { anew(objectTypeForState) dup() @@ -614,7 +607,8 @@ internal fun InstructionAdapter.generateContinuationConstructorCall( getParameterTypesIndicesForCoroutineConstructor( methodNode.desc, methodNode.access, - needDispatchReceiver, internalNameForDispatchReceiver ?: containingClassInternalName + needDispatchReceiver, internalNameForDispatchReceiver ?: containingClassInternalName, + languageVersionSettings ) for ((type, index) in parameterTypesAndIndices) { load(index, type) @@ -703,7 +697,8 @@ private fun getParameterTypesIndicesForCoroutineConstructor( desc: String, containingFunctionAccess: Int, needDispatchReceiver: Boolean, - thisName: String + thisName: String, + languageVersionSettings: LanguageVersionSettings ): Collection> { return mutableListOf>().apply { if (needDispatchReceiver) { @@ -711,7 +706,7 @@ private fun getParameterTypesIndicesForCoroutineConstructor( } val continuationIndex = getAllParameterTypes(desc, !isStatic(containingFunctionAccess), thisName).dropLast(1).map(Type::getSize).sum() - add(CONTINUATION_ASM_TYPE to continuationIndex) + add(languageVersionSettings.continuationAsmType() to continuationIndex) } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/RedundantLocalsEliminationMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/RedundantLocalsEliminationMethodTransformer.kt index 67e880ecfd6..1b0d248fd6f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/RedundantLocalsEliminationMethodTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/RedundantLocalsEliminationMethodTransformer.kt @@ -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. */ @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.codegen.optimization.common.asSequence import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful import org.jetbrains.kotlin.codegen.optimization.common.removeAll import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.tree.* @@ -18,7 +19,7 @@ import org.jetbrains.org.objectweb.asm.tree.* // Remove all of them since these locals are // 1) going to be spilled into continuation object // 2) breaking tail-call elimination -class RedundantLocalsEliminationMethodTransformer : MethodTransformer() { +class RedundantLocalsEliminationMethodTransformer(private val languageVersionSettings: LanguageVersionSettings) : MethodTransformer() { lateinit var internalClassName: String override fun transform(internalClassName: String, methodNode: MethodNode) { this.internalClassName = internalClassName @@ -26,7 +27,7 @@ class RedundantLocalsEliminationMethodTransformer : MethodTransformer() { var changed = false changed = simpleRemove(methodNode) || changed changed = removeWithReplacement(methodNode) || changed - changed = removeAloadCheckcastContinuationAstore(methodNode) || changed + changed = removeAloadCheckcastContinuationAstore(methodNode, languageVersionSettings) || changed } while (changed) } @@ -139,12 +140,12 @@ class RedundantLocalsEliminationMethodTransformer : MethodTransformer() { // ... // ALOAD K // CHECKCAST Continuation - private fun removeAloadCheckcastContinuationAstore(methodNode: MethodNode): Boolean { + private fun removeAloadCheckcastContinuationAstore(methodNode: MethodNode, languageVersionSettings: LanguageVersionSettings): Boolean { // Here we ignore the duplicates of continuation in local variable table, // Since it increases performance greatly. val insns = findSafeAstorePredecessors(methodNode, ignoreLocalVariableTable = true) { it.opcode == Opcodes.CHECKCAST && - (it as TypeInsnNode).desc == CONTINUATION_ASM_TYPE.internalName && + (it as TypeInsnNode).desc == languageVersionSettings.continuationAsmType().internalName && it.previous?.opcode == Opcodes.ALOAD } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt index cf8fc7bd413..8541f5ab727 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt @@ -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.codegen.coroutines @@ -25,6 +14,8 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding import org.jetbrains.kotlin.codegen.inline.addFakeContinuationConstructorCallMarker import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.config.JVMConstructorCallNormalizationMode +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.psi.KtFunction @@ -46,6 +37,7 @@ class SuspendFunctionGenerationStrategy( ) : FunctionGenerationStrategy.CodegenBased(state) { private lateinit var codegen: ExpressionCodegen + private val languageVersionSettings: LanguageVersionSettings = state.configuration.languageVersionSettings private val classBuilderForCoroutineState by lazy { state.factory.newVisitor( @@ -67,7 +59,8 @@ class SuspendFunctionGenerationStrategy( mv, access, name, desc, null, null, this::classBuilderForCoroutineState, containingClassInternalName, originalSuspendDescriptor.dispatchReceiverParameter != null, - containingClassInternalNameOrNull() + containingClassInternalNameOrNull(), + languageVersionSettings ) } return CoroutineTransformerMethodVisitor( @@ -76,7 +69,8 @@ class SuspendFunctionGenerationStrategy( lineNumber = CodegenUtil.getLineNumberForElement(declaration, false) ?: 0, shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization, needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null, - internalNameForDispatchReceiver = containingClassInternalNameOrNull() + internalNameForDispatchReceiver = containingClassInternalNameOrNull(), + languageVersionSettings = languageVersionSettings ) } @@ -103,7 +97,8 @@ class SuspendFunctionGenerationStrategy( obtainClassBuilderForCoroutineState: () -> ClassBuilder, private val containingClassInternalName: String, private val needDispatchReceiver: Boolean, - private val internalNameForDispatchReceiver: String? + private val internalNameForDispatchReceiver: String?, + private val languageVersionSettings: LanguageVersionSettings ) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) { private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState) override fun performTransformations(methodNode: MethodNode) { @@ -116,7 +111,8 @@ class SuspendFunctionGenerationStrategy( needDispatchReceiver, internalNameForDispatchReceiver, containingClassInternalName, - classBuilderForCoroutineState + classBuilderForCoroutineState, + languageVersionSettings ) addFakeContinuationConstructorCallMarker(this, false) }) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt index 4c61ab5d3d8..4aeba843c98 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt @@ -1,32 +1,26 @@ /* - * 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.codegen.coroutines import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.backend.common.* +import org.jetbrains.kotlin.backend.common.COROUTINE_SUSPENDED_NAME +import org.jetbrains.kotlin.backend.common.isBuiltInIntercepted +import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineOrReturn +import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.binding.CodegenBinding import org.jetbrains.kotlin.codegen.inline.addFakeContinuationMarker +import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.topLevelClassAsmType import org.jetbrains.kotlin.codegen.topLevelClassInternalName import org.jetbrains.kotlin.coroutines.isSuspendLambda +import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor @@ -62,25 +56,28 @@ const val DO_RESUME_METHOD_NAME = "doResume" const val DATA_FIELD_NAME = "data" const val EXCEPTION_FIELD_NAME = "exception" -@JvmField -val COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME = - DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("jvm")).child(Name.identifier("internal")) +fun LanguageVersionSettings.coroutinesJvmInternalPackageFqName() = + coroutinesPackageFqName().child(Name.identifier("jvm")).child(Name.identifier("internal")) -@JvmField -val CONTINUATION_ASM_TYPE = DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME.topLevelClassAsmType() +fun LanguageVersionSettings.continuationAsmType() = + continuationInterfaceFqName().topLevelClassAsmType() -@JvmField -val COROUTINE_CONTEXT_ASM_TYPE = - DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineContext")).topLevelClassAsmType() +fun continuationAsmTypes() = listOf( + LanguageVersionSettingsImpl(LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3).continuationAsmType(), + LanguageVersionSettingsImpl(LanguageVersion.KOTLIN_1_2, ApiVersion.KOTLIN_1_2).continuationAsmType() +) -@JvmField -val COROUTINE_IMPL_ASM_TYPE = COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineImpl")).topLevelClassAsmType() +fun LanguageVersionSettings.coroutineContextAsmType() = + coroutinesPackageFqName().child(Name.identifier("CoroutineContext")).topLevelClassAsmType() -private val COROUTINES_INTRINSICS_FILE_FACADE_INTERNAL_NAME = - DescriptorUtils.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME.child(Name.identifier("IntrinsicsKt")).topLevelClassAsmType() +fun LanguageVersionSettings.coroutineImplAsmType() = + coroutinesJvmInternalPackageFqName().child(Name.identifier("CoroutineImpl")).topLevelClassAsmType() -private val INTERNAL_COROUTINE_INTRINSICS_OWNER_INTERNAL_NAME = - COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineIntrinsics")).topLevelClassInternalName() +private fun LanguageVersionSettings.coroutinesIntrinsicsFileFacadeInternalName() = + coroutinesIntrinsicsPackageFqName().child(Name.identifier("IntrinsicsKt")).topLevelClassAsmType() + +private fun LanguageVersionSettings.internalCoroutineIntrinsicsOwnerInternalName() = + coroutinesJvmInternalPackageFqName().child(Name.identifier("CoroutineIntrinsics")).topLevelClassInternalName() private val NORMALIZE_CONTINUATION_METHOD_NAME = "normalizeContinuation" private val GET_CONTEXT_METHOD_NAME = "getContext" @@ -101,11 +98,12 @@ val INITIAL_SUSPEND_DESCRIPTOR_FOR_DO_RESUME = object : FunctionDescriptor.UserD // and fake `this` expression that used as argument for second parameter fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor( project: Project, - bindingContext: BindingContext + bindingContext: BindingContext, + isReleaseCoroutines: Boolean ): ResolvedCallWithRealDescriptor? { if (this is VariableAsFunctionResolvedCall) { val replacedFunctionCall = - functionCall.replaceSuspensionFunctionWithRealDescriptor(project, bindingContext) + functionCall.replaceSuspensionFunctionWithRealDescriptor(project, bindingContext, isReleaseCoroutines) ?: return null @Suppress("UNCHECKED_CAST") @@ -122,9 +120,9 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor( val newCandidateDescriptor = when (function) { is FunctionImportedFromObject -> - getOrCreateJvmSuspendFunctionView(function.callableFromObject, bindingContext).asImportedFromObject() + getOrCreateJvmSuspendFunctionView(function.callableFromObject, isReleaseCoroutines, bindingContext).asImportedFromObject() is SimpleFunctionDescriptor -> - getOrCreateJvmSuspendFunctionView(function, bindingContext) + getOrCreateJvmSuspendFunctionView(function, isReleaseCoroutines, bindingContext) else -> throw AssertionError("Unexpected suspend function descriptor: $function") } @@ -160,6 +158,13 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor( return ResolvedCallWithRealDescriptor(newCall, thisExpression) } +fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(state: GenerationState): ResolvedCallWithRealDescriptor? = + replaceSuspensionFunctionWithRealDescriptor( + state.project, + state.bindingContext, + state.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) + ) + private fun ResolvedCall.asMutableResolvedCall(bindingContext: BindingContext): MutableResolvedCall { return when (this) { is ResolvedCallImpl<*> -> this as MutableResolvedCall @@ -178,14 +183,16 @@ private fun NewResolvedCallImpl.asDummyOldResolvedCall(bindi ) } -fun ResolvedCall<*>.isSuspendNoInlineCall(codegen: ExpressionCodegen): Boolean { +fun ResolvedCall<*>.isSuspendNoInlineCall(codegen: ExpressionCodegen, languageVersionSettings: LanguageVersionSettings): Boolean { val isInlineLambda = this.safeAs() ?.variableCall?.resultingDescriptor?.safeAs() ?.let { it.isCrossinline || (!it.isNoinline && codegen.context.functionDescriptor.isInline) } == true val functionDescriptor = resultingDescriptor as? FunctionDescriptor ?: return false if (!functionDescriptor.unwrapInitialDescriptorForSuspendFunction().isSuspend) return false - if (functionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm() || functionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm()) return true + if (functionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm(languageVersionSettings) || + functionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm(languageVersionSettings) + ) return true return !(functionDescriptor.isInline || isInlineLambda) } @@ -200,6 +207,7 @@ fun CallableDescriptor.isSuspendFunctionNotSuspensionView(): Boolean { @JvmOverloads fun getOrCreateJvmSuspendFunctionView( function: D, + isReleaseCoroutines: Boolean, bindingContext: BindingContext? = null, dropSuspend: Boolean = false ): D { @@ -211,14 +219,19 @@ fun getOrCreateJvmSuspendFunctionView( bindingContext?.get(CodegenBinding.SUSPEND_FUNCTION_TO_JVM_VIEW, function)?.let { return it as D } val continuationParameter = ValueParameterDescriptorImpl( - function, null, function.valueParameters.size, Annotations.EMPTY, Name.identifier("continuation"), + containingDeclaration = function, + original = null, + index = function.valueParameters.size, + annotations = Annotations.EMPTY, + name = Name.identifier("continuation"), // Add j.l.Object to invoke(), because that is the type of parameters we have in FunctionN+1 - if (function.containingDeclaration.safeAs()?.defaultType?.isBuiltinFunctionalType == true) + outType = if (function.containingDeclaration.safeAs()?.defaultType?.isBuiltinFunctionalType == true) function.builtIns.nullableAnyType else - function.getContinuationParameterTypeOfSuspendFunction(), - /* declaresDefaultValue = */ false, /* isCrossinline = */ false, - /* isNoinline = */ false, /* varargElementType = */ null, SourceElement.NO_SOURCE + function.getContinuationParameterTypeOfSuspendFunction(isReleaseCoroutines), + declaresDefaultValue = false, isCrossinline = false, + isNoinline = false, varargElementType = null, + source = SourceElement.NO_SOURCE ) return function.createCustomCopy { @@ -255,25 +268,29 @@ fun D.createCustomCopy( return result as D } -private fun FunctionDescriptor.getContinuationParameterTypeOfSuspendFunction() = - module.getContinuationOfTypeOrAny(returnType!!) +private fun FunctionDescriptor.getContinuationParameterTypeOfSuspendFunction(isReleaseCoroutines: Boolean) = + module.getContinuationOfTypeOrAny(returnType!!, isReleaseCoroutines) -fun ModuleDescriptor.getContinuationOfTypeOrAny(kotlinType: KotlinType) = - module.findContinuationClassDescriptorOrNull(NoLookupLocation.FROM_BACKEND)?.defaultType?.let { +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 FunctionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm() = - getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)?.isBuiltInSuspendCoroutineOrReturn() == true +fun FunctionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm(languageVersionSettings: LanguageVersionSettings) = + getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)?.isBuiltInSuspendCoroutineOrReturn(languageVersionSettings) == true fun createMethodNodeForSuspendCoroutineOrReturn( functionDescriptor: FunctionDescriptor, - typeMapper: KotlinTypeMapper + typeMapper: KotlinTypeMapper, + languageVersionSettings: LanguageVersionSettings ): MethodNode { - assert(functionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm()) { + assert(functionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm(languageVersionSettings)) { "functionDescriptor must be kotlin.coroutines.intrinsics.suspendOrReturn" } @@ -288,13 +305,7 @@ fun createMethodNodeForSuspendCoroutineOrReturn( node.visitVarInsn(Opcodes.ALOAD, 0) node.visitVarInsn(Opcodes.ALOAD, 1) - node.visitMethodInsn( - Opcodes.INVOKESTATIC, - INTERNAL_COROUTINE_INTRINSICS_OWNER_INTERNAL_NAME, - NORMALIZE_CONTINUATION_METHOD_NAME, - Type.getMethodDescriptor(CONTINUATION_ASM_TYPE, CONTINUATION_ASM_TYPE), - false - ) + node.invokeNormalizeContinuation(languageVersionSettings) node.visitMethodInsn( Opcodes.INVOKEINTERFACE, @@ -309,14 +320,25 @@ fun createMethodNodeForSuspendCoroutineOrReturn( return node } -fun FunctionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm() = - getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)?.isBuiltInSuspendCoroutineUninterceptedOrReturn() == true +private fun MethodNode.invokeNormalizeContinuation(languageVersionSettings: LanguageVersionSettings) { + visitMethodInsn( + Opcodes.INVOKESTATIC, + languageVersionSettings.internalCoroutineIntrinsicsOwnerInternalName(), + NORMALIZE_CONTINUATION_METHOD_NAME, + Type.getMethodDescriptor(languageVersionSettings.continuationAsmType(), languageVersionSettings.continuationAsmType()), + false + ) +} + +fun FunctionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm(languageVersionSettings: LanguageVersionSettings) = + getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)?.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings) == true fun createMethodNodeForIntercepted( functionDescriptor: FunctionDescriptor, - typeMapper: KotlinTypeMapper + typeMapper: KotlinTypeMapper, + languageVersionSettings: LanguageVersionSettings ): MethodNode { - assert(functionDescriptor.isBuiltInIntercepted()) { + assert(functionDescriptor.isBuiltInIntercepted(languageVersionSettings)) { "functionDescriptor must be kotlin.coroutines.intrinsics.intercepted" } @@ -330,21 +352,19 @@ fun createMethodNodeForIntercepted( node.visitVarInsn(Opcodes.ALOAD, 0) - node.visitMethodInsn( - Opcodes.INVOKESTATIC, - INTERNAL_COROUTINE_INTRINSICS_OWNER_INTERNAL_NAME, - NORMALIZE_CONTINUATION_METHOD_NAME, - Type.getMethodDescriptor(CONTINUATION_ASM_TYPE, CONTINUATION_ASM_TYPE), - false - ) + node.invokeNormalizeContinuation(languageVersionSettings) + node.visitInsn(Opcodes.ARETURN) node.visitMaxs(1, 1) return node } -fun createMethodNodeForCoroutineContext(functionDescriptor: FunctionDescriptor): MethodNode { - assert(functionDescriptor.isBuiltInCoroutineContext()) { +fun createMethodNodeForCoroutineContext( + functionDescriptor: FunctionDescriptor, + languageVersionSettings: LanguageVersionSettings +): MethodNode { + assert(functionDescriptor.isBuiltInCoroutineContext(languageVersionSettings)) { "functionDescriptor must be kotlin.coroutines.intrinsics.coroutineContext property getter" } @@ -353,7 +373,7 @@ fun createMethodNodeForCoroutineContext(functionDescriptor: FunctionDescriptor): Opcodes.ASM5, Opcodes.ACC_STATIC, "fake", - Type.getMethodDescriptor(COROUTINE_CONTEXT_ASM_TYPE), + Type.getMethodDescriptor(languageVersionSettings.coroutineContextAsmType()), null, null ) @@ -361,24 +381,19 @@ fun createMethodNodeForCoroutineContext(functionDescriptor: FunctionDescriptor): addFakeContinuationMarker(v) - v.invokeinterface( - CONTINUATION_ASM_TYPE.internalName, - GET_CONTEXT_METHOD_NAME, - Type.getMethodDescriptor(COROUTINE_CONTEXT_ASM_TYPE) - ) - v.areturn(COROUTINE_CONTEXT_ASM_TYPE) + v.invokeGetContext(languageVersionSettings) node.visitMaxs(1, 1) return node } - fun createMethodNodeForSuspendCoroutineUninterceptedOrReturn( functionDescriptor: FunctionDescriptor, - typeMapper: KotlinTypeMapper + typeMapper: KotlinTypeMapper, + languageVersionSettings: LanguageVersionSettings ): MethodNode { - assert(functionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm()) { + assert(functionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm(languageVersionSettings)) { "functionDescriptor must be kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn" } @@ -406,20 +421,33 @@ fun createMethodNodeForSuspendCoroutineUninterceptedOrReturn( return node } + +private fun InstructionAdapter.invokeGetContext(languageVersionSettings: LanguageVersionSettings) { + invokeinterface( + languageVersionSettings.continuationAsmType().internalName, + GET_CONTEXT_METHOD_NAME, + Type.getMethodDescriptor(languageVersionSettings.coroutineContextAsmType()) + ) + areturn(languageVersionSettings.coroutineContextAsmType()) +} + @Suppress("UNCHECKED_CAST") fun D.unwrapInitialDescriptorForSuspendFunction(): D = this.safeAs()?.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION) as D ?: this -fun FunctionDescriptor.getOriginalSuspendFunctionView(bindingContext: BindingContext): FunctionDescriptor = +fun FunctionDescriptor.getOriginalSuspendFunctionView(bindingContext: BindingContext, isReleaseCoroutines: Boolean): FunctionDescriptor = if (isSuspend) - getOrCreateJvmSuspendFunctionView(unwrapInitialDescriptorForSuspendFunction().original, bindingContext) + getOrCreateJvmSuspendFunctionView(unwrapInitialDescriptorForSuspendFunction().original, isReleaseCoroutines, bindingContext) else this -fun InstructionAdapter.loadCoroutineSuspendedMarker() { +fun FunctionDescriptor.getOriginalSuspendFunctionView(bindingContext: BindingContext, state: GenerationState) = + getOriginalSuspendFunctionView(bindingContext, state.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) + +fun InstructionAdapter.loadCoroutineSuspendedMarker(languageVersionSettings: LanguageVersionSettings) { invokestatic( - COROUTINES_INTRINSICS_FILE_FACADE_INTERNAL_NAME.internalName, + languageVersionSettings.coroutinesIntrinsicsFileFacadeInternalName().internalName, "get$COROUTINE_SUSPENDED_NAME", Type.getMethodDescriptor(AsmTypes.OBJECT_TYPE), false diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt index 97d51948f95..0453ebb96a8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt @@ -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.codegen.inline @@ -20,10 +9,10 @@ import com.intellij.util.ArrayUtil import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.StackValue -import org.jetbrains.kotlin.codegen.coroutines.COROUTINE_IMPL_ASM_TYPE import org.jetbrains.kotlin.codegen.coroutines.CoroutineTransformerMethodVisitor import org.jetbrains.kotlin.codegen.optimization.common.asSequence import org.jetbrains.kotlin.codegen.serialization.JvmCodegenStringTable +import org.jetbrains.kotlin.codegen.coroutines.coroutineImplAsmType import org.jetbrains.kotlin.codegen.writeKotlinMetadata import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass @@ -55,6 +44,7 @@ class AnonymousObjectTransformer( private var sourceInfo: String? = null private var debugInfo: String? = null private lateinit var sourceMapper: SourceMapper + private val languageVersionSettings = inliningContext.state.languageVersionSettings override fun doTransform(parentRemapper: FieldRemapper): InlineResult { val innerClassNodes = ArrayList() @@ -65,7 +55,7 @@ class AnonymousObjectTransformer( createClassReader().accept(object : ClassVisitor(API, classBuilder.visitor) { override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array) { classBuilder.defineClass(null, version, access, name, signature, superName, interfaces) - if (COROUTINE_IMPL_ASM_TYPE.internalName == superName) { + if (languageVersionSettings.coroutineImplAsmType().internalName == superName) { inliningContext.isContinuation = true } } @@ -454,6 +444,7 @@ class AnonymousObjectTransformer( ), original.access, original.name, original.desc, null, null, obtainClassBuilderForCoroutineState = { builder }, lineNumber = 0, // <- TODO + languageVersionSettings = languageVersionSettings, shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization, containingClassInternalName = builder.thisName, isForNamedFunction = false @@ -480,6 +471,7 @@ class AnonymousObjectTransformer( ), original.access, original.name, original.desc, null, null, obtainClassBuilderForCoroutineState = { (inliningContext as RegeneratedClassContext).continuationBuilders[continuationClassName]!! }, lineNumber = 0, // <- TODO + languageVersionSettings = languageVersionSettings, shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization, containingClassInternalName = builder.thisName, isForNamedFunction = true, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt index 2c9b3db5e5a..1d8b58ab9b6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -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. */ @@ -460,6 +460,7 @@ abstract class InlineCodegen( state: GenerationState, sourceCompilerForInline: SourceCompilerForInline ): SMAPAndMethodNode { + val languageVersionSettings = state.languageVersionSettings when { isSpecialEnumMethod(functionDescriptor) -> { val node = createSpecialEnumMethodBody( @@ -469,25 +470,29 @@ abstract class InlineCodegen( ) return SMAPAndMethodNode(node, SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1)) } - functionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm() -> + functionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm(languageVersionSettings) -> return SMAPAndMethodNode( - createMethodNodeForSuspendCoroutineOrReturn(functionDescriptor, state.typeMapper), - SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1) + createMethodNodeForSuspendCoroutineOrReturn(functionDescriptor, state.typeMapper, languageVersionSettings), + SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1) ) - functionDescriptor.isBuiltInIntercepted() -> + functionDescriptor.isBuiltInIntercepted(languageVersionSettings) -> return SMAPAndMethodNode( - createMethodNodeForIntercepted(functionDescriptor, state.typeMapper), - SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1) + createMethodNodeForIntercepted(functionDescriptor, state.typeMapper, languageVersionSettings), + SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1) ) - functionDescriptor.isBuiltInCoroutineContext() -> + functionDescriptor.isBuiltInCoroutineContext(languageVersionSettings) -> return SMAPAndMethodNode( - createMethodNodeForCoroutineContext(functionDescriptor), - SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1) + createMethodNodeForCoroutineContext(functionDescriptor, languageVersionSettings), + SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1) ) - functionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm() -> + functionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm(languageVersionSettings) -> return SMAPAndMethodNode( - createMethodNodeForSuspendCoroutineUninterceptedOrReturn(functionDescriptor, state.typeMapper), - SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1) + createMethodNodeForSuspendCoroutineUninterceptedOrReturn( + functionDescriptor, + state.typeMapper, + languageVersionSettings + ), + SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1) ) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt index be4d5292cbd..0a20bc7a40b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt @@ -10,7 +10,7 @@ import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.ClosureCodegen import org.jetbrains.kotlin.codegen.StackValue -import org.jetbrains.kotlin.codegen.coroutines.CONTINUATION_ASM_TYPE +import org.jetbrains.kotlin.codegen.coroutines.continuationAsmType import org.jetbrains.kotlin.codegen.inline.FieldRemapper.Companion.foldName import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods import org.jetbrains.kotlin.codegen.optimization.ApiVersionCallsPreprocessingMethodTransformer @@ -50,6 +50,7 @@ class MethodInliner( private val shouldPreprocessApiVersionCalls: Boolean = false ) { private val typeMapper = inliningContext.state.typeMapper + private val languageVersionSettings = inliningContext.state.languageVersionSettings private val invokeCalls = ArrayList() //keeps order private val transformations = ArrayList() @@ -292,7 +293,7 @@ class MethodInliner( } val isContinuationCreate = isContinuation && oldInfo != null && resultNode.name == "create" && - resultNode.desc.endsWith(")" + CONTINUATION_ASM_TYPE.descriptor) + resultNode.desc.endsWith(")" + languageVersionSettings.continuationAsmType().descriptor) for (capturedParamDesc in info.allRecapturedParameters) { if (capturedParamDesc.fieldName == THIS && isContinuationCreate) { @@ -660,7 +661,7 @@ class MethodInliner( // We can't have suspending constructors. assert(invoke.opcode != Opcodes.INVOKESPECIAL) if (Type.getReturnType(invoke.desc) != OBJECT_TYPE) return false - return Type.getArgumentTypes(invoke.desc).let { it.isNotEmpty() && it.last() == CONTINUATION_ASM_TYPE } + return Type.getArgumentTypes(invoke.desc).let { it.isNotEmpty() && it.last() == languageVersionSettings.continuationAsmType() } } private fun preprocessNodeBeforeInline(node: MethodNode, labelOwner: LabelOwner) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java index 24db145733d..a59e5292452 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java @@ -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.codegen.serialization; @@ -24,6 +13,7 @@ import org.jetbrains.kotlin.codegen.FakeDescriptorsForReferencesKt; import org.jetbrains.kotlin.codegen.binding.CodegenBinding; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; +import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor; @@ -61,6 +51,7 @@ public class JvmSerializerExtension extends SerializerExtension { private final boolean useTypeTable; private final String moduleName; private final ClassBuilderMode classBuilderMode; + private final boolean isReleaseCoroutines; public JvmSerializerExtension(@NotNull JvmSerializationBindings bindings, @NotNull GenerationState state) { this.bindings = bindings; @@ -71,6 +62,7 @@ public class JvmSerializerExtension extends SerializerExtension { this.useTypeTable = state.getUseTypeTableInSerializer(); this.moduleName = state.getModuleName(); this.classBuilderMode = state.getClassBuilderMode(); + this.isReleaseCoroutines = state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines); } @NotNull @@ -313,4 +305,9 @@ public class JvmSerializerExtension extends SerializerExtension { return builder.build(); } } + + @Override + public boolean releaseCoroutines() { + return isReleaseCoroutines; + } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/signature/KotlinToJvmSignatureMapperImpl.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/signature/KotlinToJvmSignatureMapperImpl.kt index 1226272c80a..c29c7cb564e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/signature/KotlinToJvmSignatureMapperImpl.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/signature/KotlinToJvmSignatureMapperImpl.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.codegen.signature @@ -28,7 +17,8 @@ class KotlinToJvmSignatureMapperImpl : KotlinToJvmSignatureMapper { // We use empty BindingContext, because it is only used by KotlinTypeMapper for purposes irrelevant to the needs of this class private val typeMapper = KotlinTypeMapper( BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES, - IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false) + IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false, KotlinTypeMapper.RELEASE_COROUTINES_DEFAULT + ) override fun mapToJvmMethodSignature(function: FunctionDescriptor) = typeMapper.mapAsmMethod(function) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt index fb95424ac1f..894134ae46e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt @@ -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.codegen.state @@ -53,16 +42,17 @@ private val PREDEFINED_SIGNATURES = listOf( } class BuilderFactoryForDuplicateSignatureDiagnostics( - builderFactory: ClassBuilderFactory, - bindingContext: BindingContext, - private val diagnostics: DiagnosticSink, - moduleName: String, - shouldGenerate: (JvmDeclarationOrigin) -> Boolean + builderFactory: ClassBuilderFactory, + bindingContext: BindingContext, + private val diagnostics: DiagnosticSink, + moduleName: String, + isReleaseCoroutines: Boolean, + shouldGenerate: (JvmDeclarationOrigin) -> Boolean ) : SignatureCollectingClassBuilderFactory(builderFactory, shouldGenerate) { // Avoid errors when some classes are not loaded for some reason private val typeMapper = KotlinTypeMapper( - bindingContext, ClassBuilderMode.LIGHT_CLASSES, IncompatibleClassTracker.DoNothing, moduleName, false + bindingContext, ClassBuilderMode.LIGHT_CLASSES, IncompatibleClassTracker.DoNothing, moduleName, false, isReleaseCoroutines ) private val reportDiagnosticsTasks = ArrayList<() -> Unit>() diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index 0374967c85e..f062ccf0fd8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.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.codegen.state @@ -186,8 +175,12 @@ class GenerationState private constructor( ) val bindingContext: BindingContext = bindingTrace.bindingContext val typeMapper: KotlinTypeMapper = KotlinTypeMapper( - this.bindingContext, classBuilderMode, IncompatibleClassTrackerImpl(extraJvmDiagnosticsTrace), - this.moduleName, isJvm8Target + this.bindingContext, + classBuilderMode, + IncompatibleClassTrackerImpl(extraJvmDiagnosticsTrace), + this.moduleName, + isJvm8Target, + configuration.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) ) val intrinsics: IntrinsicMethods = run { val shouldUseConsistentEquals = languageVersionSettings.supportsFeature(LanguageFeature.ThrowNpeOnExplicitEqualsForBoxedNull) && @@ -197,7 +190,7 @@ class GenerationState private constructor( val samWrapperClasses: SamWrapperClasses = SamWrapperClasses(this) val globalInlineContext: GlobalInlineContext = GlobalInlineContext(diagnostics) val mappingsClassesForWhenByEnum: MappingsClassesForWhenByEnum = MappingsClassesForWhenByEnum(this) - val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes(module) + val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes(module, configuration.languageVersionSettings) val factory: ClassFileFactory private lateinit var duplicateSignatureFactory: BuilderFactoryForDuplicateSignatureDiagnostics @@ -242,6 +235,7 @@ class GenerationState private constructor( { BuilderFactoryForDuplicateSignatureDiagnostics( it, this.bindingContext, diagnostics, this.moduleName, + isReleaseCoroutines = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines), shouldGenerate = { !shouldOnlyCollectSignatures(it) } ).apply { duplicateSignatureFactory = this } }, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java index 319d3225267..4e035c7dd1d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java @@ -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. */ @@ -85,6 +85,7 @@ public class KotlinTypeMapper { private final IncompatibleClassTracker incompatibleClassTracker; private final String moduleName; private final boolean isJvm8Target; + private final boolean isReleaseCoroutines; private final TypeMappingConfiguration typeMappingConfiguration = new TypeMappingConfiguration() { @NotNull @@ -112,6 +113,11 @@ public class KotlinTypeMapper { throw new IllegalStateException(generateErrorMessageForErrorType(kotlinType, descriptor)); } } + + @Override + public boolean releaseCoroutines() { + return isReleaseCoroutines; + } }; private static final TypeMappingConfiguration staticTypeMappingConfiguration = new TypeMappingConfiguration() { @@ -137,6 +143,11 @@ public class KotlinTypeMapper { public void processErrorType(@NotNull KotlinType kotlinType, @NotNull ClassDescriptor descriptor) { throw new IllegalStateException(generateErrorMessageForErrorType(kotlinType, descriptor)); } + + @Override + public boolean releaseCoroutines() { + return false; + } }; public KotlinTypeMapper( @@ -144,15 +155,19 @@ public class KotlinTypeMapper { @NotNull ClassBuilderMode classBuilderMode, @NotNull IncompatibleClassTracker incompatibleClassTracker, @NotNull String moduleName, - boolean isJvm8Target + boolean isJvm8Target, + boolean isReleaseCoroutines ) { this.bindingContext = bindingContext; this.classBuilderMode = classBuilderMode; this.incompatibleClassTracker = incompatibleClassTracker; this.moduleName = moduleName; this.isJvm8Target = isJvm8Target; + this.isReleaseCoroutines = isReleaseCoroutines; } + public static final boolean RELEASE_COROUTINES_DEFAULT = false; + @NotNull public BindingContext getBindingContext() { return bindingContext; @@ -363,7 +378,9 @@ public class KotlinTypeMapper { } if (CoroutineCodegenUtilKt.isSuspendFunctionNotSuspensionView(descriptor)) { - return mapReturnType(CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView((SimpleFunctionDescriptor) descriptor), sw); + return mapReturnType( + CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView((SimpleFunctionDescriptor) descriptor, isReleaseCoroutines), + sw); } if (TypeSignatureMappingKt.hasVoidReturnType(descriptor)) { @@ -1129,7 +1146,8 @@ public class KotlinTypeMapper { } if (CoroutineCodegenUtilKt.isSuspendFunctionNotSuspensionView(f)) { - return mapSignature(CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(f), kind, skipGenericSignature); + return mapSignature(CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(f, isReleaseCoroutines), kind, + skipGenericSignature); } return mapSignatureWithCustomParameters(f, kind, f.getValueParameters(), skipGenericSignature, hasSpecialBridge); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerDeserializationConfiguration.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerDeserializationConfiguration.kt index 89d657e01f3..d824431d53a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerDeserializationConfiguration.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerDeserializationConfiguration.kt @@ -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.resolve @@ -32,4 +21,6 @@ class CompilerDeserializationConfiguration(languageVersionSettings: LanguageVers override val isJvmPackageNameSupported = languageVersionSettings.supportsFeature(LanguageFeature.JvmPackageName) override val readDeserializedContracts: Boolean = languageVersionSettings.supportsFeature(LanguageFeature.ReadDeserializedContracts) + + override val releaseCoroutines: Boolean = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/coroutineCallChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/coroutineCallChecker.kt index 84113077221..028d8beff2e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/coroutineCallChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/coroutineCallChecker.kt @@ -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.resolve.calls.checkers @@ -19,6 +8,8 @@ package org.jetbrains.kotlin.resolve.calls.checkers import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.config.restrictsSuspensionFqName +import org.jetbrains.kotlin.config.isBuiltInCoroutineContext import org.jetbrains.kotlin.coroutines.hasSuspendFunctionType import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor @@ -26,7 +17,6 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.Errors -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtThisExpression @@ -34,7 +24,6 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -import org.jetbrains.kotlin.resolve.descriptorUtil.hasRestrictsSuspensionAnnotation import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope import org.jetbrains.kotlin.resolve.scopes.LexicalScope @@ -46,16 +35,14 @@ import org.jetbrains.kotlin.types.typeUtil.supertypes import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.safeAs -val COROUTINE_CONTEXT_1_2_20_FQ_NAME = DescriptorUtils.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME.child(Name.identifier("coroutineContext")) -val COROUTINE_CONTEXT_FQ_NAME = DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("coroutineContext")) +val COROUTINE_CONTEXT_1_2_20_FQ_NAME = + DescriptorUtils.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME_EXPERIMENTAL.child(Name.identifier("coroutineContext")) -fun FqName.isBuiltInCorouineContext() = - this == COROUTINE_CONTEXT_1_2_20_FQ_NAME || this == COROUTINE_CONTEXT_FQ_NAME +fun FunctionDescriptor.isBuiltInCoroutineContext(languageVersionSettings: LanguageVersionSettings) = + (this as? PropertyGetterDescriptor)?.correspondingProperty?.fqNameSafe?.isBuiltInCoroutineContext(languageVersionSettings) == true -fun FunctionDescriptor.isBuiltInCoroutineContext() = - (this as? PropertyGetterDescriptor)?.correspondingProperty?.fqNameSafe?.isBuiltInCorouineContext() == true - -fun PropertyDescriptor.isBuiltInCoroutineContext() = this.fqNameSafe.isBuiltInCorouineContext() +fun PropertyDescriptor.isBuiltInCoroutineContext(languageVersionSettings: LanguageVersionSettings) = + this.fqNameSafe.isBuiltInCoroutineContext(languageVersionSettings) object CoroutineSuspendCallChecker : CallChecker { private val ALLOWED_SCOPE_KINDS = setOf(LexicalScopeKind.FUNCTION_INNER_SCOPE, LexicalScopeKind.FUNCTION_HEADER_FOR_DESTRUCTURING) @@ -64,10 +51,8 @@ object CoroutineSuspendCallChecker : CallChecker { val descriptor = resolvedCall.candidateDescriptor when (descriptor) { is FunctionDescriptor -> if (!descriptor.isSuspend) return - is PropertyDescriptor -> when (descriptor.fqNameSafe) { - COROUTINE_CONTEXT_1_2_20_FQ_NAME, COROUTINE_CONTEXT_FQ_NAME -> {} - else -> return - } + is PropertyDescriptor -> + if (descriptor.fqNameSafe != COROUTINE_CONTEXT_1_2_20_FQ_NAME && !descriptor.isBuiltInCoroutineContext(context.languageVersionSettings)) return else -> return } @@ -153,7 +138,7 @@ private fun checkRestrictsSuspension( val enclosingSuspendReceiverValue = enclosingCallableDescriptor.extensionReceiverParameter?.value ?: return fun ReceiverValue.isRestrictsSuspensionReceiver() = (type.supertypes() + type).any { - it.constructor.declarationDescriptor?.hasRestrictsSuspensionAnnotation() == true + it.constructor.declarationDescriptor?.annotations?.hasAnnotation(context.languageVersionSettings.restrictsSuspensionFqName()) == true } infix fun ReceiverValue.sameInstance(other: ReceiverValue?): Boolean { diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt index d336e345987..93fee5ea82d 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt @@ -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. */ @@ -502,7 +502,7 @@ class DescriptorSerializer private constructor( } if (type.isSuspendFunctionType) { - val functionType = type(transformSuspendFunctionToRuntimeFunctionType(type)) + val functionType = type(transformSuspendFunctionToRuntimeFunctionType(type, extension.releaseCoroutines())) functionType.flags = Flags.getTypeFlags(true) return functionType } diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.kt index c3ebe20f274..7cc1d2153cd 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.kt @@ -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.serialization @@ -71,4 +60,6 @@ abstract class SerializerExtension { open fun serializeErrorType(type: KotlinType, builder: ProtoBuf.Type.Builder) { throw IllegalStateException("Cannot serialize error type: $type") } + + open fun releaseCoroutines(): Boolean = false } diff --git a/compiler/testData/codegen/bytecodeListing/releaseCoroutines.kt b/compiler/testData/codegen/bytecodeListing/releaseCoroutines.kt new file mode 100644 index 00000000000..7a38896d628 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/releaseCoroutines.kt @@ -0,0 +1,10 @@ +// !API_VERSION: 1.3 + +suspend fun named() {} + +suspend fun withStateMachine() { + named() + named() +} + +val l: suspend() -> Unit = {} diff --git a/compiler/testData/codegen/bytecodeListing/releaseCoroutines.txt b/compiler/testData/codegen/bytecodeListing/releaseCoroutines.txt new file mode 100644 index 00000000000..34e1e66f5db --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/releaseCoroutines.txt @@ -0,0 +1,30 @@ +@kotlin.Metadata +final class ReleaseCoroutinesKt$l$1 { + inner class ReleaseCoroutinesKt$l$1 + method (p0: kotlin.coroutines.Continuation): void + public final @org.jetbrains.annotations.Nullable method create(@org.jetbrains.annotations.Nullable p0: java.lang.Object): java.lang.Object + public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object + public final @org.jetbrains.annotations.Nullable method invoke(@org.jetbrains.annotations.Nullable p0: java.lang.Object): java.lang.Object +} + +@kotlin.Metadata +final class ReleaseCoroutinesKt$withStateMachine$1 { + synthetic field data: java.lang.Object + synthetic field exception: java.lang.Throwable + inner class ReleaseCoroutinesKt$withStateMachine$1 + method (p0: kotlin.coroutines.Continuation): void + public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object + synthetic final method getLabel(): int + synthetic final method setLabel(p0: int): void +} + +@kotlin.Metadata +public final class ReleaseCoroutinesKt { + private final static @org.jetbrains.annotations.NotNull field l: kotlin.jvm.functions.Function1 + inner class ReleaseCoroutinesKt$l$1 + inner class ReleaseCoroutinesKt$withStateMachine$1 + static method (): void + public final static @org.jetbrains.annotations.NotNull method getL(): kotlin.jvm.functions.Function1 + public final static @org.jetbrains.annotations.Nullable method named(@org.jetbrains.annotations.Nullable p0: java.lang.Object): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method withStateMachine(@org.jetbrains.annotations.Nullable p0: java.lang.Object): java.lang.Object +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 34006a96ddc..34713e695a0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -151,6 +151,12 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { doTest(fileName); } + @TestMetadata("releaseCoroutines.kt") + public void testReleaseCoroutines() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/releaseCoroutines.kt"); + doTest(fileName); + } + @TestMetadata("samAdapterAndInlinedOne.kt") public void testSamAdapterAndInlinedOne() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/samAdapterAndInlinedOne.kt"); diff --git a/compiler/util/src/org/jetbrains/kotlin/config/CoroutineLanguageVersionSettingsUtil.kt b/compiler/util/src/org/jetbrains/kotlin/config/CoroutineLanguageVersionSettingsUtil.kt new file mode 100644 index 00000000000..44a976e3cdc --- /dev/null +++ b/compiler/util/src/org/jetbrains/kotlin/config/CoroutineLanguageVersionSettingsUtil.kt @@ -0,0 +1,37 @@ +/* + * 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.config + +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.resolve.DescriptorUtils + +fun LanguageVersionSettings.coroutinesPackageFqName(): FqName { + return coroutinesPackageFqName(supportsFeature(LanguageFeature.ReleaseCoroutines)) +} + +private fun coroutinesPackageFqName(isReleaseCoroutines: Boolean): FqName { + return if (isReleaseCoroutines) + DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_RELEASE + else + DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL +} + +fun LanguageVersionSettings.coroutinesIntrinsicsPackageFqName() = + coroutinesPackageFqName().child(Name.identifier("intrinsics")) + +fun LanguageVersionSettings.continuationInterfaceFqName() = + coroutinesPackageFqName().child(Name.identifier("Continuation")) + +fun LanguageVersionSettings.restrictsSuspensionFqName() = + coroutinesPackageFqName().child(Name.identifier("RestrictsSuspension")) + +fun FqName.isBuiltInCoroutineContext(languageVersionSettings: LanguageVersionSettings) = + if (languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) + this == DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_RELEASE.child(Name.identifier("coroutineContext")) + else + this == DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.child(Name.identifier("coroutineContext")) || + this == DescriptorUtils.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME_EXPERIMENTAL.child(Name.identifier("coroutineContext")) \ No newline at end of file diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 326149f04b8..6e4bd419df4 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -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. */ @@ -68,6 +68,7 @@ enum class LanguageFeature( InlineClasses(KOTLIN_1_3), ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion(KOTLIN_1_3), ProhibitNonConstValuesAsVarargsInAnnotations(KOTLIN_1_3), + ReleaseCoroutines(KOTLIN_1_3), ReadDeserializedContracts(KOTLIN_1_3), UseReturnsEffect(KOTLIN_1_3), UseCallsInPlaceEffect(KOTLIN_1_3), diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/methodSignatureMapping.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/methodSignatureMapping.kt index 9b94738ef07..94d62554a7d 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/methodSignatureMapping.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/methodSignatureMapping.kt @@ -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.load.kotlin @@ -166,4 +155,6 @@ internal object TypeMappingConfigurationImpl : TypeMappingConfiguration override fun processErrorType(kotlinType: KotlinType, descriptor: ClassDescriptor) { // DO nothing } + + override fun releaseCoroutines() = false } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/typeSignatureMapping.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/typeSignatureMapping.kt index 45c14019360..e4eb2b0a5dd 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/typeSignatureMapping.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/typeSignatureMapping.kt @@ -1,14 +1,11 @@ /* - * 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. */ package org.jetbrains.kotlin.load.kotlin -import org.jetbrains.kotlin.builtins.FAKE_CONTINUATION_CLASS_DESCRIPTOR -import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.builtins.isSuspendFunctionType -import org.jetbrains.kotlin.builtins.transformSuspendFunctionToRuntimeFunctionType +import org.jetbrains.kotlin.builtins.* import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability import org.jetbrains.kotlin.name.ClassId @@ -43,13 +40,11 @@ interface TypeMappingConfiguration { fun getPredefinedTypeForClass(classDescriptor: ClassDescriptor): T? fun getPredefinedInternalNameForClass(classDescriptor: ClassDescriptor): String? fun processErrorType(kotlinType: KotlinType, descriptor: ClassDescriptor) + fun releaseCoroutines(): Boolean } const val NON_EXISTENT_CLASS_NAME = "error/NonExistentClass" -private val CONTINUATION_INTERNAL_NAME = - JvmClassName.byClassId(ClassId.topLevel(DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME)).internalName - fun mapType( kotlinType: KotlinType, factory: JvmTypeFactory, @@ -60,7 +55,7 @@ fun mapType( ): T { if (kotlinType.isSuspendFunctionType) { return mapType( - transformSuspendFunctionToRuntimeFunctionType(kotlinType), + transformSuspendFunctionToRuntimeFunctionType(kotlinType, typeMappingConfiguration.releaseCoroutines()), factory, mode, typeMappingConfiguration, descriptorTypeWriter, writeGenericType ) @@ -178,12 +173,24 @@ fun hasVoidReturnType(descriptor: CallableDescriptor): Boolean { && descriptor !is PropertyGetterDescriptor } -private fun mapBuiltInType(type: KotlinType, typeFactory: JvmTypeFactory, mode: TypeMappingMode): T? { +private fun continuationInternalName(releaseCoroutines: Boolean): String { + val fqName = + if (releaseCoroutines) DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_RELEASE + else DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL + return JvmClassName.byClassId(ClassId.topLevel(fqName)).internalName +} + +private fun mapBuiltInType( + type: KotlinType, + typeFactory: JvmTypeFactory, + mode: TypeMappingMode +): T? { val descriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return null - if (descriptor === FAKE_CONTINUATION_CLASS_DESCRIPTOR) { - - return typeFactory.createObjectType(CONTINUATION_INTERNAL_NAME) + if (descriptor === FAKE_CONTINUATION_CLASS_DESCRIPTOR_EXPERIMENTAL) { + return typeFactory.createObjectType(continuationInternalName(false)) + } else if (descriptor == FAKE_CONTINUATION_CLASS_DESCRIPTOR_RELEASE) { + return typeFactory.createObjectType(continuationInternalName(true)) } val primitiveType = KotlinBuiltIns.getPrimitiveType(descriptor) diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/suspendFunctionTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/suspendFunctionTypes.kt index 169c2dd9f40..7a4f9f46eb7 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/suspendFunctionTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/suspendFunctionTypes.kt @@ -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) -} \ No newline at end of file +} + +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 +} diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/descriptorUtil.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/descriptorUtil.kt index 50f17d019c3..07d6837e19e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/descriptorUtil.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/descriptorUtil.kt @@ -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" } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java index 9803fcd0f4a..0b0c9a0f091 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java @@ -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() { } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt index 2b4290436fd..f0c959dc02a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt @@ -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) diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializationConfiguration.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializationConfiguration.kt index 4622508d23d..8f16189b989 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializationConfiguration.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializationConfiguration.kt @@ -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.serialization.deserialization @@ -32,5 +21,8 @@ interface DeserializationConfiguration { val readDeserializedContracts: Boolean get() = false + val releaseCoroutines: Boolean + get() = false + object Default : DeserializationConfiguration } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt index c44f2f4d9a2..643d0340c97 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt @@ -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.serialization.deserialization @@ -99,7 +88,7 @@ class TypeDeserializer( }.toList() val simpleType = if (Flags.SUSPEND_TYPE.get(proto.flags)) { - createSuspendFunctionType(annotations, constructor, arguments, proto.nullable) + createSuspendFunctionType(annotations, constructor, arguments, proto.nullable, c.components.configuration.releaseCoroutines) } else { KotlinTypeFactory.simpleType(annotations, constructor, arguments, proto.nullable) @@ -137,15 +126,17 @@ class TypeDeserializer( } private fun createSuspendFunctionType( - annotations: Annotations, - functionTypeConstructor: TypeConstructor, - arguments: List, - nullable: Boolean + annotations: Annotations, + functionTypeConstructor: TypeConstructor, + arguments: List, + nullable: Boolean, + isReleaseCoroutines: Boolean ): SimpleType { val result = when (functionTypeConstructor.parameters.size - arguments.size) { 0 -> { val functionType = KotlinTypeFactory.simpleType(annotations, functionTypeConstructor, arguments, nullable) - functionType.takeIf { it.isFunctionType }?.let(::transformRuntimeFunctionTypeToSuspendFunction) + functionType.takeIf { it.isFunctionType } + ?.let { funType -> transformRuntimeFunctionTypeToSuspendFunction(funType, isReleaseCoroutines) } } // This case for types written by eap compiler 1.1 1 -> { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/TypeClsStubBuilder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/TypeClsStubBuilder.kt index e62c4c8d888..922bf3a3bd7 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/TypeClsStubBuilder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/TypeClsStubBuilder.kt @@ -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.idea.decompiler.stubBuilder @@ -197,10 +186,14 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) { if (parameterType.hasClassName() && parameterType.argumentCount == 1) { val classId = c.nameResolver.getClassId(parameterType.className) val fqName = classId.asSingleFqName() - if (fqName == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME) { - suspendParameterType = parameterType - continue + assert( + fqName == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL + || fqName == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_RELEASE + ) { + "Last parameter type of suspend function must be Continuation, but it is $fqName" } + suspendParameterType = parameterType + continue } } val parameter = KotlinParameterStubImpl( diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/debuggerUtil.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/debuggerUtil.kt index a7578cbc321..59c54af0d25 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/debuggerUtil.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/debuggerUtil.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.idea.debugger @@ -25,8 +14,8 @@ import com.intellij.psi.PsiElement import com.sun.jdi.* import com.sun.tools.jdi.LocalVariableImpl import org.jetbrains.kotlin.codegen.binding.CodegenBinding -import org.jetbrains.kotlin.codegen.coroutines.CONTINUATION_ASM_TYPE import org.jetbrains.kotlin.codegen.coroutines.DO_RESUME_METHOD_NAME +import org.jetbrains.kotlin.codegen.coroutines.continuationAsmTypes import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches import org.jetbrains.kotlin.idea.refactoring.getLineEndOffset @@ -160,8 +149,12 @@ fun isInSuspendMethod(location: Location): Boolean { val method = location.method() val signature = method.signature() - return signature.contains(CONTINUATION_ASM_TYPE.toString()) || - (method.name() == DO_RESUME_METHOD_NAME && signature == DO_RESUME_SIGNATURE) + for (continuationAsmType in continuationAsmTypes()) { + if (signature.contains(continuationAsmType.toString()) || + (method.name() == DO_RESUME_METHOD_NAME && signature == DO_RESUME_SIGNATURE) + ) return true + } + return false } fun suspendFunctionFirstLineLocation(location: Location): Int? { diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/KotlinSuspendCallLineMarkerProvider.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/KotlinSuspendCallLineMarkerProvider.kt index 82f064cfda1..e6dcccbd68b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/KotlinSuspendCallLineMarkerProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/KotlinSuspendCallLineMarkerProvider.kt @@ -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. */ @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext.* import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.checkers.isBuiltInCoroutineContext +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode class KotlinSuspendCallLineMarkerProvider : LineMarkerProvider { @@ -102,8 +103,12 @@ fun KtExpression.hasSuspendCalls(bindingContext: BindingContext = analyze(BodyRe } else -> { val resolvedCall = getResolvedCall(bindingContext) - (resolvedCall?.resultingDescriptor as? FunctionDescriptor)?.isSuspend == true || - (resolvedCall?.resultingDescriptor as? PropertyDescriptor)?.isBuiltInCoroutineContext() == true + if ((resolvedCall?.resultingDescriptor as? FunctionDescriptor)?.isSuspend == true) true + else { + val propertyDescriptor = resolvedCall?.resultingDescriptor as? PropertyDescriptor + val s = propertyDescriptor?.fqNameSafe?.asString() + s?.startsWith("kotlin.coroutines.") == true && s.endsWith(".coroutineContext") + } } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/AbstractUselessCallInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/AbstractUselessCallInspection.kt index 5d89226764d..c1756bd7a30 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/AbstractUselessCallInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/AbstractUselessCallInspection.kt @@ -35,10 +35,10 @@ abstract class AbstractUselessCallInspection : AbstractKotlinInspection() { protected abstract val uselessNames: Set protected abstract fun QualifiedExpressionVisitor.suggestConversionIfNeeded( - expression: KtQualifiedExpression, - calleeExpression: KtExpression, - context: BindingContext, - conversion: Conversion + expression: KtQualifiedExpression, + calleeExpression: KtExpression, + context: BindingContext, + conversion: Conversion ) inner class QualifiedExpressionVisitor internal constructor(val holder: ProblemsHolder, val isOnTheFly: Boolean) : KtVisitorVoid() { diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JsConfig.java b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JsConfig.java index 460325e1805..4ebc2af727d 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JsConfig.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JsConfig.java @@ -86,7 +86,9 @@ public class JsConfig { @Nullable List> metadataCache, @Nullable Set librariesToSkip) { this.project = project; - this.configuration = configuration; + this.configuration = configuration.copy(); + CommonConfigurationKeysKt.setLanguageVersionSettings(this.configuration, new ReleaseCoroutinesDisabledLanguageVersionSettings( + CommonConfigurationKeysKt.getLanguageVersionSettings(this.configuration))); this.metadataCache = metadataCache; this.librariesToSkip = librariesToSkip; } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/config/ReleaseCoroutinesDisabledLanguageVersionSettings.java b/js/js.frontend/src/org/jetbrains/kotlin/js/config/ReleaseCoroutinesDisabledLanguageVersionSettings.java new file mode 100644 index 00000000000..852bcf4c5ec --- /dev/null +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/config/ReleaseCoroutinesDisabledLanguageVersionSettings.java @@ -0,0 +1,52 @@ +/* + * 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.js.config; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.config.*; + +public class ReleaseCoroutinesDisabledLanguageVersionSettings implements LanguageVersionSettings { + @NotNull + private final LanguageVersionSettings delegate; + + public ReleaseCoroutinesDisabledLanguageVersionSettings(@NotNull LanguageVersionSettings delegate) { + this.delegate = delegate; + } + + @NotNull + @Override + public LanguageFeature.State getFeatureSupport(@NotNull LanguageFeature feature) { + if (feature.equals(LanguageFeature.ReleaseCoroutines)) { + return LanguageFeature.State.DISABLED; + } + return delegate.getFeatureSupport(feature); + } + + @Override + public T getFlag(@NotNull AnalysisFlag flag) { + return delegate.getFlag(flag); + } + + @NotNull + @Override + public ApiVersion getApiVersion() { + return delegate.getApiVersion(); + } + + @NotNull + @Override + public LanguageVersion getLanguageVersion() { + return delegate.getLanguageVersion(); + } + + @Override + public boolean supportsFeature(@NotNull LanguageFeature feature) { + if (feature.equals(LanguageFeature.ReleaseCoroutines)) { + return false; + } + return delegate.supportsFeature(feature); + } +} diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/JsInliner.java b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/JsInliner.java index ab33844da0b..4fc955750f7 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/JsInliner.java +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/JsInliner.java @@ -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.js.inline; @@ -21,6 +10,7 @@ import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.backend.common.CommonCoroutineCodegenUtilKt; +import org.jetbrains.kotlin.config.*; import org.jetbrains.kotlin.descriptors.CallableDescriptor; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.FunctionDescriptor; @@ -34,6 +24,7 @@ import org.jetbrains.kotlin.js.inline.context.FunctionContext; import org.jetbrains.kotlin.js.inline.context.InliningContext; import org.jetbrains.kotlin.js.inline.context.NamingContext; import org.jetbrains.kotlin.js.inline.util.*; +import org.jetbrains.kotlin.js.translate.context.TranslationContext; import org.jetbrains.kotlin.js.translate.expression.InlineMetadata; import org.jetbrains.kotlin.resolve.inline.InlineStrategy; @@ -340,7 +331,8 @@ public class JsInliner extends JsVisitorWithContextImpl { private void inline(@NotNull JsInvocation call, @NotNull JsContext context) { DeclarationDescriptor callDescriptor = MetadataProperties.getDescriptor(call); - if (isSuspendWithCurrentContinuation(callDescriptor)) { + if (isSuspendWithCurrentContinuation(callDescriptor, + CommonConfigurationKeysKt.getLanguageVersionSettings(config.getConfiguration()))) { inlineSuspendWithCurrentContinuation(call, context); return; } @@ -499,9 +491,14 @@ public class JsInliner extends JsVisitorWithContextImpl { }.accept(statement); } - private static boolean isSuspendWithCurrentContinuation(@Nullable DeclarationDescriptor descriptor) { + private static boolean isSuspendWithCurrentContinuation( + @Nullable DeclarationDescriptor descriptor, + @NotNull LanguageVersionSettings languageVersionSettings + ) { if (!(descriptor instanceof FunctionDescriptor)) return false; - return CommonCoroutineCodegenUtilKt.isBuiltInSuspendCoroutineOrReturn((FunctionDescriptor) descriptor.getOriginal()); + return CommonCoroutineCodegenUtilKt.isBuiltInSuspendCoroutineOrReturn( + (FunctionDescriptor) descriptor.getOriginal(), languageVersionSettings + ); } private void inlineSuspendWithCurrentContinuation(@NotNull JsInvocation call, @NotNull JsContext context) { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt index f1e49fce2c4..dd846067cee 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt @@ -268,14 +268,14 @@ interface DelegateIntrinsic { fun I.getDescriptor(): CallableDescriptor fun I.getArgs(): List - fun intrinsic(callInfo: I): JsExpression? = if (callInfo.canBeApply()) callInfo.getIntrinsic() else null + fun intrinsic(callInfo: I, context: TranslationContext): JsExpression? = if (callInfo.canBeApply()) callInfo.getIntrinsic(context) else null - private fun I.getIntrinsic(): JsExpression? { + private fun I.getIntrinsic(context: TranslationContext): JsExpression? { val descriptor = getDescriptor() // Now intrinsic support only FunctionDescriptor. See DelegatePropertyAccessIntrinsic.getDescriptor() if (descriptor is FunctionDescriptor) { - val intrinsic = context.intrinsics().getFunctionIntrinsic(descriptor) + val intrinsic = context.intrinsics().getFunctionIntrinsic(descriptor, context) if (intrinsic != null) { return intrinsic.apply(this, getArgs(), context) } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt index 5e8c7d5672e..151337cd95e 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt @@ -316,7 +316,7 @@ object DynamicOperatorCallCase : FunctionCallCase() { } fun FunctionCallInfo.translateFunctionCall(): JsExpression { - val intrinsic = DelegateFunctionIntrinsic.intrinsic(this) + val intrinsic = DelegateFunctionIntrinsic.intrinsic(this, context) return when { intrinsic != null -> diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/VariableCallCases.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/VariableCallCases.kt index f1c5909a571..ed89ce13db0 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/VariableCallCases.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/VariableCallCases.kt @@ -195,7 +195,7 @@ object SuperPropertyAccessCase : VariableAccessCase() { private val VariableAccessInfo.additionalArguments: List get() = value?.let { listOf(it) }.orEmpty() fun VariableAccessInfo.translateVariableAccess(): JsExpression { - val intrinsic = DelegatePropertyAccessIntrinsic.intrinsic(this) + val intrinsic = DelegatePropertyAccessIntrinsic.intrinsic(this, context) return when { intrinsic != null -> diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java index ac1db137535..2a675d5a95d 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java @@ -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.js.translate.context; @@ -19,6 +8,7 @@ package org.jetbrains.kotlin.js.translate.context; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.config.*; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor; @@ -132,7 +122,9 @@ public class TranslationContext { FunctionDescriptor function = (FunctionDescriptor) declarationDescriptor; if (function.isSuspend()) { ClassDescriptor continuationDescriptor = - DescriptorUtilKt.findContinuationClassDescriptor(getCurrentModule(), NoLookupLocation.FROM_BACKEND); + DescriptorUtilKt.findContinuationClassDescriptor( + getCurrentModule(), NoLookupLocation.FROM_BACKEND, + getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines)); return new LocalVariableDescriptor( declarationDescriptor, @@ -934,4 +926,9 @@ public class TranslationContext { public JsName getVariableForPropertyMetadata(@NotNull VariableDescriptorWithAccessors property) { return staticContext.getVariableForPropertyMetadata(property); } + + @NotNull + public LanguageVersionSettings getLanguageVersionSettings() { + return CommonConfigurationKeysKt.getLanguageVersionSettings(staticContext.getConfig().getConfiguration()); + } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.kt index 689397ec0fc..47c727cb6eb 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.kt @@ -39,8 +39,8 @@ class Intrinsics { return binaryOperationIntrinsics.getIntrinsic(expression, context) } - fun getFunctionIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? { - return functionIntrinsics.getIntrinsic(descriptor) + fun getFunctionIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? { + return functionIntrinsics.getIntrinsic(descriptor, context) } fun getObjectIntrinsic(classDescriptor: ClassDescriptor): ObjectIntrinsic? { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.kt index e2269a9f471..f80bf5033a4 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.js.translate.intrinsic.functions import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.* import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult @@ -41,10 +42,10 @@ class FunctionIntrinsics { InterceptedFIF ) - fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? { + fun getIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? { if (descriptor in intrinsicCache) return intrinsicCache[descriptor] - return factories.firstNotNullResult { it.getIntrinsic(descriptor) }.also { + return factories.firstNotNullResult { it.getIntrinsic(descriptor, context) }.also { intrinsicCache[descriptor] = it } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/CompositeFIF.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/CompositeFIF.java index f5ed8a21334..e4e681d45f7 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/CompositeFIF.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/CompositeFIF.java @@ -21,6 +21,7 @@ import com.intellij.openapi.util.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.FunctionDescriptor; +import org.jetbrains.kotlin.js.translate.context.TranslationContext; import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic; import java.util.List; @@ -35,7 +36,7 @@ public abstract class CompositeFIF implements FunctionIntrinsicFactory { @Nullable @Override - public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) { + public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor, @NotNull TranslationContext context) { for (Pair, FunctionIntrinsic> entry : patternsAndIntrinsics) { if (entry.first.test(descriptor)) { return entry.second; diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/CoroutineContextFIF.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/CoroutineContextFIF.kt index 899054120fd..b25a716bdc0 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/CoroutineContextFIF.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/CoroutineContextFIF.kt @@ -33,8 +33,8 @@ import org.jetbrains.kotlin.resolve.calls.checkers.isBuiltInCoroutineContext import org.jetbrains.kotlin.resolve.inline.InlineStrategy object CoroutineContextFIF : FunctionIntrinsicFactory { - override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? { - if (!descriptor.isBuiltInCoroutineContext()) return null + override fun getIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? { + if (!descriptor.isBuiltInCoroutineContext(context.languageVersionSettings)) return null return Intrinsic } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ExceptionPropertyIntrinsicFactory.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ExceptionPropertyIntrinsicFactory.kt index 4466f26b87e..b95cb62efd1 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ExceptionPropertyIntrinsicFactory.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ExceptionPropertyIntrinsicFactory.kt @@ -31,7 +31,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.SuperCallReceiverValue import org.jetbrains.kotlin.types.typeUtil.isNotNullThrowable object ExceptionPropertyIntrinsicFactory : FunctionIntrinsicFactory { - override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? { + override fun getIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? { if (descriptor !is PropertyGetterDescriptor) return null val classDescriptor = descriptor.correspondingProperty.containingDeclaration as? ClassDescriptor ?: return null if (!classDescriptor.defaultType.isNotNullThrowable()) return null diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/FunctionIntrinsicFactory.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/FunctionIntrinsicFactory.java index 21070f556ac..cfa3de4f924 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/FunctionIntrinsicFactory.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/FunctionIntrinsicFactory.java @@ -19,9 +19,10 @@ package org.jetbrains.kotlin.js.translate.intrinsic.functions.factories; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.FunctionDescriptor; +import org.jetbrains.kotlin.js.translate.context.TranslationContext; import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic; public interface FunctionIntrinsicFactory { @Nullable - FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor); + FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor, @NotNull TranslationContext context); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/InterceptedFIF.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/InterceptedFIF.kt index 190e73f0a9c..047b653b9b8 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/InterceptedFIF.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/InterceptedFIF.kt @@ -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.js.translate.intrinsic.functions.factories @@ -26,8 +15,8 @@ import org.jetbrains.kotlin.js.translate.utils.JsAstUtils import org.jetbrains.kotlin.js.translate.utils.TranslationUtils object InterceptedFIF: FunctionIntrinsicFactory { - override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? { - if (!descriptor.isBuiltInIntercepted()) return null + override fun getIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? { + if (!descriptor.isBuiltInIntercepted(context.languageVersionSettings)) return null return Intrinsic } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/LongOperationFIF.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/LongOperationFIF.kt index e35bb7d6267..6165ad5b93c 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/LongOperationFIF.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/LongOperationFIF.kt @@ -83,7 +83,7 @@ object LongOperationFIF : FunctionIntrinsicFactory { fun wrapIntrinsicIfPresent(intrinsic: BaseBinaryIntrinsic?, toLeft: (JsExpression) -> JsExpression, toRight: (JsExpression) -> JsExpression): FunctionIntrinsic? = if (intrinsic != null) BaseBinaryIntrinsic() { left, right -> intrinsic.applyFun(toLeft(left), toRight(right)) } else null - override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? { + override fun getIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? { val operationName = descriptor.name.asString() return when { LONG_EQUALS_ANY.test(descriptor) || LONG_BINARY_OPERATION_LONG.test(descriptor) || LONG_BIT_SHIFTS.test(descriptor) -> diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java index 6381985a516..cb5e9c42a8d 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java @@ -138,7 +138,7 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory { @Nullable @Override - public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) { + public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor, @NotNull TranslationContext context) { if (CHAR_RANGE_TO.test(descriptor)) { return new RangeToIntrinsic(descriptor); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveUnaryOperationFIF.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveUnaryOperationFIF.java index 10bd31ceb14..0f59ba82c89 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveUnaryOperationFIF.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveUnaryOperationFIF.java @@ -230,7 +230,7 @@ public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory { @Nullable @Override - public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) { + public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor, @NotNull TranslationContext context) { if (!PATTERN.test(descriptor)) { return null; } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/StringPlusCharFIF.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/StringPlusCharFIF.kt index 61498e7653f..4ce32f691b0 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/StringPlusCharFIF.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/StringPlusCharFIF.kt @@ -41,7 +41,7 @@ object StringPlusCharFIF : FunctionIntrinsicFactory { } } - override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? { + override fun getIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? { val fqName = descriptor.fqNameUnsafe.asString() if (fqName != "kotlin.String.plus" && fqName != "kotlin.plus") return null diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/SuspendCoroutineUninterceptedOrReturnFIF.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/SuspendCoroutineUninterceptedOrReturnFIF.kt index d36b9a70ed4..9e0ca3e0aa8 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/SuspendCoroutineUninterceptedOrReturnFIF.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/SuspendCoroutineUninterceptedOrReturnFIF.kt @@ -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.js.translate.intrinsic.functions.factories @@ -26,8 +15,8 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic object SuspendCoroutineUninterceptedOrReturnFIF: FunctionIntrinsicFactory { - override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? { - if (!descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn()) return null + override fun getIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? { + if (!descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(context.languageVersionSettings)) return null return Intrinsic } object Intrinsic: FunctionIntrinsic() { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ThrowableConstructorIntrinsicFactory.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ThrowableConstructorIntrinsicFactory.kt index aca1828e208..c225374a735 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ThrowableConstructorIntrinsicFactory.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ThrowableConstructorIntrinsicFactory.kt @@ -30,7 +30,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.types.typeUtil.isNotNullThrowable object ThrowableConstructorIntrinsicFactory : FunctionIntrinsicFactory { - override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? { + override fun getIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? { if (descriptor !is ConstructorDescriptor) return null if (!descriptor.constructedClass.defaultType.isNotNullThrowable()) return null diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/IntrinsicIncrementTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/IntrinsicIncrementTranslator.java index bff0f711e26..aa4240a4bb6 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/IntrinsicIncrementTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/IntrinsicIncrementTranslator.java @@ -41,7 +41,7 @@ public final class IntrinsicIncrementTranslator extends IncrementTranslator { @Override @NotNull protected JsExpression operationExpression(@NotNull TranslationContext context, @NotNull JsExpression receiver) { - FunctionIntrinsic intrinsic = context.intrinsics().getFunctionIntrinsic(resolvedCall.getResultingDescriptor()); + FunctionIntrinsic intrinsic = context.intrinsics().getFunctionIntrinsic(resolvedCall.getResultingDescriptor(), context); assert intrinsic != null; CallInfo callInfo = CallInfoKt.getCallInfo(context, resolvedCall, receiver); return intrinsic.apply(callInfo, Collections.emptyList(), context); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallArgumentTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallArgumentTranslator.kt index 263544c513a..f562c0b57bf 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallArgumentTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallArgumentTranslator.kt @@ -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.js.translate.reference @@ -50,7 +39,7 @@ import java.util.* class CallArgumentTranslator private constructor( private val resolvedCall: ResolvedCall<*>, private val receiver: JsExpression?, - context: TranslationContext + private val context: TranslationContext ) : AbstractTranslator(context) { data class ArgumentsInfo( @@ -165,7 +154,7 @@ class CallArgumentTranslator private constructor( val callableDescriptor = resolvedCall.resultingDescriptor if (callableDescriptor is FunctionDescriptor && callableDescriptor.isSuspend) { var continuationArg: JsExpression = TranslationUtils.translateContinuationArgument(context()) - if (callableDescriptor.original.isBuiltInSuspendCoroutineOrReturn()) { + if (callableDescriptor.original.isBuiltInSuspendCoroutineOrReturn(context.languageVersionSettings)) { val facadeName = context().getNameForDescriptor(TranslationUtils.getCoroutineProperty(context(), "facade")) continuationArg = JsAstUtils.pureFqn(facadeName, continuationArg) } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java index f8be78fa7fd..d5b93d49ee9 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java @@ -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.js.translate.utils; @@ -22,6 +11,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.FunctionTypesKt; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; +import org.jetbrains.kotlin.config.CoroutineLanguageVersionSettingsUtilKt; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor; import org.jetbrains.kotlin.descriptors.impl.LocalVariableAccessorDescriptor; @@ -290,7 +280,7 @@ public final class TranslationUtils { return false; } - if (context.intrinsics().getFunctionIntrinsic((FunctionDescriptor) operationDescriptor) != null) return true; + if (context.intrinsics().getFunctionIntrinsic((FunctionDescriptor) operationDescriptor, context) != null) return true; return false; } @@ -391,7 +381,8 @@ public final class TranslationUtils { @NotNull public static ClassDescriptor getCoroutineBaseClass(@NotNull TranslationContext context) { - FqName className = DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineImpl")); + FqName className = CoroutineLanguageVersionSettingsUtilKt.coroutinesPackageFqName(context.getLanguageVersionSettings()) + .child(Name.identifier("CoroutineImpl")); ClassDescriptor descriptor = FindClassInModuleKt.findClassAcrossModuleDependencies( context.getCurrentModule(), ClassId.topLevel(className)); assert descriptor != null; diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt index dd820e2dc0d..afc9a76296b 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt @@ -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.js.translate.utils @@ -21,6 +10,7 @@ import com.intellij.util.SmartList import org.jetbrains.kotlin.backend.common.COROUTINE_SUSPENDED_NAME import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.coroutinesIntrinsicsPackageFqName import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor @@ -78,7 +68,7 @@ fun generateDelegateCall( args.add(JsNameRef(jsParamName)) } - val intrinsic = context.intrinsics().getFunctionIntrinsic(toDescriptor) + val intrinsic = context.intrinsics().getFunctionIntrinsic(toDescriptor, context) val invocation = if (intrinsic is FunctionIntrinsicWithReceiverComputed) { intrinsic.apply(thisObject, args, context) } else { @@ -165,7 +155,7 @@ fun JsFunction.fillCoroutineMetadata( descriptor: FunctionDescriptor, hasController: Boolean ) { - val suspendPropertyDescriptor = context.currentModule.getPackage(DescriptorUtils.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME) + val suspendPropertyDescriptor = context.currentModule.getPackage(context.languageVersionSettings.coroutinesIntrinsicsPackageFqName()) .memberScope .getContributedVariables(COROUTINE_SUSPENDED_NAME, NoLookupLocation.FROM_BACKEND).first() diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableDeclarationChecker.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableDeclarationChecker.kt index b978595322d..7a8acf0c26d 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableDeclarationChecker.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableDeclarationChecker.kt @@ -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.android.parcel @@ -184,7 +173,9 @@ class ParcelableDeclarationChecker : DeclarationChecker { ClassBuilderMode.full(false), IncompatibleClassTracker.DoNothing, descriptor.module.name.asString(), - /* isJvm8Target */ false) + /* isJvm8Target */ false, + /* isReleaseCoroutines */ KotlinTypeMapper.RELEASE_COROUTINES_DEFAULT + ) for (parameter in primaryConstructor?.valueParameters.orEmpty()) { checkParcelableClassProperty(parameter, descriptor, diagnosticHolder, typeMapper) diff --git a/plugins/uast-kotlin-idea/src/IdeaKotlinUastBindingContextProviderService.kt b/plugins/uast-kotlin-idea/src/IdeaKotlinUastBindingContextProviderService.kt index f1178c31587..27e3c48d1ec 100644 --- a/plugins/uast-kotlin-idea/src/IdeaKotlinUastBindingContextProviderService.kt +++ b/plugins/uast-kotlin-idea/src/IdeaKotlinUastBindingContextProviderService.kt @@ -31,6 +31,7 @@ class IdeaKotlinUastBindingContextProviderService : KotlinUastBindingContextProv override fun getTypeMapper(element: KtElement): KotlinTypeMapper? { return KotlinTypeMapper( getBindingContext(element), ClassBuilderMode.LIGHT_CLASSES, - IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false) + IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false, KotlinTypeMapper.RELEASE_COROUTINES_DEFAULT + ) } } diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/CliKotlinUastBindingContextProviderService.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/CliKotlinUastBindingContextProviderService.kt index 2cbdd28685e..0f55a153d4a 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/CliKotlinUastBindingContextProviderService.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/CliKotlinUastBindingContextProviderService.kt @@ -41,7 +41,8 @@ class UastAnalysisHandlerExtension : AnalysisHandlerExtension { val typeMapper = KotlinTypeMapper( bindingContext, ClassBuilderMode.LIGHT_CLASSES, - IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false) + IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false, KotlinTypeMapper.RELEASE_COROUTINES_DEFAULT + ) this.typeMapper = typeMapper return typeMapper }