Add new quickfix for CanBePrimaryConstructorPropertyInspection

MovePropertyToConstructorIntention is used as quick fix
This commit is contained in:
Vyacheslav Gerasimov
2017-03-24 17:21:28 +03:00
parent 4700936f66
commit 543f59bf54
2 changed files with 17 additions and 35 deletions
@@ -16,21 +16,18 @@
package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInsight.FileModificationService
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
import org.jetbrains.kotlin.idea.util.CommentSaver
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.idea.intentions.MovePropertyToConstructorIntention
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtReferenceExpression
import org.jetbrains.kotlin.psi.KtVisitorVoid
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.getAnnotationEntries
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
@@ -45,8 +42,6 @@ class CanBePrimaryConstructorPropertyInspection : AbstractKotlinInspection() {
val context = property.analyzeFully()
val assignedDescriptor = context.get(BindingContext.REFERENCE_TARGET, assigned) as? ValueParameterDescriptor ?: return
// to prevent some exotic situations
if (!assignedDescriptor.annotations.isEmpty() || !assigned.getAnnotationEntries().isEmpty()) return
val containingConstructor = assignedDescriptor.containingDeclaration as? ClassConstructorDescriptor ?: return
if (containingConstructor.containingDeclaration.isData) return
@@ -67,32 +62,9 @@ class CanBePrimaryConstructorPropertyInspection : AbstractKotlinInspection() {
"Property is explicitly assigned to parameter ${assignedDescriptor.name}, can be declared directly in constructor",
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
isOnTheFly,
MakeConstructorPropertyFix(property, assignedParameter)
MovePropertyToConstructorIntention()
))
}
}
}
class MakeConstructorPropertyFix(val original: KtProperty, val parameter: KtParameter) : LocalQuickFix {
override fun getName() = "Move to constructor"
override fun getFamilyName() = "Move to constructor"
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
if (!FileModificationService.getInstance().preparePsiElementForWrite(descriptor.psiElement)) return
val commentSaver = CommentSaver(original)
val isVar = original.isVar
val modifiers = original.modifierList?.text
val factory = KtPsiFactory(project)
val valOrVar = if (isVar) factory.createVarKeyword() else factory.createValKeyword()
parameter.addBefore(valOrVar, parameter.nameIdentifier)
if (modifiers != null) {
val newModifiers = factory.createModifierList(modifiers)
parameter.addBefore(newModifiers, parameter.valOrVarKeyword)
}
original.delete()
commentSaver.restore(parameter)
}
}
}
@@ -16,7 +16,10 @@
package org.jetbrains.kotlin.idea.intentions
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
@@ -38,7 +41,14 @@ import org.jetbrains.kotlin.types.KotlinType
class MovePropertyToConstructorIntention :
SelfTargetingIntention<KtProperty>(KtProperty::class.java, "Move to constructor") {
SelfTargetingIntention<KtProperty>(KtProperty::class.java, "Move to constructor"),
LocalQuickFix {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val property = descriptor.psiElement as? KtProperty ?: return
applyTo(property, null)
}
override fun isApplicableTo(element: KtProperty, caretOffset: Int): Boolean =
!element.isLocal
&& !element.hasDelegate()