AbstractApplicabilityBasedInspection: move visitor inside base class

This commit is contained in:
Mikhail Glukhikh
2017-12-21 17:07:16 +03:00
parent 3268189215
commit 56230420f8
11 changed files with 41 additions and 109 deletions
@@ -23,9 +23,19 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtVisitorVoid
abstract class AbstractApplicabilityBasedInspection<in TElement: KtElement> : AbstractKotlinInspection() {
abstract class AbstractApplicabilityBasedInspection<TElement: KtElement>(
val elementType: Class<TElement>
) : AbstractKotlinInspection() {
abstract override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): KtVisitorVoid
final override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) =
object : KtVisitorVoid() {
override fun visitKtElement(element: KtElement) {
super.visitKtElement(element)
if (!elementType.isInstance(element) || element.textLength == 0) return
visitTargetElement(element as TElement, holder, isOnTheFly)
}
}
// This function should be called from visitor built by a derived inspection
protected fun visitTargetElement(element: TElement, holder: ProblemsHolder, isOnTheFly: Boolean) {
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInspection.*
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
@@ -25,11 +24,12 @@ import org.jetbrains.kotlin.idea.intentions.resolvedToArrayType
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.KtVisitorVoid
import org.jetbrains.kotlin.psi.createExpressionByPattern
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
class ReplaceArrayEqualityOpWithArraysEqualsInspection : AbstractApplicabilityBasedInspection<KtBinaryExpression>() {
class ReplaceArrayEqualityOpWithArraysEqualsInspection : AbstractApplicabilityBasedInspection<KtBinaryExpression>(
KtBinaryExpression::class.java
) {
override fun applyTo(element: PsiElement, project: Project, editor: Editor?) {
val expression = element as? KtBinaryExpression ?: return
val right = expression.right ?: return
@@ -57,14 +57,6 @@ class ReplaceArrayEqualityOpWithArraysEqualsInspection : AbstractApplicabilityBa
return rightResolvedCall?.resolvedToArrayType() == true && leftResolvedCall?.resolvedToArrayType() == true
}
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) =
object : KtVisitorVoid() {
override fun visitBinaryExpression(expression: KtBinaryExpression) {
super.visitBinaryExpression(expression)
visitTargetElement(expression, holder, isOnTheFly)
}
}
override fun inspectionText(element: KtBinaryExpression) = "Dangerous array comparison"
override val defaultFixText: String
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInspection.*
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
@@ -31,14 +30,9 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getExplicitReceiverValue
import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
class ReplacePutWithAssignmentInspection : AbstractApplicabilityBasedInspection<KtDotQualifiedExpression>() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): KtVisitorVoid =
object : KtVisitorVoid() {
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) {
super.visitDotQualifiedExpression(expression)
visitTargetElement(expression, holder, isOnTheFly)
}
}
class ReplacePutWithAssignmentInspection : AbstractApplicabilityBasedInspection<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java
) {
override fun isApplicable(element: KtDotQualifiedExpression): Boolean {
val callExpression = element.callExpression
@@ -16,8 +16,6 @@
package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
@@ -32,14 +30,9 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class ReplaceWithOperatorAssignmentInspection : AbstractApplicabilityBasedInspection<KtBinaryExpression>() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): KtVisitorVoid =
object : KtVisitorVoid() {
override fun visitBinaryExpression(expression: KtBinaryExpression) {
super.visitBinaryExpression(expression)
visitTargetElement(expression, holder, isOnTheFly)
}
}
class ReplaceWithOperatorAssignmentInspection : AbstractApplicabilityBasedInspection<KtBinaryExpression>(
KtBinaryExpression::class.java
) {
override fun isApplicable(element: KtBinaryExpression): Boolean {
if (element.operationToken != KtTokens.EQ) return false
@@ -17,8 +17,6 @@
package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInsight.CodeInsightUtilCore
import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
@@ -39,14 +37,7 @@ import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
class SimplifyAssertNotNullInspection : AbstractApplicabilityBasedInspection<KtCallExpression>() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): KtVisitorVoid =
object : KtVisitorVoid() {
override fun visitCallExpression(expression: KtCallExpression) {
super.visitCallExpression(expression)
visitTargetElement(expression, holder, isOnTheFly)
}
}
class SimplifyAssertNotNullInspection : AbstractApplicabilityBasedInspection<KtCallExpression>(KtCallExpression::class.java) {
override fun isApplicable(element: KtCallExpression): Boolean {
if ((element.calleeExpression as? KtNameReferenceExpression)?.getReferencedName() != "assert") return false
@@ -16,25 +16,17 @@
package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection
import org.jetbrains.kotlin.lexer.KtSingleValueToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
class SimplifyNegatedBinaryExpressionInspection : AbstractApplicabilityBasedInspection<KtPrefixExpression>() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): KtVisitorVoid =
object : KtVisitorVoid() {
override fun visitPrefixExpression(expression: KtPrefixExpression) {
super.visitPrefixExpression(expression)
visitTargetElement(expression, holder, isOnTheFly)
}
}
class SimplifyNegatedBinaryExpressionInspection : AbstractApplicabilityBasedInspection<KtPrefixExpression>(
KtPrefixExpression::class.java
) {
private fun IElementType.negate(): KtSingleValueToken? = when (this) {
KtTokens.IN_KEYWORD -> KtTokens.NOT_IN
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInspection.*
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
@@ -28,20 +27,14 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator
import org.jetbrains.kotlin.idea.refactoring.inline.KotlinInlineValHandler
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR
import org.jetbrains.kotlin.resolve.BindingContext.REFERENCE_TARGET
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
class UnnecessaryVariableInspection : AbstractApplicabilityBasedInspection<KtProperty>() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): KtVisitorVoid =
object : KtVisitorVoid() {
override fun visitProperty(property: KtProperty) {
super.visitProperty(property)
visitTargetElement(property, holder, isOnTheFly)
}
}
class UnnecessaryVariableInspection : AbstractApplicabilityBasedInspection<KtProperty>(KtProperty::class.java) {
override fun isApplicable(element: KtProperty) = statusFor(element) != null
@@ -16,30 +16,19 @@
package org.jetbrains.kotlin.idea.inspections.branchedTransformations
import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
import org.jetbrains.kotlin.idea.intentions.SelfTargetingOffsetIndependentIntention
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.*
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
class IfThenToSafeAccessInspection : AbstractApplicabilityBasedInspection<KtIfExpression>() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): KtVisitorVoid =
object : KtVisitorVoid() {
override fun visitIfExpression(expression: KtIfExpression) {
super.visitIfExpression(expression)
visitTargetElement(expression, holder, isOnTheFly)
}
}
class IfThenToSafeAccessInspection : AbstractApplicabilityBasedInspection<KtIfExpression>(KtIfExpression::class.java) {
override fun isApplicable(element: KtIfExpression): Boolean {
val ifThenToSelectData = element.buildSelectTransformationData() ?: return false
@@ -16,26 +16,16 @@
package org.jetbrains.kotlin.idea.inspections.branchedTransformations
import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.getSubjectToIntroduce
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.introduceSubject
import org.jetbrains.kotlin.psi.KtVisitorVoid
import org.jetbrains.kotlin.psi.KtWhenExpression
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
class IntroduceWhenSubjectInspection : AbstractApplicabilityBasedInspection<KtWhenExpression>() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): KtVisitorVoid =
object : KtVisitorVoid() {
override fun visitWhenExpression(expression: KtWhenExpression) {
super.visitWhenExpression(expression)
visitTargetElement(expression, holder, isOnTheFly)
}
}
class IntroduceWhenSubjectInspection : AbstractApplicabilityBasedInspection<KtWhenExpression>(KtWhenExpression::class.java) {
override fun isApplicable(element: KtWhenExpression) = element.getSubjectToIntroduce() != null
@@ -16,9 +16,7 @@
package org.jetbrains.kotlin.idea.inspections.conventionNameCalls
import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
@@ -39,14 +37,9 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.util.OperatorNameConventions
class ReplaceCallWithBinaryOperatorInspection : AbstractApplicabilityBasedInspection<KtDotQualifiedExpression>() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): KtVisitorVoid =
object : KtVisitorVoid() {
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) {
super.visitDotQualifiedExpression(expression)
visitTargetElement(expression, holder, isOnTheFly)
}
}
class ReplaceCallWithBinaryOperatorInspection : AbstractApplicabilityBasedInspection<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java
) {
private fun IElementType.inverted(): KtSingleValueToken? = when (this) {
KtTokens.LT -> KtTokens.GT
@@ -16,9 +16,7 @@
package org.jetbrains.kotlin.idea.inspections.conventionNameCalls
import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
@@ -29,7 +27,10 @@ import org.jetbrains.kotlin.idea.intentions.callExpression
import org.jetbrains.kotlin.idea.intentions.isReceiverExpressionWithValue
import org.jetbrains.kotlin.idea.intentions.toResolvedCall
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.buildExpression
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
@@ -39,7 +40,9 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.util.isValidOperator
class ReplaceGetOrSetInspection : AbstractApplicabilityBasedInspection<KtDotQualifiedExpression>() {
class ReplaceGetOrSetInspection : AbstractApplicabilityBasedInspection<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java
) {
private fun FunctionDescriptor.isExplicitOperator(): Boolean {
return if (overriddenDescriptors.isEmpty())
containingDeclaration !is JavaClassDescriptor && isOperator
@@ -47,14 +50,6 @@ class ReplaceGetOrSetInspection : AbstractApplicabilityBasedInspection<KtDotQual
overriddenDescriptors.any { it.isExplicitOperator() }
}
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): KtVisitorVoid =
object : KtVisitorVoid() {
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) {
super.visitDotQualifiedExpression(expression)
visitTargetElement(expression, holder, isOnTheFly)
}
}
private val operatorNames = setOf(OperatorNameConventions.GET, OperatorNameConventions.SET)
override fun isApplicable(element: KtDotQualifiedExpression): Boolean {