Skip to content

Commit c72bb60

Browse files
committed
feat: add variable self reference
1 parent 35862e0 commit c72bb60

File tree

6 files changed

+137
-2
lines changed

6 files changed

+137
-2
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package com.github.xepozz.php_opcodes_language.language
22

3+
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpTypes
34
import com.intellij.lang.BracePair
45
import com.intellij.lang.PairedBraceMatcher
56
import com.intellij.psi.PsiFile
67
import com.intellij.psi.tree.IElementType
78

89
class PHPOpBraceMatcher : PairedBraceMatcher {
9-
private val bracePairs = emptyArray<BracePair>()
10+
private val bracePairs = arrayOf(
11+
BracePair(PHPOpTypes.LPAREN, PHPOpTypes.RPAREN, true)
12+
)
1013

1114
override fun getPairs() = bracePairs
1215

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,18 @@ instruction_name ::= IDENTIFIER
5353

5454
argument ::= expr
5555

56-
expr ::= var_name | TEXT | NUMBER | IDENTIFIER paren_expr | IDENTIFIER
56+
expr ::= var_name | string_literal | NUMBER | IDENTIFIER paren_expr | IDENTIFIER
57+
58+
string_literal ::= TEXT
59+
{
60+
implements=["com.intellij.psi.PsiLanguageInjectionHost"]
61+
extends="com.github.xepozz.php_opcodes_language.language.psi.impl.PHPOpStringLiteralBaseImpl"
62+
}
5763

5864
paren_expr ::= LPAREN expr RPAREN
5965

6066
var_name ::= DOLLAR_SIGN IDENTIFIER
67+
{
68+
implements=["com.intellij.psi.NavigatablePsiElement" "com.intellij.psi.PsiNamedElement" "com.intellij.psi.PsiPolyVariantReference"]
69+
extends="com.github.xepozz.php_opcodes_language.language.psi.impl.PHPOpVarNameBaseImpl"
70+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.github.xepozz.php_opcodes_language.language.psi.impl
2+
3+
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpStringLiteral
4+
import com.intellij.icons.AllIcons
5+
import com.intellij.ide.projectView.PresentationData
6+
import com.intellij.lang.ASTNode
7+
import com.intellij.psi.LiteralTextEscaper
8+
import com.intellij.psi.PsiLanguageInjectionHost
9+
10+
abstract class PHPOpStringLiteralBaseImpl : PHPOpStringLiteral, PHPOpElementImpl, PsiLanguageInjectionHost {
11+
constructor(node: ASTNode) : super(node)
12+
13+
override fun getPresentation() = PresentationData(text, null, getIcon(0), null)
14+
15+
override fun getIcon(flags: Int) = AllIcons.Nodes.Property
16+
17+
override fun isValidHost() = true
18+
19+
override fun updateText(newText: String): PsiLanguageInjectionHost? {
20+
// this.replace(PHPOpElementFactory.createStringLiteral(project, newText))
21+
return this
22+
}
23+
24+
override fun createLiteralTextEscaper() = LiteralTextEscaper.createSimple(this)
25+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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.PHPOpTypes
5+
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpVarName
6+
import com.intellij.icons.AllIcons
7+
import com.intellij.ide.projectView.PresentationData
8+
import com.intellij.lang.ASTNode
9+
import com.intellij.openapi.util.NlsSafe
10+
import com.intellij.openapi.util.TextRange
11+
import com.intellij.psi.PsiElement
12+
import com.intellij.psi.PsiElementResolveResult
13+
import com.intellij.psi.PsiNamedElement
14+
import com.intellij.psi.PsiPolyVariantReference
15+
import com.intellij.psi.search.LocalSearchScope
16+
import com.intellij.psi.search.SearchScope
17+
import com.jetbrains.php.lang.psi.PhpPsiUtil
18+
19+
abstract class PHPOpVarNameBaseImpl : PHPOpVarName, PHPOpElementImpl, PsiNamedElement, PsiPolyVariantReference {
20+
constructor(node: ASTNode) : super(node)
21+
22+
override fun getName(): String {
23+
val keyNode = this.node.findChildByType(PHPOpTypes.IDENTIFIER)
24+
25+
return keyNode?.text ?: ""
26+
}
27+
28+
override fun setName(name: @NlsSafe String): PsiElement? {
29+
TODO("Not yet implemented")
30+
}
31+
32+
override fun getPresentation() = PresentationData(text, null, getIcon(0), null)
33+
34+
override fun getIcon(flags: Int) = AllIcons.Nodes.Property
35+
36+
override fun getElement() = this
37+
38+
override fun getRangeInElement() = TextRange(0, textLength)
39+
40+
override fun resolve() = multiResolve(false).firstOrNull()?.element
41+
42+
override fun multiResolve(incompleteCode: Boolean) = PsiElementResolveResult.createResults(this)
43+
44+
override fun getCanonicalText(): String = text
45+
46+
override fun handleElementRename(newName: String) = this.setName(newName)
47+
48+
override fun bindToElement(element: PsiElement): PsiElement? {
49+
throw UnsupportedOperationException("Method bindToElement is not yet implemented in " + this.javaClass.getName())
50+
}
51+
52+
override fun isReferenceTo(psiElement: PsiElement): Boolean {
53+
return when (psiElement) {
54+
is PHPOpVarName -> this.text == psiElement.text
55+
else -> false
56+
}
57+
}
58+
59+
override fun isSoft() = false
60+
61+
override fun getUseScope(): SearchScope {
62+
val block = PhpPsiUtil.getParentOfClass(this, PHPOpBlock::class.java) ?: return super.getUseScope()
63+
return LocalSearchScope(block)
64+
}
65+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.github.xepozz.php_opcodes_language.language.reference
2+
3+
import com.github.xepozz.php_opcodes_language.language.psi.PHPOpVarName
4+
import com.intellij.patterns.PlatformPatterns
5+
import com.intellij.psi.PsiElement
6+
import com.intellij.psi.PsiReference
7+
import com.intellij.psi.PsiReferenceContributor
8+
import com.intellij.psi.PsiReferenceProvider
9+
import com.intellij.psi.PsiReferenceRegistrar
10+
import com.intellij.util.ProcessingContext
11+
12+
class PHPOpReferenceContributor : PsiReferenceContributor() {
13+
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
14+
registrar.registerReferenceProvider(
15+
PlatformPatterns.psiElement(PHPOpVarName::class.java),
16+
object : PsiReferenceProvider() {
17+
override fun getReferencesByElement(
18+
element: PsiElement,
19+
context: ProcessingContext
20+
): Array<out PsiReference?> {
21+
if (element !is PHPOpVarName) return PsiReference.EMPTY_ARRAY
22+
23+
return arrayOf(element)
24+
}
25+
}
26+
)
27+
}
28+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,9 @@
4343
<lang.foldingBuilder
4444
language="PHP Opcodes"
4545
implementationClass="com.github.xepozz.php_opcodes_language.language.PHPOpFoldingBuilder"/>
46+
47+
<psi.referenceContributor
48+
language="PHP Opcodes"
49+
implementation="com.github.xepozz.php_opcodes_language.language.reference.PHPOpReferenceContributor"/>
4650
</extensions>
4751
</idea-plugin>

0 commit comments

Comments
 (0)