11package com.github.tempest.framework
22
3+ import com.github.tempest.framework.php.getPhpViewVariables
4+ import com.intellij.codeInsight.completion.InsertionContext
5+ import com.intellij.codeInsight.completion.XmlAttributeInsertHandler
36import com.intellij.openapi.vfs.findPsiFile
47import com.intellij.patterns.PlatformPatterns
8+ import com.intellij.patterns.XmlPatterns
59import com.intellij.psi.PsiElement
10+ import com.intellij.psi.PsiPolyVariantReferenceBase
611import com.intellij.psi.PsiReference
712import com.intellij.psi.PsiReferenceBase
813import com.intellij.psi.PsiReferenceContributor
914import com.intellij.psi.PsiReferenceProvider
1015import com.intellij.psi.PsiReferenceRegistrar
16+ import com.intellij.psi.PsiReferenceRegistrar.HIGHER_PRIORITY
17+ import com.intellij.psi.ResolveResult
1118import com.intellij.psi.html.HtmlTag
1219import com.intellij.psi.search.FilenameIndex
1320import com.intellij.psi.search.GlobalSearchScope
21+ import com.intellij.psi.xml.XmlAttribute
1422import com.intellij.psi.xml.XmlChildRole
1523import com.intellij.util.ProcessingContext
24+ import com.jetbrains.php.completion.PhpLookupElement
25+ import com.jetbrains.php.lang.psi.PhpFile
1626
1727class ComponentReferenceContributor : PsiReferenceContributor () {
1828 override fun registerReferenceProviders (registrar : PsiReferenceRegistrar ) {
@@ -40,18 +50,67 @@ class ComponentReferenceContributor : PsiReferenceContributor() {
4050 {
4151 val psiFile = it.findPsiFile(project) ? : return @processFilesByName true
4252// println("found file $it for ${element.name}, range ${range}")
43- result.add(
44- object : PsiReferenceBase <PsiElement >(element, range, false ) {
45- override fun resolve () = psiFile
46- }
47- )
53+ result.add(PsiReferenceBase .createSelfReference(element, range, psiFile))
4854
4955 true
5056 })
5157
5258 return result.toTypedArray()
59+ // .apply { println("found references for ${element.name} ${this.joinToString { it.toString() }}") }
5360 }
61+
5462 }
5563 )
64+
65+ registrar.registerReferenceProvider(
66+ XmlPatterns .xmlAttribute(),
67+ object : PsiReferenceProvider () {
68+ override fun getReferencesByElement (
69+ element : PsiElement ,
70+ context : ProcessingContext
71+ ): Array <out PsiReference > {
72+ val result = mutableListOf<PsiReference >()
73+ val attribute = element as ? XmlAttribute ? : return emptyArray()
74+ val htmlTag = attribute.parent as ? HtmlTag ? : return emptyArray()
75+
76+ result.add(TempestAttributeReference (element, htmlTag))
77+ return result.toTypedArray()
78+ // .apply { println("found references for ${element} ${this.joinToString { it.toString() }}") }
79+ }
80+ },
81+ HIGHER_PRIORITY
82+ )
83+ }
84+ }
85+
86+ class TempestAttributeReference (element : XmlAttribute , private val htmlTag : HtmlTag ) :
87+ PsiPolyVariantReferenceBase <PsiElement >(element, element.nameElement.textRangeInParent, false ) {
88+ override fun getVariants (): Array <out Any > {
89+ val fileReferences = htmlTag.references.filter { it is Immediate <* > }
90+
91+ val lookupPrefix = element.text.commonPrefixWith(" ::" )
92+
93+ return fileReferences
94+ .mapNotNull { it.resolve() as ? PhpFile }
95+ .flatMap { it.getPhpViewVariables() }
96+ .flatMap {
97+ listOf (
98+ object : PhpLookupElement (it) {
99+ override fun getLookupString () = lookupPrefix + lookupString
100+ override fun getAllLookupStrings () = setOf (lookupPrefix + lookupString)
101+ override fun handleInsert (context : InsertionContext ) {
102+ XmlAttributeInsertHandler .INSTANCE .handleInsert(context, this )
103+ }
104+ },
105+ )
106+ }
107+ .toTypedArray()
108+ }
109+
110+ override fun multiResolve (incompleteCode : Boolean ): Array <out ResolveResult ?> {
111+ // println("resolve ${element.text} for ${htmlTag.name}")
112+ // println("range ${element.textRangeInParent} ${element.textRange}")
113+
114+ return emptyArray()
56115 }
57- }
116+ }
0 commit comments