mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[kotlin] k2 extract function: rely on compiler checks to detect suspend problems
- otherwise we would need to check enclosing suspend functions manually ^KTIJ-29873 fixed GitOrigin-RevId: 177244574eea1ac93381da4debab6b368b9eb300
This commit is contained in:
committed by
intellij-monorepo-bot
parent
477463f520
commit
786684a1e7
+5
@@ -1148,6 +1148,11 @@ public abstract class ExtractionTestGenerated extends AbstractExtractionTest {
|
||||
runTest("testData/refactoring/extractFunction/basic/suspendCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendCallInsideSuspendContinuation.kt")
|
||||
public void testSuspendCallInsideSuspendContinuation() throws Exception {
|
||||
runTest("testData/refactoring/extractFunction/basic/suspendCallInsideSuspendContinuation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendCallWithExtractedParameter.kt")
|
||||
public void testSuspendCallWithExtractedParameter() throws Exception {
|
||||
runTest("testData/refactoring/extractFunction/basic/suspendCallWithExtractedParameter.kt");
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// PARAM_TYPES: D
|
||||
// PARAM_DESCRIPTOR: value-parameter d: D defined in test1
|
||||
fun m(block: suspend () -> Unit) {}
|
||||
|
||||
class D {
|
||||
suspend fun await() {}
|
||||
}
|
||||
|
||||
fun test1(d: D) {
|
||||
<selection>m {
|
||||
d.await()
|
||||
}</selection>
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// PARAM_TYPES: D
|
||||
// PARAM_DESCRIPTOR: value-parameter d: D defined in test1
|
||||
fun m(block: suspend () -> Unit) {}
|
||||
|
||||
class D {
|
||||
suspend fun await() {}
|
||||
}
|
||||
|
||||
fun test1(d: D) {
|
||||
__dummyTestFun__(d)
|
||||
}
|
||||
|
||||
private fun __dummyTestFun__(d: D) {
|
||||
m {
|
||||
d.await()
|
||||
}
|
||||
}
|
||||
+21
-13
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.analysis.api.components.KtDataFlowExitPointSnapshot
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtDiagnosticCheckerFilter
|
||||
import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KtFirDiagnostic
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
@@ -56,6 +55,7 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||
import org.jetbrains.kotlin.psi.KtBreakExpression
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtContinueExpression
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
@@ -224,26 +224,34 @@ internal class ExtractionDataAnalyzer(private val extractionData: ExtractionData
|
||||
replacementMap = replacementMap,
|
||||
controlFlow = flow,
|
||||
returnType = returnType,
|
||||
modifiers = if (hasSuspendReference(extractionData)) listOf(KtTokens.SUSPEND_KEYWORD) else emptyList(),
|
||||
modifiers = emptyList(),
|
||||
optInMarkers = experimentalMarkers.optInMarkers,
|
||||
annotationClassIds = experimentalMarkers.propagatingMarkerClassIds
|
||||
)
|
||||
val config = ExtractionGeneratorConfiguration(
|
||||
descriptor,
|
||||
ExtractionGeneratorOptions(inTempFile = true, allowExpressionBody = false)
|
||||
)
|
||||
|
||||
val generatedDeclaration = Generator.generateDeclaration(config, null).declaration
|
||||
val illegalSuspendInside = analyzeCopy(generatedDeclaration, DanglingFileResolutionMode.PREFER_SELF) {
|
||||
generatedDeclaration.descendantsOfType<KtExpression>()
|
||||
.flatMap {
|
||||
it.getDiagnostics(KtDiagnosticCheckerFilter.ONLY_COMMON_CHECKERS)
|
||||
.map { it.diagnosticClass }
|
||||
}
|
||||
.any { it == KtFirDiagnostic.IllegalSuspendFunctionCall::class || it == KtFirDiagnostic.IllegalSuspendPropertyAccess::class }
|
||||
}
|
||||
if (illegalSuspendInside) {
|
||||
descriptor = descriptor.copy(modifiers = listOf(KtTokens.SUSPEND_KEYWORD))
|
||||
}
|
||||
|
||||
|
||||
for (analyser in ExtractFunctionDescriptorModifier.EP_NAME.extensionList) {
|
||||
descriptor = analyser.modifyDescriptor(descriptor)
|
||||
}
|
||||
return descriptor
|
||||
}
|
||||
|
||||
private fun hasSuspendReference(extractionData: ExtractionData): Boolean {
|
||||
return extractionData.expressions
|
||||
.flatMap { it.descendantsOfType<KtSimpleNameExpression>() }
|
||||
.any { nameExpression ->
|
||||
analyze(nameExpression) {
|
||||
val symbol = nameExpression.mainReference.resolveToSymbol()
|
||||
symbol is KtFunctionSymbol && symbol.isSuspend
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private data class ExperimentalMarkers(
|
||||
|
||||
+5
@@ -306,6 +306,11 @@ public abstract class K2IntroduceFunctionTestGenerated extends AbstractK2Introdu
|
||||
runTest("../../idea/tests/testData/refactoring/extractFunction/basic/suspendCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendCallInsideSuspendContinuation.kt")
|
||||
public void testSuspendCallInsideSuspendContinuation() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/extractFunction/basic/suspendCallInsideSuspendContinuation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendCallWithExtractedParameter.kt")
|
||||
public void testSuspendCallWithExtractedParameter() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/extractFunction/basic/suspendCallWithExtractedParameter.kt");
|
||||
|
||||
Reference in New Issue
Block a user