Skip to content

Commit bcf7de0

Browse files
committed
Add inspection for duplicate local variable/parameters
1 parent 0219614 commit bcf7de0

File tree

5 files changed

+91
-0
lines changed

5 files changed

+91
-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 an inspection for checking duplicate local variables and parameters.
8+
59
### Fixed
610

711
- Fix project opening not working as expected in IntelliJ 2023 builds.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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.ResolveState
8+
import io.runescript.plugin.ide.RsBundle
9+
import io.runescript.plugin.lang.psi.RsArrayVariableDeclarationStatement
10+
import io.runescript.plugin.lang.psi.RsLocalVariableDeclarationStatement
11+
import io.runescript.plugin.lang.psi.RsLocalVariableExpression
12+
import io.runescript.plugin.lang.psi.RsParameter
13+
import io.runescript.plugin.lang.psi.RsVisitor
14+
import io.runescript.plugin.lang.psi.scope.RsLocalVariableResolver
15+
import io.runescript.plugin.lang.psi.scope.RsResolveMode
16+
import io.runescript.plugin.lang.psi.scope.RsScopesUtil
17+
18+
class RuneScriptDuplicateLocalVariableInspection : LocalInspectionTool() {
19+
20+
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
21+
return object : RsVisitor() {
22+
23+
override fun visitParameter(o: RsParameter) {
24+
val name = o.localVariableExpression.name ?: return
25+
var prev = o.prevSibling
26+
while (prev != null) {
27+
if (prev is RsParameter) {
28+
val prevName = prev.localVariableExpression.name
29+
if (name == prevName) {
30+
holder.registerProblem(
31+
o.localVariableExpression,
32+
RsBundle.message("inspection.error.duplicate.parameter", name),
33+
ProblemHighlightType.GENERIC_ERROR
34+
)
35+
break
36+
}
37+
}
38+
prev = prev.prevSibling
39+
}
40+
}
41+
42+
override fun visitLocalVariableDeclarationStatement(o: RsLocalVariableDeclarationStatement) {
43+
val prev = o.prevSibling ?: o.parent ?: return
44+
val expr = o.expressionList[0] as RsLocalVariableExpression
45+
val name = expr.name ?: return
46+
val resolver = RsLocalVariableResolver(name, RsResolveMode.Variables)
47+
RsScopesUtil.walkUpScopes(resolver, ResolveState.initial(), prev)
48+
if (resolver.declaration != null) {
49+
holder.registerProblem(
50+
expr,
51+
RsBundle.message("inspection.error.duplicate.local.variable", name),
52+
ProblemHighlightType.GENERIC_ERROR
53+
)
54+
}
55+
}
56+
57+
override fun visitArrayVariableDeclarationStatement(o: RsArrayVariableDeclarationStatement) {
58+
val prev = o.prevSibling ?: o.parent ?: return
59+
val expr = o.expressionList[0] as RsLocalVariableExpression
60+
val name = expr.name ?: return
61+
val resolver = RsLocalVariableResolver(name, RsResolveMode.Arrays)
62+
RsScopesUtil.walkUpScopes(resolver, ResolveState.initial(), prev)
63+
if (resolver.declaration != null) {
64+
holder.registerProblem(
65+
expr,
66+
RsBundle.message("inspection.error.duplicate.array.variable", name),
67+
ProblemHighlightType.GENERIC_ERROR
68+
)
69+
}
70+
}
71+
}
72+
}
73+
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
enabledByDefault="true"
2525
level="ERROR"
2626
implementationClass="io.runescript.plugin.ide.inspections.RuneScriptUnresolvedLocalVariableInspection"/>
27+
<localInspection language="RuneScript"
28+
groupName="RuneScript"
29+
displayName="Duplicate local variable"
30+
enabledByDefault="true"
31+
level="ERROR"
32+
implementationClass="io.runescript.plugin.ide.inspections.RuneScriptDuplicateLocalVariableInspection"/>
2733
<localInspection language="RuneScript"
2834
groupName="RuneScript"
2935
displayName="Unresolved game variable"
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 a local variable that is declared multiple times in the same scope.</p>
4+
</body>
5+
</html>

src/main/resources/messages/RsBundle.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ inspection.error.trigger.parameter.list.not.allowed=Trigger type `{0}` does not
6161
inspection.error.trigger.subject.not.found=Unresolved subject `{0}` of type `{1}`
6262
inspection.error.script.symbol.not.found=Script symbol not found for `{0}`
6363
inspection.error.trigger.code.not.allowed=Trigger type `command` does not allow for code statements
64+
inspection.error.duplicate.parameter=Duplicate parameter `{0}`
65+
inspection.error.duplicate.local.variable=Duplicate local variable `{0}`
66+
inspection.error.duplicate.array.variable=Duplicate array local variable `{0}`
6467

6568
# Intentions
6669
intention.category.expressions=RuneScript/Expressions

0 commit comments

Comments
 (0)