Do not generate accessor if private function is accessed from
coroutines intrinsic lambda. The logic is if the lambda is crossinline we need to generate the accessor. However, suspendCoroutine's and suspendCoroutineUninterceptedOrReturn's parameter, despite being crossinline, are effectively inline. Thus, we do not need to generate the accessor. #KT-27503 Fixed
This commit is contained in:
@@ -1,24 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2019 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.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.context
|
package org.jetbrains.kotlin.codegen.context
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn
|
||||||
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.isTopLevelInPackage
|
||||||
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getParentResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
|
|
||||||
class InlineLambdaContext(
|
class InlineLambdaContext(
|
||||||
functionDescriptor: FunctionDescriptor,
|
functionDescriptor: FunctionDescriptor,
|
||||||
@@ -30,7 +26,7 @@ class InlineLambdaContext(
|
|||||||
) : MethodContext(functionDescriptor, contextKind, parentContext, closure, false) {
|
) : MethodContext(functionDescriptor, contextKind, parentContext, closure, false) {
|
||||||
|
|
||||||
override fun getFirstCrossInlineOrNonInlineContext(): CodegenContext<*> {
|
override fun getFirstCrossInlineOrNonInlineContext(): CodegenContext<*> {
|
||||||
if (isCrossInline) 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 { parentContext as? ClosureContext } ?:
|
||||||
throw AssertionError(
|
throw AssertionError(
|
||||||
@@ -43,4 +39,12 @@ class InlineLambdaContext(
|
|||||||
return grandParent.firstCrossInlineOrNonInlineContext
|
return grandParent.firstCrossInlineOrNonInlineContext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// suspendCoroutine and suspendCoroutineUninterceptedOrReturn accept crossinline parameter, but it is effectively inline
|
||||||
|
private fun isSuspendIntrinsicParameter(): Boolean {
|
||||||
|
if (contextDescriptor !is AnonymousFunctionDescriptor) return false
|
||||||
|
val resolvedCall = (contextDescriptor.source.getPsi() as? KtElement).getParentResolvedCall(state.bindingContext) ?: return false
|
||||||
|
val descriptor = resolvedCall.resultingDescriptor as? FunctionDescriptor ?: return false
|
||||||
|
return descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(state.languageVersionSettings)
|
||||||
|
|| descriptor.isTopLevelInPackage("suspendCoroutine", state.languageVersionSettings.coroutinesPackageFqName().asString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// COMMON_COROUTINES_TEST
|
||||||
|
import COROUTINES_PACKAGE.*
|
||||||
|
|
||||||
|
private fun foo() {}
|
||||||
|
|
||||||
|
private suspend fun bar() = suspendCoroutine<Unit> {
|
||||||
|
foo()
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
@kotlin.Metadata
|
||||||
|
public final class PrivateAccessorKt {
|
||||||
|
synthetic final static @org.jetbrains.annotations.Nullable method bar(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
|
private final static method foo(): void
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
@kotlin.Metadata
|
||||||
|
public final class PrivateAccessorKt {
|
||||||
|
synthetic final static @org.jetbrains.annotations.Nullable method bar(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
|
private final static method foo(): void
|
||||||
|
}
|
||||||
+82
-59
@@ -25,10 +25,6 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
|||||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runTestWithPackageReplacement(String testDataFilePath, String packageName) throws Exception {
|
|
||||||
KotlinTestUtils.runTest(filePath -> doTestWithCoroutinesPackageReplacement(filePath, packageName), TargetBackend.ANY, testDataFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAllFilesPresentInBytecodeListing() throws Exception {
|
public void testAllFilesPresentInBytecodeListing() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeListing"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeListing"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
@@ -53,26 +49,6 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
|||||||
runTest("compiler/testData/codegen/bytecodeListing/companionObjectVisibility_lv13.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/companionObjectVisibility_lv13.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("coroutineContextIntrinsic.kt")
|
|
||||||
public void testCoroutineContextIntrinsic_1_2() throws Exception {
|
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutineContextIntrinsic.kt", "kotlin.coroutines.experimental");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("coroutineContextIntrinsic.kt")
|
|
||||||
public void testCoroutineContextIntrinsic_1_3() throws Exception {
|
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutineContextIntrinsic.kt", "kotlin.coroutines");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("coroutineFields.kt")
|
|
||||||
public void testCoroutineFields_1_2() throws Exception {
|
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutineFields.kt", "kotlin.coroutines.experimental");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("coroutineFields.kt")
|
|
||||||
public void testCoroutineFields_1_3() throws Exception {
|
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutineFields.kt", "kotlin.coroutines");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("defaultImpls.kt")
|
@TestMetadata("defaultImpls.kt")
|
||||||
public void testDefaultImpls() throws Exception {
|
public void testDefaultImpls() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeListing/defaultImpls.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/defaultImpls.kt");
|
||||||
@@ -118,51 +94,16 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
|||||||
runTest("compiler/testData/codegen/bytecodeListing/noToArrayInJava.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/noToArrayInJava.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("oomInReturnUnit.kt")
|
|
||||||
public void testOomInReturnUnit_1_2() throws Exception {
|
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/oomInReturnUnit.kt", "kotlin.coroutines.experimental");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("oomInReturnUnit.kt")
|
|
||||||
public void testOomInReturnUnit_1_3() throws Exception {
|
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/oomInReturnUnit.kt", "kotlin.coroutines");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("privateDefaultSetter.kt")
|
@TestMetadata("privateDefaultSetter.kt")
|
||||||
public void testPrivateDefaultSetter() throws Exception {
|
public void testPrivateDefaultSetter() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeListing/privateDefaultSetter.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/privateDefaultSetter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("privateSuspendFun.kt")
|
|
||||||
public void testPrivateSuspendFun() throws Exception {
|
|
||||||
runTest("compiler/testData/codegen/bytecodeListing/privateSuspendFun.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("samAdapterAndInlinedOne.kt")
|
@TestMetadata("samAdapterAndInlinedOne.kt")
|
||||||
public void testSamAdapterAndInlinedOne() throws Exception {
|
public void testSamAdapterAndInlinedOne() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeListing/samAdapterAndInlinedOne.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/samAdapterAndInlinedOne.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("suspendReifiedFun.kt")
|
|
||||||
public void testSuspendReifiedFun_1_2() throws Exception {
|
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/suspendReifiedFun.kt", "kotlin.coroutines.experimental");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("suspendReifiedFun.kt")
|
|
||||||
public void testSuspendReifiedFun_1_3() throws Exception {
|
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/suspendReifiedFun.kt", "kotlin.coroutines");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("tcoContinuation.kt")
|
|
||||||
public void testTcoContinuation_1_2() throws Exception {
|
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/tcoContinuation.kt", "kotlin.coroutines.experimental");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("tcoContinuation.kt")
|
|
||||||
public void testTcoContinuation_1_3() throws Exception {
|
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/tcoContinuation.kt", "kotlin.coroutines");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/bytecodeListing/annotations")
|
@TestMetadata("compiler/testData/codegen/bytecodeListing/annotations")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
@@ -259,6 +200,88 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/bytecodeListing/coroutines")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Coroutines extends AbstractBytecodeListingTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runTestWithPackageReplacement(String testDataFilePath, String packageName) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(filePath -> doTestWithCoroutinesPackageReplacement(filePath, packageName), TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInCoroutines() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeListing/coroutines"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineContextIntrinsic.kt")
|
||||||
|
public void testCoroutineContextIntrinsic_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutines/coroutineContextIntrinsic.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineContextIntrinsic.kt")
|
||||||
|
public void testCoroutineContextIntrinsic_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutines/coroutineContextIntrinsic.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineFields.kt")
|
||||||
|
public void testCoroutineFields_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutines/coroutineFields.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineFields.kt")
|
||||||
|
public void testCoroutineFields_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutines/coroutineFields.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("oomInReturnUnit.kt")
|
||||||
|
public void testOomInReturnUnit_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutines/oomInReturnUnit.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("oomInReturnUnit.kt")
|
||||||
|
public void testOomInReturnUnit_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutines/oomInReturnUnit.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateAccessor.kt")
|
||||||
|
public void testPrivateAccessor_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutines/privateAccessor.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateAccessor.kt")
|
||||||
|
public void testPrivateAccessor_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutines/privateAccessor.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateSuspendFun.kt")
|
||||||
|
public void testPrivateSuspendFun() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeListing/coroutines/privateSuspendFun.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendReifiedFun.kt")
|
||||||
|
public void testSuspendReifiedFun_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutines/suspendReifiedFun.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendReifiedFun.kt")
|
||||||
|
public void testSuspendReifiedFun_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutines/suspendReifiedFun.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("tcoContinuation.kt")
|
||||||
|
public void testTcoContinuation_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutines/tcoContinuation.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("tcoContinuation.kt")
|
||||||
|
public void testTcoContinuation_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutines/tcoContinuation.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/bytecodeListing/inline")
|
@TestMetadata("compiler/testData/codegen/bytecodeListing/inline")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user