in gdscript/src/main/kotlin/gdscript/codeInsight/GdInlayParameterHintProvider.kt [63:140]
override fun getParameterHints(element: PsiElement): List<InlayInfo> {
if (element is GdCallEx) {
val id = PsiTreeUtil.findChildOfType(element, GdRefIdRef::class.java) ?: return emptyList()
val method = GdClassMemberReference(id).resolveDeclaration()
var params: Array<String> = emptyArray()
when (method) {
is GdMethodDeclTl -> {
params = method.parameters.keys.toArray(emptyArray())
if (method.name == "emit") {
val signal = PsiGdSignalUtil.getDeclaration(element)
if (signal != null) {
params = signal.parameters.keys.toArray(emptyArray())
}
}
}
is GdVarDeclSt -> {
if (method.expr is GdFuncDeclEx) {
val lambda = method.expr as GdFuncDeclEx
params = lambda.parameters.keys.toArray(emptyArray())
} else {
return emptyList()
}
}
else -> {
val file = GdClassMemberReference(id).resolve()
if (file !is GdFile) {
return emptyList()
}
val methods = PsiTreeUtil.getStubChildrenOfTypeAsList(file, GdMethodDeclTl::class.java)
val usedParams = element.argList?.argExprList
for (hint in methods) {
if (!hint.isConstructor) continue
val hints = hint.paramList?.paramList
if (hints == null || usedParams == null || hints.size != usedParams.size) continue
var ok = true
for (i in 0 until hints.size) {
val t1 = usedParams[i].expr.returnType
val t2 = hints[i].returnType
ok = ok && GdExprUtil.typeAccepts(t1, t2, element)
}
if (ok) {
params = hints.map { it.varNmi.name }.toTypedArray()
break
}
}
}
}
if (params.isEmpty()) return emptyList()
val args = element.argList?.argExprList
return params.mapIndexedNotNull { i, it ->
val param = args?.getOrNull(i) ?: return@mapIndexedNotNull null
InlayInfo(
it,
param.startOffset,
it == param.expr.text,
)
}
} else if (element is GdAnnotationTl) {
val definition = GdAnnotationUtil.get(element)?.parameters ?: return emptyList()
val keys = definition.keys.toTypedArray()
return element.annotationParams?.exprList?.mapIndexedNotNull { index, it ->
if (index < keys.size) {
InlayInfo(keys[index], it.startOffset, keys[index] == it.text)
} else null
} ?: emptyList()
}
return emptyList()
}