New J2K: convert all custom post-processing to applicability based ones

This commit is contained in:
Ilya Kirillov
2019-09-17 18:16:20 +03:00
parent 509fcb17c7
commit 3724e2bb02
8 changed files with 72 additions and 134 deletions
@@ -184,8 +184,10 @@ private val inspectionLikePostProcessingGroup =
RemoveExplicitOpenInInterfaceProcessing(), RemoveExplicitOpenInInterfaceProcessing(),
RemoveRedundantOverrideVisibilityProcessing(), RemoveRedundantOverrideVisibilityProcessing(),
inspectionBasedProcessing(MoveLambdaOutsideParenthesesInspection()), inspectionBasedProcessing(MoveLambdaOutsideParenthesesInspection()),
ConvertToStringTemplateProcessing(), intentionBasedProcessing(ConvertToStringTemplateIntention()) {
UsePropertyAccessSyntaxProcessing(), ConvertToStringTemplateIntention.shouldSuggestToConvert(it)
},
intentionBasedProcessing(UsePropertyAccessSyntaxIntention()),
UninitializedVariableReferenceFromInitializerToThisReferenceProcessing(), UninitializedVariableReferenceFromInitializerToThisReferenceProcessing(),
UnresolvedVariableReferenceFromInitializerToThisReferenceProcessing(), UnresolvedVariableReferenceFromInitializerToThisReferenceProcessing(),
RemoveRedundantSamAdaptersProcessing(), RemoveRedundantSamAdaptersProcessing(),
@@ -193,7 +195,7 @@ private val inspectionLikePostProcessingGroup =
inspectionBasedProcessing(ReplacePutWithAssignmentInspection()), inspectionBasedProcessing(ReplacePutWithAssignmentInspection()),
UseExpressionBodyProcessing(), UseExpressionBodyProcessing(),
inspectionBasedProcessing(UnnecessaryVariableInspection()), inspectionBasedProcessing(UnnecessaryVariableInspection()),
RemoveExplicitPropertyTypeWithInspectionProcessing(), generalInspectionBasedProcessing(RedundantExplicitTypeInspection()),
JavaObjectEqualsToEqOperatorProcessing(), JavaObjectEqualsToEqOperatorProcessing(),
RemoveExplicitPropertyTypeProcessing(), RemoveExplicitPropertyTypeProcessing(),
RemoveRedundantNullabilityProcessing(), RemoveRedundantNullabilityProcessing(),
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.nj2k.postProcessing.processings package org.jetbrains.kotlin.nj2k.postProcessing.processings
import com.intellij.psi.PsiElement
import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.psi.search.searches.ReferencesSearch
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor 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.replaced
import org.jetbrains.kotlin.idea.core.setVisibility import org.jetbrains.kotlin.idea.core.setVisibility
import org.jetbrains.kotlin.idea.debugger.sequence.psi.callName 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.RedundantSamConstructorInspection
import org.jetbrains.kotlin.idea.inspections.UseExpressionBodyInspection import org.jetbrains.kotlin.idea.inspections.UseExpressionBodyInspection
import org.jetbrains.kotlin.idea.inspections.collections.isCalling 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.RemoveExplicitTypeArgumentsIntention
import org.jetbrains.kotlin.idea.intentions.UsePropertyAccessSyntaxIntention
import org.jetbrains.kotlin.idea.intentions.addUseSiteTarget import org.jetbrains.kotlin.idea.intentions.addUseSiteTarget
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.idea.references.mainReference 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.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.nj2k.postProcessing.ApplicabilityBasedInspectionLikeProcessing 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.*
import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
@@ -119,138 +113,94 @@ class RemoveJavaStreamsCollectCallTypeArgumentsProcessing :
} }
class RemoveRedundantOverrideVisibilityProcessing : InspectionLikeProcessing { class RemoveRedundantOverrideVisibilityProcessing :
override val writeActionNeeded = true ApplicabilityBasedInspectionLikeProcessing<KtCallableDeclaration>(KtCallableDeclaration::class) {
override fun createAction(element: PsiElement, settings: ConverterSettings?): (() -> Unit)? { override fun isApplicableTo(element: KtCallableDeclaration, settings: ConverterSettings?): Boolean {
if (element !is KtCallableDeclaration || !element.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return null if (!element.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return false
val modifier = element.visibilityModifierType() ?: return null return element.visibilityModifier() != null
return { element.setVisibility(modifier) } }
override fun apply(element: KtCallableDeclaration) {
val modifier = element.visibilityModifierType() ?: return
element.setVisibility(modifier)
} }
} }
class ConvertToStringTemplateProcessing : InspectionLikeProcessing { class UseExpressionBodyProcessing : ApplicabilityBasedInspectionLikeProcessing<KtPropertyAccessor>(KtPropertyAccessor::class) {
override val writeActionNeeded = true private val inspection = UseExpressionBodyInspection(convertEmptyToUnit = false)
override fun isApplicableTo(element: KtPropertyAccessor, settings: ConverterSettings?): Boolean =
inspection.isActiveFor(element)
val intention = ConvertToStringTemplateIntention() override fun apply(element: KtPropertyAccessor) {
inspection.simplify(element, false)
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
}
} }
} }
class UsePropertyAccessSyntaxProcessing : InspectionLikeProcessing { class RemoveRedundantCastToNullableProcessing :
override val writeActionNeeded = true ApplicabilityBasedInspectionLikeProcessing<KtBinaryExpressionWithTypeRHS>(KtBinaryExpressionWithTypeRHS::class) {
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
override fun isApplicableTo(element: KtBinaryExpressionWithTypeRHS, settings: ConverterSettings?): Boolean {
if (element.right?.typeElement !is KtNullableType) return false
val context = element.analyze() val context = element.analyze()
val leftType = context.getType(element.left) ?: return null val leftType = context.getType(element.left) ?: return false
val rightType = context.get(BindingContext.TYPE, element.right) ?: return null val rightType = context.get(BindingContext.TYPE, element.right) ?: return false
return !leftType.isMarkedNullable && rightType.isMarkedNullable
}
if (!leftType.isMarkedNullable && rightType.isMarkedNullable) { override fun apply(element: KtBinaryExpressionWithTypeRHS) {
return { val type = element.right?.typeElement as? KtNullableType ?: return
val type = element.right?.typeElement as? KtNullableType type.replace(type.innerType ?: return)
type?.replace(type.innerType!!) }
} }
class RemoveRedundantSamAdaptersProcessing :
ApplicabilityBasedInspectionLikeProcessing<KtCallExpression>(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 : class UninitializedVariableReferenceFromInitializerToThisReferenceProcessing :
InspectionLikeProcessing { ApplicabilityBasedInspectionLikeProcessing<KtSimpleNameExpression>(KtSimpleNameExpression::class) {
override val writeActionNeeded = true
override fun createAction(element: PsiElement, settings: ConverterSettings?): (() -> Unit)? { override fun isApplicableTo(element: KtSimpleNameExpression, settings: ConverterSettings?): Boolean {
if (element !is KtSimpleNameExpression) return null val anonymousObject = element.getStrictParentOfType<KtClassOrObject>()?.takeIf { it.name == null } ?: return false
val anonymousObject = element.getStrictParentOfType<KtClassOrObject>()?.takeIf { it.name == null } ?: return null val resolved = element.mainReference.resolve() ?: return false
val resolved = element.mainReference.resolve() ?: return null
if (resolved.isAncestor(element, strict = true)) { if (resolved.isAncestor(element, strict = true)) {
if (resolved is KtVariableDeclaration && resolved.hasInitializer()) { if (resolved is KtVariableDeclaration && resolved.hasInitializer()) {
if (resolved.initializer!!.getChildOfType<KtClassOrObject>() == anonymousObject) { if (resolved.initializer?.getChildOfType<KtClassOrObject>() == anonymousObject) {
return { element.replaced(KtPsiFactory(element).createThisExpression()) } return true
} }
} }
} }
return false
}
return null override fun apply(element: KtSimpleNameExpression) {
element.replaced(KtPsiFactory(element).createThisExpression())
} }
} }
class UnresolvedVariableReferenceFromInitializerToThisReferenceProcessing : class UnresolvedVariableReferenceFromInitializerToThisReferenceProcessing :
InspectionLikeProcessing { ApplicabilityBasedInspectionLikeProcessing<KtSimpleNameExpression>(KtSimpleNameExpression::class) {
override val writeActionNeeded = true
override fun createAction(element: PsiElement, settings: ConverterSettings?): (() -> Unit)? { override fun isApplicableTo(element: KtSimpleNameExpression, settings: ConverterSettings?): Boolean {
if (element !is KtSimpleNameExpression || element.mainReference.resolve() != null) return null val anonymousObject = element.getStrictParentOfType<KtClassOrObject>() ?: return false
val variable = anonymousObject.getStrictParentOfType<KtVariableDeclaration>() ?: return false
if (variable.nameAsName != element.getReferencedNameAsName()) return false
if (variable.initializer?.getChildOfType<KtClassOrObject>() != anonymousObject) return false
return element.mainReference.resolve() == null
}
val anonymousObject = element.getStrictParentOfType<KtClassOrObject>() ?: return null override fun apply(element: KtSimpleNameExpression) {
element.replaced(KtPsiFactory(element).createThisExpression())
val variable = anonymousObject.getStrictParentOfType<KtVariableDeclaration>() ?: return null
if (variable.nameAsName == element.getReferencedNameAsName() &&
variable.initializer?.getChildOfType<KtClassOrObject>() == anonymousObject
) {
return { element.replaced(KtPsiFactory(element).createThisExpression()) }
}
return null
} }
} }
@@ -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>(KtClass::class) { class RemoveExplicitOpenInInterfaceProcessing : ApplicabilityBasedInspectionLikeProcessing<KtClass>(KtClass::class) {
override fun isApplicableTo(element: KtClass, settings: ConverterSettings?): Boolean = override fun isApplicableTo(element: KtClass, settings: ConverterSettings?): Boolean =
element.isValid element.isValid
+1 -1
View File
@@ -17,7 +17,7 @@ class Test(str: String) {
fun test() { fun test() {
sout("String") sout("String")
val test: String = "String2" val test = "String2"
sout(test) sout(test)
sout(dummy(test)) sout(dummy(test))
test.Test(test) test.Test(test)
+1 -1
View File
@@ -14,7 +14,7 @@ class Test(str: String?) {
fun test() { fun test() {
sout("String") sout("String")
val test: String = "String2" val test = "String2"
sout(test) sout(test)
sout(dummy(test)) sout(dummy(test))
test.Test(test) test.Test(test)
@@ -1,7 +1,7 @@
internal class Foo { internal class Foo {
fun foo(o: HashSet<*>) { fun foo(o: HashSet<*>) {
val o2: HashSet<*> = o val o2: HashSet<*> = o
var foo: Int = 0 var foo = 0
foo = o2.size foo = o2.size
} }
} }
@@ -2,17 +2,15 @@
// !specifyLocalVariableTypeByDefault: true // !specifyLocalVariableTypeByDefault: true
internal class Library { internal class Library {
fun call() {} fun call() {}
val string: String val string: String
get() = "" get() = ""
} }
internal class User { internal class User {
fun main() { fun main() {
val lib: Library = Library() val lib = Library()
lib.call() lib.call()
lib.string.isEmpty() lib.string.isEmpty()
Library().call() Library().call()
Library().string.isEmpty() Library().string.isEmpty()
} }
@@ -1,5 +1,6 @@
// !specifyLocalVariableTypeByDefault: true // !specifyLocalVariableTypeByDefault: true
fun foo() { fun foo() {
val i: Int = 1 val i = 1
val s: String = "" val s = ""
} }
@@ -1,7 +1,7 @@
// !specifyLocalVariableTypeByDefault: true // !specifyLocalVariableTypeByDefault: true
fun foo(list: List<String?>) { fun foo(list: List<String?>) {
val array: IntArray = IntArray(10) val array = IntArray(10)
for (i: Int in 0..9) { for (i: Int in 0..9) {
array[i] = i array[i] = i
} }