Skip to content

Commit a122071

Browse files
committed
feat: annotate T\d and V\d params as variables
1 parent 44394bb commit a122071

File tree

5 files changed

+153
-11
lines changed

5 files changed

+153
-11
lines changed

src/main/kotlin/com/github/xepozz/php_opcodes_language/language/PHPOpAnnotator.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.github.xepozz.php_opcodes_language.language
22

33
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpInstructionName
4+
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpParameter
45
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpVarName
56
import com.intellij.lang.annotation.AnnotationHolder
67
import com.intellij.lang.annotation.Annotator
@@ -18,6 +19,14 @@ class PHPOpAnnotator : Annotator {
1819
.textAttributes(PhpHighlightingData.VAR)
1920
.create()
2021
}
22+
is PHPOpParameter -> {
23+
if (element.text.matches(Regex("[TV]\\d+"))) {
24+
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
25+
.range(element)
26+
.textAttributes(PhpHighlightingData.VAR)
27+
.create()
28+
}
29+
}
2130

2231
is PHPOpInstructionName -> {
2332
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)

src/main/kotlin/com/github/xepozz/php_opcodes_language/language/parser/PHPOp.bnf

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,29 @@ phpOpFile ::= item_*
3333
private item_ ::= block | COMMENT | EOL
3434

3535
block ::= block_name COLON statements
36-
3736
block_name ::= var_name | string_literal | IDENTIFIER COLON COLON IDENTIFIER | IDENTIFIER
3837

3938
statements ::= (statement | COMMENT | EOL)+
40-
4139
statement ::= NUMBER (assignment_instruction | instruction) | live_range
4240

43-
assignment_instruction ::= IDENTIFIER EQUALS_SIGN instruction
44-
41+
assignment_instruction ::= parameter EQUALS_SIGN instruction
4542
instruction ::= instruction_name argument*
46-
4743
instruction_name ::= IDENTIFIER
4844

4945
argument ::= expr | paren_expr
46+
private expr ::= var_name | string_literal | NUMBER | paren_parameter | parameter | EQUALS_SIGN
5047

51-
expr ::= var_name | string_literal | NUMBER | IDENTIFIER paren_expr | IDENTIFIER | EQUALS_SIGN
48+
paren_parameter ::= IDENTIFIER paren_expr
49+
{
50+
implements=["com.intellij.psi.NavigatablePsiElement" "com.intellij.psi.PsiNamedElement" "com.intellij.psi.PsiPolyVariantReference"]
51+
extends="com.github.xepozz.php_opcodes_language.language.psi.impl.PHPOpParenParameterBaseImpl"
52+
}
53+
54+
parameter ::= IDENTIFIER
55+
{
56+
implements=["com.intellij.psi.NavigatablePsiElement" "com.intellij.psi.PsiNamedElement" "com.intellij.psi.PsiPolyVariantReference"]
57+
extends="com.github.xepozz.php_opcodes_language.language.psi.impl.PHPOpParameterBaseImpl"
58+
}
5259

5360
string_literal ::= TEXT
5461
{
@@ -60,8 +67,8 @@ paren_expr ::= LPAREN expr RPAREN
6067

6168
var_name ::= DOLLAR_SIGN IDENTIFIER
6269
{
63-
implements=["com.intellij.psi.NavigatablePsiElement" "com.intellij.psi.PsiNamedElement" "com.intellij.psi.PsiPolyVariantReference"]
64-
extends="com.github.xepozz.php_opcodes_language.language.psi.impl.PHPOpVarNameBaseImpl"
70+
implements=["com.intellij.psi.NavigatablePsiElement" "com.intellij.psi.PsiNamedElement" "com.intellij.psi.PsiPolyVariantReference"]
71+
extends="com.github.xepozz.php_opcodes_language.language.psi.impl.PHPOpVarNameBaseImpl"
6572
}
6673

6774
live_range ::= 'LIVE RANGES:' live_range_statements
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.github.xepozz.php_opcodes_language.language.psi.impl
2+
3+
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpBlock
4+
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpParameter
5+
import com.intellij.icons.AllIcons
6+
import com.intellij.ide.projectView.PresentationData
7+
import com.intellij.lang.ASTNode
8+
import com.intellij.openapi.util.NlsSafe
9+
import com.intellij.openapi.util.TextRange
10+
import com.intellij.psi.PsiElement
11+
import com.intellij.psi.PsiElementResolveResult
12+
import com.intellij.psi.search.LocalSearchScope
13+
import com.intellij.psi.search.SearchScope
14+
import com.jetbrains.php.lang.psi.PhpPsiUtil
15+
16+
abstract class PHPOpParameterBaseImpl : PHPOpParameter, PHPOpElementImpl {
17+
constructor(node: ASTNode) : super(node)
18+
19+
override fun getName(): String = text
20+
21+
override fun setName(name: @NlsSafe String): PsiElement? {
22+
TODO("Not yet implemented")
23+
}
24+
25+
override fun getPresentation() = PresentationData(text, null, getIcon(0), null)
26+
27+
override fun getIcon(flags: Int) = AllIcons.Nodes.Property
28+
29+
override fun getElement() = this
30+
31+
override fun getRangeInElement() = TextRange(0, textLength)
32+
33+
override fun resolve() = multiResolve(false).firstOrNull()?.element
34+
35+
override fun multiResolve(incompleteCode: Boolean) = PsiElementResolveResult.createResults(this)
36+
37+
override fun getCanonicalText(): String = text
38+
39+
override fun handleElementRename(newName: String) = this.setName(newName)
40+
41+
override fun bindToElement(element: PsiElement): PsiElement? {
42+
throw UnsupportedOperationException("Method bindToElement is not yet implemented in " + this.javaClass.getName())
43+
}
44+
45+
override fun isReferenceTo(psiElement: PsiElement): Boolean {
46+
return when (psiElement) {
47+
is PHPOpParameter -> this.text == psiElement.text
48+
else -> false
49+
}
50+
}
51+
52+
override fun isSoft() = false
53+
54+
override fun getUseScope(): SearchScope {
55+
val block = PhpPsiUtil.getParentOfClass(this, PHPOpBlock::class.java) ?: return super.getUseScope()
56+
return LocalSearchScope(block)
57+
}
58+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.github.xepozz.php_opcodes_language.language.psi.impl
2+
3+
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpBlock
4+
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpParenParameter
5+
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpTypes
6+
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpVarName
7+
import com.intellij.icons.AllIcons
8+
import com.intellij.ide.projectView.PresentationData
9+
import com.intellij.lang.ASTNode
10+
import com.intellij.openapi.util.NlsSafe
11+
import com.intellij.openapi.util.TextRange
12+
import com.intellij.psi.PsiElement
13+
import com.intellij.psi.PsiElementResolveResult
14+
import com.intellij.psi.search.LocalSearchScope
15+
import com.intellij.psi.search.SearchScope
16+
import com.jetbrains.php.lang.psi.PhpPsiUtil
17+
18+
abstract class PHPOpParenParameterBaseImpl : PHPOpParenParameter, PHPOpElementImpl {
19+
constructor(node: ASTNode) : super(node)
20+
21+
override fun getName(): String {
22+
val keyNode = this.node.findChildByType(PHPOpTypes.IDENTIFIER)
23+
24+
return keyNode?.text ?: ""
25+
}
26+
27+
override fun setName(name: @NlsSafe String): PsiElement? {
28+
TODO("Not yet implemented")
29+
}
30+
31+
override fun getPresentation() = PresentationData(text, null, getIcon(0), null)
32+
33+
override fun getIcon(flags: Int) = AllIcons.Nodes.Property
34+
35+
override fun getElement() = this
36+
37+
override fun getRangeInElement() = TextRange(0, textLength)
38+
39+
override fun resolve() = multiResolve(false).firstOrNull()?.element
40+
41+
override fun multiResolve(incompleteCode: Boolean) = PsiElementResolveResult.createResults(this)
42+
43+
override fun getCanonicalText(): String = text
44+
45+
override fun handleElementRename(newName: String) = this.setName(newName)
46+
47+
override fun bindToElement(element: PsiElement): PsiElement? {
48+
throw UnsupportedOperationException("Method bindToElement is not yet implemented in " + this.javaClass.getName())
49+
}
50+
51+
override fun isReferenceTo(psiElement: PsiElement): Boolean {
52+
return when (psiElement) {
53+
is PHPOpVarName -> this.text == psiElement.text
54+
else -> false
55+
}
56+
}
57+
58+
override fun isSoft() = false
59+
60+
override fun getUseScope(): SearchScope {
61+
val block = PhpPsiUtil.getParentOfClass(this, PHPOpBlock::class.java) ?: return super.getUseScope()
62+
return LocalSearchScope(block)
63+
}
64+
}

src/main/kotlin/com/github/xepozz/php_opcodes_language/language/reference/PHPOpReferenceContributor.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.github.xepozz.php_opcodes_language.language.reference
22

3+
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpParameter
34
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpVarName
45
import com.intellij.patterns.PlatformPatterns
56
import com.intellij.psi.PsiElement
@@ -12,13 +13,16 @@ import com.intellij.util.ProcessingContext
1213
class PHPOpReferenceContributor : PsiReferenceContributor() {
1314
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
1415
registrar.registerReferenceProvider(
15-
PlatformPatterns.psiElement(PHPOpVarName::class.java),
16+
PlatformPatterns.or(
17+
PlatformPatterns.psiElement(PHPOpVarName::class.java),
18+
PlatformPatterns.psiElement(PHPOpParameter::class.java)
19+
),
1620
object : PsiReferenceProvider() {
1721
override fun getReferencesByElement(
1822
element: PsiElement,
1923
context: ProcessingContext
20-
): Array<out PsiReference?> {
21-
if (element !is PHPOpVarName) return PsiReference.EMPTY_ARRAY
24+
): Array<PsiReference> {
25+
if (element !is PsiReference) return PsiReference.EMPTY_ARRAY
2226

2327
return arrayOf(element)
2428
}

0 commit comments

Comments
 (0)