Remove obsolete experimental coroutines support
in compiler.
This commit is contained in:
+3
-9
@@ -5,21 +5,15 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.coroutinesIntrinsicsPackageFqName
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.isTopLevelInPackage
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
val COROUTINE_SUSPENDED_NAME = Name.identifier("COROUTINE_SUSPENDED")
|
||||
|
||||
fun FunctionDescriptor.isBuiltInIntercepted(languageVersionSettings: LanguageVersionSettings): Boolean =
|
||||
!languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) &&
|
||||
isTopLevelInPackage("intercepted", languageVersionSettings.coroutinesIntrinsicsPackageFqName().asString())
|
||||
|
||||
fun FunctionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings: LanguageVersionSettings): Boolean =
|
||||
fun FunctionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(): Boolean =
|
||||
isTopLevelInPackage(
|
||||
"suspendCoroutineUninterceptedOrReturn",
|
||||
languageVersionSettings.coroutinesIntrinsicsPackageFqName().asString()
|
||||
StandardNames.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME.asString()
|
||||
)
|
||||
|
||||
@@ -475,7 +475,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
|
||||
List<Type> superCtorArgTypes = new ArrayList<>();
|
||||
if (superClassAsmType.equals(LAMBDA) || functionReferenceTarget != null ||
|
||||
CoroutineCodegenUtilKt.isCoroutineSuperClass(state.getLanguageVersionSettings(), superClassAsmType.getInternalName())
|
||||
CoroutineCodegenUtilKt.isCoroutineSuperClass(superClassAsmType.getInternalName())
|
||||
) {
|
||||
iv.iconst(CodegenUtilKt.getArity(funDescriptor));
|
||||
superCtorArgTypes.add(Type.INT_TYPE);
|
||||
|
||||
@@ -89,7 +89,6 @@ import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContextImpl;
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS;
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker;
|
||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker;
|
||||
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
@@ -1288,11 +1287,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
@NotNull
|
||||
private static CallableDescriptor unwrapOriginalReceiverOwnerForSuspendLambda(@NotNull MethodContext context) {
|
||||
FunctionDescriptor originalForDoResume =
|
||||
context.getFunctionDescriptor().getUserData(CoroutineCodegenUtilKt.INITIAL_SUSPEND_DESCRIPTOR_FOR_DO_RESUME);
|
||||
FunctionDescriptor originalForInvokeSuspend =
|
||||
context.getFunctionDescriptor().getUserData(CoroutineCodegenUtilKt.INITIAL_SUSPEND_DESCRIPTOR_FOR_INVOKE_SUSPEND);
|
||||
|
||||
if (originalForDoResume != null) {
|
||||
return originalForDoResume;
|
||||
if (originalForInvokeSuspend != null) {
|
||||
return originalForInvokeSuspend;
|
||||
}
|
||||
|
||||
if (context.getFunctionDescriptor().isSuspend()) {
|
||||
@@ -2617,26 +2616,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
? coroutineInstanceValueForSuspensionPoint
|
||||
: getContinuationParameterFromEnclosingSuspendFunction(resolvedCall);
|
||||
|
||||
if (coroutineInstanceValue != null && needsExperimentalCoroutinesWrapper(resolvedCall.getCandidateDescriptor())) {
|
||||
StackValue releaseContinuation = coroutineInstanceValue;
|
||||
coroutineInstanceValue = new StackValue(CoroutineCodegenUtilKt.EXPERIMENTAL_CONTINUATION_ASM_TYPE) {
|
||||
@Override
|
||||
public void putSelector(
|
||||
@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v
|
||||
) {
|
||||
releaseContinuation.put(CoroutineCodegenUtilKt.RELEASE_CONTINUATION_ASM_TYPE, v);
|
||||
invokeCoroutineMigrationMethod(
|
||||
v,
|
||||
"toExperimentalContinuation",
|
||||
Type.getMethodDescriptor(
|
||||
CoroutineCodegenUtilKt.EXPERIMENTAL_CONTINUATION_ASM_TYPE,
|
||||
CoroutineCodegenUtilKt.RELEASE_CONTINUATION_ASM_TYPE
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
tempVariables.put(continuationExpression, coroutineInstanceValue);
|
||||
}
|
||||
|
||||
@@ -2774,7 +2753,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
SuspensionPointKind suspensionPointKind =
|
||||
CoroutineCodegenUtilKt.isSuspensionPoint(resolvedCall, this, state.getLanguageVersionSettings());
|
||||
CoroutineCodegenUtilKt.isSuspensionPoint(resolvedCall, this);
|
||||
boolean maybeSuspensionPoint = suspensionPointKind != SuspensionPointKind.NEVER && !insideCallableReference();
|
||||
boolean isConstructor = resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor;
|
||||
if (!(callableMethod instanceof IntrinsicWithSpecialReceiver)) {
|
||||
@@ -2833,7 +2812,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
KotlinType unboxedInlineClass = CoroutineCodegenUtilKt.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass(
|
||||
(FunctionDescriptor) resolvedCall.getResultingDescriptor(), typeMapper);
|
||||
if (unboxedInlineClass != null) {
|
||||
CoroutineCodegenUtilKt.generateCoroutineSuspendedCheck(v, state.getLanguageVersionSettings());
|
||||
CoroutineCodegenUtilKt.generateCoroutineSuspendedCheck(v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2948,7 +2927,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
FunctionDescriptor original =
|
||||
CoroutineCodegenUtilKt.getOriginalSuspendFunctionView(
|
||||
unwrapInitialSignatureDescriptor(DescriptorUtils.unwrapFakeOverride((FunctionDescriptor) descriptor.getOriginal())),
|
||||
bindingContext, state
|
||||
bindingContext
|
||||
);
|
||||
|
||||
FunctionDescriptor functionDescriptor =
|
||||
@@ -5243,7 +5222,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
}
|
||||
|
||||
CodegenUtilKt.generateAsCast(
|
||||
v, rightKotlinType, boxedRightType, safeAs, state.getLanguageVersionSettings(), state.getUnifiedNullChecks()
|
||||
v, rightKotlinType, boxedRightType, safeAs, state.getUnifiedNullChecks()
|
||||
);
|
||||
|
||||
return Unit.INSTANCE;
|
||||
@@ -5297,7 +5276,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
return null;
|
||||
}
|
||||
|
||||
CodegenUtilKt.generateIsCheck(v, rhsKotlinType, type, state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines));
|
||||
CodegenUtilKt.generateIsCheck(v, rhsKotlinType, type);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -481,8 +481,7 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
if (!functionDescriptor.isExternal()) {
|
||||
generateMethodBody(mv, functionDescriptor, methodContext, jvmSignature, strategy, memberCodegen, state.getJvmDefaultMode(),
|
||||
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines));
|
||||
generateMethodBody(mv, functionDescriptor, methodContext, jvmSignature, strategy, memberCodegen, state.getJvmDefaultMode());
|
||||
}
|
||||
else if (staticInCompanionObject) {
|
||||
// native @JvmStatic foo() in companion object should delegate to the static native function moved to the outer class
|
||||
@@ -583,8 +582,7 @@ public class FunctionCodegen {
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull FunctionGenerationStrategy strategy,
|
||||
@NotNull MemberCodegen<?> parentCodegen,
|
||||
@NotNull JvmDefaultMode jvmDefaultMode,
|
||||
boolean isReleaseCoroutines
|
||||
@NotNull JvmDefaultMode jvmDefaultMode
|
||||
) {
|
||||
mv.visitCode();
|
||||
|
||||
@@ -594,8 +592,7 @@ public class FunctionCodegen {
|
||||
KotlinTypeMapper typeMapper = parentCodegen.typeMapper;
|
||||
if (BuiltinSpecialBridgesUtil.shouldHaveTypeSafeBarrier(functionDescriptor, typeMapper::mapAsmMethod)) {
|
||||
generateTypeCheckBarrierIfNeeded(
|
||||
new InstructionAdapter(mv), functionDescriptor, signature.getReturnType(), null, typeMapper,
|
||||
isReleaseCoroutines);
|
||||
new InstructionAdapter(mv), functionDescriptor, signature.getReturnType(), null, typeMapper);
|
||||
}
|
||||
|
||||
Label methodEntry = null;
|
||||
@@ -1430,8 +1427,7 @@ public class FunctionCodegen {
|
||||
MemberCodegen.markLineNumberForDescriptor(owner.getThisDescriptor(), iv);
|
||||
|
||||
if (delegateTo.getArgumentTypes().length > 0 && isSpecialBridge) {
|
||||
generateTypeCheckBarrierIfNeeded(iv, descriptor, bridge.getReturnType(), delegateTo.getArgumentTypes(), typeMapper,
|
||||
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines));
|
||||
generateTypeCheckBarrierIfNeeded(iv, descriptor, bridge.getReturnType(), delegateTo.getArgumentTypes(), typeMapper);
|
||||
}
|
||||
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
@@ -1477,8 +1473,7 @@ public class FunctionCodegen {
|
||||
@NotNull FunctionDescriptor descriptor,
|
||||
@NotNull Type returnType,
|
||||
@Nullable Type[] delegateParameterTypes,
|
||||
@NotNull KotlinTypeMapper typeMapper,
|
||||
boolean isReleaseCoroutines
|
||||
@NotNull KotlinTypeMapper typeMapper
|
||||
) {
|
||||
BuiltinMethodsWithSpecialGenericSignature.TypeSafeBarrierDescription typeSafeBarrierDescription =
|
||||
BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(descriptor);
|
||||
@@ -1512,7 +1507,7 @@ public class FunctionCodegen {
|
||||
} else {
|
||||
targetBoxedType = boxType(delegateParameterTypes[i]);
|
||||
}
|
||||
CodegenUtilKt.generateIsCheck(iv, kotlinType, targetBoxedType, isReleaseCoroutines);
|
||||
CodegenUtilKt.generateIsCheck(iv, kotlinType, targetBoxedType);
|
||||
iv.ifeq(defaultBranch);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.builtins.createFunctionType
|
||||
import org.jetbrains.kotlin.codegen.coroutines.coroutinesJvmInternalPackageFqName
|
||||
import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView
|
||||
import org.jetbrains.kotlin.codegen.coroutines.isSuspendLambdaOrLocalFunction
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
@@ -33,8 +32,7 @@ class JvmRuntimeTypes(
|
||||
private val generateOptimizedCallableReferenceSuperClasses: Boolean
|
||||
) {
|
||||
private val kotlinJvmInternalPackage = MutablePackageFragmentDescriptor(module, FqName("kotlin.jvm.internal"))
|
||||
private val kotlinCoroutinesJvmInternalPackage =
|
||||
MutablePackageFragmentDescriptor(module, languageVersionSettings.coroutinesJvmInternalPackageFqName())
|
||||
private val kotlinCoroutinesJvmInternalPackage = MutablePackageFragmentDescriptor(module, COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME)
|
||||
|
||||
private fun internal(className: String, packageFragment: PackageFragmentDescriptor = kotlinJvmInternalPackage): Lazy<ClassDescriptor> =
|
||||
lazy { createClass(packageFragment, className) }
|
||||
@@ -53,24 +51,16 @@ class JvmRuntimeTypes(
|
||||
private val localVariableReference: ClassDescriptor by internal("LocalVariableReference")
|
||||
private val mutableLocalVariableReference: ClassDescriptor by internal("MutableLocalVariableReference")
|
||||
|
||||
private val coroutineImpl: ClassDescriptor by internal("CoroutineImpl", kotlinCoroutinesJvmInternalPackage)
|
||||
private val continuationImpl: ClassDescriptor by coroutinesInternal("ContinuationImpl")
|
||||
private val restrictedContinuationImpl: ClassDescriptor by coroutinesInternal("RestrictedContinuationImpl")
|
||||
private val suspendLambda: ClassDescriptor by coroutinesInternal("SuspendLambda")
|
||||
private val restrictedSuspendLambda: ClassDescriptor by coroutinesInternal("RestrictedSuspendLambda")
|
||||
|
||||
private val suspendFunctionInterface: ClassDescriptor? by lazy {
|
||||
if (languageVersionSettings.isReleaseCoroutines())
|
||||
createClass(kotlinCoroutinesJvmInternalPackage, "SuspendFunction", ClassKind.INTERFACE)
|
||||
else null
|
||||
createClass(kotlinCoroutinesJvmInternalPackage, "SuspendFunction", ClassKind.INTERFACE)
|
||||
}
|
||||
|
||||
private fun createCoroutineSuperClass(className: String): ClassDescriptor {
|
||||
return if (languageVersionSettings.isReleaseCoroutines())
|
||||
createClass(kotlinCoroutinesJvmInternalPackage, className)
|
||||
else
|
||||
coroutineImpl
|
||||
}
|
||||
private fun createCoroutineSuperClass(className: String): ClassDescriptor = createClass(kotlinCoroutinesJvmInternalPackage, className)
|
||||
|
||||
private val propertyReferences: List<ClassDescriptor> by propertyClasses("PropertyReference", "")
|
||||
private val mutablePropertyReferences: List<ClassDescriptor> by propertyClasses("MutablePropertyReference", "")
|
||||
@@ -94,7 +84,7 @@ class JvmRuntimeTypes(
|
||||
fun getSupertypesForClosure(descriptor: FunctionDescriptor): Collection<KotlinType> {
|
||||
val actualFunctionDescriptor =
|
||||
if (descriptor.isSuspend)
|
||||
getOrCreateJvmSuspendFunctionView(descriptor, languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines))
|
||||
getOrCreateJvmSuspendFunctionView(descriptor)
|
||||
else
|
||||
descriptor
|
||||
|
||||
@@ -118,7 +108,7 @@ class JvmRuntimeTypes(
|
||||
if (descriptor.isSuspend) {
|
||||
return mutableListOf<KotlinType>().apply {
|
||||
if (actualFunctionDescriptor.extensionReceiverParameter?.type
|
||||
?.isRestrictsSuspensionReceiver(languageVersionSettings) == true
|
||||
?.isRestrictsSuspensionReceiver() == true
|
||||
) {
|
||||
if (descriptor.isSuspendLambdaOrLocalFunction()) {
|
||||
add(restrictedSuspendLambda.defaultType)
|
||||
|
||||
-49
@@ -477,7 +477,6 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
SimpleFunctionDescriptor jvmSuspendFunctionView =
|
||||
CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(
|
||||
functionDescriptor,
|
||||
languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines),
|
||||
this.bindingContext
|
||||
);
|
||||
|
||||
@@ -714,54 +713,6 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
super.visitCallExpression(expression);
|
||||
checkSamCall(expression);
|
||||
checkCrossinlineCall(expression);
|
||||
recordSuspendFunctionTypeWrapperForArguments(expression);
|
||||
}
|
||||
|
||||
private void recordSuspendFunctionTypeWrapperForArguments(@NotNull KtCallExpression expression) {
|
||||
ResolvedCall<?> call = CallUtilKt.getResolvedCall(expression, bindingContext);
|
||||
if (call == null) return;
|
||||
|
||||
CallableDescriptor descriptor = call.getResultingDescriptor();
|
||||
if (!CodegenUtilKt.needsExperimentalCoroutinesWrapper(descriptor)) return;
|
||||
|
||||
List<ResolvedValueArgument> argumentsByIndex = call.getValueArgumentsByIndex();
|
||||
if (argumentsByIndex == null) return;
|
||||
|
||||
for (ValueParameterDescriptor parameter : descriptor.getValueParameters()) {
|
||||
ResolvedValueArgument resolvedValueArgument = argumentsByIndex.get(parameter.getIndex());
|
||||
if (!(resolvedValueArgument instanceof ExpressionValueArgument)) continue;
|
||||
ValueArgument valueArgument = ((ExpressionValueArgument) resolvedValueArgument).getValueArgument();
|
||||
if (valueArgument == null) continue;
|
||||
KtExpression argumentExpression = valueArgument.getArgumentExpression();
|
||||
if (argumentExpression == null) continue;
|
||||
|
||||
recordSuspendFunctionTypeWrapperForArgument(parameter, argumentExpression);
|
||||
}
|
||||
|
||||
ReceiverValue receiver = call.getExtensionReceiver();
|
||||
if (descriptor.getExtensionReceiverParameter() != null && receiver instanceof ExpressionReceiver) {
|
||||
recordSuspendFunctionTypeWrapperForArgument(
|
||||
descriptor.getExtensionReceiverParameter(),
|
||||
((ExpressionReceiver) receiver).getExpression()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void recordSuspendFunctionTypeWrapperForArgument(ParameterDescriptor parameter, KtExpression argumentExpression) {
|
||||
if (FunctionTypesKt.isSuspendFunctionTypeOrSubtype(parameter.getType())) {
|
||||
|
||||
// SuspendFunctionN type is mapped to is mapped to FunctionTypeN+1, but we also need to remove an argument for return type
|
||||
// So, it could be parameter.getType().getArguments().size() + 1 - 1
|
||||
int functionTypeArity = parameter.getType().getArguments().size();
|
||||
|
||||
Type functionType = Type.getObjectType(NUMBERED_FUNCTION_PREFIX + functionTypeArity);
|
||||
|
||||
bindingTrace.record(
|
||||
FUNCTION_TYPE_FOR_SUSPEND_WRAPPER,
|
||||
argumentExpression,
|
||||
functionType
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkCrossinlineCall(@NotNull KtCallExpression expression) {
|
||||
|
||||
@@ -13,15 +13,13 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
|
||||
import org.jetbrains.kotlin.codegen.context.MultifileClassFacadeContext
|
||||
import org.jetbrains.kotlin.codegen.coroutines.continuationAsmType
|
||||
import org.jetbrains.kotlin.codegen.coroutines.CONTINUATION_ASM_TYPE
|
||||
import org.jetbrains.kotlin.codegen.coroutines.unwrapInitialDescriptorForSuspendFunction
|
||||
import org.jetbrains.kotlin.codegen.inline.NUMBERED_FUNCTION_PREFIX
|
||||
import org.jetbrains.kotlin.codegen.inline.ReificationArgument
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
@@ -45,8 +43,6 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.Synthetic
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor.CoroutinesCompatibilityMode
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||
@@ -70,8 +66,7 @@ internal val JAVA_LANG_DEPRECATED = Type.getType(Deprecated::class.java).descrip
|
||||
fun generateIsCheck(
|
||||
v: InstructionAdapter,
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type,
|
||||
isReleaseCoroutines: Boolean
|
||||
asmType: Type
|
||||
) {
|
||||
if (TypeUtils.isNullableType(kotlinType)) {
|
||||
val nope = Label()
|
||||
@@ -82,7 +77,7 @@ fun generateIsCheck(
|
||||
|
||||
ifnull(nope)
|
||||
|
||||
TypeIntrinsics.instanceOf(this, kotlinType, asmType, isReleaseCoroutines)
|
||||
TypeIntrinsics.instanceOf(this, kotlinType, asmType)
|
||||
|
||||
goTo(end)
|
||||
|
||||
@@ -93,7 +88,7 @@ fun generateIsCheck(
|
||||
mark(end)
|
||||
}
|
||||
} else {
|
||||
TypeIntrinsics.instanceOf(v, kotlinType, asmType, isReleaseCoroutines)
|
||||
TypeIntrinsics.instanceOf(v, kotlinType, asmType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +97,6 @@ fun generateAsCast(
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type,
|
||||
isSafe: Boolean,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
unifiedNullChecks: Boolean,
|
||||
) {
|
||||
if (!isSafe) {
|
||||
@@ -112,7 +106,7 @@ fun generateAsCast(
|
||||
} else {
|
||||
with(v) {
|
||||
dup()
|
||||
TypeIntrinsics.instanceOf(v, kotlinType, asmType, languageVersionSettings.isReleaseCoroutines())
|
||||
TypeIntrinsics.instanceOf(v, kotlinType, asmType)
|
||||
val ok = Label()
|
||||
ifne(ok)
|
||||
pop()
|
||||
@@ -444,14 +438,10 @@ fun KotlinType.isInlineClassTypeWithPrimitiveEquality(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
fun CallableDescriptor.needsExperimentalCoroutinesWrapper() =
|
||||
(this as? DeserializedMemberDescriptor)?.coroutinesExperimentalCompatibilityMode == CoroutinesCompatibilityMode.NEEDS_WRAPPER
|
||||
|
||||
fun recordCallLabelForLambdaArgument(declaration: KtFunctionLiteral, bindingTrace: BindingTrace) {
|
||||
val labelName = getCallLabelForLambdaArgument(declaration, bindingTrace.bindingContext) ?: return
|
||||
val functionDescriptor = bindingTrace[BindingContext.FUNCTION, declaration] ?: return
|
||||
bindingTrace.record(CodegenBinding.CALL_LABEL_FOR_LAMBDA_ARGUMENT, functionDescriptor, labelName)
|
||||
|
||||
}
|
||||
|
||||
fun getCallLabelForLambdaArgument(declaration: KtFunctionLiteral, bindingContext: BindingContext): String? {
|
||||
@@ -647,7 +637,7 @@ private fun generateLambdaForRunSuspend(
|
||||
}
|
||||
|
||||
visitVarInsn(ALOAD, 1)
|
||||
val continuationInternalName = state.languageVersionSettings.continuationAsmType().internalName
|
||||
val continuationInternalName = CONTINUATION_ASM_TYPE.internalName
|
||||
|
||||
visitTypeInsn(
|
||||
CHECKCAST,
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
package org.jetbrains.kotlin.codegen.context
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure
|
||||
import org.jetbrains.kotlin.config.coroutinesPackageFqName
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.isTopLevelInPackage
|
||||
@@ -17,25 +17,26 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getParentResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
|
||||
class InlineLambdaContext(
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
contextKind: OwnerKind,
|
||||
parentContext: CodegenContext<*>,
|
||||
closure: MutableClosure?,
|
||||
val isCrossInline: Boolean,
|
||||
private val isPropertyReference: Boolean
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
contextKind: OwnerKind,
|
||||
parentContext: CodegenContext<*>,
|
||||
closure: MutableClosure?,
|
||||
val isCrossInline: Boolean,
|
||||
private val isPropertyReference: Boolean
|
||||
) : MethodContext(functionDescriptor, contextKind, parentContext, closure, false) {
|
||||
|
||||
override fun getFirstCrossInlineOrNonInlineContext(): CodegenContext<*> {
|
||||
if (isCrossInline && !isSuspendIntrinsicParameter()) return this
|
||||
|
||||
val parent = if (isPropertyReference) parentContext as? AnonymousClassContext else { parentContext as? ClosureContext } ?:
|
||||
throw AssertionError(
|
||||
"Parent of inlining lambda body should be " +
|
||||
"${if (isPropertyReference) "ClosureContext" else "AnonymousClassContext"}, but: $parentContext"
|
||||
)
|
||||
val parent = if (isPropertyReference) parentContext as? AnonymousClassContext else {
|
||||
parentContext as? ClosureContext
|
||||
} ?: throw AssertionError(
|
||||
"Parent of inlining lambda body should be " +
|
||||
"${if (isPropertyReference) "ClosureContext" else "AnonymousClassContext"}, but: $parentContext"
|
||||
)
|
||||
|
||||
val grandParent = parent.parentContext ?:
|
||||
throw AssertionError("Parent context of lambda class context should exist: $contextDescriptor")
|
||||
val grandParent =
|
||||
parent.parentContext ?: throw AssertionError("Parent context of lambda class context should exist: $contextDescriptor")
|
||||
return grandParent.firstCrossInlineOrNonInlineContext
|
||||
}
|
||||
|
||||
@@ -44,7 +45,7 @@ class InlineLambdaContext(
|
||||
if (contextDescriptor !is AnonymousFunctionDescriptor) return false
|
||||
val resolvedCall = (contextDescriptor.source.getPsi() as? KtElement).getParentResolvedCall(state.bindingContext) ?: return false
|
||||
val descriptor = resolvedCall.resultingDescriptor as? FunctionDescriptor ?: return false
|
||||
return descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(state.languageVersionSettings)
|
||||
|| descriptor.isTopLevelInPackage("suspendCoroutine", state.languageVersionSettings.coroutinesPackageFqName().asString())
|
||||
return descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn()
|
||||
|| descriptor.isTopLevelInPackage("suspendCoroutine", StandardNames.COROUTINES_PACKAGE_FQ_NAME.asString())
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.coroutines
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.codegen.optimization.boxing.isPrimitiveBoxing
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
@@ -15,10 +16,9 @@ import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import java.util.*
|
||||
|
||||
private val BOXING_CLASS_INTERNAL_NAME =
|
||||
RELEASE_COROUTINES_VERSION_SETTINGS.coroutinesJvmInternalPackageFqName().child(Name.identifier("Boxing")).topLevelClassInternalName()
|
||||
StandardNames.COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.child(Name.identifier("Boxing")).topLevelClassInternalName()
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
object ChangeBoxingMethodTransformer : MethodTransformer() {
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.codegen.coroutines
|
||||
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA
|
||||
@@ -17,8 +18,6 @@ import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHO
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
@@ -41,7 +40,6 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
@@ -56,7 +54,7 @@ abstract class AbstractCoroutineCodegen(
|
||||
element: KtElement,
|
||||
closureContext: ClosureContext,
|
||||
classBuilder: ClassBuilder,
|
||||
private val userDataForDoResume: Map<out CallableDescriptor.UserDataKey<*>, *>? = null
|
||||
private val userDataForInvokeSuspend: Map<out CallableDescriptor.UserDataKey<*>, *>? = null
|
||||
) : ClosureCodegen(
|
||||
outerExpressionCodegen.state,
|
||||
element, null, closureContext, null,
|
||||
@@ -67,17 +65,10 @@ abstract class AbstractCoroutineCodegen(
|
||||
protected val languageVersionSettings = outerExpressionCodegen.state.languageVersionSettings
|
||||
|
||||
protected val methodToImplement =
|
||||
if (languageVersionSettings.isReleaseCoroutines())
|
||||
createImplMethod(
|
||||
INVOKE_SUSPEND_METHOD_NAME,
|
||||
SUSPEND_CALL_RESULT_NAME to classDescriptor.module.getResult(classDescriptor.builtIns.anyType)
|
||||
)
|
||||
else
|
||||
createImplMethod(
|
||||
DO_RESUME_METHOD_NAME,
|
||||
"data" to classDescriptor.builtIns.nullableAnyType,
|
||||
"throwable" to classDescriptor.builtIns.throwable.defaultType.makeNullable()
|
||||
)
|
||||
createImplMethod(
|
||||
INVOKE_SUSPEND_METHOD_NAME,
|
||||
SUSPEND_CALL_RESULT_NAME to classDescriptor.module.getResult(classDescriptor.builtIns.anyType)
|
||||
)
|
||||
|
||||
private fun createImplMethod(name: String, vararg parameters: Pair<String, KotlinType>) =
|
||||
SimpleFunctionDescriptorImpl.create(
|
||||
@@ -94,7 +85,7 @@ abstract class AbstractCoroutineCodegen(
|
||||
builtIns.nullableAnyType,
|
||||
Modality.FINAL,
|
||||
DescriptorVisibilities.PUBLIC,
|
||||
userDataForDoResume
|
||||
userDataForInvokeSuspend
|
||||
)
|
||||
}
|
||||
|
||||
@@ -109,7 +100,7 @@ abstract class AbstractCoroutineCodegen(
|
||||
|
||||
override fun generateConstructor(): Method {
|
||||
val args = calculateConstructorParameters(typeMapper, languageVersionSettings, closure, asmType)
|
||||
val argTypes = args.map { it.fieldType }.plus(languageVersionSettings.continuationAsmType()).toTypedArray()
|
||||
val argTypes = args.map { it.fieldType }.plus(CONTINUATION_ASM_TYPE).toTypedArray()
|
||||
|
||||
val constructor = Method("<init>", Type.VOID_TYPE, argTypes)
|
||||
val mv = v.newMethod(
|
||||
@@ -124,18 +115,17 @@ abstract class AbstractCoroutineCodegen(
|
||||
iv.generateClosureFieldsInitializationFromParameters(closure, args)
|
||||
|
||||
iv.load(0, AsmTypes.OBJECT_TYPE)
|
||||
val hasArityParameter = !languageVersionSettings.isReleaseCoroutines() || passArityToSuperClass
|
||||
if (hasArityParameter) {
|
||||
iv.iconst(if (passArityToSuperClass) funDescriptor.arity else 0)
|
||||
if (passArityToSuperClass) {
|
||||
iv.iconst(funDescriptor.arity)
|
||||
}
|
||||
|
||||
iv.load(argTypes.map { it.size }.sum(), AsmTypes.OBJECT_TYPE)
|
||||
|
||||
val parameters =
|
||||
if (hasArityParameter)
|
||||
listOf(Type.INT_TYPE, languageVersionSettings.continuationAsmType())
|
||||
if (passArityToSuperClass)
|
||||
listOf(Type.INT_TYPE, CONTINUATION_ASM_TYPE)
|
||||
else
|
||||
listOf(languageVersionSettings.continuationAsmType())
|
||||
listOf(CONTINUATION_ASM_TYPE)
|
||||
|
||||
val superClassConstructorDescriptor = Type.getMethodDescriptor(
|
||||
Type.VOID_TYPE,
|
||||
@@ -148,9 +138,7 @@ abstract class AbstractCoroutineCodegen(
|
||||
FunctionCodegen.endVisit(iv, "constructor", element)
|
||||
}
|
||||
|
||||
if (languageVersionSettings.isReleaseCoroutines()) {
|
||||
v.newField(JvmDeclarationOrigin.NO_ORIGIN, AsmUtil.NO_FLAG_PACKAGE_PRIVATE, "label", "I", null, null)
|
||||
}
|
||||
v.newField(JvmDeclarationOrigin.NO_ORIGIN, AsmUtil.NO_FLAG_PACKAGE_PRIVATE, "label", "I", null, null)
|
||||
|
||||
return constructor
|
||||
}
|
||||
@@ -167,7 +155,7 @@ class CoroutineCodegenForLambda private constructor(
|
||||
private val forInline: Boolean
|
||||
) : AbstractCoroutineCodegen(
|
||||
outerExpressionCodegen, element, closureContext, classBuilder,
|
||||
userDataForDoResume = mapOf(INITIAL_SUSPEND_DESCRIPTOR_FOR_DO_RESUME to originalSuspendFunctionDescriptor)
|
||||
userDataForInvokeSuspend = mapOf(INITIAL_SUSPEND_DESCRIPTOR_FOR_INVOKE_SUSPEND to originalSuspendFunctionDescriptor)
|
||||
) {
|
||||
private val builtIns = funDescriptor.builtIns
|
||||
|
||||
@@ -215,8 +203,7 @@ class CoroutineCodegenForLambda private constructor(
|
||||
funDescriptor.typeParameters,
|
||||
funDescriptor.valueParameters,
|
||||
funDescriptor.module.getContinuationOfTypeOrAny(
|
||||
builtIns.unitType,
|
||||
state.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
|
||||
builtIns.unitType
|
||||
),
|
||||
funDescriptor.modality,
|
||||
DescriptorVisibilities.PUBLIC
|
||||
@@ -231,14 +218,11 @@ class CoroutineCodegenForLambda private constructor(
|
||||
"too many arguments of create to have an erased signature: $argumentsNum: $typedCreate"
|
||||
}
|
||||
return typedCreate.module.resolveClassByFqName(
|
||||
languageVersionSettings.coroutinesJvmInternalPackageFqName().child(
|
||||
if (languageVersionSettings.isReleaseCoroutines())
|
||||
Name.identifier("BaseContinuationImpl")
|
||||
else
|
||||
Name.identifier("CoroutineImpl")
|
||||
StandardNames.COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.child(
|
||||
Name.identifier("BaseContinuationImpl")
|
||||
),
|
||||
NoLookupLocation.FROM_BACKEND
|
||||
).sure { "BaseContinuationImpl or CoroutineImpl is not found" }.defaultType.memberScope
|
||||
).sure { "BaseContinuationImpl is not found" }.defaultType.memberScope
|
||||
.getContributedFunctions(typedCreate.name, NoLookupLocation.FROM_BACKEND)
|
||||
.find { it.valueParameters.size == argumentsNum }
|
||||
.sure { "erased parent of $typedCreate is not found" }
|
||||
@@ -365,7 +349,7 @@ class CoroutineCodegenForLambda private constructor(
|
||||
v.thisName,
|
||||
typeMapper.mapFunctionName(createCoroutineDescriptor, null),
|
||||
Type.getMethodDescriptor(
|
||||
languageVersionSettings.continuationAsmType(),
|
||||
CONTINUATION_ASM_TYPE,
|
||||
*createArgumentTypes.toTypedArray()
|
||||
),
|
||||
false
|
||||
@@ -373,11 +357,7 @@ class CoroutineCodegenForLambda private constructor(
|
||||
checkcast(Type.getObjectType(v.thisName))
|
||||
|
||||
// .doResume(Unit)
|
||||
if (languageVersionSettings.isReleaseCoroutines()) {
|
||||
invokeInvokeSuspendWithUnit(v.thisName)
|
||||
} else {
|
||||
invokeDoResumeWithUnit(v.thisName)
|
||||
}
|
||||
invokeInvokeSuspendWithUnit(v.thisName)
|
||||
areturn(AsmTypes.OBJECT_TYPE)
|
||||
}
|
||||
|
||||
@@ -540,15 +520,14 @@ class CoroutineCodegenForLambda private constructor(
|
||||
override fun wrapMethodVisitor(mv: MethodVisitor, access: Int, name: String, desc: String): MethodVisitor {
|
||||
val stateMachineBuilder = CoroutineTransformerMethodVisitor(
|
||||
mv, access, name, desc, null, null,
|
||||
containingClassInternalName = v.thisName,
|
||||
obtainClassBuilderForCoroutineState = { v },
|
||||
isForNamedFunction = false,
|
||||
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
disableTailCallOptimizationForFunctionReturningUnit = false,
|
||||
reportSuspensionPointInsideMonitor = { reportSuspensionPointInsideMonitor(element, state, it) },
|
||||
lineNumber = CodegenUtil.getLineNumberForElement(element, false) ?: 0,
|
||||
sourceFile = element.containingKtFile.name,
|
||||
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
containingClassInternalName = v.thisName,
|
||||
isForNamedFunction = false,
|
||||
languageVersionSettings = languageVersionSettings,
|
||||
disableTailCallOptimizationForFunctionReturningUnit = false,
|
||||
useOldSpilledVarTypeAnalysis = state.configuration.getBoolean(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS),
|
||||
initialVarsCountByType = varsCountByType
|
||||
)
|
||||
@@ -625,7 +604,7 @@ class CoroutineCodegenForNamedFunction private constructor(
|
||||
private val labelFieldStackValue by lazy {
|
||||
StackValue.field(
|
||||
FieldInfo.createForHiddenField(
|
||||
computeLabelOwner(languageVersionSettings, v.thisName),
|
||||
Type.getObjectType(v.thisName),
|
||||
Type.INT_TYPE,
|
||||
COROUTINE_LABEL_FIELD_NAME
|
||||
),
|
||||
@@ -647,44 +626,25 @@ class CoroutineCodegenForNamedFunction private constructor(
|
||||
}
|
||||
|
||||
override fun generateClosureBody() {
|
||||
generateResumeImpl()
|
||||
|
||||
if (!languageVersionSettings.isReleaseCoroutines()) {
|
||||
generateGetLabelMethod()
|
||||
generateSetLabelMethod()
|
||||
}
|
||||
generateInvokeSuspend()
|
||||
|
||||
v.newField(
|
||||
JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_SYNTHETIC or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
||||
languageVersionSettings.dataFieldName(), AsmTypes.OBJECT_TYPE.descriptor, null, null
|
||||
CONTINUATION_RESULT_FIELD_NAME, AsmTypes.OBJECT_TYPE.descriptor, null, null
|
||||
)
|
||||
|
||||
if (!languageVersionSettings.isReleaseCoroutines()) {
|
||||
v.newField(
|
||||
JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_SYNTHETIC or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
||||
EXCEPTION_FIELD_NAME, AsmTypes.JAVA_THROWABLE_TYPE.descriptor, null, null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateResumeImpl() {
|
||||
private fun generateInvokeSuspend() {
|
||||
functionCodegen.generateMethod(
|
||||
OtherOrigin(element),
|
||||
methodToImplement,
|
||||
object : FunctionGenerationStrategy.CodegenBased(state) {
|
||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||
StackValue.field(
|
||||
AsmTypes.OBJECT_TYPE, Type.getObjectType(v.thisName), languageVersionSettings.dataFieldName(), false,
|
||||
AsmTypes.OBJECT_TYPE, Type.getObjectType(v.thisName), CONTINUATION_RESULT_FIELD_NAME, false,
|
||||
StackValue.LOCAL_0
|
||||
).store(StackValue.local(1, AsmTypes.OBJECT_TYPE), codegen.v)
|
||||
|
||||
if (!languageVersionSettings.isReleaseCoroutines()) {
|
||||
StackValue.field(
|
||||
AsmTypes.JAVA_THROWABLE_TYPE, Type.getObjectType(v.thisName), EXCEPTION_FIELD_NAME, false,
|
||||
StackValue.LOCAL_0
|
||||
).store(StackValue.local(2, AsmTypes.JAVA_THROWABLE_TYPE), codegen.v)
|
||||
}
|
||||
|
||||
labelFieldStackValue.store(
|
||||
StackValue.operation(Type.INT_TYPE) {
|
||||
labelFieldStackValue.put(Type.INT_TYPE, it)
|
||||
@@ -736,7 +696,7 @@ class CoroutineCodegenForNamedFunction private constructor(
|
||||
with(codegen.v) {
|
||||
// We need to box the returned inline class in resume path.
|
||||
// But first, check for COROUTINE_SUSPENDED, since the function can return it
|
||||
generateCoroutineSuspendedCheck(languageVersionSettings)
|
||||
generateCoroutineSuspendedCheck()
|
||||
// Now we box the inline class
|
||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, typeMapper.mapType(inlineClassToBoxInInvokeSuspend), this)
|
||||
StackValue.boxInlineClass(inlineClassToBoxInInvokeSuspend, this, typeMapper)
|
||||
|
||||
+27
-79
@@ -9,15 +9,10 @@ import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.inline.*
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.*
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||
@@ -49,7 +44,6 @@ class CoroutineTransformerMethodVisitor(
|
||||
obtainClassBuilderForCoroutineState: () -> ClassBuilder,
|
||||
private val isForNamedFunction: Boolean,
|
||||
private val shouldPreserveClassInitialization: Boolean,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
// Since tail-call optimization of functions with Unit return type relies on ability of call-site to recognize them,
|
||||
// in order to ignore return value and push Unit, when we cannot ensure this ability, for example, when the function overrides function,
|
||||
// returning Any, we need to disable tail-call optimization for these functions.
|
||||
@@ -73,7 +67,6 @@ class CoroutineTransformerMethodVisitor(
|
||||
|
||||
private var continuationIndex = if (isForNamedFunction) -1 else 0
|
||||
private var dataIndex = if (isForNamedFunction) -1 else 1
|
||||
private var exceptionIndex = if (isForNamedFunction || languageVersionSettings.isReleaseCoroutines()) -1 else 2
|
||||
|
||||
override fun performTransformations(methodNode: MethodNode) {
|
||||
removeFakeContinuationConstructorCall(methodNode)
|
||||
@@ -89,9 +82,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
val suspensionPoints = collectSuspensionPoints(methodNode)
|
||||
RedundantLocalsEliminationMethodTransformer(suspensionPoints)
|
||||
.transform(containingClassInternalName, methodNode)
|
||||
if (languageVersionSettings.isReleaseCoroutines()) {
|
||||
ChangeBoxingMethodTransformer.transform(containingClassInternalName, methodNode)
|
||||
}
|
||||
ChangeBoxingMethodTransformer.transform(containingClassInternalName, methodNode)
|
||||
updateMaxStack(methodNode)
|
||||
|
||||
checkForSuspensionPointInsideMonitor(methodNode, suspensionPoints)
|
||||
@@ -105,7 +96,6 @@ class CoroutineTransformerMethodVisitor(
|
||||
}
|
||||
|
||||
val examiner = MethodNodeExaminer(
|
||||
languageVersionSettings,
|
||||
containingClassInternalName,
|
||||
methodNode,
|
||||
suspensionPoints,
|
||||
@@ -119,9 +109,6 @@ class CoroutineTransformerMethodVisitor(
|
||||
}
|
||||
|
||||
dataIndex = methodNode.maxLocals++
|
||||
if (!languageVersionSettings.isReleaseCoroutines()) {
|
||||
exceptionIndex = methodNode.maxLocals++
|
||||
}
|
||||
continuationIndex = methodNode.maxLocals++
|
||||
|
||||
prepareMethodNodePreludeForNamedFunction(methodNode)
|
||||
@@ -158,7 +145,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
insertBefore(
|
||||
actualCoroutineStart,
|
||||
insnListOf(
|
||||
*withInstructionAdapter { loadCoroutineSuspendedMarker(languageVersionSettings) }.toArray(),
|
||||
*withInstructionAdapter { loadCoroutineSuspendedMarker() }.toArray(),
|
||||
tableSwitchLabel,
|
||||
// Allow debugger to stop on enter into suspend function
|
||||
LineNumberNode(lineNumber, tableSwitchLabel),
|
||||
@@ -176,7 +163,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
)
|
||||
|
||||
insert(firstStateLabel, withInstructionAdapter {
|
||||
generateResumeWithExceptionCheck(languageVersionSettings.isReleaseCoroutines(), dataIndex, exceptionIndex)
|
||||
generateResumeWithExceptionCheck(dataIndex)
|
||||
})
|
||||
insert(last, defaultLabel)
|
||||
|
||||
@@ -194,9 +181,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
|
||||
updateLvtAccordingToLiveness(methodNode, isForNamedFunction, stateLabels)
|
||||
|
||||
if (languageVersionSettings.isReleaseCoroutines()) {
|
||||
writeDebugMetadata(methodNode, suspensionPointLineNumbers, spilledToVariableMapping)
|
||||
}
|
||||
writeDebugMetadata(methodNode, suspensionPointLineNumbers, spilledToVariableMapping)
|
||||
}
|
||||
|
||||
// When suspension point is inlined, it is in range of fake inliner variables.
|
||||
@@ -263,7 +248,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
methodNode.localVariables.add(
|
||||
LocalVariableNode(
|
||||
SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME,
|
||||
languageVersionSettings.continuationAsmType().descriptor,
|
||||
CONTINUATION_ASM_TYPE.descriptor,
|
||||
null,
|
||||
startLabel,
|
||||
endLabel,
|
||||
@@ -402,7 +387,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
methodNode.instructions.add(withInstructionAdapter { mark(endLabel) })
|
||||
methodNode.visitLocalVariable(
|
||||
CONTINUATION_VARIABLE_NAME,
|
||||
languageVersionSettings.continuationAsmType().descriptor,
|
||||
CONTINUATION_ASM_TYPE.descriptor,
|
||||
null,
|
||||
startLabel,
|
||||
endLabel,
|
||||
@@ -430,33 +415,17 @@ class CoroutineTransformerMethodVisitor(
|
||||
}
|
||||
|
||||
private fun InstructionAdapter.getLabel() {
|
||||
if (isForNamedFunction && !languageVersionSettings.isReleaseCoroutines())
|
||||
invokevirtual(
|
||||
classBuilderForCoroutineState.thisName,
|
||||
"getLabel",
|
||||
Type.getMethodDescriptor(Type.INT_TYPE),
|
||||
false
|
||||
)
|
||||
else
|
||||
getfield(
|
||||
computeLabelOwner(languageVersionSettings, classBuilderForCoroutineState.thisName).internalName,
|
||||
COROUTINE_LABEL_FIELD_NAME, Type.INT_TYPE.descriptor
|
||||
)
|
||||
getfield(
|
||||
Type.getObjectType(classBuilderForCoroutineState.thisName).internalName,
|
||||
COROUTINE_LABEL_FIELD_NAME, Type.INT_TYPE.descriptor
|
||||
)
|
||||
}
|
||||
|
||||
private fun InstructionAdapter.setLabel() {
|
||||
if (isForNamedFunction && !languageVersionSettings.isReleaseCoroutines())
|
||||
invokevirtual(
|
||||
classBuilderForCoroutineState.thisName,
|
||||
"setLabel",
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE),
|
||||
false
|
||||
)
|
||||
else
|
||||
putfield(
|
||||
computeLabelOwner(languageVersionSettings, classBuilderForCoroutineState.thisName).internalName,
|
||||
COROUTINE_LABEL_FIELD_NAME, Type.INT_TYPE.descriptor
|
||||
)
|
||||
putfield(
|
||||
Type.getObjectType(classBuilderForCoroutineState.thisName).internalName,
|
||||
COROUTINE_LABEL_FIELD_NAME, Type.INT_TYPE.descriptor
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateMaxStack(methodNode: MethodNode) {
|
||||
@@ -534,8 +503,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
needDispatchReceiver,
|
||||
internalNameForDispatchReceiver,
|
||||
containingClassInternalName,
|
||||
classBuilderForCoroutineState,
|
||||
languageVersionSettings
|
||||
classBuilderForCoroutineState
|
||||
)
|
||||
|
||||
visitVarInsn(Opcodes.ASTORE, continuationIndex)
|
||||
@@ -543,19 +511,13 @@ class CoroutineTransformerMethodVisitor(
|
||||
visitLabel(afterCoroutineStateCreated)
|
||||
|
||||
visitVarInsn(Opcodes.ALOAD, continuationIndex)
|
||||
getfield(classBuilderForCoroutineState.thisName, languageVersionSettings.dataFieldName(), AsmTypes.OBJECT_TYPE.descriptor)
|
||||
getfield(classBuilderForCoroutineState.thisName, CONTINUATION_RESULT_FIELD_NAME, AsmTypes.OBJECT_TYPE.descriptor)
|
||||
visitVarInsn(Opcodes.ASTORE, dataIndex)
|
||||
|
||||
val resultStartLabel = Label()
|
||||
visitLabel(resultStartLabel)
|
||||
|
||||
addContinuationAndResultToLvt(methodNode, afterCoroutineStateCreated, resultStartLabel)
|
||||
|
||||
if (!languageVersionSettings.isReleaseCoroutines()) {
|
||||
visitVarInsn(Opcodes.ALOAD, continuationIndex)
|
||||
getfield(classBuilderForCoroutineState.thisName, EXCEPTION_FIELD_NAME, AsmTypes.JAVA_THROWABLE_TYPE.descriptor)
|
||||
visitVarInsn(Opcodes.ASTORE, exceptionIndex)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -692,7 +654,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
// k + 1 - data
|
||||
// k + 2 - exception
|
||||
for (slot in 0 until localsCount) {
|
||||
if (slot == continuationIndex || slot == dataIndex || slot == exceptionIndex) continue
|
||||
if (slot == continuationIndex || slot == dataIndex) continue
|
||||
val value = frame.getLocal(slot)
|
||||
if (value.type == null || !livenessFrame.isAlive(slot)) continue
|
||||
|
||||
@@ -992,7 +954,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
|
||||
insert(possibleTryCatchBlockStart, withInstructionAdapter {
|
||||
nop()
|
||||
generateResumeWithExceptionCheck(languageVersionSettings.isReleaseCoroutines(), dataIndex, exceptionIndex)
|
||||
generateResumeWithExceptionCheck(dataIndex)
|
||||
|
||||
// Load continuation argument just like suspending function returns it
|
||||
load(dataIndex, AsmTypes.OBJECT_TYPE)
|
||||
@@ -1118,8 +1080,7 @@ internal fun InstructionAdapter.generateContinuationConstructorCall(
|
||||
needDispatchReceiver: Boolean,
|
||||
internalNameForDispatchReceiver: String?,
|
||||
containingClassInternalName: String,
|
||||
classBuilderForCoroutineState: ClassBuilder,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
classBuilderForCoroutineState: ClassBuilder
|
||||
) {
|
||||
anew(objectTypeForState)
|
||||
dup()
|
||||
@@ -1128,8 +1089,7 @@ internal fun InstructionAdapter.generateContinuationConstructorCall(
|
||||
getParameterTypesIndicesForCoroutineConstructor(
|
||||
methodNode.desc,
|
||||
methodNode.access,
|
||||
needDispatchReceiver, internalNameForDispatchReceiver ?: containingClassInternalName,
|
||||
languageVersionSettings
|
||||
needDispatchReceiver, internalNameForDispatchReceiver ?: containingClassInternalName
|
||||
)
|
||||
for ((type, index) in parameterTypesAndIndices) {
|
||||
load(index, type)
|
||||
@@ -1149,22 +1109,11 @@ internal fun InstructionAdapter.generateContinuationConstructorCall(
|
||||
)
|
||||
}
|
||||
|
||||
private fun InstructionAdapter.generateResumeWithExceptionCheck(isReleaseCoroutines: Boolean, dataIndex: Int, exceptionIndex: Int) {
|
||||
private fun InstructionAdapter.generateResumeWithExceptionCheck(dataIndex: Int) {
|
||||
// Check if resumeWithException has been called
|
||||
|
||||
if (isReleaseCoroutines) {
|
||||
load(dataIndex, AsmTypes.OBJECT_TYPE)
|
||||
invokestatic("kotlin/ResultKt", "throwOnFailure", "(Ljava/lang/Object;)V", false)
|
||||
} else {
|
||||
load(exceptionIndex, AsmTypes.OBJECT_TYPE)
|
||||
dup()
|
||||
val noExceptionLabel = Label()
|
||||
ifnull(noExceptionLabel)
|
||||
athrow()
|
||||
|
||||
mark(noExceptionLabel)
|
||||
pop()
|
||||
}
|
||||
load(dataIndex, AsmTypes.OBJECT_TYPE)
|
||||
invokestatic("kotlin/ResultKt", "throwOnFailure", "(Ljava/lang/Object;)V", false)
|
||||
}
|
||||
|
||||
private fun Type.fieldNameForVar(index: Int) = descriptor.first() + "$" + index
|
||||
@@ -1235,16 +1184,15 @@ private fun getParameterTypesIndicesForCoroutineConstructor(
|
||||
desc: String,
|
||||
containingFunctionAccess: Int,
|
||||
needDispatchReceiver: Boolean,
|
||||
thisName: String,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
thisName: String
|
||||
): Collection<Pair<Type, Int>> {
|
||||
return mutableListOf<Pair<Type, Int>>().apply {
|
||||
if (needDispatchReceiver) {
|
||||
add(Type.getObjectType(thisName) to 0)
|
||||
}
|
||||
val continuationIndex =
|
||||
getAllParameterTypes(desc, !isStatic(containingFunctionAccess), thisName).dropLast(1).map(Type::getSize).sum()
|
||||
add(languageVersionSettings.continuationAsmType() to continuationIndex)
|
||||
getAllParameterTypes(desc, !isStatic(containingFunctionAccess), thisName).dropLast(1).sumOf(Type::getSize)
|
||||
add(CONTINUATION_ASM_TYPE to continuationIndex)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-7
@@ -88,18 +88,17 @@ class SuspendFunctionGenerationStrategy(
|
||||
return CoroutineTransformerMethodVisitor(
|
||||
mv, access, name, desc, null, null, containingClassInternalName, this::classBuilderForCoroutineState,
|
||||
isForNamedFunction = true,
|
||||
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
disableTailCallOptimizationForFunctionReturningUnit = originalSuspendDescriptor.returnType?.isUnit() == true &&
|
||||
originalSuspendDescriptor.overriddenDescriptors.isNotEmpty() &&
|
||||
!originalSuspendDescriptor.allOverriddenFunctionsReturnUnit(),
|
||||
reportSuspensionPointInsideMonitor = { reportSuspensionPointInsideMonitor(declaration, state, it) },
|
||||
lineNumber = CodegenUtil.getLineNumberForElement(declaration, false) ?: 0,
|
||||
sourceFile = declaration.containingKtFile.name,
|
||||
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null,
|
||||
internalNameForDispatchReceiver = (originalSuspendDescriptor.containingDeclaration as? ClassDescriptor)?.let {
|
||||
if (it.isInlineClass()) state.typeMapper.mapType(it).internalName else null
|
||||
} ?: containingClassInternalNameOrNull(),
|
||||
languageVersionSettings = languageVersionSettings,
|
||||
disableTailCallOptimizationForFunctionReturningUnit = originalSuspendDescriptor.returnType?.isUnit() == true &&
|
||||
originalSuspendDescriptor.overriddenDescriptors.isNotEmpty() &&
|
||||
!originalSuspendDescriptor.allOverriddenFunctionsReturnUnit(),
|
||||
useOldSpilledVarTypeAnalysis = state.configuration.getBoolean(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS)
|
||||
)
|
||||
}
|
||||
@@ -155,8 +154,7 @@ class SuspendFunctionGenerationStrategy(
|
||||
needDispatchReceiver,
|
||||
internalNameForDispatchReceiver,
|
||||
containingClassInternalName,
|
||||
classBuilderForCoroutineState,
|
||||
languageVersionSettings
|
||||
classBuilderForCoroutineState
|
||||
)
|
||||
addFakeContinuationConstructorCallMarker(this, false)
|
||||
pop() // Otherwise stack-transformation breaks
|
||||
|
||||
+1
-3
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
|
||||
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.utils.sure
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
@@ -27,7 +26,6 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
||||
|
||||
internal class MethodNodeExaminer(
|
||||
val languageVersionSettings: LanguageVersionSettings,
|
||||
containingClassInternalName: String,
|
||||
val methodNode: MethodNode,
|
||||
suspensionPoints: List<SuspensionPoint>,
|
||||
@@ -116,7 +114,7 @@ internal class MethodNodeExaminer(
|
||||
val label = Label()
|
||||
methodNode.instructions.insertBefore(pop, withInstructionAdapter {
|
||||
dup()
|
||||
loadCoroutineSuspendedMarker(languageVersionSettings)
|
||||
loadCoroutineSuspendedMarker()
|
||||
ifacmpne(label)
|
||||
areturn(AsmTypes.OBJECT_TYPE)
|
||||
mark(label)
|
||||
|
||||
+58
-156
@@ -9,6 +9,8 @@ import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.backend.common.COROUTINE_SUSPENDED_NAME
|
||||
import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalClassDescriptor
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
@@ -54,67 +56,27 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
const val COROUTINE_LABEL_FIELD_NAME = "label"
|
||||
const val SUSPEND_FUNCTION_CREATE_METHOD_NAME = "create"
|
||||
const val DO_RESUME_METHOD_NAME = "doResume"
|
||||
const val INVOKE_SUSPEND_METHOD_NAME = "invokeSuspend"
|
||||
const val EXCEPTION_FIELD_NAME = "exception"
|
||||
const val CONTINUATION_RESULT_FIELD_NAME = "result"
|
||||
|
||||
val RELEASE_COROUTINES_VERSION_SETTINGS = LanguageVersionSettingsImpl(LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3)
|
||||
private const val GET_CONTEXT_METHOD_NAME = "getContext"
|
||||
|
||||
fun LanguageVersionSettings.isResumeImplMethodName(name: String) =
|
||||
if (isReleaseCoroutines())
|
||||
name == INVOKE_SUSPEND_METHOD_NAME
|
||||
else
|
||||
name == DO_RESUME_METHOD_NAME
|
||||
val DEBUG_METADATA_ANNOTATION_ASM_TYPE: Type =
|
||||
COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.child(Name.identifier("DebugMetadata")).topLevelClassAsmType()
|
||||
|
||||
fun LanguageVersionSettings.dataFieldName(): String = if (isReleaseCoroutines()) "result" else "data"
|
||||
fun coroutineContextAsmType(): Type =
|
||||
StandardNames.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineContext")).topLevelClassAsmType()
|
||||
|
||||
fun isResumeImplMethodNameFromAnyLanguageSettings(name: String) = name == INVOKE_SUSPEND_METHOD_NAME || name == DO_RESUME_METHOD_NAME
|
||||
|
||||
fun LanguageVersionSettings.coroutinesJvmInternalPackageFqName() =
|
||||
coroutinesPackageFqName().child(Name.identifier("jvm")).child(Name.identifier("internal"))
|
||||
|
||||
val DEBUG_METADATA_ANNOTATION_ASM_TYPE = RELEASE_COROUTINES_VERSION_SETTINGS.coroutinesJvmInternalPackageFqName()
|
||||
.child(Name.identifier("DebugMetadata")).topLevelClassAsmType()
|
||||
|
||||
fun LanguageVersionSettings.continuationAsmType() =
|
||||
continuationInterfaceFqName().topLevelClassAsmType()
|
||||
|
||||
fun continuationAsmTypes() = listOf(
|
||||
LanguageVersionSettingsImpl(LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3).continuationAsmType(),
|
||||
LanguageVersionSettingsImpl(LanguageVersion.KOTLIN_1_2, ApiVersion.KOTLIN_1_2).continuationAsmType()
|
||||
)
|
||||
|
||||
fun LanguageVersionSettings.coroutineContextAsmType() =
|
||||
coroutinesPackageFqName().child(Name.identifier("CoroutineContext")).topLevelClassAsmType()
|
||||
|
||||
fun LanguageVersionSettings.isCoroutineSuperClass(internalName: String): Boolean {
|
||||
val coroutinesJvmInternalPackage = coroutinesJvmInternalPackageFqName()
|
||||
|
||||
return if (isReleaseCoroutines())
|
||||
coroutinesJvmInternalPackage.identifiedChild("ContinuationImpl") == internalName ||
|
||||
coroutinesJvmInternalPackage.identifiedChild("RestrictedContinuationImpl") == internalName ||
|
||||
coroutinesJvmInternalPackage.identifiedChild("SuspendLambda") == internalName ||
|
||||
coroutinesJvmInternalPackage.identifiedChild("RestrictedSuspendLambda") == internalName
|
||||
else
|
||||
coroutinesJvmInternalPackage.identifiedChild("CoroutineImpl") == internalName
|
||||
}
|
||||
fun String.isCoroutineSuperClass(): Boolean =
|
||||
COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.identifiedChild("ContinuationImpl") == this ||
|
||||
COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.identifiedChild("RestrictedContinuationImpl") == this ||
|
||||
COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.identifiedChild("SuspendLambda") == this ||
|
||||
COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.identifiedChild("RestrictedSuspendLambda") == this
|
||||
|
||||
private fun FqName.identifiedChild(name: String) = child(Name.identifier(name)).topLevelClassInternalName()
|
||||
|
||||
private fun LanguageVersionSettings.coroutinesIntrinsicsFileFacadeInternalName() =
|
||||
coroutinesIntrinsicsPackageFqName().child(Name.identifier("IntrinsicsKt")).topLevelClassAsmType()
|
||||
|
||||
private fun LanguageVersionSettings.internalCoroutineIntrinsicsOwnerInternalName() =
|
||||
coroutinesJvmInternalPackageFqName().child(Name.identifier("CoroutineIntrinsics")).topLevelClassInternalName()
|
||||
|
||||
fun computeLabelOwner(languageVersionSettings: LanguageVersionSettings, thisName: String): Type =
|
||||
if (languageVersionSettings.isReleaseCoroutines())
|
||||
Type.getObjectType(thisName)
|
||||
else
|
||||
languageVersionSettings.coroutinesJvmInternalPackageFqName().child(Name.identifier("CoroutineImpl")).topLevelClassAsmType()
|
||||
|
||||
private const val NORMALIZE_CONTINUATION_METHOD_NAME = "normalizeContinuation"
|
||||
private const val GET_CONTEXT_METHOD_NAME = "getContext"
|
||||
private val coroutinesIntrinsicsFileFacadeInternalName: Type =
|
||||
COROUTINES_INTRINSICS_PACKAGE_FQ_NAME.child(Name.identifier("IntrinsicsKt")).topLevelClassAsmType()
|
||||
|
||||
data class ResolvedCallWithRealDescriptor(val resolvedCall: ResolvedCall<*>, val fakeContinuationExpression: KtExpression)
|
||||
|
||||
@@ -122,7 +84,7 @@ data class ResolvedCallWithRealDescriptor(val resolvedCall: ResolvedCall<*>, val
|
||||
val INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION = object : CallableDescriptor.UserDataKey<FunctionDescriptor> {}
|
||||
|
||||
@JvmField
|
||||
val INITIAL_SUSPEND_DESCRIPTOR_FOR_DO_RESUME = object : CallableDescriptor.UserDataKey<FunctionDescriptor> {}
|
||||
val INITIAL_SUSPEND_DESCRIPTOR_FOR_INVOKE_SUSPEND = object : CallableDescriptor.UserDataKey<FunctionDescriptor> {}
|
||||
|
||||
val CONTINUATION_PARAMETER_NAME = Name.identifier("continuation")
|
||||
|
||||
@@ -158,9 +120,9 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
|
||||
val newCandidateDescriptor =
|
||||
when (function) {
|
||||
is FunctionImportedFromObject ->
|
||||
getOrCreateJvmSuspendFunctionView(function.callableFromObject, isReleaseCoroutines, bindingContext).asImportedFromObject()
|
||||
getOrCreateJvmSuspendFunctionView(function.callableFromObject, bindingContext).asImportedFromObject()
|
||||
is SimpleFunctionDescriptor ->
|
||||
getOrCreateJvmSuspendFunctionView(function, isReleaseCoroutines, bindingContext)
|
||||
getOrCreateJvmSuspendFunctionView(function, bindingContext)
|
||||
else ->
|
||||
throw AssertionError("Unexpected suspend function descriptor: $function")
|
||||
}
|
||||
@@ -223,10 +185,10 @@ private fun NewResolvedCallImpl<VariableDescriptor>.asDummyOldResolvedCall(bindi
|
||||
|
||||
enum class SuspensionPointKind { NEVER, NOT_INLINE, ALWAYS }
|
||||
|
||||
fun ResolvedCall<*>.isSuspensionPoint(codegen: ExpressionCodegen, languageVersionSettings: LanguageVersionSettings): SuspensionPointKind {
|
||||
fun ResolvedCall<*>.isSuspensionPoint(codegen: ExpressionCodegen): SuspensionPointKind {
|
||||
val functionDescriptor = resultingDescriptor as? FunctionDescriptor ?: return SuspensionPointKind.NEVER
|
||||
if (!functionDescriptor.unwrapInitialDescriptorForSuspendFunction().isSuspend) return SuspensionPointKind.NEVER
|
||||
if (functionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm(languageVersionSettings)) return SuspensionPointKind.ALWAYS
|
||||
if (functionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm()) return SuspensionPointKind.ALWAYS
|
||||
if (functionDescriptor.isInline) return SuspensionPointKind.NEVER
|
||||
|
||||
val isInlineLambda = this.safeAs<VariableAsFunctionResolvedCall>()
|
||||
@@ -242,7 +204,6 @@ fun CallableDescriptor.isSuspendFunctionNotSuspensionView(): Boolean {
|
||||
|
||||
fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(function: D, state: GenerationState): D = getOrCreateJvmSuspendFunctionView(
|
||||
function,
|
||||
state.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines),
|
||||
state.bindingContext
|
||||
)
|
||||
|
||||
@@ -252,7 +213,6 @@ fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(function: D, stat
|
||||
@JvmOverloads
|
||||
fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(
|
||||
function: D,
|
||||
isReleaseCoroutines: Boolean,
|
||||
bindingContext: BindingContext? = null
|
||||
): D {
|
||||
assert(function.isSuspend) {
|
||||
@@ -272,7 +232,7 @@ fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(
|
||||
outType = if (function.containingDeclaration.safeAs<ClassDescriptor>()?.isBuiltinFunctionalClassDescriptor == true)
|
||||
function.builtIns.nullableAnyType
|
||||
else
|
||||
function.getContinuationParameterTypeOfSuspendFunction(isReleaseCoroutines),
|
||||
function.getContinuationParameterTypeOfSuspendFunction(),
|
||||
declaresDefaultValue = false, isCrossinline = false,
|
||||
isNoinline = false, varargElementType = null,
|
||||
source = SourceElement.NO_SOURCE
|
||||
@@ -309,8 +269,7 @@ fun <D : FunctionDescriptor> D.createCustomCopy(
|
||||
return result as D
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.getContinuationParameterTypeOfSuspendFunction(isReleaseCoroutines: Boolean) =
|
||||
module.getContinuationOfTypeOrAny(returnType!!, if (this.needsExperimentalCoroutinesWrapper()) false else isReleaseCoroutines)
|
||||
private fun FunctionDescriptor.getContinuationParameterTypeOfSuspendFunction() = module.getContinuationOfTypeOrAny(returnType!!)
|
||||
|
||||
fun ModuleDescriptor.getResult(kotlinType: KotlinType) =
|
||||
module.resolveTopLevelClass(
|
||||
@@ -323,44 +282,11 @@ fun ModuleDescriptor.getResult(kotlinType: KotlinType) =
|
||||
)
|
||||
} ?: ErrorUtils.createErrorType("For Result")
|
||||
|
||||
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() =
|
||||
getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)?.isBuiltInSuspendCoroutineUninterceptedOrReturn() == true
|
||||
|
||||
fun FunctionDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm(languageVersionSettings: LanguageVersionSettings) =
|
||||
getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)?.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings) == true
|
||||
|
||||
fun createMethodNodeForIntercepted(languageVersionSettings: LanguageVersionSettings): MethodNode {
|
||||
val node =
|
||||
MethodNode(
|
||||
Opcodes.API_VERSION,
|
||||
Opcodes.ACC_STATIC,
|
||||
"fake",
|
||||
Type.getMethodDescriptor(languageVersionSettings.continuationAsmType(), languageVersionSettings.continuationAsmType()),
|
||||
null, null
|
||||
)
|
||||
|
||||
node.visitVarInsn(Opcodes.ALOAD, 0)
|
||||
|
||||
node.invokeNormalizeContinuation(languageVersionSettings)
|
||||
|
||||
node.visitInsn(Opcodes.ARETURN)
|
||||
node.visitMaxs(1, 1)
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
fun createMethodNodeForCoroutineContext(
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
): MethodNode {
|
||||
assert(functionDescriptor.isBuiltInCoroutineContext(languageVersionSettings)) {
|
||||
fun createMethodNodeForCoroutineContext(functionDescriptor: FunctionDescriptor): MethodNode {
|
||||
assert(functionDescriptor.isBuiltInCoroutineContext()) {
|
||||
"functionDescriptor must be kotlin.coroutines.intrinsics.coroutineContext property getter"
|
||||
}
|
||||
|
||||
@@ -369,7 +295,7 @@ fun createMethodNodeForCoroutineContext(
|
||||
Opcodes.API_VERSION,
|
||||
Opcodes.ACC_STATIC,
|
||||
"fake",
|
||||
Type.getMethodDescriptor(languageVersionSettings.coroutineContextAsmType()),
|
||||
Type.getMethodDescriptor(coroutineContextAsmType()),
|
||||
null, null
|
||||
)
|
||||
|
||||
@@ -377,20 +303,20 @@ fun createMethodNodeForCoroutineContext(
|
||||
|
||||
addFakeContinuationMarker(v)
|
||||
|
||||
v.invokeGetContext(languageVersionSettings)
|
||||
v.invokeGetContext()
|
||||
|
||||
node.visitMaxs(1, 1)
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
fun createMethodNodeForSuspendCoroutineUninterceptedOrReturn(languageVersionSettings: LanguageVersionSettings): MethodNode {
|
||||
fun createMethodNodeForSuspendCoroutineUninterceptedOrReturn(): MethodNode {
|
||||
val node =
|
||||
MethodNode(
|
||||
Opcodes.API_VERSION,
|
||||
Opcodes.ACC_STATIC,
|
||||
"fake",
|
||||
Type.getMethodDescriptor(OBJECT_TYPE, AsmTypes.FUNCTION1, languageVersionSettings.continuationAsmType()),
|
||||
Type.getMethodDescriptor(OBJECT_TYPE, AsmTypes.FUNCTION1, CONTINUATION_ASM_TYPE),
|
||||
null, null
|
||||
)
|
||||
|
||||
@@ -405,25 +331,22 @@ fun createMethodNodeForSuspendCoroutineUninterceptedOrReturn(languageVersionSett
|
||||
"($OBJECT_TYPE)$OBJECT_TYPE"
|
||||
)
|
||||
|
||||
if (languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) {
|
||||
val elseLabel = Label()
|
||||
// if (result === COROUTINE_SUSPENDED) {
|
||||
dup()
|
||||
loadCoroutineSuspendedMarker(languageVersionSettings)
|
||||
ifacmpne(elseLabel)
|
||||
// DebugProbesKt.probeCoroutineSuspended(continuation)
|
||||
load(1, OBJECT_TYPE) // continuation
|
||||
checkcast(languageVersionSettings.continuationAsmType())
|
||||
invokestatic(
|
||||
languageVersionSettings.coroutinesJvmInternalPackageFqName().child(Name.identifier("DebugProbesKt"))
|
||||
.topLevelClassAsmType().internalName,
|
||||
"probeCoroutineSuspended",
|
||||
"(${languageVersionSettings.continuationAsmType()})V",
|
||||
false
|
||||
)
|
||||
// }
|
||||
mark(elseLabel)
|
||||
}
|
||||
val elseLabel = Label()
|
||||
// if (result === COROUTINE_SUSPENDED) {
|
||||
dup()
|
||||
loadCoroutineSuspendedMarker()
|
||||
ifacmpne(elseLabel)
|
||||
// DebugProbesKt.probeCoroutineSuspended(continuation)
|
||||
load(1, OBJECT_TYPE) // continuation
|
||||
checkcast(CONTINUATION_ASM_TYPE)
|
||||
invokestatic(
|
||||
COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.child(Name.identifier("DebugProbesKt")).topLevelClassAsmType().internalName,
|
||||
"probeCoroutineSuspended",
|
||||
"($CONTINUATION_ASM_TYPE)V",
|
||||
false
|
||||
)
|
||||
// }
|
||||
mark(elseLabel)
|
||||
}
|
||||
|
||||
node.visitInsn(Opcodes.ARETURN)
|
||||
@@ -433,13 +356,13 @@ fun createMethodNodeForSuspendCoroutineUninterceptedOrReturn(languageVersionSett
|
||||
}
|
||||
|
||||
|
||||
private fun InstructionAdapter.invokeGetContext(languageVersionSettings: LanguageVersionSettings) {
|
||||
private fun InstructionAdapter.invokeGetContext() {
|
||||
invokeinterface(
|
||||
languageVersionSettings.continuationAsmType().internalName,
|
||||
CONTINUATION_ASM_TYPE.internalName,
|
||||
GET_CONTEXT_METHOD_NAME,
|
||||
Type.getMethodDescriptor(languageVersionSettings.coroutineContextAsmType())
|
||||
Type.getMethodDescriptor(coroutineContextAsmType())
|
||||
)
|
||||
areturn(languageVersionSettings.coroutineContextAsmType())
|
||||
areturn(coroutineContextAsmType())
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@@ -447,15 +370,12 @@ fun <D : CallableDescriptor?> D.unwrapInitialDescriptorForSuspendFunction(): D =
|
||||
this.safeAs<SimpleFunctionDescriptor>()?.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION) as D ?: this
|
||||
|
||||
|
||||
fun FunctionDescriptor.getOriginalSuspendFunctionView(bindingContext: BindingContext, isReleaseCoroutines: Boolean): FunctionDescriptor =
|
||||
fun FunctionDescriptor.getOriginalSuspendFunctionView(bindingContext: BindingContext): FunctionDescriptor =
|
||||
if (isSuspend)
|
||||
getOrCreateJvmSuspendFunctionView(unwrapInitialDescriptorForSuspendFunction().original, isReleaseCoroutines, bindingContext)
|
||||
getOrCreateJvmSuspendFunctionView(unwrapInitialDescriptorForSuspendFunction().original, bindingContext)
|
||||
else
|
||||
this
|
||||
|
||||
fun FunctionDescriptor.getOriginalSuspendFunctionView(bindingContext: BindingContext, state: GenerationState) =
|
||||
getOriginalSuspendFunctionView(bindingContext, state.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines))
|
||||
|
||||
// For each suspend function, we have a corresponding JVM view function that has an extra continuation parameter,
|
||||
// and, more importantly, returns 'kotlin.Any' (so that it can return as a reference value or a special COROUTINE_SUSPENDED object).
|
||||
// This also causes boxing of primitives and inline class values.
|
||||
@@ -482,38 +402,24 @@ fun FunctionDescriptor.originalReturnTypeOfSuspendFunctionReturningUnboxedInline
|
||||
return originalReturnType
|
||||
}
|
||||
|
||||
fun InstructionAdapter.loadCoroutineSuspendedMarker(languageVersionSettings: LanguageVersionSettings) {
|
||||
fun InstructionAdapter.loadCoroutineSuspendedMarker() {
|
||||
invokestatic(
|
||||
languageVersionSettings.coroutinesIntrinsicsFileFacadeInternalName().internalName,
|
||||
coroutinesIntrinsicsFileFacadeInternalName.internalName,
|
||||
"get$COROUTINE_SUSPENDED_NAME",
|
||||
Type.getMethodDescriptor(OBJECT_TYPE),
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
fun InstructionAdapter.generateCoroutineSuspendedCheck(languageVersionSettings: LanguageVersionSettings) {
|
||||
fun InstructionAdapter.generateCoroutineSuspendedCheck() {
|
||||
dup()
|
||||
loadCoroutineSuspendedMarker(languageVersionSettings)
|
||||
loadCoroutineSuspendedMarker()
|
||||
val elseLabel = Label()
|
||||
ifacmpne(elseLabel)
|
||||
areturn(OBJECT_TYPE)
|
||||
mark(elseLabel)
|
||||
}
|
||||
|
||||
fun InstructionAdapter.invokeDoResumeWithUnit(thisName: String) {
|
||||
// .doResume(Unit, null)
|
||||
StackValue.putUnitInstance(this)
|
||||
|
||||
aconst(null)
|
||||
|
||||
invokevirtual(
|
||||
thisName,
|
||||
DO_RESUME_METHOD_NAME,
|
||||
Type.getMethodDescriptor(OBJECT_TYPE, OBJECT_TYPE, AsmTypes.JAVA_THROWABLE_TYPE),
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
fun InstructionAdapter.invokeInvokeSuspendWithUnit(thisName: String) {
|
||||
StackValue.putUnitInstance(this)
|
||||
|
||||
@@ -537,18 +443,14 @@ fun FunctionDescriptor.isSuspendLambdaOrLocalFunction() = this.isSuspend && when
|
||||
}
|
||||
|
||||
fun FunctionDescriptor.isLocalSuspendFunctionNotSuspendLambda() = isSuspendLambdaOrLocalFunction() && this !is AnonymousFunctionDescriptor
|
||||
|
||||
@JvmField
|
||||
val EXPERIMENTAL_CONTINUATION_ASM_TYPE = StandardNames.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL.topLevelClassAsmType()
|
||||
|
||||
@JvmField
|
||||
val RELEASE_CONTINUATION_ASM_TYPE = StandardNames.CONTINUATION_INTERFACE_FQ_NAME_RELEASE.topLevelClassAsmType()
|
||||
val CONTINUATION_ASM_TYPE = StandardNames.CONTINUATION_INTERFACE_FQ_NAME.topLevelClassAsmType()
|
||||
|
||||
fun FunctionDescriptor.isInvokeSuspendOfLambda(): Boolean {
|
||||
if (this !is SimpleFunctionDescriptor) return false
|
||||
if (valueParameters.size != 1 ||
|
||||
valueParameters[0].name.asString() != SUSPEND_CALL_RESULT_NAME ||
|
||||
name.asString() != "invokeSuspend"
|
||||
name.asString() != INVOKE_SUSPEND_METHOD_NAME
|
||||
) return false
|
||||
return containingDeclaration is SyntheticClassDescriptorForLambda
|
||||
}
|
||||
+1
-1
@@ -62,7 +62,7 @@ class AnonymousObjectTransformer(
|
||||
createClassReader().accept(object : ClassVisitor(Opcodes.API_VERSION, classBuilder.visitor) {
|
||||
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<String>) {
|
||||
classBuilder.defineClass(null, maxOf(version, state.classFileVersion), access, name, signature, superName, interfaces)
|
||||
if (languageVersionSettings.isCoroutineSuperClass(superName)) {
|
||||
if (superName.isCoroutineSuperClass()) {
|
||||
inliningContext.isContinuation = true
|
||||
}
|
||||
superClassName = superName
|
||||
|
||||
@@ -104,7 +104,7 @@ class DefaultLambda(info: ExtractedDefaultLambda, sourceCompiler: SourceCompiler
|
||||
// TODO: suspend lambdas are their own continuations, so the body is pre-inlined into `invokeSuspend`
|
||||
// and thus can't be detangled from the state machine. To make them inlinable, this needs to be redesigned.
|
||||
// See `SuspendLambdaLowering`.
|
||||
require(!sourceCompiler.state.languageVersionSettings.isCoroutineSuperClass(superName)) {
|
||||
require(!superName.isCoroutineSuperClass()) {
|
||||
"suspend default lambda ${lambdaClassType.internalName} cannot be inlined; use a function reference instead"
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.coroutines.continuationAsmType
|
||||
import org.jetbrains.kotlin.codegen.coroutines.CONTINUATION_ASM_TYPE
|
||||
import org.jetbrains.kotlin.codegen.inline.FieldRemapper.Companion.foldName
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.CoroutineTransformer
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.markNoinlineLambdaIfSuspend
|
||||
@@ -688,7 +688,7 @@ class MethodInliner(
|
||||
}
|
||||
|
||||
for ((index, param) in paramTypes.reversed().withIndex()) {
|
||||
if (param != languageVersionSettings.continuationAsmType() && param != OBJECT_TYPE) continue
|
||||
if (param != CONTINUATION_ASM_TYPE && param != OBJECT_TYPE) continue
|
||||
val sourceIndices = (frame.getStack(frame.stackSize - index - 1) as? Aload0BasicValue)?.indices ?: continue
|
||||
for (sourceIndex in sourceIndices) {
|
||||
val src = processingNode.instructions[sourceIndex]
|
||||
|
||||
+2
-4
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -158,8 +157,7 @@ class PsiSourceCompilerForInline(
|
||||
}
|
||||
|
||||
FunctionCodegen.generateMethodBody(
|
||||
adapter, descriptor, context, jvmMethodSignature, strategy, parentCodegen, state.jvmDefaultMode,
|
||||
state.languageVersionSettings.isReleaseCoroutines()
|
||||
adapter, descriptor, context, jvmMethodSignature, strategy, parentCodegen, state.jvmDefaultMode
|
||||
)
|
||||
|
||||
if (isLambda) {
|
||||
@@ -235,7 +233,7 @@ class PsiSourceCompilerForInline(
|
||||
}
|
||||
|
||||
override fun compileInlineFunction(jvmSignature: JvmMethodSignature): SMAPAndMethodNode {
|
||||
generateInlineIntrinsic(state.languageVersionSettings, functionDescriptor, jvmSignature.asmMethod, codegen.typeSystem)?.let {
|
||||
generateInlineIntrinsic(functionDescriptor, jvmSignature.asmMethod, codegen.typeSystem)?.let {
|
||||
return it
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,6 @@ import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -233,7 +231,7 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
|
||||
if (stubCheckcast !is TypeInsnNode) return false
|
||||
|
||||
val newMethodNode = MethodNode(Opcodes.API_VERSION)
|
||||
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe, languageVersionSettings, unifiedNullChecks)
|
||||
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe, unifiedNullChecks)
|
||||
|
||||
instructions.insert(insn, newMethodNode.instructions)
|
||||
// Keep stubCheckcast to avoid VerifyErrors on 1.8+ bytecode,
|
||||
@@ -257,7 +255,7 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
|
||||
if (stubInstanceOf !is TypeInsnNode) return false
|
||||
|
||||
val newMethodNode = MethodNode(Opcodes.API_VERSION)
|
||||
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType, languageVersionSettings.isReleaseCoroutines())
|
||||
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType)
|
||||
|
||||
instructions.insert(insn, newMethodNode.instructions)
|
||||
instructions.remove(stubInstanceOf)
|
||||
|
||||
+13
-19
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.codegen.inline.*
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
@@ -49,18 +48,16 @@ class CoroutineTransformer(
|
||||
fun suspendLambdaWithGeneratedStateMachine(node: MethodNode): Boolean =
|
||||
!isContinuationNotLambda() && isSuspendLambda(node) && isStateMachine(node)
|
||||
|
||||
private fun isContinuationNotLambda(): Boolean = inliningContext.isContinuation &&
|
||||
if (state.languageVersionSettings.isReleaseCoroutines()) superClassName.endsWith("ContinuationImpl")
|
||||
else methods.any { it.name == "getLabel" }
|
||||
private fun isContinuationNotLambda(): Boolean = inliningContext.isContinuation && superClassName.endsWith("ContinuationImpl")
|
||||
|
||||
private fun isStateMachine(node: MethodNode): Boolean =
|
||||
node.instructions.asSequence().any { insn -> insn is LdcInsnNode && insn.cst == ILLEGAL_STATE_ERROR_MESSAGE }
|
||||
|
||||
private fun isSuspendLambda(node: MethodNode) = isResumeImpl(node)
|
||||
private fun isSuspendLambda(node: MethodNode) = isInvokeSuspend(node)
|
||||
|
||||
fun newMethod(node: MethodNode): DeferredMethodVisitor {
|
||||
return when {
|
||||
isResumeImpl(node) -> {
|
||||
isInvokeSuspend(node) -> {
|
||||
assert(!isStateMachine(node)) {
|
||||
"Inlining/transforming state-machine"
|
||||
}
|
||||
@@ -71,9 +68,8 @@ class CoroutineTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
private fun isResumeImpl(node: MethodNode): Boolean =
|
||||
state.languageVersionSettings.isResumeImplMethodName(node.name.removeSuffix(FOR_INLINE_SUFFIX)) &&
|
||||
inliningContext.isContinuation
|
||||
private fun isInvokeSuspend(node: MethodNode): Boolean =
|
||||
node.name.removeSuffix(FOR_INLINE_SUFFIX) == INVOKE_SUSPEND_METHOD_NAME && inliningContext.isContinuation
|
||||
|
||||
private fun isSuspendFunctionWithFakeConstructorCall(node: MethodNode): Boolean = findFakeContinuationConstructorClassName(node) != null
|
||||
|
||||
@@ -88,16 +84,15 @@ class CoroutineTransformer(
|
||||
val sourceCompilerForInline = inliningContext.root.sourceCompilerForInline
|
||||
val stateMachineBuilder = CoroutineTransformerMethodVisitor(
|
||||
createNewMethodFrom(node, name), node.access, name, node.desc, null, null,
|
||||
containingClassInternalName = classBuilder.thisName,
|
||||
obtainClassBuilderForCoroutineState = { classBuilder },
|
||||
isForNamedFunction = false,
|
||||
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
disableTailCallOptimizationForFunctionReturningUnit = false,
|
||||
reportSuspensionPointInsideMonitor = { sourceCompilerForInline.reportSuspensionPointInsideMonitor(it) },
|
||||
// TODO: this linenumbers might not be correct and since they are used only for step-over, check them.
|
||||
lineNumber = inliningContext.callSiteInfo.lineNumber,
|
||||
sourceFile = inliningContext.callSiteInfo.file?.name ?: "",
|
||||
languageVersionSettings = state.languageVersionSettings,
|
||||
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
containingClassInternalName = classBuilder.thisName,
|
||||
isForNamedFunction = false,
|
||||
disableTailCallOptimizationForFunctionReturningUnit = false,
|
||||
useOldSpilledVarTypeAnalysis = state.configuration.getBoolean(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS)
|
||||
)
|
||||
|
||||
@@ -123,17 +118,16 @@ class CoroutineTransformer(
|
||||
val sourceCompilerForInline = inliningContext.root.sourceCompilerForInline
|
||||
val stateMachineBuilder = CoroutineTransformerMethodVisitor(
|
||||
createNewMethodFrom(node, name), node.access, name, node.desc, null, null,
|
||||
containingClassInternalName = classBuilder.thisName,
|
||||
obtainClassBuilderForCoroutineState = { (inliningContext as RegeneratedClassContext).continuationBuilders[continuationClassName]!! },
|
||||
isForNamedFunction = true,
|
||||
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
disableTailCallOptimizationForFunctionReturningUnit = disableTailCallOptimization,
|
||||
reportSuspensionPointInsideMonitor = { sourceCompilerForInline.reportSuspensionPointInsideMonitor(it) },
|
||||
lineNumber = inliningContext.callSiteInfo.lineNumber,
|
||||
sourceFile = inliningContext.callSiteInfo.file?.name ?: "",
|
||||
languageVersionSettings = state.languageVersionSettings,
|
||||
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
containingClassInternalName = classBuilder.thisName,
|
||||
isForNamedFunction = true,
|
||||
needDispatchReceiver = true,
|
||||
internalNameForDispatchReceiver = classBuilder.thisName,
|
||||
disableTailCallOptimizationForFunctionReturningUnit = disableTailCallOptimization,
|
||||
putContinuationParameterToLvt = !state.isIrBackend,
|
||||
useOldSpilledVarTypeAnalysis = state.configuration.getBoolean(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS)
|
||||
)
|
||||
|
||||
@@ -5,13 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.isBuiltInIntercepted
|
||||
import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForCoroutineContext
|
||||
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForIntercepted
|
||||
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForSuspendCoroutineUninterceptedOrReturn
|
||||
import org.jetbrains.kotlin.codegen.createMethodNodeForAlwaysEnabledAssert
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicArrayConstructors
|
||||
@@ -30,25 +28,22 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
fun generateInlineIntrinsicForIr(languageVersionSettings: LanguageVersionSettings, descriptor: FunctionDescriptor): SMAPAndMethodNode? =
|
||||
fun generateInlineIntrinsicForIr(descriptor: FunctionDescriptor): SMAPAndMethodNode? =
|
||||
when {
|
||||
// TODO: implement these as codegen intrinsics (see IrIntrinsicMethods)
|
||||
descriptor.isBuiltInIntercepted(languageVersionSettings) ->
|
||||
createMethodNodeForIntercepted(languageVersionSettings)
|
||||
descriptor.isBuiltInCoroutineContext(languageVersionSettings) ->
|
||||
createMethodNodeForCoroutineContext(descriptor, languageVersionSettings)
|
||||
descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings) ->
|
||||
createMethodNodeForSuspendCoroutineUninterceptedOrReturn(languageVersionSettings)
|
||||
descriptor.isBuiltInCoroutineContext() ->
|
||||
createMethodNodeForCoroutineContext(descriptor)
|
||||
descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn() ->
|
||||
createMethodNodeForSuspendCoroutineUninterceptedOrReturn()
|
||||
else -> null
|
||||
}?.let { SMAPAndMethodNode(it, SMAP(listOf())) }
|
||||
|
||||
internal fun generateInlineIntrinsic(
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
descriptor: FunctionDescriptor,
|
||||
asmMethod: Method,
|
||||
typeSystem: TypeSystemCommonBackendContext
|
||||
): SMAPAndMethodNode? {
|
||||
return generateInlineIntrinsicForIr(languageVersionSettings, descriptor) ?: when {
|
||||
return generateInlineIntrinsicForIr(descriptor) ?: when {
|
||||
isSpecialEnumMethod(descriptor) ->
|
||||
createSpecialEnumMethodBody(descriptor.name.asString(), descriptor.original.typeParameters.single(), typeSystem)
|
||||
TypeOfChecker.isTypeOf(descriptor) ->
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.jetbrains.org.objectweb.asm.tree.*
|
||||
|
||||
object TypeIntrinsics {
|
||||
@JvmStatic
|
||||
fun instanceOf(v: InstructionAdapter, jetType: KotlinType, boxedAsmType: Type, isReleaseCoroutines: Boolean) {
|
||||
fun instanceOf(v: InstructionAdapter, jetType: KotlinType, boxedAsmType: Type) {
|
||||
val functionTypeArity = getFunctionTypeArity(jetType)
|
||||
if (functionTypeArity >= 0) {
|
||||
v.iconst(functionTypeArity)
|
||||
@@ -27,28 +27,26 @@ object TypeIntrinsics {
|
||||
return
|
||||
}
|
||||
|
||||
if (isReleaseCoroutines) {
|
||||
val suspendFunctionTypeArity = getSuspendFunctionTypeArity(jetType)
|
||||
if (suspendFunctionTypeArity >= 0) {
|
||||
val notSuspendLambda = Label()
|
||||
val end = Label()
|
||||
val suspendFunctionTypeArity = getSuspendFunctionTypeArity(jetType)
|
||||
if (suspendFunctionTypeArity >= 0) {
|
||||
val notSuspendLambda = Label()
|
||||
val end = Label()
|
||||
|
||||
with(v) {
|
||||
dup()
|
||||
instanceOf(AsmTypes.SUSPEND_FUNCTION_TYPE)
|
||||
ifeq(notSuspendLambda)
|
||||
iconst(suspendFunctionTypeArity + 1)
|
||||
typeIntrinsic(IS_FUNCTON_OF_ARITY_METHOD_NAME, IS_FUNCTON_OF_ARITY_DESCRIPTOR)
|
||||
goTo(end)
|
||||
with(v) {
|
||||
dup()
|
||||
instanceOf(AsmTypes.SUSPEND_FUNCTION_TYPE)
|
||||
ifeq(notSuspendLambda)
|
||||
iconst(suspendFunctionTypeArity + 1)
|
||||
typeIntrinsic(IS_FUNCTON_OF_ARITY_METHOD_NAME, IS_FUNCTON_OF_ARITY_DESCRIPTOR)
|
||||
goTo(end)
|
||||
|
||||
mark(notSuspendLambda)
|
||||
pop()
|
||||
iconst(0)
|
||||
mark(notSuspendLambda)
|
||||
pop()
|
||||
iconst(0)
|
||||
|
||||
mark(end)
|
||||
}
|
||||
return
|
||||
mark(end)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val isMutableCollectionMethodName = getIsMutableCollectionMethodName(jetType)
|
||||
|
||||
+2
-3
@@ -17,9 +17,8 @@
|
||||
package org.jetbrains.kotlin.codegen.optimization.boxing
|
||||
|
||||
import com.google.common.collect.ImmutableSet
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.coroutines.RELEASE_COROUTINES_VERSION_SETTINGS
|
||||
import org.jetbrains.kotlin.codegen.coroutines.coroutinesJvmInternalPackageFqName
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
|
||||
@@ -216,7 +215,7 @@ fun AbstractInsnNode.isPrimitiveBoxing() =
|
||||
}
|
||||
|
||||
private val BOXING_CLASS_INTERNAL_NAME =
|
||||
RELEASE_COROUTINES_VERSION_SETTINGS.coroutinesJvmInternalPackageFqName().child(Name.identifier("Boxing")).topLevelClassInternalName()
|
||||
StandardNames.COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME.child(Name.identifier("Boxing")).topLevelClassInternalName()
|
||||
|
||||
private fun isJvmPrimitiveName(name: String) = JvmPrimitiveType.values().any { it.javaKeywordName == name }
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ import org.jetbrains.kotlin.psi.KtCodeFragment
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.PrecomputedSuppressCache
|
||||
@@ -158,8 +157,7 @@ class GenerationState private constructor(
|
||||
CompilerDeserializationConfiguration(languageVersionSettings)
|
||||
|
||||
val deprecationProvider = DeprecationResolver(
|
||||
LockBasedStorageManager.NO_LOCKS, languageVersionSettings, CoroutineCompatibilitySupport.ENABLED,
|
||||
JavaDeprecationSettings
|
||||
LockBasedStorageManager.NO_LOCKS, languageVersionSettings, JavaDeprecationSettings
|
||||
)
|
||||
|
||||
init {
|
||||
|
||||
@@ -193,7 +193,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
if (descriptor.isSuspendFunctionNotSuspensionView()) {
|
||||
return mapReturnType(getOrCreateJvmSuspendFunctionView(descriptor as SimpleFunctionDescriptor, isReleaseCoroutines), sw)
|
||||
return mapReturnType(getOrCreateJvmSuspendFunctionView(descriptor as SimpleFunctionDescriptor), sw)
|
||||
}
|
||||
|
||||
if (hasVoidReturnType(descriptor)) {
|
||||
@@ -804,7 +804,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
if (f.isSuspendFunctionNotSuspensionView()) {
|
||||
return mapSignature(getOrCreateJvmSuspendFunctionView(f, isReleaseCoroutines), kind, skipGenericSignature)
|
||||
return mapSignature(getOrCreateJvmSuspendFunctionView(f), kind, skipGenericSignature)
|
||||
}
|
||||
|
||||
if (isDeclarationOfBigArityFunctionInvoke(f) || isDeclarationOfBigArityCreateCoroutineMethod(f)) {
|
||||
|
||||
-2
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.load.java.components.JavaDeprecationSettings
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -84,7 +83,6 @@ class CliLightClassGenerationSupport(
|
||||
get() = DeprecationResolver(
|
||||
LockBasedStorageManager.NO_LOCKS,
|
||||
languageVersionSettings,
|
||||
CoroutineCompatibilitySupport.ENABLED,
|
||||
JavaDeprecationSettings
|
||||
)
|
||||
|
||||
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
fun LanguageVersionSettings.coroutinesPackageFqName(): FqName {
|
||||
return coroutinesPackageFqName(isReleaseCoroutines())
|
||||
}
|
||||
|
||||
fun LanguageVersionSettings.isReleaseCoroutines() = supportsFeature(LanguageFeature.ReleaseCoroutines)
|
||||
|
||||
private fun coroutinesPackageFqName(isReleaseCoroutines: Boolean): FqName {
|
||||
return if (isReleaseCoroutines)
|
||||
StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE
|
||||
else
|
||||
StandardNames.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 == StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE.child(Name.identifier("coroutineContext"))
|
||||
else
|
||||
this == StandardNames.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.child(Name.identifier("coroutineContext")) ||
|
||||
this == StandardNames.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME_EXPERIMENTAL.child(Name.identifier("coroutineContext"))
|
||||
+3
-3
@@ -33,13 +33,13 @@ import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.COROUTINE_CONTEXT_1_3_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.COROUTINE_CONTEXT_FQ_NAME
|
||||
import org.jetbrains.kotlin.serialization.deserialization.KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
|
||||
|
||||
object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
|
||||
private val RESTRICTS_SUSPENSION_CLASS_ID =
|
||||
ClassId(StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE, Name.identifier("RestrictsSuspension"))
|
||||
ClassId(StandardNames.COROUTINES_PACKAGE_FQ_NAME, Name.identifier("RestrictsSuspension"))
|
||||
|
||||
private val BUILTIN_SUSPEND_NAME = KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME.shortName()
|
||||
|
||||
@@ -56,7 +56,7 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
|
||||
if (reference is FirResolvedCallableReference) return
|
||||
when (symbol) {
|
||||
is FirNamedFunctionSymbol -> if (!symbol.isSuspend) return
|
||||
is FirPropertySymbol -> if (symbol.callableId.asSingleFqName() != COROUTINE_CONTEXT_1_3_FQ_NAME) return
|
||||
is FirPropertySymbol -> if (symbol.callableId.asSingleFqName() != COROUTINE_CONTEXT_FQ_NAME) return
|
||||
else -> return
|
||||
}
|
||||
val enclosingSuspendFunction = findEnclosingSuspendFunction(context)
|
||||
|
||||
+1
-1
@@ -9,4 +9,4 @@ import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
|
||||
val CONTINUATION_INTERFACE_CLASS_ID = ClassId.topLevel(StandardNames.CONTINUATION_INTERFACE_FQ_NAME_RELEASE)
|
||||
val CONTINUATION_INTERFACE_CLASS_ID = ClassId.topLevel(StandardNames.CONTINUATION_INTERFACE_FQ_NAME)
|
||||
|
||||
-2
@@ -26,6 +26,4 @@ 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)
|
||||
}
|
||||
|
||||
+15
-30
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.coroutines.hasSuspendFunctionType
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
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.KtCodeFragment
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
@@ -33,20 +34,17 @@ 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 =
|
||||
StandardNames.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME_EXPERIMENTAL.child(Name.identifier("coroutineContext"))
|
||||
val COROUTINE_CONTEXT_FQ_NAME =
|
||||
StandardNames.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("coroutineContext"))
|
||||
|
||||
val COROUTINE_CONTEXT_1_2_30_FQ_NAME =
|
||||
StandardNames.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.child(Name.identifier("coroutineContext"))
|
||||
fun FqName.isBuiltInCoroutineContext(): Boolean =
|
||||
this == StandardNames.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("coroutineContext"))
|
||||
|
||||
val COROUTINE_CONTEXT_1_3_FQ_NAME =
|
||||
StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE.child(Name.identifier("coroutineContext"))
|
||||
fun FunctionDescriptor.isBuiltInCoroutineContext() =
|
||||
(this as? PropertyGetterDescriptor)?.correspondingProperty?.fqNameSafe?.isBuiltInCoroutineContext() == true
|
||||
|
||||
fun FunctionDescriptor.isBuiltInCoroutineContext(languageVersionSettings: LanguageVersionSettings) =
|
||||
(this as? PropertyGetterDescriptor)?.correspondingProperty?.fqNameSafe?.isBuiltInCoroutineContext(languageVersionSettings) == true
|
||||
|
||||
fun PropertyDescriptor.isBuiltInCoroutineContext(languageVersionSettings: LanguageVersionSettings) =
|
||||
this.fqNameSafe.isBuiltInCoroutineContext(languageVersionSettings)
|
||||
fun PropertyDescriptor.isBuiltInCoroutineContext() =
|
||||
fqNameSafe.isBuiltInCoroutineContext()
|
||||
|
||||
private val ALLOWED_SCOPE_KINDS = setOf(LexicalScopeKind.FUNCTION_INNER_SCOPE, LexicalScopeKind.FUNCTION_HEADER_FOR_DESTRUCTURING)
|
||||
|
||||
@@ -60,11 +58,7 @@ 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_1_2_30_FQ_NAME, COROUTINE_CONTEXT_1_3_FQ_NAME -> {
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
is PropertyDescriptor -> if (descriptor.fqNameSafe != COROUTINE_CONTEXT_FQ_NAME) return
|
||||
else -> return
|
||||
}
|
||||
|
||||
@@ -92,17 +86,6 @@ object CoroutineSuspendCallChecker : CallChecker {
|
||||
context.trace.report(Errors.UNSUPPORTED.on(reportOn, "suspend function calls in a context of default parameter value"))
|
||||
}
|
||||
|
||||
if ((descriptor.fqNameSafe == COROUTINE_CONTEXT_1_2_20_FQ_NAME || descriptor.fqNameSafe == COROUTINE_CONTEXT_1_2_30_FQ_NAME) &&
|
||||
context.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
|
||||
) {
|
||||
context.trace.report(
|
||||
Errors.UNSUPPORTED.on(
|
||||
reportOn,
|
||||
"experimental coroutineContext of release coroutine: use kotlin.coroutines.coroutineContext instead"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
context.trace.record(
|
||||
BindingContext.ENCLOSING_SUSPEND_FUNCTION_FOR_SUSPEND_FUNCTION_CALL,
|
||||
resolvedCall.call,
|
||||
@@ -169,8 +152,10 @@ fun checkCoroutinesFeature(languageVersionSettings: LanguageVersionSettings, dia
|
||||
}
|
||||
}
|
||||
|
||||
fun KotlinType.isRestrictsSuspensionReceiver(languageVersionSettings: LanguageVersionSettings) = (listOf(this) + this.supertypes()).any {
|
||||
it.constructor.declarationDescriptor?.annotations?.hasAnnotation(languageVersionSettings.restrictsSuspensionFqName()) == true
|
||||
fun KotlinType.isRestrictsSuspensionReceiver() = (listOf(this) + this.supertypes()).any {
|
||||
it.constructor.declarationDescriptor?.annotations?.hasAnnotation(
|
||||
StandardNames.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("RestrictsSuspension"))
|
||||
) == true
|
||||
}
|
||||
|
||||
private fun checkRestrictsSuspension(
|
||||
@@ -179,7 +164,7 @@ private fun checkRestrictsSuspension(
|
||||
reportOn: PsiElement,
|
||||
context: CallCheckerContext
|
||||
) {
|
||||
fun ReceiverValue.isRestrictsSuspensionReceiver() = type.isRestrictsSuspensionReceiver(context.languageVersionSettings)
|
||||
fun ReceiverValue.isRestrictsSuspensionReceiver() = type.isRestrictsSuspensionReceiver()
|
||||
|
||||
infix fun ReceiverValue.sameInstance(other: ReceiverValue?): Boolean {
|
||||
if (other == null) return false
|
||||
|
||||
-2
@@ -47,7 +47,6 @@ import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
||||
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
||||
import org.jetbrains.kotlin.resolve.constants.KClassValue
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationSettings
|
||||
@@ -338,7 +337,6 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
|
||||
val deprecationResolver = DeprecationResolver(
|
||||
LockBasedStorageManager("ExperimentalUsageChecker"),
|
||||
languageVersionSettings,
|
||||
CoroutineCompatibilitySupport.ENABLED,
|
||||
DeprecationSettings.Default
|
||||
)
|
||||
|
||||
|
||||
@@ -132,17 +132,6 @@ internal data class DeprecatedByOverridden(private val deprecations: Collection<
|
||||
"Overrides deprecated member in '${DescriptorUtils.getContainingClass(target)!!.fqNameSafe.asString()}'"
|
||||
}
|
||||
|
||||
internal data class DeprecatedExperimentalCoroutine(
|
||||
override val target: DeclarationDescriptor,
|
||||
override val deprecationLevel: DeprecationLevelValue
|
||||
) : Deprecation {
|
||||
override val message: String? =
|
||||
if (deprecationLevel == WARNING)
|
||||
"Experimental coroutines support will be dropped in 1.4"
|
||||
else
|
||||
"Experimental coroutine cannot be used with API version 1.3"
|
||||
}
|
||||
|
||||
internal data class DeprecatedOperatorMod(
|
||||
val languageVersionSettings: LanguageVersionSettings,
|
||||
val currentDeprecation: Deprecation
|
||||
|
||||
@@ -27,8 +27,6 @@ import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor.CoroutinesCompatibilityMode.COMPATIBLE
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor.CoroutinesCompatibilityMode.NEEDS_WRAPPER
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
@@ -38,7 +36,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
class DeprecationResolver(
|
||||
storageManager: StorageManager,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
private val coroutineCompatibilitySupport: CoroutineCompatibilitySupport,
|
||||
private val deprecationSettings: DeprecationSettings
|
||||
) {
|
||||
private val deprecations = storageManager.createMemoizedFunction { descriptor: DeclarationDescriptor ->
|
||||
@@ -226,7 +223,6 @@ class DeprecationResolver(
|
||||
for (deprecation in getDeprecationByVersionRequirement(this)) {
|
||||
result.add(deprecation)
|
||||
}
|
||||
getDeprecationByCoroutinesVersion(this)?.let(result::add)
|
||||
getDeprecationFromUserData(this)?.let(result::add)
|
||||
}
|
||||
|
||||
@@ -242,19 +238,6 @@ class DeprecationResolver(
|
||||
descriptor.valueParameters.singleOrNull()?.type?.let(KotlinBuiltIns::isInt) == true &&
|
||||
languageVersionSettings.apiVersion < ApiVersion.KOTLIN_1_3
|
||||
|
||||
private fun getDeprecationByCoroutinesVersion(target: DeclarationDescriptor): DeprecatedExperimentalCoroutine? {
|
||||
if (target !is DeserializedMemberDescriptor) return null
|
||||
|
||||
target.coroutinesExperimentalCompatibilityMode.let { mode ->
|
||||
return when {
|
||||
mode == COMPATIBLE -> null
|
||||
mode == NEEDS_WRAPPER && coroutineCompatibilitySupport.enabled ->
|
||||
DeprecatedExperimentalCoroutine(target, DeprecationLevelValue.WARNING)
|
||||
else -> DeprecatedExperimentalCoroutine(target, DeprecationLevelValue.ERROR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getDeprecationFromUserData(target: DeclarationDescriptor): Deprecation? =
|
||||
target.safeAs<CallableDescriptor>()?.getUserData(DEPRECATED_FUNCTION_KEY)
|
||||
|
||||
|
||||
@@ -73,18 +73,6 @@ internal fun createDeprecationDiagnostic(
|
||||
}
|
||||
}
|
||||
|
||||
@DefaultImplementation(CoroutineCompatibilitySupport::class)
|
||||
class CoroutineCompatibilitySupport private constructor(val enabled: Boolean) : PlatformSpecificExtension<CoroutineCompatibilitySupport>{
|
||||
@Suppress("unused")
|
||||
constructor() : this(true)
|
||||
|
||||
companion object {
|
||||
val ENABLED = CoroutineCompatibilitySupport(true)
|
||||
|
||||
val DISABLED = CoroutineCompatibilitySupport(false)
|
||||
}
|
||||
}
|
||||
|
||||
@DefaultImplementation(DeprecationSettings.Default::class)
|
||||
interface DeprecationSettings {
|
||||
fun propagatedToOverrides(deprecationAnnotation: AnnotationDescriptor): Boolean
|
||||
|
||||
+1
-1
@@ -700,7 +700,7 @@ class DoubleColonExpressionResolver(
|
||||
) {
|
||||
val descriptor =
|
||||
if (resolutionResults?.isSingleResult == true) resolutionResults.resultingDescriptor else null
|
||||
if (descriptor is PropertyDescriptor && descriptor.isBuiltInCoroutineContext(languageVersionSettings)) {
|
||||
if (descriptor is PropertyDescriptor && descriptor.isBuiltInCoroutineContext()) {
|
||||
context.trace.report(UNSUPPORTED.on(expression.callableReference, "Callable reference to suspend property"))
|
||||
} else if (descriptor is FunctionDescriptor && descriptor.isSuspend
|
||||
&& !context.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
|
||||
|
||||
+4
-12
@@ -14,9 +14,9 @@ import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
import org.jetbrains.kotlin.backend.common.ir.isPure
|
||||
import org.jetbrains.kotlin.backend.common.lower.at
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.coroutinesIntrinsicsPackageFqName
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
@@ -54,26 +54,18 @@ fun IrFunction.isTopLevelInPackage(name: String, packageName: String): Boolean {
|
||||
return packageName == packageFqName
|
||||
}
|
||||
|
||||
fun IrFunction.isBuiltInIntercepted(languageVersionSettings: LanguageVersionSettings): Boolean =
|
||||
!languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) &&
|
||||
isTopLevelInPackage("intercepted", languageVersionSettings.coroutinesIntrinsicsPackageFqName().asString())
|
||||
|
||||
fun IrFunction.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings: LanguageVersionSettings): Boolean =
|
||||
fun IrFunction.isBuiltInSuspendCoroutineUninterceptedOrReturn(): Boolean =
|
||||
isTopLevelInPackage(
|
||||
"suspendCoroutineUninterceptedOrReturn",
|
||||
languageVersionSettings.coroutinesIntrinsicsPackageFqName().asString()
|
||||
StandardNames.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME.asString()
|
||||
)
|
||||
|
||||
open class DefaultInlineFunctionResolver(open val context: CommonBackendContext) : InlineFunctionResolver {
|
||||
override fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction {
|
||||
val function = symbol.owner
|
||||
val languageVersionSettings = context.configuration.languageVersionSettings
|
||||
// TODO: Remove these hacks when coroutine intrinsics are fixed.
|
||||
return when {
|
||||
function.isBuiltInIntercepted(languageVersionSettings) ->
|
||||
error("Continuation.intercepted is not available with release coroutines")
|
||||
|
||||
function.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings) ->
|
||||
function.isBuiltInSuspendCoroutineUninterceptedOrReturn() ->
|
||||
context.ir.symbols.suspendCoroutineUninterceptedOrReturn.owner
|
||||
|
||||
symbol == context.ir.symbols.coroutineContextGetter ->
|
||||
|
||||
@@ -248,7 +248,7 @@ class JvmSymbols(
|
||||
val assertionErrorConstructor = javaLangAssertionError.constructors.single()
|
||||
|
||||
val continuationClass: IrClassSymbol =
|
||||
createClass(StandardNames.CONTINUATION_INTERFACE_FQ_NAME_RELEASE, ClassKind.INTERFACE) { klass ->
|
||||
createClass(StandardNames.CONTINUATION_INTERFACE_FQ_NAME, ClassKind.INTERFACE) { klass ->
|
||||
klass.addTypeParameter("T", irBuiltIns.anyNType, Variance.IN_VARIANCE)
|
||||
}
|
||||
|
||||
|
||||
+9
-10
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.codegen.coroutines.INVOKE_SUSPEND_METHOD_NAME
|
||||
import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_IMPL_NAME_SUFFIX
|
||||
import org.jetbrains.kotlin.codegen.coroutines.reportSuspensionPointInsideMonitor
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
@@ -45,7 +45,7 @@ internal fun MethodNode.acceptWithStateMachine(
|
||||
) {
|
||||
val state = classCodegen.context.state
|
||||
val languageVersionSettings = state.languageVersionSettings
|
||||
assert(languageVersionSettings.isReleaseCoroutines()) { "Experimental coroutines are unsupported in JVM_IR backend" }
|
||||
assert(languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) { "Experimental coroutines are unsupported in JVM_IR backend" }
|
||||
val element = if (irFunction.isSuspend)
|
||||
irFunction.psiElement ?: classCodegen.irClass.psiElement
|
||||
else
|
||||
@@ -67,21 +67,20 @@ internal fun MethodNode.acceptWithStateMachine(
|
||||
|
||||
val visitor = CoroutineTransformerMethodVisitor(
|
||||
methodVisitor, access, name, desc, signature, exceptions.toTypedArray(),
|
||||
containingClassInternalName = classCodegen.type.internalName,
|
||||
obtainClassBuilderForCoroutineState = obtainContinuationClassBuilder,
|
||||
isForNamedFunction = irFunction.isSuspend,
|
||||
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
disableTailCallOptimizationForFunctionReturningUnit = irFunction.isSuspend && irFunction.suspendFunctionOriginal().let {
|
||||
it.returnType.isUnit() && it.anyOfOverriddenFunctionsReturnsNonUnit()
|
||||
},
|
||||
reportSuspensionPointInsideMonitor = { reportSuspensionPointInsideMonitor(element as KtElement, state, it) },
|
||||
lineNumber = lineNumber,
|
||||
sourceFile = classCodegen.irClass.file.name,
|
||||
languageVersionSettings = languageVersionSettings,
|
||||
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
containingClassInternalName = classCodegen.type.internalName,
|
||||
isForNamedFunction = irFunction.isSuspend, // SuspendLambda.invokeSuspend is not suspend
|
||||
sourceFile = classCodegen.irClass.file.name, // SuspendLambda.invokeSuspend is not suspend
|
||||
needDispatchReceiver = irFunction.isSuspend && (irFunction.dispatchReceiverParameter != null
|
||||
|| irFunction.origin == JvmLoweredDeclarationOrigin.SUSPEND_IMPL_STATIC_FUNCTION),
|
||||
internalNameForDispatchReceiver = classCodegen.type.internalName,
|
||||
putContinuationParameterToLvt = false,
|
||||
disableTailCallOptimizationForFunctionReturningUnit = irFunction.isSuspend && irFunction.suspendFunctionOriginal().let {
|
||||
it.returnType.isUnit() && it.anyOfOverriddenFunctionsReturnsNonUnit()
|
||||
},
|
||||
useOldSpilledVarTypeAnalysis = state.configuration.getBoolean(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS),
|
||||
initialVarsCountByType = varsCountByType,
|
||||
)
|
||||
|
||||
+2
-3
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fixStackAndJump
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
@@ -534,7 +533,7 @@ class ExpressionCodegen(
|
||||
MaterialValue(this, unboxedInlineClassIrType.asmType, unboxedInlineClassIrType).apply {
|
||||
if (!irFunction.shouldContainSuspendMarkers()) {
|
||||
// Since the coroutine transformer won't run, we need to do this manually.
|
||||
mv.generateCoroutineSuspendedCheck(state.languageVersionSettings)
|
||||
mv.generateCoroutineSuspendedCheck()
|
||||
}
|
||||
mv.checkcast(type)
|
||||
}
|
||||
@@ -1050,7 +1049,7 @@ class ExpressionCodegen(
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(typeOperand, ReifiedTypeInliner.OperationKind.IS)
|
||||
mv.instanceOf(type)
|
||||
} else {
|
||||
TypeIntrinsics.instanceOf(mv, kotlinType, type, state.languageVersionSettings.isReleaseCoroutines())
|
||||
TypeIntrinsics.instanceOf(mv, kotlinType, type)
|
||||
}
|
||||
expression.onStack
|
||||
}
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ class IrSourceCompilerForInline(
|
||||
}
|
||||
|
||||
override fun compileInlineFunction(jvmSignature: JvmMethodSignature): SMAPAndMethodNode {
|
||||
generateInlineIntrinsicForIr(state.languageVersionSettings, callee.toIrBasedDescriptor())?.let {
|
||||
generateInlineIntrinsicForIr(callee.toIrBasedDescriptor())?.let {
|
||||
return it
|
||||
}
|
||||
if (jvmSignature.asmMethod.name != callee.name.asString()) {
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ private class AddContinuationLowering(context: JvmBackendContext) : SuspendLower
|
||||
copyTypeParametersFrom(irFunction)
|
||||
val resultField = addField {
|
||||
origin = JvmLoweredDeclarationOrigin.CONTINUATION_CLASS_RESULT_FIELD
|
||||
name = Name.identifier(context.state.languageVersionSettings.dataFieldName())
|
||||
name = Name.identifier(CONTINUATION_RESULT_FIELD_NAME)
|
||||
type = context.ir.symbols.resultOfAnyType
|
||||
visibility = JavaDescriptorVisibilities.PACKAGE_VISIBILITY
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ object IdSignatureValues {
|
||||
@JvmField val comparable = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Comparable")
|
||||
@JvmField val charSequence = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "CharSequence")
|
||||
@JvmField val iterable = getPublicSignature(StandardNames.COLLECTIONS_PACKAGE_FQ_NAME, "Iterable")
|
||||
@JvmField val continuation = getPublicSignature(StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE, "Continuation")
|
||||
@JvmField val continuation = getPublicSignature(StandardNames.COROUTINES_PACKAGE_FQ_NAME, "Continuation")
|
||||
@JvmField val result = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Result")
|
||||
@JvmField val sequence = IdSignature.CommonSignature("kotlin.sequences", "Sequence", null, 0)
|
||||
}
|
||||
@@ -157,7 +157,7 @@ fun IrType.isClassType(fqName: FqNameUnsafe, hasQuestionMark: Boolean): Boolean
|
||||
|
||||
fun IrType.isKotlinResult(): Boolean = isClassType(StandardNames.RESULT_FQ_NAME.toUnsafe(), false)
|
||||
|
||||
fun IrType.isNullableContinuation(): Boolean = isClassType(StandardNames.CONTINUATION_INTERFACE_FQ_NAME_RELEASE.toUnsafe(), true)
|
||||
fun IrType.isNullableContinuation(): Boolean = isClassType(StandardNames.CONTINUATION_INTERFACE_FQ_NAME.toUnsafe(), true)
|
||||
|
||||
// FIR and backend instances have different mask.
|
||||
fun IrType.isKClass(): Boolean = isClassType(StandardNames.FqNames.kClass, false)
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ internal class KtUltraLightSuspendContinuationParameter(
|
||||
get() {
|
||||
val descriptor = ktFunction.resolve() as? FunctionDescriptor
|
||||
val returnType = descriptor?.returnType ?: return null
|
||||
return support.moduleDescriptor.getContinuationOfTypeOrAny(returnType, support.isReleasedCoroutine)
|
||||
return support.moduleDescriptor.getContinuationOfTypeOrAny(returnType)
|
||||
}
|
||||
|
||||
private val psiType by lazyPub {
|
||||
|
||||
+1
-1
@@ -624,7 +624,7 @@ class DescriptorSerializer private constructor(
|
||||
}
|
||||
|
||||
if (type.isSuspendFunctionType) {
|
||||
val functionType = type(transformSuspendFunctionToRuntimeFunctionType(type, extension.releaseCoroutines()))
|
||||
val functionType = type(transformSuspendFunctionToRuntimeFunctionType(type))
|
||||
functionType.flags = Flags.getTypeFlags(true, false)
|
||||
return functionType
|
||||
}
|
||||
|
||||
-5
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile
|
||||
import org.jetbrains.kotlin.codegen.coroutines.DO_RESUME_METHOD_NAME
|
||||
import org.jetbrains.kotlin.codegen.coroutines.INVOKE_SUSPEND_METHOD_NAME
|
||||
import org.jetbrains.kotlin.inline.inlineFunctionsJvmNames
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
@@ -137,10 +136,6 @@ object InlineTestUtil {
|
||||
return null
|
||||
}
|
||||
|
||||
if (name == DO_RESUME_METHOD_NAME && desc == "(Ljava/lang/Object;Ljava/lang/Throwable;)Ljava/lang/Object;") {
|
||||
return null
|
||||
}
|
||||
|
||||
if (name == INVOKE_SUSPEND_METHOD_NAME && desc == "(Ljava/lang/Object;)Ljava/lang/Object;") {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -22,15 +22,13 @@ object StandardNames {
|
||||
|
||||
@JvmField val CHAR_CODE = Name.identifier("code")
|
||||
|
||||
@JvmField val COROUTINES_PACKAGE_FQ_NAME_RELEASE = FqName("kotlin.coroutines")
|
||||
@JvmField val COROUTINES_PACKAGE_FQ_NAME = FqName("kotlin.coroutines")
|
||||
|
||||
@JvmField val COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL = COROUTINES_PACKAGE_FQ_NAME_RELEASE.child(Name.identifier("experimental"))
|
||||
@JvmField val COROUTINES_JVM_INTERNAL_PACKAGE_FQ_NAME = FqName("kotlin.coroutines.jvm.internal")
|
||||
|
||||
@JvmField val COROUTINES_INTRINSICS_PACKAGE_FQ_NAME_EXPERIMENTAL = COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.child(Name.identifier("intrinsics"))
|
||||
@JvmField val COROUTINES_INTRINSICS_PACKAGE_FQ_NAME = FqName("kotlin.coroutines.intrinsics")
|
||||
|
||||
@JvmField val CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL = COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.child(Name.identifier("Continuation"))
|
||||
|
||||
@JvmField val CONTINUATION_INTERFACE_FQ_NAME_RELEASE = COROUTINES_PACKAGE_FQ_NAME_RELEASE.child(Name.identifier("Continuation"))
|
||||
@JvmField val CONTINUATION_INTERFACE_FQ_NAME = COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("Continuation"))
|
||||
|
||||
@JvmField val RESULT_FQ_NAME = FqName("kotlin.Result")
|
||||
|
||||
@@ -68,7 +66,7 @@ object StandardNames {
|
||||
ANNOTATION_PACKAGE_FQ_NAME,
|
||||
KOTLIN_REFLECT_FQ_NAME,
|
||||
BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier("internal")),
|
||||
COROUTINES_PACKAGE_FQ_NAME_RELEASE
|
||||
COROUTINES_PACKAGE_FQ_NAME
|
||||
)
|
||||
|
||||
object FqNames {
|
||||
@@ -237,7 +235,7 @@ object StandardNames {
|
||||
|
||||
@JvmStatic
|
||||
fun getSuspendFunctionClassId(parameterCount: Int): ClassId {
|
||||
return ClassId(COROUTINES_PACKAGE_FQ_NAME_RELEASE, Name.identifier(getSuspendFunctionName(parameterCount)))
|
||||
return ClassId(COROUTINES_PACKAGE_FQ_NAME, Name.identifier(getSuspendFunctionName(parameterCount)))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ enum class FunctionClassKind(
|
||||
val isReflectType: Boolean
|
||||
) {
|
||||
Function(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Function", isSuspendType = false, isReflectType = false),
|
||||
SuspendFunction(StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE, "SuspendFunction", isSuspendType = true, isReflectType = false),
|
||||
SuspendFunction(StandardNames.COROUTINES_PACKAGE_FQ_NAME, "SuspendFunction", isSuspendType = true, isReflectType = false),
|
||||
KFunction(StandardNames.KOTLIN_REFLECT_FQ_NAME, "KFunction", isSuspendType = false, isReflectType = true),
|
||||
KSuspendFunction(StandardNames.KOTLIN_REFLECT_FQ_NAME, "KSuspendFunction", isSuspendType = true, isReflectType = true);
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ object StandardClassIds {
|
||||
val constantAllowedTypes = primitiveTypes + unsignedTypes + String
|
||||
|
||||
val Continuation =
|
||||
ClassId(StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE, StandardNames.CONTINUATION_INTERFACE_FQ_NAME_RELEASE.shortName())
|
||||
ClassId(StandardNames.COROUTINES_PACKAGE_FQ_NAME, StandardNames.CONTINUATION_INTERFACE_FQ_NAME.shortName())
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun FunctionN(n: Int): ClassId {
|
||||
|
||||
+8
-6
@@ -17,7 +17,7 @@
|
||||
package org.jetbrains.kotlin.load.java.lazy.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.isContinuation
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.CONTINUATION_INTERFACE_FQ_NAME
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
@@ -228,10 +228,8 @@ class LazyJavaClassMemberScope(
|
||||
|
||||
private fun SimpleFunctionDescriptor.createSuspendView(): SimpleFunctionDescriptor? {
|
||||
val continuationParameter = valueParameters.lastOrNull()?.takeIf {
|
||||
isContinuation(
|
||||
it.type.constructor.declarationDescriptor?.fqNameUnsafe?.takeIf(FqNameUnsafe::isSafe)?.toSafe(),
|
||||
c.components.settings.isReleaseCoroutines
|
||||
)
|
||||
it.type.constructor.declarationDescriptor?.fqNameUnsafe?.takeIf(FqNameUnsafe::isSafe)
|
||||
?.toSafe() == CONTINUATION_INTERFACE_FQ_NAME
|
||||
} ?: return null
|
||||
|
||||
val functionDescriptor = newCopyBuilder()
|
||||
@@ -699,7 +697,11 @@ class LazyJavaClassMemberScope(
|
||||
classDescriptor.declaredTypeParameters +
|
||||
constructor.typeParameters.map { p -> c.typeParameterResolver.resolveTypeParameter(p)!! }
|
||||
|
||||
constructorDescriptor.initialize(valueParameters.descriptors, constructor.visibility.toDescriptorVisibility(), constructorTypeParameters)
|
||||
constructorDescriptor.initialize(
|
||||
valueParameters.descriptors,
|
||||
constructor.visibility.toDescriptorVisibility(),
|
||||
constructorTypeParameters
|
||||
)
|
||||
constructorDescriptor.setHasStableParameterNames(false)
|
||||
constructorDescriptor.setHasSynthesizedParameterNames(valueParameters.hasSynthesizedNames)
|
||||
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ fun <T : Any> mapType(
|
||||
|
||||
if (kotlinType.isSuspendFunctionType) {
|
||||
return mapType(
|
||||
transformSuspendFunctionToRuntimeFunctionType(kotlinType, typeMappingConfiguration.releaseCoroutines()),
|
||||
transformSuspendFunctionToRuntimeFunctionType(kotlinType),
|
||||
factory, mode, typeMappingConfiguration, descriptorTypeWriter, writeGenericType
|
||||
)
|
||||
}
|
||||
|
||||
@@ -305,7 +305,7 @@ public abstract class KotlinBuiltIns {
|
||||
|
||||
@NotNull
|
||||
public ClassDescriptor getSuspendFunction(int parameterCount) {
|
||||
return getBuiltInClassByFqName(COROUTINES_PACKAGE_FQ_NAME_RELEASE.child(Name.identifier(getSuspendFunctionName(parameterCount))));
|
||||
return getBuiltInClassByFqName(COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier(getSuspendFunctionName(parameterCount))));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -316,7 +316,7 @@ public abstract class KotlinBuiltIns {
|
||||
@NotNull
|
||||
public ClassDescriptor getKSuspendFunction(int parameterCount) {
|
||||
Name name = Name.identifier(FunctionClassKind.KSuspendFunction.getClassNamePrefix() + parameterCount);
|
||||
return getBuiltInClassByFqName(COROUTINES_PACKAGE_FQ_NAME_RELEASE.child(name));
|
||||
return getBuiltInClassByFqName(COROUTINES_PACKAGE_FQ_NAME.child(name));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.builtins
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.BUILT_INS_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.KOTLIN_REFLECT_FQ_NAME
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.K_FUNCTION_PREFIX
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.K_SUSPEND_FUNCTION_PREFIX
|
||||
@@ -204,7 +204,7 @@ class ReflectionTypes(module: ModuleDescriptor, private val notFoundClasses: Not
|
||||
|| shortName == "KCallable" || shortName == "KAnnotatedElement"
|
||||
|
||||
}
|
||||
if (packageName == BUILT_INS_PACKAGE_FQ_NAME || packageName == COROUTINES_PACKAGE_FQ_NAME_RELEASE) {
|
||||
if (packageName == BUILT_INS_PACKAGE_FQ_NAME || packageName == COROUTINES_PACKAGE_FQ_NAME) {
|
||||
return shortName.startsWith("Function") // FunctionN, Function
|
||||
|| shortName.startsWith("SuspendFunction")
|
||||
}
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.builtins.functions
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.BUILT_INS_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.KOTLIN_REFLECT_FQ_NAME
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
@@ -102,7 +102,7 @@ class FunctionClassDescriptor(
|
||||
FunctionClassKind.SuspendFunction -> // SuspendFunction$N<...> <: Function
|
||||
listOf(functionClassId)
|
||||
FunctionClassKind.KSuspendFunction -> // KSuspendFunction$N<...> <: KFunction
|
||||
listOf(kFunctionClassId, ClassId(COROUTINES_PACKAGE_FQ_NAME_RELEASE, FunctionClassKind.SuspendFunction.numberedClassName(arity)))
|
||||
listOf(kFunctionClassId, ClassId(COROUTINES_PACKAGE_FQ_NAME, FunctionClassKind.SuspendFunction.numberedClassName(arity)))
|
||||
}
|
||||
|
||||
val moduleDescriptor = containingDeclaration.containingDeclaration
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.builtins.functions
|
||||
|
||||
import org.jetbrains.kotlin.builtins.FunctionInterfacePackageFragment
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.BUILT_INS_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.KOTLIN_REFLECT_FQ_NAME
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.deserialization.ClassDescriptorFactory
|
||||
@@ -79,7 +79,7 @@ fun functionInterfacePackageFragmentProvider(
|
||||
val fragments = listOf(
|
||||
KOTLIN_REFLECT_FQ_NAME,
|
||||
BUILT_INS_PACKAGE_FQ_NAME,
|
||||
COROUTINES_PACKAGE_FQ_NAME_RELEASE
|
||||
COROUTINES_PACKAGE_FQ_NAME
|
||||
).map { fqName ->
|
||||
FunctionInterfacePackageFragmentImpl(classFactory, module, fqName)
|
||||
}
|
||||
|
||||
@@ -5,10 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.builtins
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.CONTINUATION_INTERFACE_FQ_NAME_RELEASE
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.CONTINUATION_INTERFACE_FQ_NAME
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
@@ -17,18 +15,17 @@ 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.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
|
||||
private val FAKE_CONTINUATION_CLASS_DESCRIPTOR_EXPERIMENTAL =
|
||||
private val FAKE_CONTINUATION_CLASS_DESCRIPTOR =
|
||||
MutableClassDescriptor(
|
||||
EmptyPackageFragmentDescriptor(ErrorUtils.getErrorModule(), COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL),
|
||||
EmptyPackageFragmentDescriptor(ErrorUtils.getErrorModule(), COROUTINES_PACKAGE_FQ_NAME),
|
||||
ClassKind.INTERFACE, /* isInner = */ false, /* isExternal = */ false,
|
||||
CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL.shortName(), SourceElement.NO_SOURCE, LockBasedStorageManager.NO_LOCKS
|
||||
CONTINUATION_INTERFACE_FQ_NAME.shortName(), SourceElement.NO_SOURCE, LockBasedStorageManager.NO_LOCKS
|
||||
).apply {
|
||||
modality = Modality.ABSTRACT
|
||||
visibility = DescriptorVisibilities.PUBLIC
|
||||
@@ -40,48 +37,26 @@ private val FAKE_CONTINUATION_CLASS_DESCRIPTOR_EXPERIMENTAL =
|
||||
createTypeConstructor()
|
||||
}
|
||||
|
||||
private val FAKE_CONTINUATION_CLASS_DESCRIPTOR_RELEASE =
|
||||
MutableClassDescriptor(
|
||||
EmptyPackageFragmentDescriptor(ErrorUtils.getErrorModule(), COROUTINES_PACKAGE_FQ_NAME_RELEASE),
|
||||
ClassKind.INTERFACE, /* isInner = */ false, /* isExternal = */ false,
|
||||
CONTINUATION_INTERFACE_FQ_NAME_RELEASE.shortName(), SourceElement.NO_SOURCE, LockBasedStorageManager.NO_LOCKS
|
||||
).apply {
|
||||
modality = Modality.ABSTRACT
|
||||
visibility = DescriptorVisibilities.PUBLIC
|
||||
setTypeParameterDescriptors(
|
||||
TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||
this, Annotations.EMPTY, false, Variance.IN_VARIANCE, Name.identifier("T"), 0, LockBasedStorageManager.NO_LOCKS
|
||||
).let(::listOf)
|
||||
)
|
||||
createTypeConstructor()
|
||||
}
|
||||
|
||||
fun transformSuspendFunctionToRuntimeFunctionType(suspendFunType: KotlinType, isReleaseCoroutines: Boolean): SimpleType {
|
||||
fun transformSuspendFunctionToRuntimeFunctionType(suspendFunType: KotlinType): SimpleType {
|
||||
assert(suspendFunType.isSuspendFunctionType) {
|
||||
"This type should be suspend function type: $suspendFunType"
|
||||
}
|
||||
|
||||
return createFunctionType(
|
||||
suspendFunType.builtIns,
|
||||
suspendFunType.annotations,
|
||||
suspendFunType.getReceiverTypeFromFunctionType(),
|
||||
suspendFunType.getValueParameterTypesFromFunctionType().map(TypeProjection::getType) +
|
||||
KotlinTypeFactory.simpleType(
|
||||
suspendFunType.builtIns,
|
||||
suspendFunType.annotations,
|
||||
suspendFunType.getReceiverTypeFromFunctionType(),
|
||||
suspendFunType.getValueParameterTypesFromFunctionType().map(TypeProjection::getType) +
|
||||
KotlinTypeFactory.simpleType(
|
||||
Annotations.EMPTY,
|
||||
// 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.
|
||||
if (isReleaseCoroutines) FAKE_CONTINUATION_CLASS_DESCRIPTOR_RELEASE.typeConstructor
|
||||
else FAKE_CONTINUATION_CLASS_DESCRIPTOR_EXPERIMENTAL.typeConstructor,
|
||||
FAKE_CONTINUATION_CLASS_DESCRIPTOR.typeConstructor,
|
||||
listOf(suspendFunType.getReturnTypeFromFunctionType().asTypeProjection()), nullable = false
|
||||
),
|
||||
// TODO: names
|
||||
null,
|
||||
suspendFunType.builtIns.nullableAnyType
|
||||
),
|
||||
// TODO: names
|
||||
null,
|
||||
suspendFunType.builtIns.nullableAnyType
|
||||
).makeNullableAsSpecified(suspendFunType.isMarkedNullable)
|
||||
}
|
||||
|
||||
fun isContinuation(name: FqName?, isReleaseCoroutines: Boolean): Boolean {
|
||||
return if (isReleaseCoroutines) name == CONTINUATION_INTERFACE_FQ_NAME_RELEASE
|
||||
else name == CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL
|
||||
}
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.CONTINUATION_INTERFACE_FQ_NAME_RELEASE
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.CONTINUATION_INTERFACE_FQ_NAME
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -30,19 +29,15 @@ fun ModuleDescriptor.resolveClassByFqName(fqName: FqName, lookupLocation: Lookup
|
||||
?.getContributedClassifier(fqName.shortName(), lookupLocation) as? ClassDescriptor
|
||||
}
|
||||
|
||||
fun ModuleDescriptor.findContinuationClassDescriptorOrNull(lookupLocation: LookupLocation, releaseCoroutines: Boolean) =
|
||||
if (releaseCoroutines)
|
||||
resolveClassByFqName(CONTINUATION_INTERFACE_FQ_NAME_RELEASE, lookupLocation)
|
||||
else
|
||||
resolveClassByFqName(CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL, lookupLocation)
|
||||
fun ModuleDescriptor.findContinuationClassDescriptorOrNull(lookupLocation: LookupLocation): ClassDescriptor? =
|
||||
resolveClassByFqName(CONTINUATION_INTERFACE_FQ_NAME, lookupLocation)
|
||||
|
||||
fun ModuleDescriptor.findContinuationClassDescriptor(lookupLocation: LookupLocation, releaseCoroutines: Boolean) =
|
||||
findContinuationClassDescriptorOrNull(lookupLocation, releaseCoroutines).sure { "Continuation interface is not found" }
|
||||
fun ModuleDescriptor.findContinuationClassDescriptor(lookupLocation: LookupLocation) =
|
||||
findContinuationClassDescriptorOrNull(lookupLocation).sure { "Continuation interface is not found" }
|
||||
|
||||
fun ModuleDescriptor.getContinuationOfTypeOrAny(kotlinType: KotlinType, isReleaseCoroutines: Boolean) =
|
||||
fun ModuleDescriptor.getContinuationOfTypeOrAny(kotlinType: KotlinType) =
|
||||
module.findContinuationClassDescriptorOrNull(
|
||||
NoLookupLocation.FROM_DESERIALIZATION,
|
||||
isReleaseCoroutines
|
||||
NoLookupLocation.FROM_DESERIALIZATION
|
||||
)?.defaultType?.let {
|
||||
KotlinTypeFactory.simpleType(
|
||||
it,
|
||||
|
||||
-3
@@ -27,9 +27,6 @@ interface DeserializationConfiguration {
|
||||
val readDeserializedContracts: Boolean
|
||||
get() = false
|
||||
|
||||
val releaseCoroutines: Boolean
|
||||
get() = false
|
||||
|
||||
/**
|
||||
* We may want to preserve the order of the declarations the same as in the serialized object
|
||||
* (for example, to later create a decompiled code with the original order of declarations).
|
||||
|
||||
+13
-103
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.serialization.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl
|
||||
@@ -16,13 +15,9 @@ import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.*
|
||||
import org.jetbrains.kotlin.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor.CoroutinesCompatibilityMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||
|
||||
class MemberDeserializer(private val c: DeserializationContext) {
|
||||
private val annotationDeserializer = AnnotationDeserializer(c.components.moduleDescriptor, c.components.notFoundClasses)
|
||||
@@ -147,40 +142,21 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
||||
property.initialize(
|
||||
getter, setter,
|
||||
FieldDescriptorImpl(getPropertyFieldAnnotations(proto, isDelegate = false), property),
|
||||
FieldDescriptorImpl(getPropertyFieldAnnotations(proto, isDelegate = true), property),
|
||||
property.checkExperimentalCoroutine(local.typeDeserializer)
|
||||
FieldDescriptorImpl(getPropertyFieldAnnotations(proto, isDelegate = true), property)
|
||||
)
|
||||
|
||||
return property
|
||||
}
|
||||
|
||||
private fun DeserializedMemberDescriptor.checkExperimentalCoroutine(
|
||||
typeDeserializer: TypeDeserializer
|
||||
): DeserializedMemberDescriptor.CoroutinesCompatibilityMode {
|
||||
if (!versionAndReleaseCoroutinesMismatch()) return CoroutinesCompatibilityMode.COMPATIBLE
|
||||
|
||||
forceUpperBoundsComputation(typeDeserializer)
|
||||
|
||||
return if (typeDeserializer.experimentalSuspendFunctionTypeEncountered)
|
||||
CoroutinesCompatibilityMode.INCOMPATIBLE
|
||||
else
|
||||
CoroutinesCompatibilityMode.COMPATIBLE
|
||||
}
|
||||
|
||||
private fun forceUpperBoundsComputation(typeDeserializer: TypeDeserializer) {
|
||||
typeDeserializer.ownTypeParameters.forEach { it.upperBounds }
|
||||
}
|
||||
|
||||
private fun DeserializedSimpleFunctionDescriptor.initializeWithCoroutinesExperimentalityStatus(
|
||||
extensionReceiverParameter: ReceiverParameterDescriptor?,
|
||||
dispatchReceiverParameter: ReceiverParameterDescriptor?,
|
||||
typeParameters: List<TypeParameterDescriptor>,
|
||||
unsubstitutedValueParameters: List<ValueParameterDescriptor>,
|
||||
unsubstitutedReturnType: KotlinType?,
|
||||
modality: Modality?,
|
||||
visibility: DescriptorVisibility,
|
||||
userDataMap: Map<out CallableDescriptor.UserDataKey<*>, *>,
|
||||
isSuspend: Boolean
|
||||
extensionReceiverParameter: ReceiverParameterDescriptor?,
|
||||
dispatchReceiverParameter: ReceiverParameterDescriptor?,
|
||||
typeParameters: List<TypeParameterDescriptor>,
|
||||
unsubstitutedValueParameters: List<ValueParameterDescriptor>,
|
||||
unsubstitutedReturnType: KotlinType?,
|
||||
modality: Modality?,
|
||||
visibility: DescriptorVisibility,
|
||||
userDataMap: Map<out CallableDescriptor.UserDataKey<*>, *>
|
||||
) {
|
||||
initialize(
|
||||
extensionReceiverParameter,
|
||||
@@ -190,63 +166,12 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
||||
unsubstitutedReturnType,
|
||||
modality,
|
||||
visibility,
|
||||
userDataMap,
|
||||
computeExperimentalityModeForFunctions(
|
||||
extensionReceiverParameter,
|
||||
unsubstitutedValueParameters,
|
||||
typeParameters,
|
||||
unsubstitutedReturnType,
|
||||
isSuspend
|
||||
)
|
||||
userDataMap
|
||||
)
|
||||
}
|
||||
|
||||
private fun DeserializedCallableMemberDescriptor.computeExperimentalityModeForFunctions(
|
||||
extensionReceiverParameter: ReceiverParameterDescriptor?,
|
||||
parameters: Collection<ValueParameterDescriptor>,
|
||||
typeParameters: Collection<TypeParameterDescriptor>,
|
||||
returnType: KotlinType?,
|
||||
isSuspend: Boolean
|
||||
): DeserializedMemberDescriptor.CoroutinesCompatibilityMode {
|
||||
if (!versionAndReleaseCoroutinesMismatch()) return CoroutinesCompatibilityMode.COMPATIBLE
|
||||
if (fqNameOrNull() == KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME) return CoroutinesCompatibilityMode.COMPATIBLE
|
||||
|
||||
val types = parameters.map { it.type } + listOfNotNull(extensionReceiverParameter?.type)
|
||||
|
||||
if (returnType?.containsSuspendFunctionType() == true) return CoroutinesCompatibilityMode.INCOMPATIBLE
|
||||
if (typeParameters.any { typeParameter -> typeParameter.upperBounds.any { it.containsSuspendFunctionType() } }) {
|
||||
return CoroutinesCompatibilityMode.INCOMPATIBLE
|
||||
}
|
||||
|
||||
val maxFromParameters = types.map { type ->
|
||||
when {
|
||||
type.isSuspendFunctionType && type.arguments.size <= 3 ->
|
||||
if (type.arguments.any { it.type.containsSuspendFunctionType() })
|
||||
CoroutinesCompatibilityMode.INCOMPATIBLE
|
||||
else
|
||||
CoroutinesCompatibilityMode.NEEDS_WRAPPER
|
||||
|
||||
type.containsSuspendFunctionType() -> CoroutinesCompatibilityMode.INCOMPATIBLE
|
||||
|
||||
else -> CoroutinesCompatibilityMode.COMPATIBLE
|
||||
}
|
||||
}.maxOrNull() ?: CoroutinesCompatibilityMode.COMPATIBLE
|
||||
|
||||
return maxOf(
|
||||
if (isSuspend)
|
||||
CoroutinesCompatibilityMode.NEEDS_WRAPPER
|
||||
else
|
||||
CoroutinesCompatibilityMode.COMPATIBLE,
|
||||
maxFromParameters
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun KotlinType.containsSuspendFunctionType() = contains(UnwrappedType::isSuspendFunctionType)
|
||||
|
||||
|
||||
private fun DeserializedMemberDescriptor.versionAndReleaseCoroutinesMismatch(): Boolean =
|
||||
c.components.configuration.releaseCoroutines && versionRequirements.none {
|
||||
versionRequirements.none {
|
||||
it.version == VersionRequirement.Version(1, 3) && it.kind == ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION
|
||||
}
|
||||
|
||||
@@ -285,8 +210,7 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
||||
local.typeDeserializer.type(proto.returnType(c.typeTable)),
|
||||
ProtoEnumFlags.modality(Flags.MODALITY.get(flags)),
|
||||
ProtoEnumFlags.descriptorVisibility(Flags.VISIBILITY.get(flags)),
|
||||
emptyMap<CallableDescriptor.UserDataKey<*>, Any?>(),
|
||||
Flags.IS_SUSPEND.get(flags)
|
||||
emptyMap<CallableDescriptor.UserDataKey<*>, Any?>()
|
||||
)
|
||||
function.isOperator = Flags.IS_OPERATOR.get(flags)
|
||||
function.isInfix = Flags.IS_INFIX.get(flags)
|
||||
@@ -321,8 +245,7 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
||||
typeAlias.initialize(
|
||||
local.typeDeserializer.ownTypeParameters,
|
||||
local.typeDeserializer.simpleType(proto.underlyingType(c.typeTable), expandTypeAliases = false),
|
||||
local.typeDeserializer.simpleType(proto.expandedType(c.typeTable), expandTypeAliases = false),
|
||||
typeAlias.checkExperimentalCoroutine(local.typeDeserializer)
|
||||
local.typeDeserializer.simpleType(proto.expandedType(c.typeTable), expandTypeAliases = false)
|
||||
)
|
||||
|
||||
return typeAlias
|
||||
@@ -349,19 +272,6 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
||||
|
||||
descriptor.setHasStableParameterNames(!Flags.IS_CONSTRUCTOR_WITH_NON_STABLE_PARAMETER_NAMES.get(proto.flags))
|
||||
|
||||
val doesClassContainIncompatibility =
|
||||
(c.containingDeclaration as? DeserializedClassDescriptor)
|
||||
?.c?.typeDeserializer?.experimentalSuspendFunctionTypeEncountered == true
|
||||
&& descriptor.versionAndReleaseCoroutinesMismatch()
|
||||
|
||||
descriptor.coroutinesExperimentalCompatibilityMode =
|
||||
if (doesClassContainIncompatibility)
|
||||
CoroutinesCompatibilityMode.INCOMPATIBLE
|
||||
else descriptor.computeExperimentalityModeForFunctions(
|
||||
null, descriptor.valueParameters, descriptor.typeParameters,
|
||||
descriptor.returnType, isSuspend = false
|
||||
)
|
||||
|
||||
return descriptor
|
||||
}
|
||||
|
||||
|
||||
+3
-11
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.serialization.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.builtins.*
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.CONTINUATION_INTERFACE_FQ_NAME
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
@@ -25,8 +26,7 @@ class TypeDeserializer(
|
||||
private val parent: TypeDeserializer?,
|
||||
typeParameterProtos: List<ProtoBuf.TypeParameter>,
|
||||
private val debugName: String,
|
||||
private val containerPresentableName: String,
|
||||
var experimentalSuspendFunctionTypeEncountered: Boolean = false
|
||||
private val containerPresentableName: String
|
||||
) {
|
||||
private val classifierDescriptors: (Int) -> ClassifierDescriptor? =
|
||||
c.storageManager.createMemoizedFunctionWithNullableValues { fqNameIndex ->
|
||||
@@ -195,13 +195,9 @@ class TypeDeserializer(
|
||||
}
|
||||
|
||||
private fun transformRuntimeFunctionTypeToSuspendFunction(funType: KotlinType): SimpleType? {
|
||||
val isReleaseCoroutines = c.components.configuration.releaseCoroutines
|
||||
|
||||
val continuationArgumentType = funType.getValueParameterTypesFromFunctionType().lastOrNull()?.type ?: return null
|
||||
val continuationArgumentFqName = continuationArgumentType.constructor.declarationDescriptor?.fqNameSafe
|
||||
if (continuationArgumentType.arguments.size != 1 || !(isContinuation(continuationArgumentFqName, true) ||
|
||||
isContinuation(continuationArgumentFqName, false))
|
||||
) {
|
||||
if (continuationArgumentType.arguments.size != 1 || continuationArgumentFqName != CONTINUATION_INTERFACE_FQ_NAME) {
|
||||
return funType as SimpleType?
|
||||
}
|
||||
|
||||
@@ -212,10 +208,6 @@ class TypeDeserializer(
|
||||
return createSimpleSuspendFunctionType(funType, suspendReturnType)
|
||||
}
|
||||
|
||||
// Load experimental suspend function type as suspend function type
|
||||
experimentalSuspendFunctionTypeEncountered = experimentalSuspendFunctionTypeEncountered ||
|
||||
(isReleaseCoroutines && isContinuation(continuationArgumentFqName, !isReleaseCoroutines))
|
||||
|
||||
return createSimpleSuspendFunctionType(funType, suspendReturnType)
|
||||
}
|
||||
|
||||
|
||||
+2
-63
@@ -34,14 +34,6 @@ interface DeserializedMemberDescriptor : DeserializedDescriptor, MemberDescripto
|
||||
// Information about the origin of this callable's container (class or package part on JVM) or null if there's no such information.
|
||||
// TODO: merge with sourceElement of containingDeclaration
|
||||
override val containerSource: DeserializedContainerSource?
|
||||
|
||||
val coroutinesExperimentalCompatibilityMode: CoroutinesCompatibilityMode
|
||||
|
||||
enum class CoroutinesCompatibilityMode {
|
||||
COMPATIBLE,
|
||||
NEEDS_WRAPPER,
|
||||
INCOMPATIBLE
|
||||
}
|
||||
}
|
||||
|
||||
interface DeserializedCallableMemberDescriptor : DeserializedMemberDescriptor, CallableMemberDescriptor
|
||||
@@ -64,34 +56,6 @@ class DeserializedSimpleFunctionDescriptor(
|
||||
source ?: SourceElement.NO_SOURCE
|
||||
) {
|
||||
|
||||
override var coroutinesExperimentalCompatibilityMode = DeserializedMemberDescriptor.CoroutinesCompatibilityMode.COMPATIBLE
|
||||
private set
|
||||
|
||||
fun initialize(
|
||||
extensionReceiverParameter: ReceiverParameterDescriptor?,
|
||||
dispatchReceiverParameter: ReceiverParameterDescriptor?,
|
||||
typeParameters: List<TypeParameterDescriptor>,
|
||||
unsubstitutedValueParameters: List<ValueParameterDescriptor>,
|
||||
unsubstitutedReturnType: KotlinType?,
|
||||
modality: Modality?,
|
||||
visibility: DescriptorVisibility,
|
||||
userDataMap: Map<out CallableDescriptor.UserDataKey<*>, *>,
|
||||
isExperimentalCoroutineInReleaseEnvironment: DeserializedMemberDescriptor.CoroutinesCompatibilityMode
|
||||
): SimpleFunctionDescriptorImpl {
|
||||
return super.initialize(
|
||||
extensionReceiverParameter,
|
||||
dispatchReceiverParameter,
|
||||
typeParameters,
|
||||
unsubstitutedValueParameters,
|
||||
unsubstitutedReturnType,
|
||||
modality,
|
||||
visibility,
|
||||
userDataMap
|
||||
).also {
|
||||
this.coroutinesExperimentalCompatibilityMode = isExperimentalCoroutineInReleaseEnvironment
|
||||
}
|
||||
}
|
||||
|
||||
override fun createSubstitutedCopy(
|
||||
newOwner: DeclarationDescriptor,
|
||||
original: FunctionDescriptor?,
|
||||
@@ -105,7 +69,6 @@ class DeserializedSimpleFunctionDescriptor(
|
||||
proto, nameResolver, typeTable, versionRequirementTable, containerSource, source
|
||||
).also {
|
||||
it.setHasStableParameterNames(hasStableParameterNames())
|
||||
it.coroutinesExperimentalCompatibilityMode = coroutinesExperimentalCompatibilityMode
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,20 +96,6 @@ class DeserializedPropertyDescriptor(
|
||||
containingDeclaration, original, annotations, modality, visibility, isVar, name, kind, SourceElement.NO_SOURCE,
|
||||
isLateInit, isConst, isExpect, false, isExternal, isDelegated
|
||||
) {
|
||||
override var coroutinesExperimentalCompatibilityMode = DeserializedMemberDescriptor.CoroutinesCompatibilityMode.COMPATIBLE
|
||||
private set
|
||||
|
||||
fun initialize(
|
||||
getter: PropertyGetterDescriptorImpl?,
|
||||
setter: PropertySetterDescriptor?,
|
||||
backingField: FieldDescriptor?,
|
||||
delegateField: FieldDescriptor?,
|
||||
isExperimentalCoroutineInReleaseEnvironment: DeserializedMemberDescriptor.CoroutinesCompatibilityMode
|
||||
) {
|
||||
super.initialize(getter, setter, backingField, delegateField)
|
||||
.also { this.coroutinesExperimentalCompatibilityMode = isExperimentalCoroutineInReleaseEnvironment }
|
||||
}
|
||||
|
||||
override fun createSubstitutedCopy(
|
||||
newOwner: DeclarationDescriptor,
|
||||
newModality: Modality,
|
||||
@@ -180,9 +129,6 @@ class DeserializedClassConstructorDescriptor(
|
||||
) : DeserializedCallableMemberDescriptor,
|
||||
ClassConstructorDescriptorImpl(containingDeclaration, original, annotations, isPrimary, kind, source ?: SourceElement.NO_SOURCE) {
|
||||
|
||||
override var coroutinesExperimentalCompatibilityMode = DeserializedMemberDescriptor.CoroutinesCompatibilityMode.COMPATIBLE
|
||||
internal set
|
||||
|
||||
override fun createSubstitutedCopy(
|
||||
newOwner: DeclarationDescriptor,
|
||||
original: FunctionDescriptor?,
|
||||
@@ -196,7 +142,6 @@ class DeserializedClassConstructorDescriptor(
|
||||
proto, nameResolver, typeTable, versionRequirementTable, containerSource, source
|
||||
).also {
|
||||
it.setHasStableParameterNames(hasStableParameterNames())
|
||||
it.coroutinesExperimentalCompatibilityMode = coroutinesExperimentalCompatibilityMode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,14 +174,10 @@ class DeserializedTypeAliasDescriptor(
|
||||
private lateinit var typeConstructorParameters: List<TypeParameterDescriptor>
|
||||
private lateinit var defaultTypeImpl: SimpleType
|
||||
|
||||
override var coroutinesExperimentalCompatibilityMode = DeserializedMemberDescriptor.CoroutinesCompatibilityMode.COMPATIBLE
|
||||
private set
|
||||
|
||||
fun initialize(
|
||||
declaredTypeParameters: List<TypeParameterDescriptor>,
|
||||
underlyingType: SimpleType,
|
||||
expandedType: SimpleType,
|
||||
isExperimentalCoroutineInReleaseEnvironment: DeserializedMemberDescriptor.CoroutinesCompatibilityMode
|
||||
expandedType: SimpleType
|
||||
) {
|
||||
initialize(declaredTypeParameters)
|
||||
this.underlyingType = underlyingType
|
||||
@@ -244,7 +185,6 @@ class DeserializedTypeAliasDescriptor(
|
||||
typeConstructorParameters = computeConstructorTypeParameters()
|
||||
defaultTypeImpl = computeDefaultType()
|
||||
constructors = getTypeAliasConstructors()
|
||||
this.coroutinesExperimentalCompatibilityMode = isExperimentalCoroutineInReleaseEnvironment
|
||||
}
|
||||
|
||||
override val classDescriptor: ClassDescriptor?
|
||||
@@ -261,8 +201,7 @@ class DeserializedTypeAliasDescriptor(
|
||||
substituted.initialize(
|
||||
declaredTypeParameters,
|
||||
substitutor.safeSubstitute(underlyingType, Variance.INVARIANT).asSimpleType(),
|
||||
substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType(),
|
||||
coroutinesExperimentalCompatibilityMode
|
||||
substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType()
|
||||
)
|
||||
|
||||
return substituted
|
||||
|
||||
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.js.resolve.diagnostics.*
|
||||
import org.jetbrains.kotlin.resolve.PlatformConfiguratorBase
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.InstantiationOfAnnotationClassesCallChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport
|
||||
import org.jetbrains.kotlin.types.DynamicTypesAllowed
|
||||
|
||||
object JsPlatformConfigurator : PlatformConfiguratorBase(
|
||||
@@ -51,7 +50,6 @@ object JsPlatformConfigurator : PlatformConfiguratorBase(
|
||||
container.useInstance(ExtensionFunctionToExternalIsInlinable)
|
||||
container.useInstance(JsQualifierChecker)
|
||||
container.useInstance(JsNativeDiagnosticSuppressor)
|
||||
container.useInstance(CoroutineCompatibilitySupport.DISABLED)
|
||||
}
|
||||
|
||||
override fun configureModuleDependentCheckers(container: StorageComponentContainer) {
|
||||
|
||||
+2
-2
@@ -131,8 +131,8 @@ public class TranslationContext {
|
||||
if (function.isSuspend()) {
|
||||
ClassDescriptor continuationDescriptor =
|
||||
DescriptorUtilKt.findContinuationClassDescriptor(
|
||||
getCurrentModule(), NoLookupLocation.FROM_BACKEND,
|
||||
getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines));
|
||||
getCurrentModule(), NoLookupLocation.FROM_BACKEND
|
||||
);
|
||||
|
||||
return new ValueParameterDescriptorImpl(function, null, function.getValueParameters().size(),
|
||||
Annotations.Companion.getEMPTY(), Name.identifier("continuation"),
|
||||
|
||||
-1
@@ -38,7 +38,6 @@ class FunctionIntrinsics {
|
||||
AsDynamicFIF,
|
||||
CoroutineContextFIF,
|
||||
SuspendCoroutineUninterceptedOrReturnFIF,
|
||||
InterceptedFIF,
|
||||
TypeOfFIF
|
||||
)
|
||||
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.resolve.calls.checkers.isBuiltInCoroutineContext
|
||||
|
||||
object CoroutineContextFIF : FunctionIntrinsicFactory {
|
||||
override fun getIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? {
|
||||
if (!descriptor.isBuiltInCoroutineContext(context.languageVersionSettings)) return null
|
||||
if (!descriptor.isBuiltInCoroutineContext()) return null
|
||||
return Intrinsic
|
||||
}
|
||||
|
||||
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.isBuiltInIntercepted
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpression
|
||||
import org.jetbrains.kotlin.js.translate.callTranslator.CallInfo
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
||||
|
||||
object InterceptedFIF: FunctionIntrinsicFactory {
|
||||
override fun getIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? {
|
||||
if (!descriptor.isBuiltInIntercepted(context.languageVersionSettings)) return null
|
||||
return Intrinsic
|
||||
}
|
||||
|
||||
object Intrinsic: FunctionIntrinsic() {
|
||||
override fun apply(callInfo: CallInfo, arguments: List<JsExpression>, context: TranslationContext): JsExpression {
|
||||
val continuation = callInfo.extensionReceiver ?: error("intercepted shall be extension function")
|
||||
val facadeName = context.getNameForDescriptor(TranslationUtils.getCoroutineProperty(context, "facade"))
|
||||
return JsAstUtils.pureFqn(facadeName, continuation)
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntri
|
||||
|
||||
object SuspendCoroutineUninterceptedOrReturnFIF: FunctionIntrinsicFactory {
|
||||
override fun getIntrinsic(descriptor: FunctionDescriptor, context: TranslationContext): FunctionIntrinsic? {
|
||||
if (!descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(context.languageVersionSettings)) return null
|
||||
if (!descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn()) return null
|
||||
return Intrinsic
|
||||
}
|
||||
object Intrinsic: FunctionIntrinsic() {
|
||||
|
||||
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.builtins.FunctionTypesKt;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.StandardNames;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
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;
|
||||
@@ -397,8 +396,7 @@ public final class TranslationUtils {
|
||||
|
||||
@NotNull
|
||||
public static ClassDescriptor getCoroutineBaseClass(@NotNull TranslationContext context) {
|
||||
FqName className = CoroutineLanguageVersionSettingsUtilKt.coroutinesPackageFqName(context.getLanguageVersionSettings())
|
||||
.child(Name.identifier("CoroutineImpl"));
|
||||
FqName className = StandardNames.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("CoroutineImpl"));
|
||||
ClassDescriptor descriptor = FindClassInModuleKt.findClassAcrossModuleDependencies(
|
||||
context.getCurrentModule(), ClassId.topLevel(className));
|
||||
assert descriptor != null;
|
||||
|
||||
@@ -11,8 +11,8 @@ import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.backend.common.COROUTINE_SUSPENDED_NAME
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.coroutinesIntrinsicsPackageFqName
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
@@ -185,7 +185,7 @@ fun JsFunction.fillCoroutineMetadata(
|
||||
descriptor: FunctionDescriptor,
|
||||
hasController: Boolean
|
||||
) {
|
||||
val suspendPropertyDescriptor = context.currentModule.getPackage(context.languageVersionSettings.coroutinesIntrinsicsPackageFqName())
|
||||
val suspendPropertyDescriptor = context.currentModule.getPackage(StandardNames.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME)
|
||||
.memberScope
|
||||
.getContributedVariables(COROUTINE_SUSPENDED_NAME, NoLookupLocation.FROM_BACKEND).first()
|
||||
|
||||
|
||||
+4
-6
@@ -14,8 +14,6 @@ import org.jetbrains.kotlin.backend.konan.descriptors.kotlinNativeInternal
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.findMainEntryPoint
|
||||
import org.jetbrains.kotlin.backend.konan.lower.TestProcessor
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.config.coroutinesIntrinsicsPackageFqName
|
||||
import org.jetbrains.kotlin.config.coroutinesPackageFqName
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
||||
@@ -359,11 +357,11 @@ internal class KonanSymbols(
|
||||
|
||||
override val suspendCoroutineUninterceptedOrReturn = internalFunction("suspendCoroutineUninterceptedOrReturn")
|
||||
|
||||
private val coroutinesIntrinsicsPackage = context.builtIns.builtInsModule.getPackage(
|
||||
context.config.configuration.languageVersionSettings.coroutinesIntrinsicsPackageFqName()).memberScope
|
||||
private val coroutinesIntrinsicsPackage =
|
||||
context.builtIns.builtInsModule.getPackage(StandardNames.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME).memberScope
|
||||
|
||||
private val coroutinesPackage = context.builtIns.builtInsModule.getPackage(
|
||||
context.config.configuration.languageVersionSettings.coroutinesPackageFqName()).memberScope
|
||||
private val coroutinesPackage =
|
||||
context.builtIns.builtInsModule.getPackage(StandardNames.COROUTINES_PACKAGE_FQ_NAME).memberScope
|
||||
|
||||
override val coroutineContextGetter = symbolTable.referenceSimpleFunction(
|
||||
coroutinesPackage
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ internal class NativeSuspendFunctionsLowering(ctx: Context): AbstractSuspendFunc
|
||||
override val stateMachineMethodName = Name.identifier("invokeSuspend")
|
||||
|
||||
override fun getCoroutineBaseClass(function: IrFunction): IrClassSymbol =
|
||||
(if (function.isRestrictedSuspendFunction(context.irBuiltIns.languageVersionSettings)) {
|
||||
(if (function.isRestrictedSuspendFunction()) {
|
||||
symbols.restrictedContinuationImpl
|
||||
} else {
|
||||
symbols.continuationImpl
|
||||
|
||||
+2
-2
@@ -374,8 +374,8 @@ val IrType.isSimpleTypeWithQuestionMark: Boolean
|
||||
fun IrClass.defaultOrNullableType(hasQuestionMark: Boolean) =
|
||||
if (hasQuestionMark) this.defaultType.makeNullable() else this.defaultType
|
||||
|
||||
fun IrFunction.isRestrictedSuspendFunction(languageVersionSettings: LanguageVersionSettings): Boolean =
|
||||
this.descriptor.extensionReceiverParameter?.type?.isRestrictsSuspensionReceiver(languageVersionSettings) == true
|
||||
fun IrFunction.isRestrictedSuspendFunction(): Boolean =
|
||||
this.descriptor.extensionReceiverParameter?.type?.isRestrictsSuspensionReceiver() == true
|
||||
|
||||
fun IrBuilderWithScope.irByte(value: Byte) =
|
||||
IrConstImpl.byte(startOffset, endOffset, context.irBuiltIns.byteType, value)
|
||||
|
||||
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.builtins.konan
|
||||
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.COROUTINES_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -18,7 +18,7 @@ class KonanBuiltIns(storageManager: StorageManager) : KotlinBuiltIns(storageMana
|
||||
override fun getSuspendFunction(parameterCount: Int) =
|
||||
builtInsModule.findClassAcrossModuleDependencies(
|
||||
ClassId(
|
||||
COROUTINES_PACKAGE_FQ_NAME_RELEASE,
|
||||
COROUTINES_PACKAGE_FQ_NAME,
|
||||
Name.identifier("SuspendFunction$parameterCount")
|
||||
)
|
||||
)!!
|
||||
|
||||
+4
-16
@@ -28,8 +28,6 @@ import org.jetbrains.kotlin.base.kapt3.KaptFlag
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.coroutines.CONTINUATION_PARAMETER_NAME
|
||||
import org.jetbrains.kotlin.codegen.needsExperimentalCoroutinesWrapper
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
@@ -1022,7 +1020,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
|
||||
if (sourceElement == null) return@getNonErrorType null
|
||||
|
||||
if (sourceElement.hasDeclaredReturnType() && isContinuationParameter(parameterDescriptor)) {
|
||||
val continuationTypeFqName = getContinuationTypeFqName(descriptor)
|
||||
val continuationTypeFqName = StandardNames.CONTINUATION_INTERFACE_FQ_NAME
|
||||
val functionReturnType = sourceElement.typeReference!!.text
|
||||
KtPsiFactory(kaptContext.project).createType("$continuationTypeFqName<$functionReturnType>")
|
||||
} else {
|
||||
@@ -1056,19 +1054,9 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
|
||||
val containingCallable = descriptor.containingDeclaration
|
||||
|
||||
return containingCallable.valueParameters.lastOrNull() == descriptor
|
||||
&& descriptor.name == CONTINUATION_PARAMETER_NAME
|
||||
&& descriptor.source == SourceElement.NO_SOURCE
|
||||
&& descriptor.type.constructor.declarationDescriptor?.fqNameSafe == getContinuationTypeFqName(containingCallable)
|
||||
}
|
||||
|
||||
private fun getContinuationTypeFqName(descriptor: CallableDescriptor): FqName {
|
||||
val areCoroutinesReleased = !descriptor.needsExperimentalCoroutinesWrapper()
|
||||
&& kaptContext.generationState.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
|
||||
|
||||
return when (areCoroutinesReleased) {
|
||||
true -> StandardNames.CONTINUATION_INTERFACE_FQ_NAME_RELEASE
|
||||
false -> StandardNames.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL
|
||||
}
|
||||
&& descriptor.name == CONTINUATION_PARAMETER_NAME
|
||||
&& descriptor.source == SourceElement.NO_SOURCE
|
||||
&& descriptor.type.constructor.declarationDescriptor?.fqNameSafe == StandardNames.CONTINUATION_INTERFACE_FQ_NAME
|
||||
}
|
||||
|
||||
private fun <T : JCExpression?> getNonErrorType(
|
||||
|
||||
Reference in New Issue
Block a user