diff --git a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/KotlinOptionsToCompilerOptionsInGradleScriptInspection.kt b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/KotlinOptionsToCompilerOptionsInGradleScriptInspection.kt index 79d22c154f93..7f375de11436 100644 --- a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/KotlinOptionsToCompilerOptionsInGradleScriptInspection.kt +++ b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/KotlinOptionsToCompilerOptionsInGradleScriptInspection.kt @@ -42,50 +42,50 @@ private val kotlinCompileTasksNames = setOf( internal class KotlinOptionsToCompilerOptionsInGradleScriptInspection : AbstractKotlinGradleScriptInspection() { override fun isAvailableForFile(file: PsiFile): Boolean { - if (super.isAvailableForFile(file)) { + return if (super.isAvailableForFile(file)) { if (isUnitTestMode()) { // Inspection tests don't treat tested build script files properly, and thus they ignore Kotlin versions used in scripts - return true + true } else { - return kotlinVersionIsEqualOrHigher(major = 2, minor = 0, patch = 0, file) + kotlinVersionIsEqualOrHigher(major = 2, minor = 0, patch = 0, file) } } else { - return false + false } } override fun buildVisitor( holder: ProblemsHolder, - isOnTheFly: Boolean - ) = object : KtVisitorVoid() { + isOnTheFly: Boolean, + ): KtVisitorVoid { + return object : KtVisitorVoid() { + override fun visitReferenceExpression(expression: KtReferenceExpression) { + if (expression.text.equals("kotlinOptions")) { - override fun visitReferenceExpression(expression: KtReferenceExpression) { - if (expression.text.equals("kotlinOptions")) { + if (isDescendantOfDslInWhichReplacementIsNotNeeded(expression)) return - if (isDescendantOfDslInWhichReplacementIsNotNeeded(expression)) return + val expressionParent = expression.parent - val expressionParent = expression.parent + if (!isUnitTestMode()) { // ATM, we don't have proper dependencies for tests on Gradle build scripts + analyze(expression) { + val jvmClassForKotlinCompileTask = (expression.resolveToCall() + ?.successfulFunctionCallOrNull()?.partiallyAppliedSymbol?.signature?.symbol + ?.containingDeclaration as? KaClassLikeSymbol)?.importableFqName?.toString() - if (!isUnitTestMode()) { // ATM, we don't have proper dependencies for tests on Gradle build scripts - analyze(expression) { - val jvmClassForKotlinCompileTask = (expression.resolveToCall() - ?.successfulFunctionCallOrNull()?.partiallyAppliedSymbol?.signature?.symbol - ?.containingDeclaration as? KaClassLikeSymbol)?.importableFqName?.toString() - - ?: expression.resolveExpression()?.containingSymbol?.importableFqName?.toString() ?: return - if (!kotlinCompileTasksNames.contains(jvmClassForKotlinCompileTask)) { - return + ?: expression.resolveExpression()?.containingSymbol?.importableFqName?.toString() ?: return + if (!kotlinCompileTasksNames.contains(jvmClassForKotlinCompileTask)) { + return + } } } - } - when (expressionParent) { - is KtDotQualifiedExpression -> { // like `kotlinOptions.sourceMapEmbedSources` OR kotlinOptions.options - val parentOfExpressionParent = expressionParent.parent - if (elementContainsOperationForbiddenToReplaceOrCantBeProcessed(parentOfExpressionParent)) return - } + when (expressionParent) { + is KtDotQualifiedExpression -> { // like `kotlinOptions.sourceMapEmbedSources` OR kotlinOptions.options + val parentOfExpressionParent = expressionParent.parent + if (elementContainsOperationForbiddenToReplaceOrCantBeProcessed(parentOfExpressionParent)) return + } - is KtCallExpression -> { - /* + is KtCallExpression -> { + /* Like the following. Raise a problem for this. compileKotlin.kotlinOptions { jvmTarget = "1.8" @@ -93,27 +93,28 @@ internal class KotlinOptionsToCompilerOptionsInGradleScriptInspection : Abstract apiVersion = "1.9" } */ - val lambdaStatements = expressionParent.lambdaArguments.getOrNull(0) - ?.getLambdaExpression()?.bodyExpression?.statements?.requireNoNulls() + val lambdaStatements = expressionParent.lambdaArguments.getOrNull(0) + ?.getLambdaExpression()?.bodyExpression?.statements?.requireNoNulls() - if (lambdaStatements?.isNotEmpty() == true) { // compileKotlin.kotlinOptions { .. } - lambdaStatements.forEach { - if (expressionsContainForbiddenOperations(it)) return + if (lambdaStatements?.isNotEmpty() == true) { // compileKotlin.kotlinOptions { .. } + lambdaStatements.forEach { + if (expressionsContainForbiddenOperations(it)) return + } } } + + else -> return } - else -> return + holder.problem( + expression, + KotlinBundle.message("inspection.kotlin.options.to.compiler.options.display.name") + ) + .highlight(ProblemHighlightType.GENERIC_ERROR_OR_WARNING) + .fix( + ReplaceKotlinOptionsWithCompilerOptionsFix() + ).register() } - - holder.problem( - expression, - KotlinBundle.message("inspection.kotlin.options.to.compiler.options.display.name") - ) - .highlight(ProblemHighlightType.GENERIC_ERROR_OR_WARNING) - .fix( - ReplaceKotlinOptionsWithCompilerOptionsFix() - ).register() } } } @@ -126,10 +127,10 @@ internal class KotlinOptionsToCompilerOptionsInGradleScriptInspection : Abstract is KtDotQualifiedExpression -> { val psiElementParent = psiElement.parent - if (psiElementParent is KtBinaryExpression) { - return expressionContainsOperationForbiddenToReplace(psiElementParent) + return if (psiElementParent is KtBinaryExpression) { + expressionContainsOperationForbiddenToReplace(psiElementParent) } else { // Can't be processed - return true + true } } @@ -140,11 +141,7 @@ internal class KotlinOptionsToCompilerOptionsInGradleScriptInspection : Abstract private fun isDescendantOfDslInWhichReplacementIsNotNeeded(ktExpression: KtExpression): Boolean { val scriptText = ktExpression.containingFile.text if (scriptText.contains("android")) { - ktExpression.prevLeafs.forEach { - if ("android" == it.text) { - return true - } - } + return ktExpression.prevLeafs.any { it.text == "android" } } return false } @@ -153,25 +150,20 @@ internal class KotlinOptionsToCompilerOptionsInGradleScriptInspection : Abstract if (element is KtBinaryExpression) { // for sth like `kotlinOptions.sourceMapEmbedSources = "inlining"` if (expressionContainsOperationForbiddenToReplace(element)) return true } else { - element.children.forEach { - if (expressionsContainForbiddenOperations(it)) return true - } + return element.children.any { expressionsContainForbiddenOperations(it) } } return false } } private class ReplaceKotlinOptionsWithCompilerOptionsFix() : KotlinModCommandQuickFix() { - override fun getFamilyName(): @IntentionFamilyName String { - return KotlinBundle.message("replace.kotlin.options.with.compiler.options") - } + override fun getFamilyName(): @IntentionFamilyName String = KotlinBundle.message("replace.kotlin.options.with.compiler.options") override fun applyFix( project: Project, element: KtExpression, - updater: ModPsiUpdater + updater: ModPsiUpdater, ) { - val expressionsToFix = mutableListOf() val expressionParent = element.parent when (expressionParent) { diff --git a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/utils/AbstractKotlinGradleScriptInspection.kt b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/utils/AbstractKotlinGradleScriptInspection.kt index 1fcc3bd41aa9..598884b006ad 100644 --- a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/utils/AbstractKotlinGradleScriptInspection.kt +++ b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/utils/AbstractKotlinGradleScriptInspection.kt @@ -7,10 +7,10 @@ import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.AbstractKot abstract class AbstractKotlinGradleScriptInspection : AbstractKotlinInspection() { override fun isAvailableForFile(file: PsiFile): Boolean { - if (file.name.endsWith(".gradle.kts")) { - return super.isAvailableForFile(file) + return if (file.virtualFile.nameSequence.endsWith(".gradle.kts")) { + super.isAvailableForFile(file) } else { - return false + false } } } \ No newline at end of file diff --git a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/configuration/utils/KotlinOptionsToCompilerOptionsMigrator.kt b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/configuration/utils/KotlinOptionsToCompilerOptionsMigrator.kt index efe663b61ae5..8940340c8f5b 100644 --- a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/configuration/utils/KotlinOptionsToCompilerOptionsMigrator.kt +++ b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/configuration/utils/KotlinOptionsToCompilerOptionsMigrator.kt @@ -24,28 +24,28 @@ data class Replacement(val expressionToReplace: KtExpression, val replacement: S @ApiStatus.Internal fun expressionContainsOperationForbiddenToReplace(binaryExpression: KtBinaryExpression): Boolean { val operationReference = binaryExpression.operationReference.text - if (operationReference == "-=") { - return true + return if (operationReference == "-=") { + true } else { val rightPartOfBinaryExpression = binaryExpression.right ?: return true if (rightPartOfBinaryExpression is KtBinaryExpression) { - return checkIfExpressionContainsMinusOperator(rightPartOfBinaryExpression) + checkIfExpressionContainsMinusOperator(rightPartOfBinaryExpression) } else { - return false + false } } } private fun checkIfExpressionContainsMinusOperator(binaryExpression: KtBinaryExpression): Boolean { val operationReference = binaryExpression.operationReference.text - if (operationReference == "-") { - return true + return if (operationReference == "-") { + true } else { val leftPartOfBinaryExpression = binaryExpression.left ?: return true if (leftPartOfBinaryExpression is KtBinaryExpression) { - return checkIfExpressionContainsMinusOperator(leftPartOfBinaryExpression) + checkIfExpressionContainsMinusOperator(leftPartOfBinaryExpression) } else { - return false + false } } } @@ -235,7 +235,7 @@ private fun getCompilerOptionForVersionValue( replacement: StringBuilder, optionName: String, operationReplacer: String, -): CompilerOption? { +): CompilerOption { val processedOptionValue = optionValue.removeSurrounding("\"").removeSurrounding("'") val convertedValue = versionOptionData.mappingRule.apply(processedOptionValue) val compilerOptionValue = if (convertedValue != null) { @@ -249,7 +249,6 @@ private fun getCompilerOptionForVersionValue( "$optionName.$operationReplacer($compilerOptionValue)" ) return CompilerOption(replacement.toString(), versionOptionData.fqClassName, compilerOptionValue) - return null } private fun getCompilerOptionForJsValue( @@ -303,8 +302,11 @@ private fun jvmTargetValueMappingRule(inputValue: String): String? { if (inputValue == "1.8") return "1_8" val numericValue = inputValue.removePrefix("1.").toIntOrNull() if (numericValue != null) { - if (numericValue <= 7) return null // JvmTarget class has values starting from 8 - else return numericValue.toString() + return if (numericValue <= 7) { + null // JvmTarget class has values starting from 8 + } else { + numericValue.toString() + } } // parse JavaVersion.VERSION_N.toString() @@ -313,10 +315,10 @@ private fun jvmTargetValueMappingRule(inputValue: String): String? { "1_8" -> return "1_8" else -> { val numericValue = version.removePrefix("1_").toIntOrNull() ?: return null - if (numericValue > 8) { - return numericValue.toString() + return if (numericValue > 8) { + numericValue.toString() } else { // Kotlin doesn't support jvmTarget 7 and less - return null + null } } } @@ -325,9 +327,11 @@ private fun jvmTargetValueMappingRule(inputValue: String): String? { private val kotlinVersionRegex = Regex("\\d\\.\\d") private fun kotlinVersionValueMappingRule(inputValue: String): String? { - if (kotlinVersionRegex.matches(inputValue)) { - return inputValue.replace(".", "_") - } else return null + return if (kotlinVersionRegex.matches(inputValue)) { + inputValue.replace(".", "_") + } else { + null + } } private data class VersionOption(val newOptionType: String, val fqClassName: FqName, val mappingRule: Function)