Skip to content

Commit

Permalink
Cleanup inspection highlighting in editor
Browse files Browse the repository at this point in the history
  • Loading branch information
jzbrooks committed Sep 14, 2022
1 parent 77bd62a commit 29e6301
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,27 @@ import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.elementType
import io.github.facilityapi.intellij.FsdBundle
import io.github.facilityapi.intellij.psi.FsdDataSpec
import io.github.facilityapi.intellij.psi.FsdDecoratedElement
import io.github.facilityapi.intellij.psi.FsdDecoratedEnumValue
import io.github.facilityapi.intellij.psi.FsdDecoratedErrorSpec
import io.github.facilityapi.intellij.psi.FsdDecoratedField
import io.github.facilityapi.intellij.psi.FsdEnumSpec
import io.github.facilityapi.intellij.psi.FsdErrorList
import io.github.facilityapi.intellij.psi.FsdErrorSetSpec
import io.github.facilityapi.intellij.psi.FsdMethodSpec
import io.github.facilityapi.intellij.psi.FsdServiceItems
import io.github.facilityapi.intellij.psi.FsdTypes

class DuplicateMemberInspection : LocalInspectionTool() {
override fun buildVisitor(
holder: ProblemsHolder,
isOnTheFly: Boolean,
session: LocalInspectionToolSession
): PsiElementVisitor = object : PsiElementVisitor() {
private val serviceMemberFix = ServiceFix()
private val fieldFix = FieldFix()
private val fix = Fix()

override fun visitElement(element: PsiElement) {
if (element is FsdServiceItems) {
Expand All @@ -41,7 +45,7 @@ class DuplicateMemberInspection : LocalInspectionTool() {
for ((memberName, memberIds) in duplicateMembers) {
val message = FsdBundle.getMessage("inspections.bugs.duplicate.member.service", memberName)
for (memberId in memberIds) {
holder.registerProblem(memberId, message, serviceMemberFix)
holder.registerProblem(memberId, message, fix)
}
}
}
Expand All @@ -66,7 +70,7 @@ class DuplicateMemberInspection : LocalInspectionTool() {
for ((caseName, cases) in duplicateNames) {
val message = FsdBundle.getMessage("inspections.bugs.duplicate.member.enumerated", caseName)
for (case in cases) {
holder.registerProblem(case, message, fieldFix)
holder.registerProblem(case.enumValue!!.identifier, message, fix)
}
}
}
Expand All @@ -79,7 +83,7 @@ class DuplicateMemberInspection : LocalInspectionTool() {
for ((errorName, errors) in duplicateErrors) {
val message = FsdBundle.getMessage("inspections.bugs.duplicate.member.error", errorName)
for (error in errors) {
holder.registerProblem(error, message, fieldFix)
holder.registerProblem(error.errorSpec!!.identifier, message, fix)
}
}
}
Expand All @@ -93,34 +97,25 @@ class DuplicateMemberInspection : LocalInspectionTool() {
for ((fieldName, elements) in duplicateField) {
val message = FsdBundle.getMessage(bundleKey, fieldName)
for (element in elements) {
holder.registerProblem(element, message, fieldFix)
holder.registerProblem(element.field.identifier, message, fix)
}
}
}
}

class FieldFix : LocalQuickFix {
class Fix : LocalQuickFix {
override fun getFamilyName() = NAME

override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
descriptor.psiElement.delete()
}

companion object {
val NAME = FsdBundle.getMessage("inspections.bugs.duplicate.member.quickfix")
}
}

class ServiceFix : LocalQuickFix {
private val PsiElement.isServiceItem: Boolean
get() = this is FsdMethodSpec || this is FsdDataSpec || this is FsdEnumSpec || this is FsdErrorSetSpec
val decoratedElement = PsiTreeUtil.getParentOfType(descriptor.psiElement, FsdDecoratedElement::class.java)!!
val nextSibling = PsiTreeUtil.skipWhitespacesForward(decoratedElement)

override fun getFamilyName() = NAME
decoratedElement.delete()

override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
var element: PsiElement? = descriptor.psiElement
while (element != null && !element.isServiceItem) { element = element.parent }
element?.delete()
val isListItem = decoratedElement is FsdDecoratedEnumValue || decoratedElement is FsdDecoratedErrorSpec
if (isListItem && nextSibling != null && nextSibling.elementType == FsdTypes.COMMA) {
nextSibling.delete()
}
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class DuplicateMemberInspectionTest : BasePlatformTestCase() {
text
}
}
}
""".trimIndent()

checkFix(before, after)
Expand Down Expand Up @@ -330,6 +330,31 @@ class DuplicateMemberInspectionTest : BasePlatformTestCase() {
checkFix(before, after)
}

fun testDuplicateEnumFieldFixRemovesComma() {
val before = """
service MessageService {
enum ConversationKind
{
person,
<caret>group,
group
}
}
"""

val after = """
service MessageService {
enum ConversationKind
{
person,
group
}
}
"""

checkFix(before, after)
}

fun testDuplicatedErrorValueFix() {
val before = """
service MessageService {
Expand All @@ -353,6 +378,29 @@ class DuplicateMemberInspectionTest : BasePlatformTestCase() {
checkFix(before, after)
}

fun testDuplicatedErrorValueFixRemovesComma() {
val before = """
service MessageService {
errors MessageError
{
<caret>accountBanned,
accountBanned
}
}
"""

val after = """
service MessageService {
errors MessageError
{
accountBanned
}
}
"""

checkFix(before, after)
}

private fun checkInspection(code: String, errorDescription: String) {
myFixture.configureByText(FsdLanguage.associatedFileType, code)
myFixture.enableInspections(DuplicateMemberInspection())
Expand All @@ -370,7 +418,7 @@ class DuplicateMemberInspectionTest : BasePlatformTestCase() {
myFixture.enableInspections(DuplicateMemberInspection())
myFixture.doHighlighting()

val intention = myFixture.findSingleIntention(DuplicateMemberInspection.FieldFix.NAME)
val intention = myFixture.findSingleIntention(DuplicateMemberInspection.Fix.NAME)
myFixture.launchAction(intention)

myFixture.checkResult(after)
Expand Down

0 comments on commit 29e6301

Please sign in to comment.