FIR IDE: resolve implicit ctor delegation calls

This commit is contained in:
Jinseong Jeon
2021-08-05 14:22:09 -07:00
committed by Ilya Kirillov
parent f7f51cf38e
commit 75c76e2b57
7 changed files with 93 additions and 0 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.components
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.realPsi
import org.jetbrains.kotlin.fir.references.*
@@ -71,6 +72,7 @@ internal class KtFirCallResolver(
is FirFunctionCall -> resolveCall(fir)
is FirAnnotationCall -> fir.asAnnotationCall()
is FirDelegatedConstructorCall -> fir.asDelegatedConstructorCall()
is FirConstructor -> fir.asDelegatedConstructorCall()
is FirSafeCallExpression -> fir.regularQualifiedAccess.safeAs<FirFunctionCall>()?.let { resolveCall(it) }
else -> null
}
@@ -132,6 +134,18 @@ internal class KtFirCallResolver(
return KtDelegatedConstructorCall(createArgumentMapping(), target, kind)
}
private fun FirConstructor.asDelegatedConstructorCall(): KtDelegatedConstructorCall? {
// A delegation call may not be present in the source code:
//
// class A {
// constructor(i: Int) // <--- implicit constructor delegation call (empty element after RPAR)
// }
//
// and FIR built/found from that implicit `KtConstructorDelegationCall` is `FirConstructor`,
// which may have a pointer to the delegated constructor.
return delegatedConstructor?.asDelegatedConstructorCall()
}
private fun FirReference.createCallTarget(): KtCallTarget? {
return when (this) {
is FirSuperReference -> createCallTarget(source)
@@ -0,0 +1,9 @@
class A {
constructor(i: Int)
}
fun call() {
val a = <expr>A(42)</expr>
}
// CALL: KtFunctionCall: targetFunction = <constructor>(i: kotlin.Int): A
@@ -0,0 +1,3 @@
KtFunctionCall:
argumentMapping = { 42 -> (i: kotlin.Int) }
targetFunction = <constructor>(i: kotlin.Int): A
@@ -0,0 +1,3 @@
class A {
constructor(i: Int)
}
@@ -0,0 +1,52 @@
KtFirValueParameterSymbol:
annotatedType: [] kotlin/Int
annotationClassIds: []
annotations: []
callableIdIfNonLocal: null
hasDefaultValue: false
isExtension: false
isVararg: false
name: i
origin: SOURCE
receiverType: null
symbolKind: LOCAL
KtFirConstructorSymbol:
annotatedType: [] A
annotationClassIds: []
annotations: []
callableIdIfNonLocal: null
containingClassIdIfNonLocal: A
dispatchType: null
hasStableParameterNames: true
isExtension: false
isPrimary: false
origin: SOURCE
receiverType: null
symbolKind: MEMBER
typeParameters: []
valueParameters: [
KtFirValueParameterSymbol(i)
]
visibility: Public
KtFirNamedClassOrObjectSymbol:
annotationClassIds: []
annotations: []
classIdIfNonLocal: A
classKind: CLASS
companionObject: null
isData: false
isExternal: false
isFun: false
isInline: false
isInner: false
modality: FINAL
name: A
origin: SOURCE
superTypes: [
[] kotlin/Any
]
symbolKind: TOP_LEVEL
typeParameters: []
visibility: Public
@@ -66,6 +66,12 @@ public class ResolveCallTestGenerated extends AbstractResolveCallTest {
runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionWithReceiverSafeCall.kt");
}
@Test
@TestMetadata("implicitConstructorDelegationCall.kt")
public void testImplicitConstructorDelegationCall() throws Exception {
runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/implicitConstructorDelegationCall.kt");
}
@Test
@TestMetadata("implicitConstuctorCall.kt")
public void testImplicitConstuctorCall() throws Exception {
@@ -96,6 +96,12 @@ public class SymbolByPsiTestGenerated extends AbstractSymbolByPsiTest {
runTest("idea/idea-frontend-fir/testData/symbols/symbolByPsi/functionWithTypeParams.kt");
}
@Test
@TestMetadata("implicitConstructorDelegationCall.kt")
public void testImplicitConstructorDelegationCall() throws Exception {
runTest("idea/idea-frontend-fir/testData/symbols/symbolByPsi/implicitConstructorDelegationCall.kt");
}
@Test
@TestMetadata("implicitReturn.kt")
public void testImplicitReturn() throws Exception {