Skip to content

Commit 78a1812

Browse files
committed
chore: add fallback search to vertx endpoint detector
1 parent 4bce115 commit 78a1812

File tree

1 file changed

+47
-5
lines changed
  • marker/jvm-marker/src/main/kotlin/spp/jetbrains/marker/jvm/detect/endpoint

1 file changed

+47
-5
lines changed

marker/jvm-marker/src/main/kotlin/spp/jetbrains/marker/jvm/detect/endpoint/VertxEndpoint.kt

+47-5
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@ package spp.jetbrains.marker.jvm.detect.endpoint
1818

1919
import com.intellij.openapi.application.ApplicationManager
2020
import com.intellij.openapi.diagnostic.logger
21+
import com.intellij.openapi.util.Key
2122
import com.intellij.psi.util.descendants
2223
import com.intellij.psi.util.findParentInFile
2324
import io.vertx.core.Future
2425
import io.vertx.core.Promise
2526
import io.vertx.core.http.HttpMethod
26-
import spp.jetbrains.artifact.model.ArtifactLiteralValue
27-
import spp.jetbrains.artifact.model.CallArtifact
28-
import spp.jetbrains.artifact.model.FunctionArtifact
29-
import spp.jetbrains.artifact.model.getCallerExpressions
27+
import spp.jetbrains.artifact.model.*
28+
import spp.jetbrains.artifact.service.ArtifactScopeService
3029
import spp.jetbrains.artifact.service.toArtifact
3130
import spp.jetbrains.marker.jvm.detect.JVMEndpointDetector
3231
import spp.jetbrains.marker.service.getFullyQualifiedName
@@ -38,6 +37,7 @@ class VertxEndpoint : JVMEndpointDetector.JVMEndpointNameDetector {
3837

3938
private val log = logger<VertxEndpoint>()
4039
private val httpMethods = HttpMethod.values().map { it.name() }.toSet()
40+
private val DETECTED_ENDPOINT = Key.create<EndpointDetector.DetectedEndpoint>("VertxEndpoint.DetectedEndpoint")
4141

4242
override fun detectEndpointNames(guideMark: GuideMark): Future<List<EndpointDetector.DetectedEndpoint>> {
4343
if (guideMark !is MethodGuideMark) {
@@ -52,21 +52,63 @@ class VertxEndpoint : JVMEndpointDetector.JVMEndpointNameDetector {
5252
return@runReadAction
5353
}
5454

55+
var fallbackSearch = false
5556
val callers = mutableListOf<EndpointDetector.DetectedEndpoint>()
56-
artifact.getCallerExpressions().forEach {
57+
val callerExpressions = try {
58+
artifact.getCallerExpressions()
59+
} catch (e: IllegalArgumentException) {
60+
log.warn("Failed to get caller expressions for ${artifact.getFullyQualifiedName()}", e)
61+
fallbackSearch = true
62+
emptyList()
63+
}
64+
callerExpressions.forEach {
5765
it.findParentInFile {
5866
val innerArtifact = it.toArtifact()
5967
if (innerArtifact !is CallArtifact) return@findParentInFile false
6068
check(innerArtifact)?.let { callers.add(it) }
6169
false
6270
}
6371
}
72+
73+
if (fallbackSearch) {
74+
//won't be able to search for references in files outside current file
75+
//instead use regex to search for calls to router.post, router.get, etc
76+
if (artifact.psiElement.getUserData(DETECTED_ENDPOINT) != null) {
77+
callers.add(artifact.psiElement.getUserData(DETECTED_ENDPOINT)!!)
78+
} else {
79+
artifact.getCalls().forEach { checkSimple(it) }
80+
}
81+
}
82+
6483
promise.complete(callers.toSet().toList())
6584
}
6685

6786
return promise.future()
6887
}
6988

89+
private fun checkSimple(artifact: CallArtifact) {
90+
val importRegex = Regex("""import io\.vertx""")
91+
importRegex.find(artifact.containingFile.text) ?: return
92+
93+
val regex = Regex("""router\.([a-zA-Z]+)\("([^"]+)"\)\.handler\(this::([a-zA-Z]+)\)""")
94+
val match = regex.matchEntire(artifact.text) ?: return
95+
val httpMethod = match.groupValues[1].uppercase()
96+
val endpointName = match.groupValues[2]
97+
val referenceMethod = match.groupValues[3]
98+
99+
val fileFunctions = ArtifactScopeService.getFunctions(artifact.containingFile)
100+
val refFunction = fileFunctions.firstOrNull { it.name == referenceMethod } ?: return
101+
102+
val endpoint = EndpointDetector.DetectedEndpoint(
103+
"$httpMethod:$endpointName",
104+
false,
105+
endpointName,
106+
httpMethod
107+
)
108+
refFunction.putUserData(DETECTED_ENDPOINT, endpoint)
109+
log.info("Detected endpoint: $endpoint")
110+
}
111+
70112
private fun check(artifact: CallArtifact): EndpointDetector.DetectedEndpoint? {
71113
val routerCall = getRouterCall(artifact) ?: return null
72114
val endpointType = routerCall.getName()!!.uppercase().substringAfter(".")

0 commit comments

Comments
 (0)