diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/FunctionCallHighlightingVisitor.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/FunctionCallHighlightingVisitor.kt
index 1580ca5817d..ff6da658f97 100644
--- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/FunctionCallHighlightingVisitor.kt
+++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/FunctionCallHighlightingVisitor.kt
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.idea.fir.highlighter.visitors
import com.intellij.lang.annotation.AnnotationHolder
import com.intellij.openapi.editor.colors.TextAttributesKey
import org.jetbrains.kotlin.idea.frontend.api.*
+import org.jetbrains.kotlin.idea.frontend.api.symbols.KtAnonymousFunctionSymbol
+import org.jetbrains.kotlin.idea.frontend.api.symbols.KtConstructorSymbol
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
@@ -55,15 +57,16 @@ internal class FunctionCallHighlightingVisitor(
private fun getTextAttributesForCal(callInfo: CallInfo): TextAttributesKey? = when {
callInfo.isSuspendCall -> Colors.SUSPEND_FUNCTION_CALL
- callInfo is ConstructorCallInfo ->
- Colors.CONSTRUCTOR_CALL
- callInfo is SimpleKtFunctionCallInfo -> when {
- callInfo.targetFunction.getKotlinFqName() == KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME ->Colors.KEYWORD
- callInfo.targetFunction.isExtensionDeclaration() -> Colors.EXTENSION_FUNCTION_CALL
- callInfo.targetFunction.parent is KtFile -> Colors.PACKAGE_FUNCTION_CALL
- else -> Colors.FUNCTION_CALL
+ callInfo is FunctionCallInfo -> when (val function = callInfo.targetFunction) {
+ is KtConstructorSymbol -> Colors.CONSTRUCTOR_CALL
+ is KtAnonymousFunctionSymbol -> null
+ is KtFunctionSymbol -> when {
+ function.fqName == KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME -> Colors.KEYWORD
+ function.isExtension -> Colors.EXTENSION_FUNCTION_CALL
+ function.symbolKind == KtSymbolKind.TOP_LEVEL -> Colors.PACKAGE_FUNCTION_CALL
+ else -> Colors.FUNCTION_CALL
+ }
}
- callInfo is SimpleJavaFunctionCallInfo -> Colors.FUNCTION_CALL
callInfo is VariableAsFunctionCallInfo -> Colors.VARIABLE_AS_FUNCTION_CALL
callInfo is VariableAsFunctionLikeCallInfo -> Colors.VARIABLE_AS_FUNCTION_LIKE_CALL
else -> null
diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/CallInfo.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/CallInfo.kt
index f7bf394a37b..638fc3b3e78 100644
--- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/CallInfo.kt
+++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/CallInfo.kt
@@ -5,78 +5,26 @@
package org.jetbrains.kotlin.idea.frontend.api
-import com.intellij.psi.PsiClass
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiMethod
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.psi.KtClass
-import org.jetbrains.kotlin.psi.KtClassOrObject
-import org.jetbrains.kotlin.psi.KtConstructor
-import org.jetbrains.kotlin.psi.KtNamedFunction
+import org.jetbrains.kotlin.idea.frontend.api.symbols.*
sealed class CallInfo {
abstract val isSuspendCall: Boolean
- abstract val targetFunction: PsiElement?
- abstract val isJavaFunctionCall: Boolean
+ abstract val targetFunction: KtFunctionLikeSymbol?
}
-data class VariableAsFunctionCallInfo(val target: PsiElement, override val isSuspendCall: Boolean) : CallInfo() {
- override val targetFunction: PsiElement? = null
- override val isJavaFunctionCall: Boolean = false
+data class VariableAsFunctionCallInfo(val target: KtVariableLikeSymbol, override val isSuspendCall: Boolean) : CallInfo() {
+ override val targetFunction: KtFunctionLikeSymbol? = null
}
-data class VariableAsFunctionLikeCallInfo(val target: PsiElement, val invokeFunction: KtNamedFunction) : CallInfo() {
- override val isSuspendCall: Boolean get() = invokeFunction.hasModifier(KtTokens.SUSPEND_KEYWORD)
- override val targetFunction: PsiElement? get() = invokeFunction
- override val isJavaFunctionCall: Boolean = false
+data class VariableAsFunctionLikeCallInfo(val target: KtVariableLikeSymbol, val invokeFunction: KtFunctionSymbol) : CallInfo() {
+ override val isSuspendCall: Boolean get() = invokeFunction.isSuspend
+ override val targetFunction get() = invokeFunction
}
-// SimpleFunctionCallInfo
-
-sealed class SimpleFunctionCallInfo : CallInfo() {
- abstract override val targetFunction: PsiElement
-}
-
-data class SimpleKtFunctionCallInfo(override val targetFunction: KtNamedFunction) : SimpleFunctionCallInfo() {
- override val isSuspendCall: Boolean get() = targetFunction.hasModifier(KtTokens.SUSPEND_KEYWORD)
- override val isJavaFunctionCall: Boolean = true
-}
-
-data class SimpleJavaFunctionCallInfo(override val targetFunction: PsiMethod) : SimpleFunctionCallInfo() {
- override val isSuspendCall: Boolean = false
- override val isJavaFunctionCall: Boolean = false
-}
-
-
-// ConstructorCallInfo
-
-sealed class ConstructorCallInfo : CallInfo() {
- final override val isSuspendCall: Boolean = false
- abstract val isPrimary: Boolean
-}
-
-data class KtExplicitConstructorCallInfo(
- override val targetFunction: KtConstructor<*>,
- override val isPrimary: Boolean
-) : ConstructorCallInfo() {
- override val isJavaFunctionCall: Boolean = false
-}
-
-data class KtImplicitPrimaryConstructorCallInfo(val owner: KtClass) : ConstructorCallInfo() {
- override val targetFunction: PsiElement? = null
- override val isJavaFunctionCall: Boolean = false
- override val isPrimary: Boolean = true
-}
-
-data class JavaExplicitConstructorCallInfo(
- override val targetFunction: PsiMethod,
- override val isPrimary: Boolean
-) : ConstructorCallInfo() {
- override val isJavaFunctionCall: Boolean = true
-}
-
-data class JavaImplicitPrimaryConstructorCallInfo(val owner: PsiClass) : ConstructorCallInfo() {
- override val targetFunction: PsiElement? = null
- override val isJavaFunctionCall: Boolean = true
- override val isPrimary: Boolean = true
-}
+data class FunctionCallInfo(override val targetFunction: KtFunctionLikeSymbol) : CallInfo() {
+ override val isSuspendCall: Boolean
+ get() = when (targetFunction) {
+ is KtFunctionSymbol -> targetFunction.isSuspend
+ else -> false
+ }
+}
\ No newline at end of file
diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/FirAnalysisSession.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/FirAnalysisSession.kt
index da25929b60b..273e6c208b9 100644
--- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/FirAnalysisSession.kt
+++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/FirAnalysisSession.kt
@@ -6,10 +6,6 @@
package org.jetbrains.kotlin.idea.frontend.api.fir
import com.intellij.openapi.project.Project
-import com.intellij.psi.PsiClass
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiField
-import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.fir.declarations.*
@@ -25,7 +21,7 @@ import org.jetbrains.kotlin.idea.fir.*
import org.jetbrains.kotlin.idea.fir.low.level.api.LowLevelFirApiFacade
import org.jetbrains.kotlin.idea.frontend.api.*
import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper
-import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper.toTargetPsi
+import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper.toTargetSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
@@ -35,6 +31,8 @@ class FirAnalysisSession(
) : FrontendAnalysisSession(project) {
constructor(element: KtElement) : this(element.project)
+ internal val symbolBuilder = KtSymbolByFirBuilder(validityToken)
+
init {
assertIsValid()
}
@@ -114,55 +112,39 @@ class FirAnalysisSession(
private fun resolveCall(firCall: FirFunctionCall, callExpression: KtExpression): CallInfo? {
val session = callExpression.session
- val resolvedFunctionPsi = firCall.calleeReference.toTargetPsi(session)
+ val resolvedFunctionSymbol = firCall.calleeReference.toTargetSymbol(session, symbolBuilder)
val resolvedCalleeSymbol = (firCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol
return when {
resolvedCalleeSymbol is FirConstructorSymbol -> {
val fir = resolvedCalleeSymbol.fir
- when (resolvedFunctionPsi) {
- is KtClass -> KtImplicitPrimaryConstructorCallInfo(resolvedFunctionPsi)
- is PsiClass -> JavaImplicitPrimaryConstructorCallInfo(resolvedFunctionPsi)
- is KtConstructor<*> -> KtExplicitConstructorCallInfo(resolvedFunctionPsi, fir.isPrimary)
- is PsiMethod -> JavaExplicitConstructorCallInfo(resolvedFunctionPsi, fir.isPrimary)
- else -> {
- val classId = resolvedCalleeSymbol.callableId.classId
- val firClass = classId?.let(session.firSymbolProvider::getClassLikeSymbolByFqName)
- when (val psiClass = firClass?.fir?.findPsi(callExpression.project)) {
- is PsiClass -> JavaImplicitPrimaryConstructorCallInfo(psiClass)
- is KtClass -> KtImplicitPrimaryConstructorCallInfo(psiClass)
- else -> null
- }
- }
- }
+ FunctionCallInfo(symbolBuilder.buildFirConstructorSymbol(fir))
}
firCall.dispatchReceiver is FirQualifiedAccessExpression && firCall.isImplicitFunctionCall() -> {
val target = with(FirReferenceResolveHelper) {
val calleeReference = (firCall.dispatchReceiver as FirQualifiedAccessExpression).calleeReference
- calleeReference.toTargetPsi(session)
+ calleeReference.toTargetSymbol(session, symbolBuilder)
}
when (target) {
null -> null
- is KtValVarKeywordOwner, is PsiField -> {
+ is KtVariableLikeSymbol -> {
val functionSymbol =
(firCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirNamedFunctionSymbol
when (functionSymbol?.callableId) {
null -> null
in kotlinFunctionInvokeCallableIds -> VariableAsFunctionCallInfo(target, functionSymbol.fir.isSuspend)
- else -> (resolvedFunctionPsi as? KtNamedFunction)?.let { VariableAsFunctionLikeCallInfo(target, it) }
+ else -> (resolvedFunctionSymbol as? KtSimpleFunctionSymbol)
+ ?.let { VariableAsFunctionLikeCallInfo(target, it) }
}
}
- else -> resolvedFunctionPsi?.asSimpleFunctionCall()
+ else -> resolvedFunctionSymbol?.asSimpleFunctionCall()
}
}
- else -> resolvedFunctionPsi?.asSimpleFunctionCall()
+ else -> resolvedFunctionSymbol?.asSimpleFunctionCall()
}
}
- private fun PsiElement.asSimpleFunctionCall() = when (this) {
- is KtNamedFunction -> SimpleKtFunctionCallInfo(this)
- is PsiMethod -> SimpleJavaFunctionCallInfo(this)
- else -> null
- }
+ private fun KtSymbol.asSimpleFunctionCall() =
+ (this as? KtSimpleFunctionSymbol)?.let(::FunctionCallInfo)
private fun forEachSuperClass(firClass: FirClass<*>, action: (FirResolvedTypeRef) -> Unit) {
firClass.superTypeRefs.forEach { superType ->
diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallInTheSameFile.kt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallInTheSameFile.kt
index 0d64c6ea5e8..dcea8d939c6 100644
--- a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallInTheSameFile.kt
+++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallInTheSameFile.kt
@@ -4,4 +4,4 @@ fun call() {
function(1)
}
-// CALL: SimpleKtFunctionCallInfo: targetFunction = function(a: Int): IMPLICIT_TYPE
\ No newline at end of file
+// CALL: FunctionCallInfo: targetFunction = function(a: kotlin.Int): kotlin.Unit
\ No newline at end of file
diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionWithReceiverCall.kt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionWithReceiverCall.kt
index 925fafed6f6..53eab0c512e 100644
--- a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionWithReceiverCall.kt
+++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionWithReceiverCall.kt
@@ -4,4 +4,4 @@ fun call() {
"str".function(1)
}
-// CALL: SimpleKtFunctionCallInfo: targetFunction = function( : String, a: Int): IMPLICIT_TYPE
\ No newline at end of file
+// CALL: FunctionCallInfo: targetFunction = function(: kotlin.String, a: kotlin.Int): kotlin.Unit
\ No newline at end of file
diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionWithReceiverSafeCall.kt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionWithReceiverSafeCall.kt
index 7ec3271c80a..c5927c2c429 100644
--- a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionWithReceiverSafeCall.kt
+++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionWithReceiverSafeCall.kt
@@ -4,4 +4,4 @@ fun call() {
"str"?.function(1)
}
-// CALL: SimpleKtFunctionCallInfo: targetFunction = function( : String, a: Int): IMPLICIT_TYPE
\ No newline at end of file
+// CALL: FunctionCallInfo: targetFunction = function(: kotlin.String, a: kotlin.Int): kotlin.Unit
\ No newline at end of file
diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/implicitConstuctorCall.kt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/implicitConstuctorCall.kt
index 6832ad518b9..1efa530e7d5 100644
--- a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/implicitConstuctorCall.kt
+++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/implicitConstuctorCall.kt
@@ -4,4 +4,4 @@ fun call() {
val a = A()
}
-// CALL: KtImplicitPrimaryConstructorCallInfo: owner = Implicit constructor of A
\ No newline at end of file
+// CALL: FunctionCallInfo: targetFunction = (): A
\ No newline at end of file
diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/implicitJavaConstuctorCall.kt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/implicitJavaConstuctorCall.kt
index 36429367409..6b30b9a4a09 100644
--- a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/implicitJavaConstuctorCall.kt
+++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/implicitJavaConstuctorCall.kt
@@ -3,4 +3,4 @@ fun call() {
val a = A()
}
-// CALL: JavaImplicitPrimaryConstructorCallInfo: owner = Implicit constructor of A
\ No newline at end of file
+// CALL: FunctionCallInfo: targetFunction = (): A
\ No newline at end of file
diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/javaFunctionCall.kt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/javaFunctionCall.kt
index 391cb3e03c6..f54b3426f93 100644
--- a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/javaFunctionCall.kt
+++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/javaFunctionCall.kt
@@ -3,4 +3,4 @@ fun call() {
javaClass.javaMethod()
}
-// CALL: SimpleJavaFunctionCallInfo: targetFunction = JavaClass.javaMethod(): void
\ No newline at end of file
+// CALL: FunctionCallInfo: targetFunction = JavaClass.javaMethod(): kotlin.Unit
\ No newline at end of file
diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/variableAsFunction.kt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/variableAsFunction.kt
index 52b2df848fb..5a5383f2b8e 100644
--- a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/variableAsFunction.kt
+++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/variableAsFunction.kt
@@ -2,4 +2,4 @@ fun call(x: (Int) -> String) {
x(1)
}
-// CALL: VariableAsFunctionCallInfo: target = x, isSuspendCall = false
\ No newline at end of file
+// CALL: VariableAsFunctionCallInfo: target = x: kotlin.Function1, isSuspendCall = false
\ No newline at end of file
diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/variableAsFunctionLikeCall.kt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/variableAsFunctionLikeCall.kt
index 4e1c191f86f..31a733dc2d7 100644
--- a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/variableAsFunctionLikeCall.kt
+++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/variableAsFunctionLikeCall.kt
@@ -1,7 +1,7 @@
operator fun Int.invoke(): String {}
-fun call(x: Int) {
+fun call(x: kotlin.int) {
x()
}
-// CALL: SimpleKtFunctionCallInfo: targetFunction = invoke( : Int): String
\ No newline at end of file
+// CALL: FunctionCallInfo: targetFunction = invoke(: kotlin.Int): kotlin.String
\ No newline at end of file
diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt
index 51498c9394a..25ed4c60263 100644
--- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt
+++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt
@@ -18,6 +18,8 @@ import com.intellij.psi.PsiParameter
import com.intellij.testFramework.LightPlatformTestCase
import org.intellij.plugins.relaxNG.compact.psi.util.PsiFunction
import org.jetbrains.kotlin.idea.frontend.api.CallInfo
+import org.jetbrains.kotlin.idea.frontend.api.TypeInfo
+import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightTestCase
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
@@ -42,29 +44,31 @@ abstract class AbstractResolveCallTest : @Suppress("DEPRECATION") KotlinLightCod
val elements = editor.caretModel.caretsAndSelections.map { selection ->
getSingleSelectedElement(selection)
}
- val callInfos = executeOnPooledThreadInReadAction {
+
+ val actualText = executeOnPooledThreadInReadAction {
val analysisSession = FirAnalysisSession(file as KtFile)
- elements.map { element ->
+ val callInfos = elements.map { element ->
when (element) {
is KtCallExpression -> analysisSession.resolveCall(element)
is KtBinaryExpression -> analysisSession.resolveCall(element)
else -> error("Selected should be either KtCallExpression or KtBinaryExpression but was $element")
}
}
- }
- if (callInfos.isEmpty()) {
- error("There are should be at least one call selected")
- }
- val textWithoutLatestComments = run {
- val rawText = File(path).readText()
- """(?m)^// CALL:\s.*$""".toRegex().replace(rawText, "").trimEnd()
- }
- val actualText = buildString {
- append(textWithoutLatestComments)
- append("\n\n")
- callInfos.joinTo(this, separator = "\n") { info ->
- "// CALL: ${info?.stringRepresentation()}"
+ if (callInfos.isEmpty()) {
+ error("There are should be at least one call selected")
+ }
+
+ val textWithoutLatestComments = run {
+ val rawText = File(path).readText()
+ """(?m)^// CALL:\s.*$""".toRegex().replace(rawText, "").trimEnd()
+ }
+ buildString {
+ append(textWithoutLatestComments)
+ append("\n\n")
+ callInfos.joinTo(this, separator = "\n") { info ->
+ "// CALL: ${info?.stringRepresentation()}"
+ }
}
}
KotlinTestUtils.assertEqualsToFile(File(path), actualText)
@@ -111,31 +115,22 @@ private fun File.getExternalFiles(): List {
}
private fun CallInfo.stringRepresentation(): String {
+ fun TypeInfo.render() = asDenotableTypeStringRepresentation().replace('/', '.')
fun Any.stringValue(): String? = when (this) {
- is PsiMethod -> buildString {
- append(getKotlinFqName()!!)
- @Suppress("UnstableApiUsage")
- parameters.joinTo(this, prefix = "(", postfix = ")") { parameter ->
- "${parameter.name}: ${(parameter as PsiParameter).typeElement!!.text}"
- }
- append(": ${returnTypeElement!!.text}")
- }
- is KtFunction -> buildString {
- append(getKotlinFqName()!!)
+ is KtFunctionLikeSymbol -> buildString {
+ append(if (this@stringValue is KtFunctionSymbol) fqName else "")
append("(")
- receiverTypeReference?.let { receiver ->
- append(" : ${receiver.text}")
+ (this@stringValue as? KtFunctionSymbol)?.receiverType?.let { receiver ->
+ append(": ${receiver.render()}")
if (valueParameters.isNotEmpty()) append(", ")
}
- valueParameters.joinTo(this,) { parameter ->
- "${parameter.name}: ${parameter.typeReference!!.text}"
+ valueParameters.joinTo(this) { parameter ->
+ "${parameter.name}: ${parameter.type.render()}"
}
append(")")
- append(": ${typeReference?.text ?: "IMPLICIT_TYPE"}")
+ append(": ${type.render()}")
}
- is KtClass -> "Implicit constructor of ${getKotlinFqName()!!}"
- is PsiClass -> "Implicit constructor of ${getKotlinFqName()!!}"
- is KtParameter -> name!!
+ is KtParameterSymbol -> "$name: ${type.render()}"
is Boolean -> toString()
else -> error("unexpected parameter type ${this::class}")
}