FIR Analysis API: reimplement KtFirCallResolver with new data model

This commit is contained in:
Tianyu Geng
2021-11-23 19:34:55 -08:00
committed by Ilya Kirillov
parent c9f9ce99c1
commit 9b05019137
196 changed files with 4309 additions and 639 deletions
@@ -12,17 +12,22 @@ import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnosticWithPsi
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KT_DIAGNOSTIC_CONVERTER
import org.jetbrains.kotlin.analysis.api.fir.types.KtFirGenericSubstitutor
import org.jetbrains.kotlin.analysis.api.fir.types.KtFirMapBackedSubstitutor
import org.jetbrains.kotlin.analysis.api.fir.types.KtFirType
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostics
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
@@ -77,24 +82,40 @@ internal interface KtFirAnalysisSessionComponent {
)
}
fun FirQualifiedAccessExpression.createSubstitutorFromTypeArguments(): KtSubstitutor? {
fun FirQualifiedAccess.createSubstitutorFromTypeArguments(): KtSubstitutor? {
return createConeSubstitutorFromTypeArguments()?.toKtSubstitutor()
}
fun FirQualifiedAccess.createSubstitutorFromTypeArguments(callableSymbol: FirCallableSymbol<*>): KtSubstitutor {
return createConeSubstitutorFromTypeArguments(callableSymbol).toKtSubstitutor()
}
fun FirQualifiedAccess.createConeSubstitutorFromTypeArguments(): ConeSubstitutor? {
val symbol = when (val calleeReference = calleeReference) {
is FirResolvedNamedReference -> calleeReference.resolvedSymbol as? FirCallableSymbol<*>
is FirErrorNamedReference -> calleeReference.candidateSymbol as? FirCallableSymbol<*>
else -> null
} ?: return null
return createSubstitutorFromTypeArguments(symbol)
return createConeSubstitutorFromTypeArguments(symbol)
}
fun FirQualifiedAccessExpression.createSubstitutorFromTypeArguments(functionSymbol: FirCallableSymbol<*>): KtSubstitutor {
fun FirQualifiedAccess.createConeSubstitutorFromTypeArguments(callableSymbol: FirCallableSymbol<*>): ConeSubstitutor {
val typeArgumentMap = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>()
for (i in typeArguments.indices) {
val type = typeArguments[i].safeAs<FirTypeProjectionWithVariance>()?.typeRef?.coneType
if (type != null) {
typeArgumentMap[functionSymbol.typeParameterSymbols[i]] = type
typeArgumentMap[callableSymbol.typeParameterSymbols[i]] = type
}
}
val coneSubstitutor = substitutorByMap(typeArgumentMap, rootModuleSession)
return firSymbolBuilder.typeBuilder.buildSubstitutor(coneSubstitutor)
return coneSubstitutor
}
fun ConeSubstitutor.toKtSubstitutor(): KtSubstitutor {
return when (this) {
ConeSubstitutor.Empty -> KtSubstitutor.Empty(analysisSession.token)
is ConeSubstitutorByMap -> KtFirMapBackedSubstitutor(this, analysisSession.firSymbolBuilder, analysisSession.token)
else -> KtFirGenericSubstitutor(this, analysisSession.firSymbolBuilder, analysisSession.token)
}
}
}
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.idea.references
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.calls.KtSimpleFunctionCall
import org.jetbrains.kotlin.analysis.api.calls.calls
import org.jetbrains.kotlin.analysis.api.calls.symbol
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.psi.KtCallExpression
@@ -21,7 +23,7 @@ class KtFirInvokeFunctionReference(expression: KtCallExpression) : KtInvokeFunct
return expression.resolveCall().calls.mapNotNull { call ->
(call as? KtSimpleFunctionCall)
?.takeIf { it.isImplicitInvoke }
?.boundSymbol
?.partiallyAppliedSymbol
?.symbol
?.takeUnless { it is KtFunctionSymbol && it.isBuiltinFunctionInvoke }
}
@@ -162,6 +162,108 @@ public class FirResolveCallTestGenerated extends AbstractFirResolveCallTest {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/arrayOfInAnnotation.kt");
}
@Test
@TestMetadata("calleeExpressionOfImplicitInvoke.kt")
public void testCalleeExpressionOfImplicitInvoke() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/calleeExpressionOfImplicitInvoke.kt");
}
@Test
@TestMetadata("checkNotNullCall.kt")
public void testCheckNotNullCall() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/checkNotNullCall.kt");
}
@Test
@TestMetadata("checkNotNullCallAsCallee.kt")
public void testCheckNotNullCallAsCallee() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/checkNotNullCallAsCallee.kt");
}
@Test
@TestMetadata("comparisonCall.kt")
public void testComparisonCall() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/comparisonCall.kt");
}
@Test
@TestMetadata("compoundAssignOnVal.kt")
public void testCompoundAssignOnVal() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/compoundAssignOnVal.kt");
}
@Test
@TestMetadata("compoundAssignOnVal_lhs.kt")
public void testCompoundAssignOnVal_lhs() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/compoundAssignOnVal_lhs.kt");
}
@Test
@TestMetadata("compoundAssignOnVar.kt")
public void testCompoundAssignOnVar() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/compoundAssignOnVar.kt");
}
@Test
@TestMetadata("compoundAssignOnVar_lhs.kt")
public void testCompoundAssignOnVar_lhs() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/compoundAssignOnVar_lhs.kt");
}
@Test
@TestMetadata("compoundAssignWithArrayAccessConvention.kt")
public void testCompoundAssignWithArrayAccessConvention() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/compoundAssignWithArrayAccessConvention.kt");
}
@Test
@TestMetadata("compoundAssignWithArrayAccessConvention_complexReceivers.kt")
public void testCompoundAssignWithArrayAccessConvention_complexReceivers() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/compoundAssignWithArrayAccessConvention_complexReceivers.kt");
}
@Test
@TestMetadata("compoundAssignWithArrayAccessConvention_lhs.kt")
public void testCompoundAssignWithArrayAccessConvention_lhs() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/compoundAssignWithArrayAccessConvention_lhs.kt");
}
@Test
@TestMetadata("compoundAssignWithArrayGetConvention.kt")
public void testCompoundAssignWithArrayGetConvention() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/compoundAssignWithArrayGetConvention.kt");
}
@Test
@TestMetadata("compoundAssignWithArrayGetConvention_lhs.kt")
public void testCompoundAssignWithArrayGetConvention_lhs() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/compoundAssignWithArrayGetConvention_lhs.kt");
}
@Test
@TestMetadata("consecutiveImplicitInvoke1.kt")
public void testConsecutiveImplicitInvoke1() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/consecutiveImplicitInvoke1.kt");
}
@Test
@TestMetadata("consecutiveImplicitInvoke2.kt")
public void testConsecutiveImplicitInvoke2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/consecutiveImplicitInvoke2.kt");
}
@Test
@TestMetadata("consecutiveImplicitInvoke3.kt")
public void testConsecutiveImplicitInvoke3() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/consecutiveImplicitInvoke3.kt");
}
@Test
@TestMetadata("consecutiveImplicitInvoke_callee.kt")
public void testConsecutiveImplicitInvoke_callee() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/consecutiveImplicitInvoke_callee.kt");
}
@Test
@TestMetadata("delegatedConstructorCall_super.kt")
public void testDelegatedConstructorCall_super() throws Exception {
@@ -192,6 +294,24 @@ public class FirResolveCallTestGenerated extends AbstractFirResolveCallTest {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/enumAsAnnotationValue.kt");
}
@Test
@TestMetadata("eqEqCall_fromAny.kt")
public void testEqEqCall_fromAny() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/eqEqCall_fromAny.kt");
}
@Test
@TestMetadata("eqEqCall_fromSuperType.kt")
public void testEqEqCall_fromSuperType() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/eqEqCall_fromSuperType.kt");
}
@Test
@TestMetadata("eqEqCall_overridden.kt")
public void testEqEqCall_overridden() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/eqEqCall_overridden.kt");
}
@Test
@TestMetadata("functionCallInTheSameFile.kt")
public void testFunctionCallInTheSameFile() throws Exception {
@@ -240,6 +360,18 @@ public class FirResolveCallTestGenerated extends AbstractFirResolveCallTest {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/functionCallWithVarargArgument.kt");
}
@Test
@TestMetadata("functionTypeVariableCall_dispatchReceiver.kt")
public void testFunctionTypeVariableCall_dispatchReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/functionTypeVariableCall_dispatchReceiver.kt");
}
@Test
@TestMetadata("functionTypeVariableCall_extensionReceiver.kt")
public void testFunctionTypeVariableCall_extensionReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/functionTypeVariableCall_extensionReceiver.kt");
}
@Test
@TestMetadata("functionWithReceiverCall.kt")
public void testFunctionWithReceiverCall() throws Exception {
@@ -252,6 +384,18 @@ public class FirResolveCallTestGenerated extends AbstractFirResolveCallTest {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/functionWithReceiverSafeCall.kt");
}
@Test
@TestMetadata("hiddenConstructor.kt")
public void testHiddenConstructor() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/hiddenConstructor.kt");
}
@Test
@TestMetadata("hiddenDeprecated.kt")
public void testHiddenDeprecated() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/hiddenDeprecated.kt");
}
@Test
@TestMetadata("implicitConstructorDelegationCall.kt")
public void testImplicitConstructorDelegationCall() throws Exception {
@@ -390,6 +534,78 @@ public class FirResolveCallTestGenerated extends AbstractFirResolveCallTest {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/memberFunctionCallWithTypeArgument.kt");
}
@Test
@TestMetadata("postfixUnaryOperatorOnVar.kt")
public void testPostfixUnaryOperatorOnVar() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/postfixUnaryOperatorOnVar.kt");
}
@Test
@TestMetadata("postfixUnaryOperatorOnVar_base.kt")
public void testPostfixUnaryOperatorOnVar_base() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/postfixUnaryOperatorOnVar_base.kt");
}
@Test
@TestMetadata("postfixUnaryOperatorWithArrayAccessConvention.kt")
public void testPostfixUnaryOperatorWithArrayAccessConvention() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/postfixUnaryOperatorWithArrayAccessConvention.kt");
}
@Test
@TestMetadata("postfixUnaryOperatorWithArrayAccessConvention_base.kt")
public void testPostfixUnaryOperatorWithArrayAccessConvention_base() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/postfixUnaryOperatorWithArrayAccessConvention_base.kt");
}
@Test
@TestMetadata("postfixUnaryOperatorWithArrayAccessConvention_complexDispatcher.kt")
public void testPostfixUnaryOperatorWithArrayAccessConvention_complexDispatcher() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/postfixUnaryOperatorWithArrayAccessConvention_complexDispatcher.kt");
}
@Test
@TestMetadata("prefixUnaryOperatorOnVar.kt")
public void testPrefixUnaryOperatorOnVar() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/prefixUnaryOperatorOnVar.kt");
}
@Test
@TestMetadata("prefixUnaryOperatorOnVar_base.kt")
public void testPrefixUnaryOperatorOnVar_base() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/prefixUnaryOperatorOnVar_base.kt");
}
@Test
@TestMetadata("prefixUnaryOperatorWithArrayAccessConvention.kt")
public void testPrefixUnaryOperatorWithArrayAccessConvention() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/prefixUnaryOperatorWithArrayAccessConvention.kt");
}
@Test
@TestMetadata("prefixUnaryOperatorWithArrayAccessConvention_base.kt")
public void testPrefixUnaryOperatorWithArrayAccessConvention_base() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/prefixUnaryOperatorWithArrayAccessConvention_base.kt");
}
@Test
@TestMetadata("prefixUnaryOperatorWithArrayAccessConvention_complexDispatcher.kt")
public void testPrefixUnaryOperatorWithArrayAccessConvention_complexDispatcher() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/prefixUnaryOperatorWithArrayAccessConvention_complexDispatcher.kt");
}
@Test
@TestMetadata("privateMember.kt")
public void testPrivateMember() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/privateMember.kt");
}
@Test
@TestMetadata("qualifiedCalleeExpressionOfImplicitInvoke.kt")
public void testQualifiedCalleeExpressionOfImplicitInvoke() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/qualifiedCalleeExpressionOfImplicitInvoke.kt");
}
@Test
@TestMetadata("resolveCallInSuperConstructorParam.kt")
public void testResolveCallInSuperConstructorParam() throws Exception {
@@ -408,6 +624,30 @@ public class FirResolveCallTestGenerated extends AbstractFirResolveCallTest {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/simpleCallWithNonMatchingArgs.kt");
}
@Test
@TestMetadata("smartCastExplicitDispatchReceiver.kt")
public void testSmartCastExplicitDispatchReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/smartCastExplicitDispatchReceiver.kt");
}
@Test
@TestMetadata("smartCastExplicitExtensionReceiver.kt")
public void testSmartCastExplicitExtensionReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/smartCastExplicitExtensionReceiver.kt");
}
@Test
@TestMetadata("smartCastImplicitDispatchReceiver.kt")
public void testSmartCastImplicitDispatchReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/smartCastImplicitDispatchReceiver.kt");
}
@Test
@TestMetadata("smartCastImplicitExtensionReceiver.kt")
public void testSmartCastImplicitExtensionReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/smartCastImplicitExtensionReceiver.kt");
}
@Test
@TestMetadata("unresolvedSuperReference.kt")
public void testUnresolvedSuperReference() throws Exception {
@@ -468,6 +708,18 @@ public class FirResolveCallTestGenerated extends AbstractFirResolveCallTest {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/variableWithExtensionInvoke.kt");
}
@Test
@TestMetadata("variableWithInvokeFunctionCall_dispatchReceiver.kt")
public void testVariableWithInvokeFunctionCall_dispatchReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/variableWithInvokeFunctionCall_dispatchReceiver.kt");
}
@Test
@TestMetadata("variableWithInvokeFunctionCall_extensionReceiver.kt")
public void testVariableWithInvokeFunctionCall_extensionReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/variableWithInvokeFunctionCall_extensionReceiver.kt");
}
@Test
@TestMetadata("variableWithMemberInvoke.kt")
public void testVariableWithMemberInvoke() throws Exception {