Fix annotation deserialization on suspend functions
Use proper initial/frontend version of suspend descriptor when writing METHOD_FOR_FUNCTION, because serializer uses this version Also this commit contains adjustments of neighboring code to the describe change #KT-16093 Fixed
This commit is contained in:
@@ -35,13 +35,11 @@ import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
|||||||
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.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
|
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
|
||||||
import org.jetbrains.kotlin.psi.KtElement;
|
import org.jetbrains.kotlin.psi.KtElement;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||||
@@ -64,7 +62,6 @@ import java.util.List;
|
|||||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
|
||||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
|
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
|
||||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.asmTypeForAnonymousClass;
|
|
||||||
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.resolve.jvm.AsmTypes.*;
|
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
||||||
@@ -233,9 +230,10 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void generateKotlinMetadataAnnotation() {
|
protected void generateKotlinMetadataAnnotation() {
|
||||||
FunctionDescriptor freeLambdaDescriptor = createFreeLambdaDescriptor(funDescriptor);
|
FunctionDescriptor frontendFunDescriptor = CodegenUtilKt.unwrapFrontendVersion(funDescriptor);
|
||||||
Method method = v.getSerializationBindings().get(METHOD_FOR_FUNCTION, funDescriptor);
|
FunctionDescriptor freeLambdaDescriptor = createFreeLambdaDescriptor(frontendFunDescriptor);
|
||||||
assert method != null : "No method for " + funDescriptor;
|
Method method = v.getSerializationBindings().get(METHOD_FOR_FUNCTION, frontendFunDescriptor);
|
||||||
|
assert method != null : "No method for " + frontendFunDescriptor;
|
||||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, freeLambdaDescriptor, method);
|
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, freeLambdaDescriptor, method);
|
||||||
|
|
||||||
final DescriptorSerializer serializer =
|
final DescriptorSerializer serializer =
|
||||||
|
|||||||
@@ -209,7 +209,11 @@ public class FunctionCodegen {
|
|||||||
getThrownExceptions(functionDescriptor, typeMapper));
|
getThrownExceptions(functionDescriptor, typeMapper));
|
||||||
|
|
||||||
if (CodegenContextUtil.isImplClassOwner(owner)) {
|
if (CodegenContextUtil.isImplClassOwner(owner)) {
|
||||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, functionDescriptor, asmMethod);
|
v.getSerializationBindings().put(
|
||||||
|
METHOD_FOR_FUNCTION,
|
||||||
|
CodegenUtilKt.<FunctionDescriptor>unwrapFrontendVersion(functionDescriptor),
|
||||||
|
asmMethod
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
generateMethodAnnotations(functionDescriptor, asmMethod, mv);
|
generateMethodAnnotations(functionDescriptor, asmMethod, mv);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
|
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
|
||||||
import org.jetbrains.kotlin.codegen.context.PackageContext
|
import org.jetbrains.kotlin.codegen.context.PackageContext
|
||||||
|
import org.jetbrains.kotlin.codegen.coroutines.unwrapInitialDescriptorForSuspendFunction
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
|
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
|
||||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter
|
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
@@ -53,7 +54,6 @@ import org.jetbrains.kotlin.types.ErrorUtils
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
import org.jetbrains.kotlin.types.isFlexible
|
|
||||||
import org.jetbrains.kotlin.utils.DFS
|
import org.jetbrains.kotlin.utils.DFS
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
@@ -375,3 +375,5 @@ fun initializeVariablesForDestructuredLambdaParameters(codegen: ExpressionCodege
|
|||||||
|
|
||||||
codegen.isShouldMarkLineNumbers = savedIsShouldMarkLineNumbers
|
codegen.isShouldMarkLineNumbers = savedIsShouldMarkLineNumbers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <D : CallableDescriptor> D.unwrapFrontendVersion() = unwrapInitialDescriptorForSuspendFunction()
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ class CoroutineCodegen private constructor(
|
|||||||
setReturnType(
|
setReturnType(
|
||||||
funDescriptor.module.getContinuationOfTypeOrAny(builtIns.unitType)
|
funDescriptor.module.getContinuationOfTypeOrAny(builtIns.unitType)
|
||||||
)
|
)
|
||||||
|
// 'create' method should not inherit initial descriptor for suspend function from original descriptor
|
||||||
|
putUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION, null)
|
||||||
setVisibility(Visibilities.PUBLIC)
|
setVisibility(Visibilities.PUBLIC)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
// !API_VERSION: 1.1
|
||||||
|
// SKIP_TXT
|
||||||
|
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
suspend fun foo(): Unit = suspendCoroutine {
|
||||||
|
it.resume(Unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun bar(): Unit = suspendCoroutineOrReturn {
|
||||||
|
it.resume(Unit)
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
// !API_VERSION: 1.0
|
||||||
|
// SKIP_TXT
|
||||||
|
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
suspend fun foo(): Unit = <!UNRESOLVED_REFERENCE!>suspendCoroutine<!> {
|
||||||
|
<!UNRESOLVED_REFERENCE!>it<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>resume<!>(Unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun bar(): Unit = <!UNRESOLVED_REFERENCE!>suspendCoroutineOrReturn<!> {
|
||||||
|
<!UNRESOLVED_REFERENCE!>it<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>resume<!>(Unit)
|
||||||
|
<!UNRESOLVED_REFERENCE!>COROUTINE_SUSPENDED<!>
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
//ALLOW_AST_ACCESS
|
||||||
|
package test
|
||||||
|
|
||||||
|
annotation class Anno(val t: String)
|
||||||
|
@Anno("foo") suspend fun foo() {}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
@test.Anno(t = "foo") public suspend fun foo(): kotlin.Unit
|
||||||
|
|
||||||
|
public final annotation class Anno : kotlin.Annotation {
|
||||||
|
/*primary*/ public constructor Anno(/*0*/ t: kotlin.String)
|
||||||
|
public final val t: kotlin.String
|
||||||
|
public final fun <get-t>(): kotlin.String
|
||||||
|
}
|
||||||
@@ -791,6 +791,18 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendCoroutineUnavailableWithNewAPI.kt")
|
||||||
|
public void testSuspendCoroutineUnavailableWithNewAPI() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCoroutineUnavailableWithNewAPI.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendCoroutineUnavailableWithOldAPI.kt")
|
||||||
|
public void testSuspendCoroutineUnavailableWithOldAPI() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendCoroutineUnavailableWithOldAPI.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("suspendDestructuring.kt")
|
@TestMetadata("suspendDestructuring.kt")
|
||||||
public void testSuspendDestructuring() throws Exception {
|
public void testSuspendDestructuring() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendDestructuring.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspendDestructuring.kt");
|
||||||
|
|||||||
@@ -4944,6 +4944,21 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/loadJava/compiledKotlinWithStdlib/coroutines")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Coroutines extends AbstractLoadJavaTest {
|
||||||
|
public void testAllFilesPresentInCoroutines() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlinWithStdlib/coroutines"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("annotatedSuspendFun.kt")
|
||||||
|
public void testAnnotatedSuspendFun() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlinWithStdlib/coroutines/annotatedSuspendFun.kt");
|
||||||
|
doTestCompiledKotlinWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/loadJava/compiledKotlinWithStdlib/mutability")
|
@TestMetadata("compiler/testData/loadJava/compiledKotlinWithStdlib/mutability")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user