diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt index dc0c5f058fb..8ca6dca9235 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt @@ -152,7 +152,7 @@ private val addOrRemoveModifiersProcessingGroup = RemoveRedundantVisibilityModifierProcessing(), RemoveRedundantModalityModifierProcessing(), inspectionBasedProcessing(AddOperatorModifierInspection()), - generalInspectionBasedProcessing(RedundantUnitReturnTypeInspection()) + RemoveExplicitUnitTypeProcessing() ) ) @@ -162,8 +162,8 @@ private val removeRedundantElementsProcessingGroup = processings = listOf( RemoveExplicitTypeArgumentsProcessing(), RemoveJavaStreamsCollectCallTypeArgumentsProcessing(), - generalInspectionBasedProcessing(RedundantCompanionReferenceInspection()), - generalInspectionBasedProcessing(ExplicitThisInspection()), + RedundantCompanionReferenceInspectionBasedProcessing(), + ExplicitThisInspectionBasedProcessing(), intentionBasedProcessing(RemoveEmptyClassBodyIntention()) ) ) @@ -173,7 +173,7 @@ private val removeRedundantSemicolonProcessing = runSingleTime = true, acceptNonKtElements = true, processings = listOf( - generalInspectionBasedProcessing(RedundantSemicolonInspection()) + RedundantSemicolonInspectionBasedProcessing() ) ) @@ -195,11 +195,11 @@ private val inspectionLikePostProcessingGroup = inspectionBasedProcessing(ReplacePutWithAssignmentInspection()), UseExpressionBodyProcessing(), inspectionBasedProcessing(UnnecessaryVariableInspection()), - generalInspectionBasedProcessing(RedundantExplicitTypeInspection()), + RedundantExplicitTypeInspectionBasedProcessing(), JavaObjectEqualsToEqOperatorProcessing(), RemoveExplicitPropertyTypeProcessing(), RemoveRedundantNullabilityProcessing(), - generalInspectionBasedProcessing(CanBeValInspection(ignoreNotUsedVals = false)), + CanBeValInspectionBasedProcessing(), inspectionBasedProcessing(FoldInitializerAndIfToElvisInspection()), intentionBasedProcessing(RemoveRedundantCallsOfConversionMethodsIntention()), inspectionBasedProcessing(JavaMapForEachInspection()), @@ -219,9 +219,10 @@ private val inspectionLikePostProcessingGroup = intentionBasedProcessing(DestructureIntention()), inspectionBasedProcessing(SimplifyAssertNotNullInspection()), intentionBasedProcessing(RemoveRedundantCallsOfConversionMethodsIntention()), - generalInspectionBasedProcessing(LiftReturnOrAssignmentInspection(skipLongExpressions = false)), + LiftReturnInspectionBasedProcessing(), + LiftAssignmentInspectionBasedProcessing(), intentionBasedProcessing(RemoveEmptyPrimaryConstructorIntention()), - generalInspectionBasedProcessing(MayBeConstantInspection()), + MayBeConstantInspectionBasedProcessing(), RemoveForExpressionLoopParameterTypeProcessing(), intentionBasedProcessing(ReplaceMapGetOrDefaultIntention()), inspectionBasedProcessing(ReplaceGuardClauseWithFunctionCallInspection()) @@ -243,7 +244,7 @@ private val processings: List = listOf( InspectionLikeProcessingGroup( processings = listOf( VarToValProcessing(), - generalInspectionBasedProcessing(CanBeValInspection(ignoreNotUsedVals = false)) + CanBeValInspectionBasedProcessing() ), runSingleTime = true ), @@ -267,8 +268,8 @@ private val processings: List = listOf( ConvertGettersAndSettersToPropertyProcessing(), InspectionLikeProcessingGroup(MoveGetterAndSetterAnnotationsToPropertyProcessing()), InspectionLikeProcessingGroup( - generalInspectionBasedProcessing(RedundantGetterInspection()), - generalInspectionBasedProcessing(RedundantSetterInspection()) + RemoveExplicitGetterInspectionBasedProcessing(), + RemoveExplicitSetterInspectionBasedProcessing() ), ConvertToDataClassProcessing() ) diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/inspectionLikePostProcessings.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/inspectionLikePostProcessings.kt index 2d3d4694942..8158cc05025 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/inspectionLikePostProcessings.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/inspectionLikePostProcessings.kt @@ -182,76 +182,6 @@ inline fun generalInspectionBasedProcessing( - inspection: TInspection, - acceptInformationLevel: Boolean = false -) = (object : InspectionLikeProcessing { - override val writeActionNeeded = false - - fun QuickFix.applyFixSmart(element: PsiElement, descriptor: D) { - if (!element.isValid) return - if (descriptor is ProblemDescriptor) { - if (this is IntentionWrapper) { - @Suppress("NOT_YET_SUPPORTED_IN_INLINE") - fun applySelfTargetingIntention(action: SelfTargetingIntention) { - val target = action.getTarget(descriptor.psiElement.startOffset, descriptor.psiElement.containingFile) ?: return - if (!action.isApplicableTo(target, descriptor.psiElement.startOffset)) return - action.applyTo(target, null) - } - - @Suppress("NOT_YET_SUPPORTED_IN_INLINE") - fun applyQuickFixActionBase(action: QuickFixActionBase) { - if (!action.isAvailable(element.project, null, descriptor.psiElement.containingFile)) return - action.invoke(element.project, null, descriptor.psiElement.containingFile) - } - - - @Suppress("NOT_YET_SUPPORTED_IN_INLINE") - fun applyIntention() { - @Suppress("UNCHECKED_CAST") - when (val action = this.action) { - is SelfTargetingIntention<*> -> applySelfTargetingIntention(action as SelfTargetingIntention) - is QuickFixActionBase<*> -> applyQuickFixActionBase(action) - } - } - - - if (this.startInWriteAction()) { - ApplicationManager.getApplication().runWriteAction(::applyIntention) - } else { - applyIntention() - } - - } - } - - ApplicationManager.getApplication().runWriteAction { - this.applyFix(element.project, descriptor) - } - } - - override fun createAction(element: PsiElement, settings: ConverterSettings?): (() -> Unit)? { - val holder = ProblemsHolder(InspectionManager.getInstance(element.project), element.containingFile, false) - val visitor = inspection.buildVisitor( - holder, - false, - LocalInspectionToolSession(element.containingFile, 0, element.containingFile.endOffset) - ) - element.accept(visitor) - if (!holder.hasResults()) return null - return { - holder.results.clear() - element.accept(visitor) - if (holder.hasResults()) { - holder.results - .filter { acceptInformationLevel || it.highlightType != ProblemHighlightType.INFORMATION } - .forEach { it.fixes?.firstOrNull()?.applyFixSmart(element, it) } - } - } - } -}) - - inline fun > inspectionBasedProcessing(inspection: TInspection, acceptInformationLevel: Boolean = false) = object : InspectionLikeProcessing { diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/inspeсtionLikeProcessings.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/inspeсtionLikeProcessings.kt index e20a24b630e..a17a4c31969 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/inspeсtionLikeProcessings.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/inspeсtionLikeProcessings.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.nj2k.postProcessing.processings +import com.intellij.psi.PsiElement import com.intellij.psi.search.searches.ReferencesSearch import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptor @@ -17,11 +18,13 @@ import org.jetbrains.kotlin.idea.core.implicitVisibility import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.setVisibility import org.jetbrains.kotlin.idea.debugger.sequence.psi.callName -import org.jetbrains.kotlin.idea.inspections.RedundantSamConstructorInspection -import org.jetbrains.kotlin.idea.inspections.UseExpressionBodyInspection +import org.jetbrains.kotlin.idea.inspections.* import org.jetbrains.kotlin.idea.inspections.collections.isCalling import org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeArgumentsIntention +import org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeIntention import org.jetbrains.kotlin.idea.intentions.addUseSiteTarget +import org.jetbrains.kotlin.idea.intentions.branchedTransformations.BranchedFoldingUtils +import org.jetbrains.kotlin.idea.quickfix.AddConstModifierFix import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.references.readWriteAccess @@ -340,4 +343,131 @@ class MoveGetterAndSetterAnnotationsToPropertyProcessing : ApplicabilityBasedIns accessor.annotationEntries.forEach { it.delete() } } } +} + +class RedundantExplicitTypeInspectionBasedProcessing : ApplicabilityBasedInspectionLikeProcessing(KtProperty::class) { + override fun isApplicableTo(element: KtProperty, settings: ConverterSettings?): Boolean = + RedundantExplicitTypeInspection.hasRedundantType(element) + + override fun apply(element: KtProperty) { + RemoveExplicitTypeIntention.removeExplicitType(element) + } +} + +class CanBeValInspectionBasedProcessing : ApplicabilityBasedInspectionLikeProcessing(KtDeclaration::class) { + override fun isApplicableTo(element: KtDeclaration, settings: ConverterSettings?): Boolean = + CanBeValInspection.canBeVal(element, ignoreNotUsedVals = false) + + override fun apply(element: KtDeclaration) { + if (element !is KtValVarKeywordOwner) return + element.valOrVarKeyword?.replace(KtPsiFactory(element).createValKeyword()) + } +} + + +class MayBeConstantInspectionBasedProcessing : ApplicabilityBasedInspectionLikeProcessing(KtProperty::class) { + override fun isApplicableTo(element: KtProperty, settings: ConverterSettings?): Boolean = + with(MayBeConstantInspection) { + val status = element.getStatus() + status == MayBeConstantInspection.Status.MIGHT_BE_CONST + || status == MayBeConstantInspection.Status.JVM_FIELD_MIGHT_BE_CONST + } + + override fun apply(element: KtProperty) { + AddConstModifierFix.addConstModifier(element) + } +} + +class RemoveExplicitUnitTypeProcessing : ApplicabilityBasedInspectionLikeProcessing(KtNamedFunction::class) { + override fun isApplicableTo(element: KtNamedFunction, settings: ConverterSettings?): Boolean { + val typeReference = element.typeReference?.typeElement ?: return false + if (!typeReference.textMatches("Unit")) return false + return RedundantUnitReturnTypeInspection.hasRedundantUnitReturnType(element) + } + + override fun apply(element: KtNamedFunction) { + RemoveExplicitTypeIntention.removeExplicitType(element) + } +} + + +class RemoveExplicitGetterInspectionBasedProcessing : + ApplicabilityBasedInspectionLikeProcessing(KtPropertyAccessor::class) { + override fun isApplicableTo(element: KtPropertyAccessor, settings: ConverterSettings?): Boolean = + element.isRedundantGetter() + + override fun apply(element: KtPropertyAccessor) { + RemoveRedundantGetterFix.removeRedundantGetter(element) + } +} + +class RemoveExplicitSetterInspectionBasedProcessing : + ApplicabilityBasedInspectionLikeProcessing(KtPropertyAccessor::class) { + override fun isApplicableTo(element: KtPropertyAccessor, settings: ConverterSettings?): Boolean = + element.isRedundantSetter() + + override fun apply(element: KtPropertyAccessor) { + RemoveRedundantSetterFix.removeRedundantSetter(element) + } +} + + +class RedundantSemicolonInspectionBasedProcessing : + ApplicabilityBasedInspectionLikeProcessing(PsiElement::class) { + override fun isApplicableTo(element: PsiElement, settings: ConverterSettings?): Boolean = + element.node.elementType == KtTokens.SEMICOLON + && RedundantSemicolonInspection.isRedundantSemicolon(element) + + override fun apply(element: PsiElement) { + element.delete() + } +} + + +class RedundantCompanionReferenceInspectionBasedProcessing : + ApplicabilityBasedInspectionLikeProcessing(KtReferenceExpression::class) { + override fun isApplicableTo(element: KtReferenceExpression, settings: ConverterSettings?): Boolean = + RedundantCompanionReferenceInspection.isRedundantCompanionReference(element) + + override fun apply(element: KtReferenceExpression) { + RemoveRedundantCompanionReferenceFix.removeRedundantCompanionReference(element) + } +} + +class ExplicitThisInspectionBasedProcessing : + ApplicabilityBasedInspectionLikeProcessing(KtExpression::class) { + override fun isApplicableTo(element: KtExpression, settings: ConverterSettings?): Boolean = + ExplicitThisInspection.hasExplicitThis(element) + + override fun apply(element: KtExpression) { + ExplicitThisExpressionFix.removeExplicitThisExpression( + with(ExplicitThisInspection) { + element.thisAsReceiverOrNull() ?: return + } + ) + } +} + +class LiftReturnInspectionBasedProcessing : + ApplicabilityBasedInspectionLikeProcessing(KtExpression::class) { + override fun isApplicableTo(element: KtExpression, settings: ConverterSettings?): Boolean = + LiftReturnOrAssignmentInspection.getState(element, false)?.any { + it.liftType == LiftReturnOrAssignmentInspection.Companion.LiftType.LIFT_RETURN_OUT + } ?: false + + override fun apply(element: KtExpression) { + BranchedFoldingUtils.foldToReturn(element) + } +} + +class LiftAssignmentInspectionBasedProcessing : + ApplicabilityBasedInspectionLikeProcessing(KtExpression::class) { + override fun isApplicableTo(element: KtExpression, settings: ConverterSettings?): Boolean = + LiftReturnOrAssignmentInspection.getState(element, false)?.any { + it.liftType == LiftReturnOrAssignmentInspection.Companion.LiftType.LIFT_ASSIGNMENT_OUT + } ?: false + + override fun apply(element: KtExpression) { + BranchedFoldingUtils.foldToAssignment(element) + } } \ No newline at end of file diff --git a/nj2k/testData/newJ2k/switch/nestedSwitchFallback.kt b/nj2k/testData/newJ2k/switch/nestedSwitchFallback.kt index f836289a10f..eec644f9c9d 100644 --- a/nj2k/testData/newJ2k/switch/nestedSwitchFallback.kt +++ b/nj2k/testData/newJ2k/switch/nestedSwitchFallback.kt @@ -1,13 +1,13 @@ fun foo(i: Int, j: Int): String { - when (i) { + return when (i) { 0 -> { when (j) { 1 -> return "0, 1" 2 -> return "0, 2" } - return "1, x" + "1, x" } - 1 -> return "1, x" - else -> return "x, x" + 1 -> "1, x" + else -> "x, x" } } \ No newline at end of file