Skip to content

Commit 66005b0

Browse files
committed
Add inspection and quick fix for unused local variables
1 parent 60abbe4 commit 66005b0

File tree

6 files changed

+94
-0
lines changed

6 files changed

+94
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44

5+
### Added
6+
7+
- Add inspection and quick fix for unused local variables.
8+
59
## [1.5.0] - 2023-11-27
610

711
### Added
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package io.runescript.plugin.ide.inspections
2+
3+
import com.intellij.codeInspection.LocalInspectionTool
4+
import com.intellij.codeInspection.ProblemHighlightType
5+
import com.intellij.codeInspection.ProblemsHolder
6+
import com.intellij.psi.PsiElementVisitor
7+
import com.intellij.psi.search.GlobalSearchScope
8+
import com.intellij.psi.search.searches.ReferencesSearch
9+
import io.runescript.plugin.ide.inspections.fixes.RsDeleteLocalVariableFix
10+
import io.runescript.plugin.lang.psi.RsLocalVariableDeclarationStatement
11+
import io.runescript.plugin.lang.psi.RsVisitor
12+
13+
class RuneScriptUnusedLocalVariableInspection : LocalInspectionTool() {
14+
15+
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
16+
return object : RsVisitor() {
17+
override fun visitLocalVariableDeclarationStatement(o: RsLocalVariableDeclarationStatement) {
18+
val expr = o.expressionList[0]
19+
val references = ReferencesSearch.search(expr, GlobalSearchScope.fileScope(expr.containingFile)).findAll()
20+
if (references.isEmpty()) {
21+
holder.registerProblem(o,
22+
"Unused local variable",
23+
ProblemHighlightType.LIKE_UNUSED_SYMBOL,
24+
RsDeleteLocalVariableFix()
25+
)
26+
}
27+
}
28+
}
29+
}
30+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package io.runescript.plugin.ide.inspections.fixes
2+
3+
import com.intellij.codeInspection.LocalQuickFix
4+
import com.intellij.codeInspection.ProblemDescriptor
5+
import com.intellij.openapi.project.Project
6+
import io.runescript.plugin.lang.psi.*
7+
import io.runescript.plugin.symbollang.psi.RsSymSymbol
8+
9+
class RsDeleteLocalVariableFix : LocalQuickFix {
10+
override fun getFamilyName(): String = "Delete local variable"
11+
12+
override fun applyFix(project: Project, previewDescriptor: ProblemDescriptor) {
13+
if (previewDescriptor.psiElement is RsLocalVariableDeclarationStatement) {
14+
val decl = previewDescriptor.psiElement as RsLocalVariableDeclarationStatement
15+
val expr = decl.expressionList.getOrNull(1)
16+
if (expr == null || expr.isSimpleToRemove()) {
17+
decl.delete()
18+
} else {
19+
val stmt = RsElementGenerator.createExpressionStatement(project, expr.text)
20+
decl.replace(stmt)
21+
}
22+
}
23+
}
24+
}
25+
26+
private fun RsExpression.isSimpleToRemove(): Boolean {
27+
return when (this) {
28+
is RsNullLiteralExpression,
29+
is RsIntegerLiteralExpression,
30+
is RsCoordLiteralExpression,
31+
is RsBooleanLiteralExpression,
32+
is RsLongLiteralExpression -> true
33+
34+
is RsParExpression -> expression.isSimpleToRemove()
35+
is RsCalcExpression -> expression.isSimpleToRemove()
36+
is RsBinaryExpression -> left.isSimpleToRemove() && right.isSimpleToRemove()
37+
is RsDynamicExpression -> {
38+
val reference = reference?.resolve() ?: return false
39+
return reference is RsSymSymbol
40+
}
41+
42+
else -> false
43+
}
44+
}

src/main/kotlin/io/runescript/plugin/lang/psi/RsElementGenerator.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ object RsElementGenerator {
5757
return element.findDescendantOfType<RsDocLink>()!!.firstChild.nextSibling
5858
}
5959

60+
fun createExpressionStatement(project: Project, text: String): RsExpressionStatement {
61+
val element = createDummyFile(project, "[proc,dummy]()()$text;")
62+
return PsiTreeUtil.findChildOfType(element, RsExpressionStatement::class.java) as RsExpressionStatement
63+
}
64+
6065
private fun createDummyFile(project: Project, text: String): PsiFile {
6166
val factory = PsiFileFactory.getInstance(project) as PsiFileFactoryImpl
6267
val name = "dummy.${RsFileType.defaultExtension}"

src/main/resources/META-INF/inspections.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@
5454
enabledByDefault="true"
5555
level="WARNING"
5656
implementationClass="io.runescript.plugin.ide.inspections.RuneScriptUnreachableCodeInspection"/>
57+
<localInspection language="RuneScript"
58+
groupName="RuneScript"
59+
displayName="Unused local variable"
60+
enabledByDefault="true"
61+
level="WARNING"
62+
implementationClass="io.runescript.plugin.ide.inspections.RuneScriptUnusedLocalVariableInspection"/>
5763
<localInspection language="RuneScript"
5864
groupName="RuneScript"
5965
displayName="Missing script symbol"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<html>
2+
<body>
3+
<p>Reports when a local variable is unused.</p>
4+
</body>
5+
</html>

0 commit comments

Comments
 (0)