[Analysis API] Create substitutor from type arguments defensively
- Call candidate collection sometimes provides candidate symbols to `createConeSubstitutorFromTypeArguments` with fewer type parameters than type arguments provided by `FirQualifiedAccess`, which lead to an NPE. Because call candidates collected for the purposes of the Analysis API are best-effort guesses, we can ignore the additional type arguments. ^KTIJ-23373 fixed ^KTIJ-21506 fixed
This commit is contained in:
+8
-8
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
|||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.types.TypeCheckerState
|
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||||
import org.jetbrains.kotlin.types.model.convertVariance
|
import org.jetbrains.kotlin.types.model.convertVariance
|
||||||
@@ -99,15 +98,16 @@ internal interface KtFirAnalysisSessionComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun FirQualifiedAccess.createConeSubstitutorFromTypeArguments(callableSymbol: FirCallableSymbol<*>): ConeSubstitutor {
|
fun FirQualifiedAccess.createConeSubstitutorFromTypeArguments(callableSymbol: FirCallableSymbol<*>): ConeSubstitutor {
|
||||||
val typeArgumentMap = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>()
|
val typeArgumentMap = buildMap {
|
||||||
for (i in typeArguments.indices) {
|
// Type arguments are ignored defensively if `callableSymbol` can't provide enough type parameters (and vice versa). For
|
||||||
val type = typeArguments[i].safeAs<FirTypeProjectionWithVariance>()?.typeRef?.coneType
|
// example, when call candidates are collected, the candidate's `callableSymbol` might have fewer type parameters than the
|
||||||
if (type != null) {
|
// inferred call's type arguments.
|
||||||
typeArgumentMap[callableSymbol.typeParameterSymbols[i]] = type
|
typeArguments.zip(callableSymbol.typeParameterSymbols).forEach { (typeArgument, typeParameterSymbol) ->
|
||||||
|
val type = typeArgument.safeAs<FirTypeProjectionWithVariance>()?.typeRef?.coneType ?: return@forEach
|
||||||
|
put(typeParameterSymbol, type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val coneSubstitutor = substitutorByMap(typeArgumentMap, rootModuleSession)
|
return substitutorByMap(typeArgumentMap, rootModuleSession)
|
||||||
return coneSubstitutor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ConeSubstitutor.toKtSubstitutor(): KtSubstitutor {
|
fun ConeSubstitutor.toKtSubstitutor(): KtSubstitutor {
|
||||||
|
|||||||
Reference in New Issue
Block a user