Skip to content

Commit

Permalink
Inspections: Create single diagnostic for inspections based on multip…
Browse files Browse the repository at this point in the history
…le intentions

 #KT-7784 Fixed
  • Loading branch information
asedunov committed May 21, 2015
1 parent 5166cdb commit 14d1d8e
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 33 deletions.
Expand Up @@ -21,48 +21,61 @@ 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.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingRangeIntention
import org.jetbrains.kotlin.psi.JetElement

public abstract class IntentionBasedInspection<T: JetElement>(
public abstract class IntentionBasedInspection<T : JetElement>(
protected val intentions: List<JetSelfTargetingRangeIntention<T>>,
protected val problemText: String?,
protected val elementType: Class<T>
) : AbstractKotlinInspection() {
constructor(intention: JetSelfTargetingRangeIntention<T>): this(listOf(intention), intention.elementType)
constructor(intention: JetSelfTargetingRangeIntention<T>) : this(listOf(intention), null, intention.elementType)

override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
return object: PsiElementVisitor() {
override fun visitElement(element: PsiElement) {
if (!elementType.isInstance(element) || element.getTextLength() == 0) return
class IntentionBasedQuickFix(
val intention: JetSelfTargetingRangeIntention<T>,
val targetElement: T
): LocalQuickFix {
private val text = intention.getText()

[suppress("UNCHECKED_CAST")]
val targetElement = element as T
override fun getFamilyName() = getName()

for (intention in intentions) {
val range = intention.applicabilityRange(targetElement) ?: continue
val elementRange = targetElement.getTextRange()
assert(range in elementRange, "Wrong applicabilityRange() result for $intention - should be within element's range")
val rangeInElement = range.shiftRight(-elementRange.getStartOffset())
override fun getName() = text

val fix = object: LocalQuickFix {
private val text = intention.getText()
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
targetElement.getOrCreateEditor()?.let { editor ->
editor.getCaretModel().moveToOffset(targetElement.getTextOffset())
intention.applyTo(targetElement, editor)
}
}
}

override fun getFamilyName() = getName()
return object : PsiElementVisitor() {
override fun visitElement(element: PsiElement) {
if (!elementType.isInstance(element) || element.getTextLength() == 0) return

override fun getName() = text
@suppress("UNCHECKED_CAST")
val targetElement = element as T

override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
targetElement.getOrCreateEditor()?.let { editor ->
editor.getCaretModel().moveToOffset(targetElement.getTextOffset())
intention.applyTo(targetElement, editor)
val ranges = intentions
.map {
val range = it.applicabilityRange(targetElement)
if (range != null) {
val elementRange = targetElement.getTextRange()
assert(range in elementRange, "Wrong applicabilityRange() result for $it - should be within element's range")
range.shiftRight(-elementRange.getStartOffset())
}
else null
}
}
.filterNotNull()
if (ranges.isEmpty()) return

holder.registerProblem(targetElement, intention.getText(), problemHighlightType, rangeInElement, fix)
}
val fixes = intentions.map { IntentionBasedQuickFix(it, targetElement) }.toTypedArray()
val rangeInElement = ranges.fold(TextRange.EMPTY_RANGE) { a, b -> a union b }
holder.registerProblem(targetElement, problemText ?: fixes.first().getName(), problemHighlightType, rangeInElement, *fixes)
}
}
}
Expand Down
Expand Up @@ -21,5 +21,6 @@ import org.jetbrains.kotlin.psi.JetPackageDirective

public class PackageDirectoryMismatchInspection: IntentionBasedInspection<JetPackageDirective>(
listOf(MoveFileToPackageMatchingDirectoryIntention(), ChangePackageToMatchDirectoryIntention()),
"Package directive doesn't match file location",
javaClass()
)
Expand Up @@ -5,15 +5,6 @@
<module>testPackageDirectoryMismatch_PackageDirectoryMismatch_0</module>
<entry_point TYPE="file" FQNAME="barPackageMismatched.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Package name does not match containing directory</problem_class>
<description>Move file to 'bar'</description>
</problem>

<problem>
<file>barPackageMismatched.kt</file>
<line>1</line>
<module>testPackageDirectoryMismatch_PackageDirectoryMismatch_0</module>
<entry_point TYPE="file" FQNAME="barPackageMismatched.kt" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Package name does not match containing directory</problem_class>
<description>Change file's package to 'foo'</description>
<description>Package directive doesn't match file location</description>
</problem>
</problems>

0 comments on commit 14d1d8e

Please sign in to comment.