[kotlin] k2 main detection: allow from write action

- called under potemkin progress

^KTIJ-30376 fixed

GitOrigin-RevId: cc6f93e923becfdb96eb9994d4cc675cedecc763
This commit is contained in:
Anna Kozlova
2024-06-24 15:14:02 +02:00
committed by intellij-monorepo-bot
parent f68ef66b57
commit df85332de0
2 changed files with 44 additions and 40 deletions

View File

@@ -4,7 +4,7 @@
<facet type="kotlin-language" name="Kotlin">
<configuration version="5" platform="JVM 17" allPlatforms="JVM [17]" useProjectSettings="false">
<compilerSettings>
<option name="additionalArguments" value="-Xjvm-default=all -opt-in=com.intellij.openapi.util.IntellijInternalApi -opt-in=org.jetbrains.kotlin.analysis.api.KaIdeApi -Xcontext-receivers" />
<option name="additionalArguments" value="-Xjvm-default=all -opt-in=com.intellij.openapi.util.IntellijInternalApi -opt-in=org.jetbrains.kotlin.utils.addToStdlib.UnsafeCastFunction -opt-in=org.jetbrains.kotlin.analysis.api.permissions.KaAllowProhibitedAnalyzeFromWriteAction -opt-in=org.jetbrains.kotlin.analysis.api.KaIdeApi -opt-in=org.jetbrains.kotlin.analysis.api.KaNonPublicApi -Xcontext-receivers" />
</compilerSettings>
<compilerArguments>
<stringArguments>

View File

@@ -4,7 +4,9 @@ package org.jetbrains.kotlin.idea.base.fir.codeInsight
import org.jetbrains.kotlin.analysis.api.KaSession
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.annotations.hasAnnotation
import org.jetbrains.kotlin.analysis.api.permissions.KaAllowAnalysisFromWriteAction
import org.jetbrains.kotlin.analysis.api.permissions.KaAllowAnalysisOnEdt
import org.jetbrains.kotlin.analysis.api.permissions.allowAnalysisFromWriteAction
import org.jetbrains.kotlin.analysis.api.permissions.allowAnalysisOnEdt
import org.jetbrains.kotlin.analysis.api.symbols.KaNamedFunctionSymbol
import org.jetbrains.kotlin.analysis.api.types.KaClassType
@@ -20,7 +22,7 @@ import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.types.Variance
internal class SymbolBasedKotlinMainFunctionDetector : KotlinMainFunctionDetector {
@OptIn(KaAllowAnalysisOnEdt::class)
@OptIn(KaAllowAnalysisOnEdt::class, KaAllowAnalysisFromWriteAction::class)
override fun isMain(function: KtNamedFunction, configuration: KotlinMainFunctionDetector.Configuration): Boolean {
if (function.isLocal || function.typeParameters.isNotEmpty()) {
return false
@@ -41,50 +43,52 @@ internal class SymbolBasedKotlinMainFunctionDetector : KotlinMainFunctionDetecto
// TODO find a better solution to avoid calling `isMain` from EDT
allowAnalysisOnEdt {
analyze(function) {
if (parameterCount == 1 && configuration.checkParameterType) {
val parameterTypeReference = function.receiverTypeReference
?: function.valueParameters[0].typeReference
?: return false
allowAnalysisFromWriteAction {
analyze(function) {
if (parameterCount == 1 && configuration.checkParameterType) {
val parameterTypeReference = function.receiverTypeReference
?: function.valueParameters[0].typeReference
?: return false
val parameterType = parameterTypeReference.type
if (!parameterType.isResolvedClassType() || !parameterType.isSubTypeOf(buildMainParameterType())) {
val parameterType = parameterTypeReference.type
if (!parameterType.isResolvedClassType() || !parameterType.isSubTypeOf(buildMainParameterType())) {
return false
}
}
val functionSymbol = function.getFunctionLikeSymbol()
if (functionSymbol !is KaNamedFunctionSymbol) {
return false
}
}
val functionSymbol = function.getFunctionLikeSymbol()
if (functionSymbol !is KaNamedFunctionSymbol) {
return false
}
val jvmName = getJvmName(functionSymbol) ?: functionSymbol.name.asString()
if (jvmName != KotlinMainFunctionDetector.MAIN_FUNCTION_NAME) {
return false
}
if (configuration.checkResultType && !function.returnType.isUnit) {
return false
}
if (!isTopLevel) {
val containingClass = functionSymbol.originalContainingClassForOverride ?: return false
val annotationJvmStatic = JvmStandardClassIds.Annotations.JvmStatic
return containingClass.classKind.isObject
&& (!configuration.checkJvmStaticAnnotation || functionSymbol.hasAnnotation(annotationJvmStatic))
}
if (parameterCount == 0) {
// We do not support parameterless entry points having JvmName("name") but different real names
// See more at https://github.com/Kotlin/KEEP/blob/master/proposals/enhancing-main-convention.md#parameterless-main
if (function.name.toString() != KotlinMainFunctionDetector.MAIN_FUNCTION_NAME) return false
val functionsInFile = function.containingKtFile.declarations.filterIsInstance<KtNamedFunction>()
// Parameterless function is considered as an entry point only if there's no entry point with an array parameter
if (functionsInFile.any { isMain(it, configuration.with { allowParameterless = false }) }) {
val jvmName = getJvmName(functionSymbol) ?: functionSymbol.name.asString()
if (jvmName != KotlinMainFunctionDetector.MAIN_FUNCTION_NAME) {
return false
}
if (configuration.checkResultType && !function.returnType.isUnit) {
return false
}
if (!isTopLevel) {
val containingClass = functionSymbol.originalContainingClassForOverride ?: return false
val annotationJvmStatic = JvmStandardClassIds.Annotations.JvmStatic
return containingClass.classKind.isObject
&& (!configuration.checkJvmStaticAnnotation || functionSymbol.hasAnnotation(annotationJvmStatic))
}
if (parameterCount == 0) {
// We do not support parameterless entry points having JvmName("name") but different real names
// See more at https://github.com/Kotlin/KEEP/blob/master/proposals/enhancing-main-convention.md#parameterless-main
if (function.name.toString() != KotlinMainFunctionDetector.MAIN_FUNCTION_NAME) return false
val functionsInFile = function.containingKtFile.declarations.filterIsInstance<KtNamedFunction>()
// Parameterless function is considered as an entry point only if there's no entry point with an array parameter
if (functionsInFile.any { isMain(it, configuration.with { allowParameterless = false }) }) {
return false
}
}
}
}
}