@@ -3,6 +3,7 @@ package com.github.tempest.framework.router.completion
33import com.github.tempest.framework.TempestFrameworkClasses
44import com.github.tempest.framework.common.completion.TopPriorityLookupElement
55import com.github.tempest.framework.common.insertHandler.InsertTextInsertHandler
6+ import com.github.tempest.framework.router.index.Route
67import com.github.tempest.framework.router.index.RouterIndexUtils
78import com.intellij.codeInsight.completion.CompletionContributor
89import com.intellij.codeInsight.completion.CompletionParameters
@@ -15,8 +16,11 @@ import com.intellij.codeInsight.lookup.LookupElementBuilder
1516import com.intellij.patterns.PlatformPatterns
1617import com.intellij.util.ProcessingContext
1718import com.jetbrains.php.PhpIcons
19+ import com.jetbrains.php.lang.PhpReferenceContributor
20+ import com.jetbrains.php.lang.psi.elements.ArrayCreationExpression
1821import com.jetbrains.php.lang.psi.elements.ConstantReference
1922import com.jetbrains.php.lang.psi.elements.FunctionReference
23+ import com.jetbrains.php.lang.psi.elements.Method
2024import com.jetbrains.php.lang.psi.elements.ParameterList
2125import com.jetbrains.php.lang.psi.elements.StringLiteralExpression
2226
@@ -52,27 +56,63 @@ class RouteParameterCompletionContributor : CompletionContributor() {
5256 val function = parameterList.parent as ? FunctionReference ? : return
5357 if (function.fqn != TempestFrameworkClasses .FUNCTION_URI ) return
5458 if (parameterList.parameters.isEmpty()) return
55- if (parameterList.parameters[0 ] == element) return
5659
57- val routePattern = function.parameters[0 ] as ? StringLiteralExpression ? : return
60+ val firstParameter = function.parameters[0 ]
61+ if (firstParameter == element) return
5862
59- RouterIndexUtils .getRoutes(routePattern.contents, element.project)
60- .flatMap { it.parameters }
61- .map { parameter ->
62- LookupElementBuilder .create(parameter.name)
63- .withIcon(PhpIcons .PARAMETER )
64- .withTailText(" Pattern: ${parameter.pattern} " .takeIf { parameter.pattern.isNotEmpty() })
65- .withTypeText(routePattern.contents)
66- .withInsertHandler { context, element ->
67- InsertTextInsertHandler (
68- " : " ,
69- DeclarativeInsertHandler .PopupOptions .MemberLookup
70- )
71- .handleInsert(context, element)
63+ when (firstParameter) {
64+ is ArrayCreationExpression -> fromArrayCreation(firstParameter, result)
65+ is StringLiteralExpression -> fromStringLiteral(firstParameter, result)
66+ }
67+ }
68+
69+ private fun fromArrayCreation (
70+ firstParameter : ArrayCreationExpression ,
71+ result : CompletionResultSet
72+ ) {
73+ PhpReferenceContributor
74+ .getCallbackRefFromArray(firstParameter)
75+ ?.resolve()
76+ ?.let { it as ? Method }
77+ ?.attributes
78+ ?.filter { it.fqn in TempestFrameworkClasses .ROUTES }
79+ ?.mapNotNull { RouterIndexUtils .createRouteFromAttribute(it) }
80+ ?.apply { fromRoutes(this , result) }
81+ }
82+
83+ private fun fromStringLiteral (
84+ routePattern : StringLiteralExpression ,
85+ result : CompletionResultSet
86+ ) {
87+ RouterIndexUtils
88+ .getRoutesByPattern(routePattern.contents, routePattern.project)
89+ .apply { fromRoutes(this , result) }
90+ }
91+
92+ private fun fromRoutes (
93+ routes : Collection <Route >,
94+ result : CompletionResultSet
95+ ) {
96+ routes
97+ .flatMap { route ->
98+ route
99+ .parameters
100+ .map { parameter ->
101+ LookupElementBuilder .create(parameter.name)
102+ .withIcon(PhpIcons .PARAMETER )
103+ .withTailText(" Pattern: ${parameter.pattern} " .takeIf { parameter.pattern.isNotEmpty() })
104+ .withTypeText(route.pattern)
105+ .withInsertHandler { context, element ->
106+ InsertTextInsertHandler (
107+ " : " ,
108+ DeclarativeInsertHandler .PopupOptions .MemberLookup
109+ )
110+ .handleInsert(context, element)
111+ }
112+ .let { PrioritizedLookupElement .withPriority(it, 10000.0 ) }
113+ .let { PrioritizedLookupElement .withExplicitProximity(it, 10000 ) }
114+ .let { TopPriorityLookupElement (it) }
72115 }
73- .let { PrioritizedLookupElement .withPriority(it, 10000.0 ) }
74- .let { PrioritizedLookupElement .withExplicitProximity(it, 10000 ) }
75- .let { TopPriorityLookupElement (it) }
76116 }
77117 .apply { result.addAllElements(this ) }
78118 .apply { if (isNotEmpty()) result.stopHere() }
0 commit comments