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 541c84b8efe..dc0c5f058fb 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 @@ -184,8 +184,10 @@ private val inspectionLikePostProcessingGroup = RemoveExplicitOpenInInterfaceProcessing(), RemoveRedundantOverrideVisibilityProcessing(), inspectionBasedProcessing(MoveLambdaOutsideParenthesesInspection()), - ConvertToStringTemplateProcessing(), - UsePropertyAccessSyntaxProcessing(), + intentionBasedProcessing(ConvertToStringTemplateIntention()) { + ConvertToStringTemplateIntention.shouldSuggestToConvert(it) + }, + intentionBasedProcessing(UsePropertyAccessSyntaxIntention()), UninitializedVariableReferenceFromInitializerToThisReferenceProcessing(), UnresolvedVariableReferenceFromInitializerToThisReferenceProcessing(), RemoveRedundantSamAdaptersProcessing(), @@ -193,7 +195,7 @@ private val inspectionLikePostProcessingGroup = inspectionBasedProcessing(ReplacePutWithAssignmentInspection()), UseExpressionBodyProcessing(), inspectionBasedProcessing(UnnecessaryVariableInspection()), - RemoveExplicitPropertyTypeWithInspectionProcessing(), + generalInspectionBasedProcessing(RedundantExplicitTypeInspection()), JavaObjectEqualsToEqOperatorProcessing(), RemoveExplicitPropertyTypeProcessing(), RemoveRedundantNullabilityProcessing(), 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 8bfe8dc9a58..e20a24b630e 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,7 +5,6 @@ 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 @@ -18,13 +17,10 @@ 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.RedundantExplicitTypeInspection import org.jetbrains.kotlin.idea.inspections.RedundantSamConstructorInspection import org.jetbrains.kotlin.idea.inspections.UseExpressionBodyInspection import org.jetbrains.kotlin.idea.inspections.collections.isCalling -import org.jetbrains.kotlin.idea.intentions.ConvertToStringTemplateIntention import org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeArgumentsIntention -import org.jetbrains.kotlin.idea.intentions.UsePropertyAccessSyntaxIntention import org.jetbrains.kotlin.idea.intentions.addUseSiteTarget import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.idea.references.mainReference @@ -34,8 +30,6 @@ import org.jetbrains.kotlin.j2k.ConverterSettings import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.nj2k.postProcessing.ApplicabilityBasedInspectionLikeProcessing -import org.jetbrains.kotlin.nj2k.postProcessing.InspectionLikeProcessing -import org.jetbrains.kotlin.nj2k.postProcessing.generalInspectionBasedProcessing import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.BindingContext @@ -119,138 +113,94 @@ class RemoveJavaStreamsCollectCallTypeArgumentsProcessing : } -class RemoveRedundantOverrideVisibilityProcessing : InspectionLikeProcessing { - override val writeActionNeeded = true +class RemoveRedundantOverrideVisibilityProcessing : + ApplicabilityBasedInspectionLikeProcessing(KtCallableDeclaration::class) { - override fun createAction(element: PsiElement, settings: ConverterSettings?): (() -> Unit)? { - if (element !is KtCallableDeclaration || !element.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return null - val modifier = element.visibilityModifierType() ?: return null - return { element.setVisibility(modifier) } + override fun isApplicableTo(element: KtCallableDeclaration, settings: ConverterSettings?): Boolean { + if (!element.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return false + return element.visibilityModifier() != null + } + + override fun apply(element: KtCallableDeclaration) { + val modifier = element.visibilityModifierType() ?: return + element.setVisibility(modifier) } } -class ConvertToStringTemplateProcessing : InspectionLikeProcessing { - override val writeActionNeeded = true +class UseExpressionBodyProcessing : ApplicabilityBasedInspectionLikeProcessing(KtPropertyAccessor::class) { + private val inspection = UseExpressionBodyInspection(convertEmptyToUnit = false) + override fun isApplicableTo(element: KtPropertyAccessor, settings: ConverterSettings?): Boolean = + inspection.isActiveFor(element) - val intention = ConvertToStringTemplateIntention() - - override fun createAction(element: PsiElement, settings: ConverterSettings?): (() -> Unit)? { - if (element is KtBinaryExpression && intention.isApplicableTo(element) && ConvertToStringTemplateIntention.shouldSuggestToConvert( - element - ) - ) { - return { intention.applyTo(element, null) } - } else { - return null - } + override fun apply(element: KtPropertyAccessor) { + inspection.simplify(element, false) } } -class UsePropertyAccessSyntaxProcessing : InspectionLikeProcessing { - override val writeActionNeeded = true - - val intention = UsePropertyAccessSyntaxIntention() - - override fun createAction(element: PsiElement, settings: ConverterSettings?): (() -> Unit)? { - if (element !is KtCallExpression) return null - val propertyName = intention.detectPropertyNameToUse(element) ?: return null - return { intention.applyTo(element, propertyName, reformat = true) } - } -} - -class RemoveRedundantSamAdaptersProcessing : InspectionLikeProcessing { - override val writeActionNeeded = true - - override fun createAction(element: PsiElement, settings: ConverterSettings?): (() -> Unit)? { - if (element !is KtCallExpression) return null - - val expressions = RedundantSamConstructorInspection.samConstructorCallsToBeConverted(element) - if (expressions.isEmpty()) return null - - return { - RedundantSamConstructorInspection.samConstructorCallsToBeConverted(element) - .forEach { RedundantSamConstructorInspection.replaceSamConstructorCall(it) } - } - } -} - -class UseExpressionBodyProcessing : InspectionLikeProcessing { - override val writeActionNeeded = true - - override fun createAction(element: PsiElement, settings: ConverterSettings?): (() -> Unit)? { - if (element !is KtPropertyAccessor) return null - - val inspection = UseExpressionBodyInspection(convertEmptyToUnit = false) - if (!inspection.isActiveFor(element)) return null - - return { - if (inspection.isActiveFor(element)) { - inspection.simplify(element, false) - } - } - } -} - -class RemoveRedundantCastToNullableProcessing : InspectionLikeProcessing { - override val writeActionNeeded = true - - override fun createAction(element: PsiElement, settings: ConverterSettings?): (() -> Unit)? { - if (element !is KtBinaryExpressionWithTypeRHS) return null +class RemoveRedundantCastToNullableProcessing : + ApplicabilityBasedInspectionLikeProcessing(KtBinaryExpressionWithTypeRHS::class) { + override fun isApplicableTo(element: KtBinaryExpressionWithTypeRHS, settings: ConverterSettings?): Boolean { + if (element.right?.typeElement !is KtNullableType) return false val context = element.analyze() - val leftType = context.getType(element.left) ?: return null - val rightType = context.get(BindingContext.TYPE, element.right) ?: return null + val leftType = context.getType(element.left) ?: return false + val rightType = context.get(BindingContext.TYPE, element.right) ?: return false + return !leftType.isMarkedNullable && rightType.isMarkedNullable + } - if (!leftType.isMarkedNullable && rightType.isMarkedNullable) { - return { - val type = element.right?.typeElement as? KtNullableType - type?.replace(type.innerType!!) - } + override fun apply(element: KtBinaryExpressionWithTypeRHS) { + val type = element.right?.typeElement as? KtNullableType ?: return + type.replace(type.innerType ?: return) + } +} + +class RemoveRedundantSamAdaptersProcessing : + ApplicabilityBasedInspectionLikeProcessing(KtCallExpression::class) { + + override fun isApplicableTo(element: KtCallExpression, settings: ConverterSettings?): Boolean = + RedundantSamConstructorInspection.samConstructorCallsToBeConverted(element).isNotEmpty() + + override fun apply(element: KtCallExpression) { + RedundantSamConstructorInspection.samConstructorCallsToBeConverted(element).forEach { call -> + RedundantSamConstructorInspection.replaceSamConstructorCall(call) } - - return null } } class UninitializedVariableReferenceFromInitializerToThisReferenceProcessing : - InspectionLikeProcessing { - override val writeActionNeeded = true + ApplicabilityBasedInspectionLikeProcessing(KtSimpleNameExpression::class) { - override fun createAction(element: PsiElement, settings: ConverterSettings?): (() -> Unit)? { - if (element !is KtSimpleNameExpression) return null - val anonymousObject = element.getStrictParentOfType()?.takeIf { it.name == null } ?: return null - - val resolved = element.mainReference.resolve() ?: return null + override fun isApplicableTo(element: KtSimpleNameExpression, settings: ConverterSettings?): Boolean { + val anonymousObject = element.getStrictParentOfType()?.takeIf { it.name == null } ?: return false + val resolved = element.mainReference.resolve() ?: return false if (resolved.isAncestor(element, strict = true)) { if (resolved is KtVariableDeclaration && resolved.hasInitializer()) { - if (resolved.initializer!!.getChildOfType() == anonymousObject) { - return { element.replaced(KtPsiFactory(element).createThisExpression()) } + if (resolved.initializer?.getChildOfType() == anonymousObject) { + return true } } } + return false + } - return null + override fun apply(element: KtSimpleNameExpression) { + element.replaced(KtPsiFactory(element).createThisExpression()) } } class UnresolvedVariableReferenceFromInitializerToThisReferenceProcessing : - InspectionLikeProcessing { - override val writeActionNeeded = true + ApplicabilityBasedInspectionLikeProcessing(KtSimpleNameExpression::class) { - override fun createAction(element: PsiElement, settings: ConverterSettings?): (() -> Unit)? { - if (element !is KtSimpleNameExpression || element.mainReference.resolve() != null) return null + override fun isApplicableTo(element: KtSimpleNameExpression, settings: ConverterSettings?): Boolean { + val anonymousObject = element.getStrictParentOfType() ?: return false + val variable = anonymousObject.getStrictParentOfType() ?: return false + if (variable.nameAsName != element.getReferencedNameAsName()) return false + if (variable.initializer?.getChildOfType() != anonymousObject) return false + return element.mainReference.resolve() == null + } - val anonymousObject = element.getStrictParentOfType() ?: return null - - val variable = anonymousObject.getStrictParentOfType() ?: return null - - if (variable.nameAsName == element.getReferencedNameAsName() && - variable.initializer?.getChildOfType() == anonymousObject - ) { - return { element.replaced(KtPsiFactory(element).createThisExpression()) } - } - - return null + override fun apply(element: KtSimpleNameExpression) { + element.replaced(KtPsiFactory(element).createThisExpression()) } } @@ -361,19 +311,6 @@ class RemoveRedundantVisibilityModifierProcessing : ApplicabilityBasedInspection } } -class RemoveExplicitPropertyTypeWithInspectionProcessing : - InspectionLikeProcessing { - override val writeActionNeeded: Boolean = true - private val processing = - generalInspectionBasedProcessing(RedundantExplicitTypeInspection()) - - override fun createAction(element: PsiElement, settings: ConverterSettings?): (() -> Unit)? { - if (settings?.specifyLocalVariableTypeByDefault == true) return null - - return processing.createAction(element, settings) - } -} - class RemoveExplicitOpenInInterfaceProcessing : ApplicabilityBasedInspectionLikeProcessing(KtClass::class) { override fun isApplicableTo(element: KtClass, settings: ConverterSettings?): Boolean = element.isValid diff --git a/nj2k/testData/newJ2k/annotations/jetbrainsNotNull.kt b/nj2k/testData/newJ2k/annotations/jetbrainsNotNull.kt index 7e541add70a..d0b198676fa 100644 --- a/nj2k/testData/newJ2k/annotations/jetbrainsNotNull.kt +++ b/nj2k/testData/newJ2k/annotations/jetbrainsNotNull.kt @@ -17,7 +17,7 @@ class Test(str: String) { fun test() { sout("String") - val test: String = "String2" + val test = "String2" sout(test) sout(dummy(test)) test.Test(test) diff --git a/nj2k/testData/newJ2k/annotations/jetbrainsNullable.kt b/nj2k/testData/newJ2k/annotations/jetbrainsNullable.kt index b3613d6f884..03821ed7124 100644 --- a/nj2k/testData/newJ2k/annotations/jetbrainsNullable.kt +++ b/nj2k/testData/newJ2k/annotations/jetbrainsNullable.kt @@ -14,7 +14,7 @@ class Test(str: String?) { fun test() { sout("String") - val test: String = "String2" + val test = "String2" sout(test) sout(dummy(test)) test.Test(test) diff --git a/nj2k/testData/newJ2k/assignmentExpression/nullability-settings.kt b/nj2k/testData/newJ2k/assignmentExpression/nullability-settings.kt index bdc86f56617..629d8806fe5 100644 --- a/nj2k/testData/newJ2k/assignmentExpression/nullability-settings.kt +++ b/nj2k/testData/newJ2k/assignmentExpression/nullability-settings.kt @@ -1,7 +1,7 @@ internal class Foo { fun foo(o: HashSet<*>) { val o2: HashSet<*> = o - var foo: Int = 0 + var foo = 0 foo = o2.size } } \ No newline at end of file diff --git a/nj2k/testData/newJ2k/callChainExpression/libraryMethodCallFromInstance-settings.kt b/nj2k/testData/newJ2k/callChainExpression/libraryMethodCallFromInstance-settings.kt index 07951c3e50b..478c7fad35b 100644 --- a/nj2k/testData/newJ2k/callChainExpression/libraryMethodCallFromInstance-settings.kt +++ b/nj2k/testData/newJ2k/callChainExpression/libraryMethodCallFromInstance-settings.kt @@ -2,17 +2,15 @@ // !specifyLocalVariableTypeByDefault: true internal class Library { fun call() {} - val string: String get() = "" } internal class User { fun main() { - val lib: Library = Library() + val lib = Library() lib.call() lib.string.isEmpty() - Library().call() Library().string.isEmpty() } diff --git a/nj2k/testData/newJ2k/settings/specifyLocalVariableTypeByDefault.kt b/nj2k/testData/newJ2k/settings/specifyLocalVariableTypeByDefault.kt index 99b32f26a69..be5eba55c95 100644 --- a/nj2k/testData/newJ2k/settings/specifyLocalVariableTypeByDefault.kt +++ b/nj2k/testData/newJ2k/settings/specifyLocalVariableTypeByDefault.kt @@ -1,5 +1,6 @@ // !specifyLocalVariableTypeByDefault: true + fun foo() { - val i: Int = 1 - val s: String = "" + val i = 1 + val s = "" } \ No newline at end of file diff --git a/nj2k/testData/newJ2k/settings/specifyLocalVariableTypeByDefaultInFor.kt b/nj2k/testData/newJ2k/settings/specifyLocalVariableTypeByDefaultInFor.kt index 4f6be3f75b1..8a1331920a9 100644 --- a/nj2k/testData/newJ2k/settings/specifyLocalVariableTypeByDefaultInFor.kt +++ b/nj2k/testData/newJ2k/settings/specifyLocalVariableTypeByDefaultInFor.kt @@ -1,7 +1,7 @@ // !specifyLocalVariableTypeByDefault: true fun foo(list: List) { - val array: IntArray = IntArray(10) + val array = IntArray(10) for (i: Int in 0..9) { array[i] = i }