FIR IDE: rework KtCall to work with error cals
This commit is contained in:
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.frontend.api
|
||||
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
|
||||
sealed class CallInfo {
|
||||
abstract val isSuspendCall: Boolean
|
||||
abstract val targetFunction: KtFunctionLikeSymbol?
|
||||
}
|
||||
|
||||
data class VariableAsFunctionCallInfo(val target: KtVariableLikeSymbol, override val isSuspendCall: Boolean) : CallInfo() {
|
||||
override val targetFunction: KtFunctionLikeSymbol? = null
|
||||
}
|
||||
|
||||
data class VariableAsFunctionLikeCallInfo(val target: KtVariableLikeSymbol, val invokeFunction: KtFunctionSymbol) : CallInfo() {
|
||||
override val isSuspendCall: Boolean get() = invokeFunction.isSuspend
|
||||
override val targetFunction get() = invokeFunction
|
||||
}
|
||||
|
||||
data class FunctionCallInfo(override val targetFunction: KtFunctionLikeSymbol) : CallInfo() {
|
||||
override val isSuspendCall: Boolean
|
||||
get() = when (targetFunction) {
|
||||
is KtFunctionSymbol -> targetFunction.isSuspend
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.idea.frontend.api
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.frontend.api.calls.KtCall
|
||||
import org.jetbrains.kotlin.idea.frontend.api.components.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
@@ -118,9 +119,9 @@ abstract class KtAnalysisSession(override val token: ValidityToken) : ValidityTo
|
||||
|
||||
fun <S : KtSymbol> KtSymbolPointer<S>.restoreSymbol(): S? = restoreSymbol(this@KtAnalysisSession)
|
||||
|
||||
fun KtCallExpression.resolveCall(): CallInfo? = callResolver.resolveCall(this)
|
||||
fun KtCallExpression.resolveCall(): KtCall? = callResolver.resolveCall(this)
|
||||
|
||||
fun KtBinaryExpression.resolveCall(): CallInfo? = callResolver.resolveCall(this)
|
||||
fun KtBinaryExpression.resolveCall(): KtCall? = callResolver.resolveCall(this)
|
||||
|
||||
fun KtReference.resolveToSymbols(): Collection<KtSymbol> {
|
||||
check(this is KtSymbolBasedReference) { "To get reference symbol the one should be KtSymbolBasedReference" }
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.frontend.api.calls
|
||||
|
||||
import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnostic
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
|
||||
/**
|
||||
* Represents direct or indirect (via invoke) function call from Kotlin code
|
||||
*/
|
||||
sealed class KtCall {
|
||||
abstract val isErrorCall: Boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Call using `()` of some variable of functional type, e.g.,
|
||||
*
|
||||
* fun x(f: () -> Int) {
|
||||
* f() // functional type call
|
||||
* }
|
||||
*/
|
||||
class KtFunctionalTypeVariableCall(val target: KtVariableLikeSymbol) : KtCall() {
|
||||
override val isErrorCall: Boolean get() = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Direct or indirect call of function declared by user
|
||||
*/
|
||||
sealed class KtDeclaredFunctionCall : KtCall() {
|
||||
abstract val targetFunction: KtCallTarget
|
||||
override val isErrorCall: Boolean
|
||||
get() = targetFunction is KtErrorCallTarget
|
||||
}
|
||||
|
||||
/**
|
||||
* Call using () on variable on some non-functional type, considers that `invoke` function is declared somewhere
|
||||
*
|
||||
* fun x(y: Int) {
|
||||
* y() // variable with invoke function call
|
||||
* }
|
||||
*
|
||||
* fun Int.invoke() {}
|
||||
*/
|
||||
class KtVariableWithInvokeFunctionCall(
|
||||
val target: KtVariableLikeSymbol,
|
||||
val invokeFunction: KtCallTarget,
|
||||
) : KtDeclaredFunctionCall() {
|
||||
override val targetFunction: KtCallTarget get() = invokeFunction
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple function call, e.g.,
|
||||
*
|
||||
* x.toString() // function call
|
||||
*/
|
||||
data class KtFunctionCall(override val targetFunction: KtCallTarget) : KtDeclaredFunctionCall()
|
||||
|
||||
/**
|
||||
* Represents function(s) in which call was resolved,
|
||||
* Can be success [KtSuccessCallTarget] in this case there only one such function
|
||||
* Or erroneous [KtErrorCallTarget] in this case there can be any count of candidates
|
||||
*/
|
||||
sealed class KtCallTarget {
|
||||
abstract val candidates: Collection<KtFunctionLikeSymbol>
|
||||
}
|
||||
|
||||
/**
|
||||
* Success call of [symbol]
|
||||
*/
|
||||
class KtSuccessCallTarget(val symbol: KtFunctionLikeSymbol) : KtCallTarget() {
|
||||
override val candidates: Collection<KtFunctionLikeSymbol>
|
||||
get() = listOf(symbol)
|
||||
}
|
||||
|
||||
/**
|
||||
* Function all with errors, possible candidates are [candidates]
|
||||
*/
|
||||
class KtErrorCallTarget(override val candidates: Collection<KtFunctionLikeSymbol>, val diagnostic: KtDiagnostic) : KtCallTarget()
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.frontend.api.calls
|
||||
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol
|
||||
|
||||
fun KtCallTarget.getSuccessCallSymbolOrNull(): KtFunctionLikeSymbol? = when (this) {
|
||||
is KtSuccessCallTarget -> symbol
|
||||
is KtErrorCallTarget -> null
|
||||
}
|
||||
|
||||
inline fun <reified S : KtFunctionLikeSymbol> KtCall.isSuccessCallOf(predicate: (S) -> Boolean): Boolean {
|
||||
if (this !is KtFunctionCall) return false
|
||||
val symbol = targetFunction.getSuccessCallSymbolOrNull() ?: return false
|
||||
if (symbol !is S) return false
|
||||
return predicate(symbol)
|
||||
}
|
||||
+3
-3
@@ -5,11 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.frontend.api.components
|
||||
|
||||
import org.jetbrains.kotlin.idea.frontend.api.CallInfo
|
||||
import org.jetbrains.kotlin.idea.frontend.api.calls.KtCall
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
|
||||
abstract class KtCallResolver : KtAnalysisSessionComponent() {
|
||||
abstract fun resolveCall(call: KtCallExpression): CallInfo?
|
||||
abstract fun resolveCall(call: KtBinaryExpression): CallInfo?
|
||||
abstract fun resolveCall(call: KtCallExpression): KtCall?
|
||||
abstract fun resolveCall(call: KtBinaryExpression): KtCall?
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.frontend.api.diagnostics
|
||||
|
||||
sealed class KtDiagnostic {
|
||||
abstract val message: String
|
||||
}
|
||||
|
||||
data class KtSimpleDiagnostic(override val message: String): KtDiagnostic()
|
||||
Reference in New Issue
Block a user