Treat inline suspend functions as inline-only
Now their bodies don't have real state machines, thus they cannot be called correctly from Java #KT-17585 In progress #KT-16603 In progress
This commit is contained in:
@@ -65,7 +65,7 @@ import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveClass;
|
|||||||
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isToArrayFromCollection;
|
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isToArrayFromCollection;
|
||||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
|
||||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isInlineOnlyOrReifiable;
|
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly;
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||||
import static org.jetbrains.kotlin.types.TypeUtils.isNullableType;
|
import static org.jetbrains.kotlin.types.TypeUtils.isNullableType;
|
||||||
@@ -351,7 +351,7 @@ public class AsmUtil {
|
|||||||
DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration();
|
||||||
Visibility memberVisibility = memberDescriptor.getVisibility();
|
Visibility memberVisibility = memberDescriptor.getVisibility();
|
||||||
|
|
||||||
if (isInlineOnlyOrReifiable(memberDescriptor)) return ACC_PRIVATE;
|
if (isEffectivelyInlineOnly(memberDescriptor)) return ACC_PRIVATE;
|
||||||
|
|
||||||
if (memberVisibility == Visibilities.LOCAL && memberDescriptor instanceof CallableMemberDescriptor) {
|
if (memberVisibility == Visibilities.LOCAL && memberDescriptor instanceof CallableMemberDescriptor) {
|
||||||
return ACC_PUBLIC;
|
return ACC_PUBLIC;
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8InterfaceWithDef
|
|||||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
|
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
|
||||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
|
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
|
||||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
|
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
|
||||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isInlineOnlyOrReifiable;
|
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly;
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
|
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||||
@@ -875,7 +875,7 @@ public class FunctionCodegen {
|
|||||||
// $default methods are never private to be accessible from other class files (e.g. inner) without the need of synthetic accessors
|
// $default methods are never private to be accessible from other class files (e.g. inner) without the need of synthetic accessors
|
||||||
// $default methods are never protected to be accessible from subclass nested classes
|
// $default methods are never protected to be accessible from subclass nested classes
|
||||||
int visibilityFlag = Visibilities.isPrivate(functionDescriptor.getVisibility()) ||
|
int visibilityFlag = Visibilities.isPrivate(functionDescriptor.getVisibility()) ||
|
||||||
isInlineOnlyOrReifiable(functionDescriptor) ?
|
isEffectivelyInlineOnly(functionDescriptor) ?
|
||||||
AsmUtil.NO_FLAG_PACKAGE_PRIVATE : Opcodes.ACC_PUBLIC;
|
AsmUtil.NO_FLAG_PACKAGE_PRIVATE : Opcodes.ACC_PUBLIC;
|
||||||
int flags = visibilityFlag | getDeprecatedAccessFlag(functionDescriptor) | ACC_SYNTHETIC;
|
int flags = visibilityFlag | getDeprecatedAccessFlag(functionDescriptor) | ACC_SYNTHETIC;
|
||||||
if (!(functionDescriptor instanceof ConstructorDescriptor)) {
|
if (!(functionDescriptor instanceof ConstructorDescriptor)) {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import java.util.*;
|
|||||||
|
|
||||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityAccessFlag;
|
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityAccessFlag;
|
||||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isNonDefaultInterfaceMember;
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isNonDefaultInterfaceMember;
|
||||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isInlineOnlyOrReifiable;
|
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly;
|
||||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PROTECTED;
|
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PROTECTED;
|
||||||
|
|
||||||
@@ -640,7 +640,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
boolean withinInline,
|
boolean withinInline,
|
||||||
boolean isSuperCall
|
boolean isSuperCall
|
||||||
) {
|
) {
|
||||||
if (isInlineOnlyOrReifiable(unwrappedDescriptor)) return false;
|
if (isEffectivelyInlineOnly(unwrappedDescriptor)) return false;
|
||||||
|
|
||||||
return isSuperCall && withinInline ||
|
return isSuperCall && withinInline ||
|
||||||
(accessFlag & ACC_PRIVATE) != 0 ||
|
(accessFlag & ACC_PRIVATE) != 0 ||
|
||||||
|
|||||||
+1
-3
@@ -139,9 +139,7 @@ class InlineAnalyzerExtension(private val reasonableInlineRules: Iterable<Reason
|
|||||||
if (checkInlinableParameter(descriptor, parameter, functionDescriptor, trace)) return
|
if (checkInlinableParameter(descriptor, parameter, functionDescriptor, trace)) return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InlineUtil.containsReifiedTypeParameters(functionDescriptor) ||
|
if (functionDescriptor.isInlineOnlyOrReifiable() || functionDescriptor.isHeader) return
|
||||||
functionDescriptor.isInlineOnlyOrReifiable() ||
|
|
||||||
functionDescriptor.isHeader) return
|
|
||||||
|
|
||||||
if (reasonableInlineRules.any { it.isInlineReasonable(functionDescriptor, function, trace.bindingContext) }) return
|
if (reasonableInlineRules.any { it.isInlineReasonable(functionDescriptor, function, trace.bindingContext) }) return
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -26,6 +26,6 @@ public final class InlineWithStateMachineKt {
|
|||||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||||
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
||||||
public final static @org.jetbrains.annotations.Nullable method mainSuspend(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
public final static @org.jetbrains.annotations.Nullable method mainSuspend(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
public final static @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
private final static method suspendHere(p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
public final static @org.jetbrains.annotations.Nullable method suspendThere(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
private final static method suspendThere(p0: java.lang.String, p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -28,5 +28,5 @@ public final class InlineWithoutStateMachineKt {
|
|||||||
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
||||||
public final static @org.jetbrains.annotations.Nullable method complexSuspend(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
public final static @org.jetbrains.annotations.Nullable method complexSuspend(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
public final static @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
public final static @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
public final static @org.jetbrains.annotations.Nullable method suspendThere(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
private final static method suspendThere(p0: java.lang.String, p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ 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.StringValue
|
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
fun KotlinBuiltIns.createDeprecatedAnnotation(
|
fun KotlinBuiltIns.createDeprecatedAnnotation(
|
||||||
message: String,
|
message: String,
|
||||||
@@ -73,6 +74,9 @@ private val INLINE_ONLY_ANNOTATION_FQ_NAME = FqName("kotlin.internal.InlineOnly"
|
|||||||
fun MemberDescriptor.isInlineOnlyOrReifiable(): Boolean =
|
fun MemberDescriptor.isInlineOnlyOrReifiable(): Boolean =
|
||||||
this is CallableMemberDescriptor && (isReifiable() || DescriptorUtils.getDirectMember(this).isReifiable() || isInlineOnly())
|
this is CallableMemberDescriptor && (isReifiable() || DescriptorUtils.getDirectMember(this).isReifiable() || isInlineOnly())
|
||||||
|
|
||||||
|
fun MemberDescriptor.isEffectivelyInlineOnly(): Boolean =
|
||||||
|
isInlineOnlyOrReifiable() || safeAs<FunctionDescriptor>()?.let { it.isSuspend && it.isInline } == true
|
||||||
|
|
||||||
fun MemberDescriptor.isInlineOnly(): Boolean {
|
fun MemberDescriptor.isInlineOnly(): Boolean {
|
||||||
if (this !is FunctionDescriptor ||
|
if (this !is FunctionDescriptor ||
|
||||||
!(hasInlineOnlyAnnotation() || DescriptorUtils.getDirectMember(this).hasInlineOnlyAnnotation())) return false
|
!(hasInlineOnlyAnnotation() || DescriptorUtils.getDirectMember(this).hasInlineOnlyAnnotation())) return false
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ package kotlin.reflect.jvm.internal
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.isInlineOnlyOrReifiable
|
import org.jetbrains.kotlin.descriptors.annotations.isEffectivelyInlineOnly
|
||||||
import java.lang.reflect.Constructor
|
import java.lang.reflect.Constructor
|
||||||
import java.lang.reflect.Member
|
import java.lang.reflect.Member
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
@@ -60,7 +60,7 @@ internal class KFunctionImpl private constructor(
|
|||||||
|
|
||||||
private fun isPrivateInBytecode(): Boolean =
|
private fun isPrivateInBytecode(): Boolean =
|
||||||
Visibilities.isPrivate(descriptor.visibility) ||
|
Visibilities.isPrivate(descriptor.visibility) ||
|
||||||
descriptor.isInlineOnlyOrReifiable()
|
descriptor.isEffectivelyInlineOnly()
|
||||||
|
|
||||||
private fun isDeclared(): Boolean = isPrivateInBytecode()
|
private fun isDeclared(): Boolean = isPrivateInBytecode()
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -17,7 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.js.translate.context
|
package org.jetbrains.kotlin.js.translate.context
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.isInlineOnlyOrReifiable
|
import org.jetbrains.kotlin.descriptors.annotations.isEffectivelyInlineOnly
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
import org.jetbrains.kotlin.js.backend.ast.metadata.exportedPackage
|
import org.jetbrains.kotlin.js.backend.ast.metadata.exportedPackage
|
||||||
import org.jetbrains.kotlin.js.backend.ast.metadata.exportedTag
|
import org.jetbrains.kotlin.js.backend.ast.metadata.exportedTag
|
||||||
@@ -44,7 +44,7 @@ internal class DeclarationExporter(val context: StaticContext) {
|
|||||||
if (exportedDeclarations.contains(descriptor)) return
|
if (exportedDeclarations.contains(descriptor)) return
|
||||||
if (descriptor is ConstructorDescriptor && descriptor.isPrimary) return
|
if (descriptor is ConstructorDescriptor && descriptor.isPrimary) return
|
||||||
if (isNativeObject(descriptor) || isLibraryObject(descriptor)) return
|
if (isNativeObject(descriptor) || isLibraryObject(descriptor)) return
|
||||||
if (descriptor.isInlineOnlyOrReifiable()) return
|
if (descriptor.isEffectivelyInlineOnly()) return
|
||||||
|
|
||||||
val suggestedName = context.nameSuggestion.suggest(descriptor) ?: return
|
val suggestedName = context.nameSuggestion.suggest(descriptor) ?: return
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user