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