Refactoring of JetSelfTargetingInspection

This commit is contained in:
Valentin Kipyatkov
2015-04-14 13:17:58 +03:00
parent 894bf000e1
commit 00a4beae1d
51 changed files with 178 additions and 253 deletions
@@ -16,22 +16,18 @@
package org.jetbrains.kotlin.idea.inspections
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.psi.JetElement
import com.intellij.psi.PsiElementVisitor
import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.openapi.project.Project
import com.intellij.codeInspection.ProblemDescriptor
import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingIntention
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.editor.EditorFactory
import com.intellij.codeInspection.*
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.EditorFactory
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingOffsetIndependentIntention
import org.jetbrains.kotlin.psi.JetElement
public abstract class IntentionBasedInspection<T: JetElement>(
protected val intention: JetSelfTargetingIntention<T>
protected val intention: JetSelfTargetingOffsetIndependentIntention<T>
) : AbstractKotlinInspection() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
return object: PsiElementVisitor() {
@@ -70,11 +66,8 @@ public abstract class IntentionBasedInspection<T: JetElement>(
}
private fun PsiElement.getOrCreateEditor(): Editor? {
val file = getContainingFile()?.getVirtualFile()
if (file == null) return null
val document = FileDocumentManager.getInstance()!!.getDocument(file)
if (document == null) return null
val file = getContainingFile()?.getVirtualFile() ?: return null
val document = FileDocumentManager.getInstance().getDocument(file) ?: return null
val editorFactory = EditorFactory.getInstance()!!
@@ -37,27 +37,42 @@ public abstract class JetSelfTargetingIntention<T: JetElement>(
this.text = text
}
override fun getText() = text
override fun getFamilyName() = familyName
final override fun getText() = text
final override fun getFamilyName() = familyName
public abstract fun isApplicableTo(element: T, caretOffset: Int): Boolean
public abstract fun isApplicableTo(element: T): Boolean
public open fun isApplicableTo(element: T, editor: Editor): Boolean = isApplicableTo(element)
public abstract fun applyTo(element: T, editor: Editor)
protected fun getTarget(editor: Editor, file: PsiFile): T? {
private fun getTarget(editor: Editor, file: PsiFile): T? {
val offset = editor.getCaretModel().getOffset()
return file.findElementAt(offset)?.getParentOfTypesAndPredicate(false, elementType) { element -> isApplicableTo(element, editor) }
return file.findElementAt(offset)?.getParentOfTypesAndPredicate(false, elementType) { element -> isApplicableTo(element, offset) }
}
override fun isAvailable(project: Project, editor: Editor, file: PsiFile)
final override fun isAvailable(project: Project, editor: Editor, file: PsiFile)
= getTarget(editor, file) != null
override fun invoke(project: Project, editor: Editor, file: PsiFile): Unit {
final override fun invoke(project: Project, editor: Editor, file: PsiFile): Unit {
val target = getTarget(editor, file) ?: error("Intention is not applicable")
applyTo(target, editor)
}
override fun startInWriteAction(): Boolean = true
override fun startInWriteAction() = true
override fun toString(): String = getText()
}
public abstract class JetSelfTargetingOffsetIndependentIntention<T: JetElement>(
elementType: Class<T>,
text: String,
familyName: String)
: JetSelfTargetingIntention<T>(elementType, text, familyName) {
deprecated("Use primary constructor, no need to use i18n")
public constructor(key: String, elementType: Class<T>) : this(elementType, JetBundle.message(key), JetBundle.message(key + ".family")) {
}
public abstract fun isApplicableTo(element: T): Boolean
override final fun isApplicableTo(element: T, caretOffset: Int): Boolean = isApplicableTo(element)
}
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.idea.caches.resolve.analyze
public class OperatorToFunctionIntention : JetSelfTargetingIntention<JetExpression>("operator.to.function", javaClass()) {
public class OperatorToFunctionIntention : JetSelfTargetingOffsetIndependentIntention<JetExpression>("operator.to.function", javaClass()) {
companion object {
private fun isApplicablePrefix(element: JetPrefixExpression): Boolean {
return when (element.getOperationReference().getReferencedNameElementType()) {
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
public class RemoveExplicitTypeArguments : JetSelfTargetingIntention<JetTypeArgumentList>(
public class RemoveExplicitTypeArguments : JetSelfTargetingOffsetIndependentIntention<JetTypeArgumentList>(
"remove.explicit.type.arguments", javaClass()) {
override fun isApplicableTo(element: JetTypeArgumentList): Boolean {
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.psi.JetPsiUtil
import org.jetbrains.kotlin.idea.JetBundle
import org.jetbrains.kotlin.psi.JetPsiFactory
public class SimplifyNegatedBinaryExpressionIntention : JetSelfTargetingIntention<JetPrefixExpression>("simplify.negated.binary.expression", javaClass()) {
public class SimplifyNegatedBinaryExpressionIntention : JetSelfTargetingOffsetIndependentIntention<JetPrefixExpression>("simplify.negated.binary.expression", javaClass()) {
private fun JetPrefixExpression.unparenthesize(): JetExpression? {
return (this.getBaseExpression() as? JetParenthesizedExpression)?.getExpression()