Skip to content

Commit 4364b19

Browse files
committed
feat: add query references
1 parent a52633f commit 4364b19

File tree

5 files changed

+193
-0
lines changed

5 files changed

+193
-0
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.github.tempest.framework.db
2+
3+
object TempestQBDictionary {
4+
val HAS_WHERE_QB_METHODS_CLASS = "\\Tempest\\Database\\Builder\\QueryBuilders\\HasWhereQueryBuilderMethods"
5+
val HAS_WHERE_QB_METHODS = listOf(
6+
"where",
7+
"whereField",
8+
"andWhere",
9+
"orWhere",
10+
"whereRaw",
11+
"andWhereRaw",
12+
"orWhereRaw",
13+
)
14+
val HAS_CONVENIENT_WHERE_METHODS_CLASS = "\\Tempest\\Database\\Builder\\QueryBuilders\\HasConvenientWhereMethods"
15+
val HAS_CONVENIENT_WHERE_METHODS = listOf(
16+
"whereIn",
17+
"whereNotIn",
18+
"whereBetween",
19+
"whereNotBetween",
20+
"whereNull",
21+
"whereNotNull",
22+
"whereNot",
23+
"whereLike",
24+
"whereNotLike",
25+
"orWhereIn",
26+
"orWhereNotIn",
27+
"orWhereBetween",
28+
"orWhereNotBetween",
29+
"orWhereNull",
30+
"orWhereNotNull",
31+
"orWhereNot",
32+
"orWhereLike",
33+
"orWhereNotLike",
34+
"whereToday",
35+
"whereYesterday",
36+
"whereThisWeek",
37+
"whereLastWeek",
38+
"whereThisMonth",
39+
"whereLastMonth",
40+
"whereThisYear",
41+
"whereLastYear",
42+
"whereAfter",
43+
"whereBefore",
44+
"orWhereToday",
45+
"orWhereYesterday",
46+
"orWhereThisWeek",
47+
"orWhereThisMonth",
48+
"orWhereThisYear",
49+
"orWhereAfter",
50+
"orWhereBefore",
51+
"whereField",
52+
"orWhere",
53+
)
54+
55+
val SELECT_METHODS = listOf(
56+
"first",
57+
"all",
58+
"orderBy",
59+
"orderByRaw",
60+
"groupBy",
61+
"having",
62+
"join",
63+
"with",
64+
"raw",
65+
"bind",
66+
"build",
67+
)
68+
69+
val WHERE_METHODS = buildList {
70+
addAll(HAS_WHERE_QB_METHODS)
71+
addAll(HAS_CONVENIENT_WHERE_METHODS)
72+
}
73+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.github.tempest.framework.db.references
2+
3+
import com.intellij.psi.util.CachedValueProvider
4+
import com.intellij.psi.util.CachedValuesManager
5+
import com.intellij.psi.util.findParentOfType
6+
import com.jetbrains.php.PhpIndex
7+
import com.jetbrains.php.lang.psi.elements.MethodReference
8+
import com.jetbrains.php.lang.psi.elements.PhpClass
9+
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression
10+
11+
object ClassTargetResolveUtils {
12+
fun resolveCached(firstParameter: StringLiteralExpression): Collection<PhpClass> =
13+
CachedValuesManager.getCachedValue(firstParameter) {
14+
CachedValueProvider.Result.create(
15+
resolve(firstParameter),
16+
firstParameter.containingFile,
17+
)
18+
}
19+
20+
21+
fun resolve(element: StringLiteralExpression): Collection<PhpClass> {
22+
val methodReference = element.findParentOfType<MethodReference>() ?: return emptyList()
23+
24+
val methodReferenceType = methodReference.declaredType
25+
if (methodReferenceType.isEmpty) return emptyList()
26+
27+
val modelType = methodReferenceType.typesWithParametrisedParts.find { it.contains("\\Tempest\\Database\\query)(\\") }
28+
val modelClass = Regex("\\\\Tempest\\\\Database\\\\query\\)\\((.+?)\\)")
29+
.find(modelType ?: "")
30+
?.groupValues[1]
31+
?: return emptyList()
32+
33+
return PhpIndex
34+
.getInstance(element.project)
35+
.getAnyByFQN(modelClass)
36+
}
37+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.github.tempest.framework.db.references
2+
3+
import com.intellij.psi.PsiElement
4+
import com.intellij.psi.PsiElementResolveResult
5+
import com.intellij.psi.PsiPolyVariantReferenceBase
6+
import com.intellij.psi.ResolveResult
7+
import com.jetbrains.php.completion.PhpLookupElement
8+
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression
9+
10+
class FieldReference(
11+
element: StringLiteralExpression,
12+
) : PsiPolyVariantReferenceBase<PsiElement>(element) {
13+
override fun getVariants(): Array<out Any?> {
14+
val element = element as? StringLiteralExpression ?: return emptyArray()
15+
return ClassTargetResolveUtils
16+
.resolve(element)
17+
.flatMap { phpClass ->
18+
phpClass.fields
19+
.map { PhpLookupElement(it) }
20+
}
21+
.toTypedArray()
22+
}
23+
24+
override fun multiResolve(incompleteCode: Boolean): Array<out ResolveResult?> {
25+
val element = element as? StringLiteralExpression ?: return emptyArray()
26+
return ClassTargetResolveUtils
27+
.resolve(element)
28+
.map {phpClass->
29+
phpClass.fields
30+
.filter { it.name == element.contents }
31+
.map { it }
32+
}
33+
.flatMap { it }
34+
.let { PsiElementResolveResult.createResults(it) }
35+
36+
}
37+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.github.tempest.framework.db.references
2+
3+
import com.github.tempest.framework.db.TempestQBDictionary
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.psi.util.findParentOfType
11+
import com.intellij.util.ProcessingContext
12+
import com.jetbrains.php.lang.psi.elements.MethodReference
13+
import com.jetbrains.php.lang.psi.elements.ParameterList
14+
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression
15+
16+
class QueryBuilderReferenceContributor : PsiReferenceContributor() {
17+
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
18+
registrar.registerReferenceProvider(
19+
PlatformPatterns.psiElement(StringLiteralExpression::class.java)
20+
.withParent(PlatformPatterns.psiElement(ParameterList::class.java))
21+
.withSuperParent(
22+
2,
23+
PlatformPatterns.psiElement(MethodReference::class.java)
24+
),
25+
object : PsiReferenceProvider() {
26+
override fun getReferencesByElement(
27+
element: PsiElement,
28+
context: ProcessingContext
29+
): Array<out PsiReference> {
30+
val element = element as? StringLiteralExpression ?: return emptyArray()
31+
val methodReference = element.findParentOfType<MethodReference>() ?: return emptyArray()
32+
if (
33+
methodReference.name !in TempestQBDictionary.WHERE_METHODS
34+
&& methodReference.name !in TempestQBDictionary.SELECT_METHODS
35+
) return emptyArray()
36+
37+
return arrayOf(FieldReference(element))
38+
}
39+
}
40+
)
41+
}
42+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@
5858
implementation="com.github.tempest.framework.console.index.ConsoleCommandsIndex"/>
5959
<fileBasedIndex
6060
implementation="com.github.tempest.framework.router.index.RoutesListIndex"/>
61+
62+
<psi.referenceContributor
63+
language="PHP"
64+
implementation="com.github.tempest.framework.db.references.QueryBuilderReferenceContributor"/>
6165
</extensions>
6266
<extensions defaultExtensionNs="com.jetbrains.php">
6367
<libraryRoot id="tempest.meta-storm" path="meta-storm" runtime="false" />

0 commit comments

Comments
 (0)