[Analysis API] KTIJ-24107 Fix resolution of qualified invoke calls on objects

^KTIJ-24107 Fixed
^KTIJ-24344 Fixed
This commit is contained in:
Roman Golyshev
2023-01-24 19:29:54 +01:00
committed by teamcity
parent aab853ad12
commit 71a368e06e
55 changed files with 852 additions and 40 deletions
@@ -960,6 +960,76 @@ public class Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated extends A
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects")
@TestDataPath("$PROJECT_ROOT")
public class InvokeOnObjects {
@Test
public void testAllFilesPresentInInvokeOnObjects() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("companionObject1.kt")
public void testCompanionObject1() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/companionObject1.kt");
}
@Test
@TestMetadata("companionObject2.kt")
public void testCompanionObject2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/companionObject2.kt");
}
@Test
@TestMetadata("companionObjectWithName1.kt")
public void testCompanionObjectWithName1() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/companionObjectWithName1.kt");
}
@Test
@TestMetadata("companionObjectWithName2.kt")
public void testCompanionObjectWithName2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/companionObjectWithName2.kt");
}
@Test
@TestMetadata("nestedObject1.kt")
public void testNestedObject1() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/nestedObject1.kt");
}
@Test
@TestMetadata("nestedObject2.kt")
public void testNestedObject2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/nestedObject2.kt");
}
@Test
@TestMetadata("nestedObject3.kt")
public void testNestedObject3() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/nestedObject3.kt");
}
@Test
@TestMetadata("nestedObject4.kt")
public void testNestedObject4() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/nestedObject4.kt");
}
@Test
@TestMetadata("simpleObject1.kt")
public void testSimpleObject1() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/simpleObject1.kt");
}
@Test
@TestMetadata("simpleObject2.kt")
public void testSimpleObject2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/simpleObject2.kt");
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls")
@TestDataPath("$PROJECT_ROOT")
@@ -1075,6 +1075,76 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte
runTest("analysis/analysis-api/testData/referenceResolve/invoke/oneParamRPar.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/referenceResolve/invoke/onObjects")
@TestDataPath("$PROJECT_ROOT")
public class OnObjects {
@Test
public void testAllFilesPresentInOnObjects() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/invoke/onObjects"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("companionObject1.kt")
public void testCompanionObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObject1.kt");
}
@Test
@TestMetadata("companionObject2.kt")
public void testCompanionObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObject2.kt");
}
@Test
@TestMetadata("companionObjectWithName1.kt")
public void testCompanionObjectWithName1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObjectWithName1.kt");
}
@Test
@TestMetadata("companionObjectWithName2.kt")
public void testCompanionObjectWithName2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObjectWithName2.kt");
}
@Test
@TestMetadata("nestedObject1.kt")
public void testNestedObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject1.kt");
}
@Test
@TestMetadata("nestedObject2.kt")
public void testNestedObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject2.kt");
}
@Test
@TestMetadata("nestedObject3.kt")
public void testNestedObject3() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject3.kt");
}
@Test
@TestMetadata("nestedObject4.kt")
public void testNestedObject4() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject4.kt");
}
@Test
@TestMetadata("simpleObject1.kt")
public void testSimpleObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/simpleObject1.kt");
}
@Test
@TestMetadata("simpleObject2.kt")
public void testSimpleObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/simpleObject2.kt");
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/referenceResolve/invoke/withErrors")
@TestDataPath("$PROJECT_ROOT")
@@ -161,20 +161,32 @@ internal class KtFirCallResolver(
}
}
if (resolveCalleeExpressionOfFunctionCall && this is FirImplicitInvokeCall) {
// For implicit invoke, we resolve the calleeExpression of the CallExpression to the call that creates the receiver of this
// implicit invoke call. For example,
// ```
// fun test(f: () -> Unit) {
// f() // calleeExpression `f` resolves to the local variable access, while `f()` resolves to the implicit `invoke` call.
// // This way `f` is also the explicit receiver of this implicit `invoke` call
// }
// ```
return explicitReceiver?.toKtCallInfo(
psi,
resolveCalleeExpressionOfFunctionCall = false,
resolveFragmentOfCall = resolveFragmentOfCall
)
if (this is FirImplicitInvokeCall) {
// If we have a PSI expression like `Foo.Bar.Baz()` and try to resolve `Bar` part,
// and the only FIR that we have for that PSI is an implicit invoke call, that means that
// `Foo.Bar` is definitely not a property access - otherwise it would have had its own FIR.
// So, it does not make sense to try to resolve such parts of qualifiers as KtCall
if ((psi as? KtExpression)?.getPossiblyQualifiedCallExpression() == null) {
return null
}
if (resolveCalleeExpressionOfFunctionCall) {
// For implicit invoke, we resolve the calleeExpression of the CallExpression to the call that creates the receiver of this
// implicit invoke call. For example,
// ```
// fun test(f: () -> Unit) {
// f() // calleeExpression `f` resolves to the local variable access, while `f()` resolves to the implicit `invoke` call.
// // This way `f` is also the explicit receiver of this implicit `invoke` call
// }
// ```
val psiToResolve = (psi as? KtCallExpression)?.calleeExpression ?: psi
return explicitReceiver?.toKtCallInfo(
psiToResolve,
resolveCalleeExpressionOfFunctionCall = false,
resolveFragmentOfCall = resolveFragmentOfCall
)
}
}
fun <T> transformErrorReference(call: FirResolvable, calleeReference: T): KtCallInfo where T : FirNamedReference, T : FirDiagnosticHolder {
@@ -45,9 +45,7 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
import org.jetbrains.kotlin.psi.psiUtil.unwrapNullability
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addIfNotNull
@@ -393,14 +391,18 @@ internal object FirReferenceResolveHelper {
if (expression is KtLabelReferenceExpression && fir is FirPropertyAccessExpression && fir.calleeReference is FirSuperReference) {
return listOfNotNull((fir.dispatchReceiver.typeRef as? FirResolvedTypeRef)?.toTargetSymbol(session, symbolBuilder))
}
val implicitInvokeReceiver = if (fir is FirImplicitInvokeCall) {
fir.explicitReceiver?.unwrapSmartcastExpression() as? FirQualifiedAccessExpression
val receiverOrImplicitInvoke = if (fir is FirImplicitInvokeCall) {
fir.explicitReceiver?.unwrapSmartcastExpression()
} else {
null
}
val calleeReference = implicitInvokeReceiver?.calleeReference ?: fir.calleeReference
return calleeReference.toTargetSymbol(session, symbolBuilder, isInLabelReference = expression is KtLabelReferenceExpression)
return if (receiverOrImplicitInvoke is FirResolvedQualifier) {
getSymbolsForResolvedQualifier(receiverOrImplicitInvoke, expression, session, symbolBuilder)
} else {
val calleeReference = (receiverOrImplicitInvoke as? FirQualifiedAccessExpression)?.calleeReference ?: fir.calleeReference
calleeReference.toTargetSymbol(session, symbolBuilder, isInLabelReference = expression is KtLabelReferenceExpression)
}
}
@@ -494,8 +496,12 @@ internal object FirReferenceResolveHelper {
}
val referencedClass = referencedSymbol.fir
val referencedSymbolsByFir = listOfNotNull(symbolBuilder.buildSymbol(referencedSymbol))
val firSourcePsi = fir.source.psi
if (firSourcePsi !is KtDotQualifiedExpression) return referencedSymbolsByFir
val fullQualifiedAccess = when (val psi = fir.source.psi) {
// for cases like `Foo.Bar()`, where `Foo.Bar` is an object, and `Foo.Bar()` is a call to `invoke` operator
is KtSimpleNameExpression -> psi.getQualifiedElement()
else -> psi
}
if (fullQualifiedAccess !is KtDotQualifiedExpression) return referencedSymbolsByFir
// When the source of an `FirResolvedQualifier` is a KtDotQualifiedExpression, we need to manually break up the qualified access and
// resolve individual parts of it because in FIR, the entire qualified access is one element.
@@ -503,14 +509,21 @@ internal object FirReferenceResolveHelper {
// TODO: handle local classes after KT-47135 is fixed
return referencedSymbolsByFir
} else {
var qualifiedAccess: KtDotQualifiedExpression = firSourcePsi
var qualifiedAccess: KtDotQualifiedExpression = fullQualifiedAccess
val referencedClassId =
if ((referencedClass as? FirRegularClass)?.isCompanion == true &&
(qualifiedAccess.selectorExpression as? KtNameReferenceExpression)?.getReferencedName() != referencedClass.classId.shortClassName.asString()
) {
// Remove the last companion name part if the qualified access does not contain it.
// This is needed because the companion name part is optional.
referencedClass.classId.outerClassId ?: return referencedSymbolsByFir
if ((referencedClass as? FirRegularClass)?.isCompanion == true) {
val deepestQualifier = qualifiedAccess.selectorExpression?.referenceExpression() as? KtNameReferenceExpression
// If we're looking for the deepest qualifier, then just resolve to the companion
if (expression === deepestQualifier) return referencedSymbolsByFir
if (deepestQualifier?.getReferencedName() != referencedClass.classId.shortClassName.asString()) {
// Remove the last companion name part if the qualified access does not contain it.
// This is needed because the companion name part is optional.
referencedClass.classId.outerClassId ?: return referencedSymbolsByFir
} else {
referencedClass.classId
}
} else {
referencedClass.classId
}
@@ -548,7 +561,7 @@ internal object FirReferenceResolveHelper {
// Handle nested classes.
while (classId != null) {
if (expression === qualifiedAccess.selectorExpression) {
if (expression === qualifiedAccess.selectorExpression?.referenceExpression()) {
return listOfNotNull(classId.toTargetPsi(session, symbolBuilder))
}
val outerClassId = classId.outerClassId
@@ -609,7 +622,13 @@ internal object FirReferenceResolveHelper {
.toList()
.asReversed()
val qualifyingReferences = qualifiers.map { it as? KtNameReferenceExpression ?: return null }
val qualifyingReferences = qualifiers.mapIndexed { index, qualifier ->
// We want to handle qualified calls like `foo.Bar.Baz()`, but not like `foo.Bar().Baz()`
if (qualifier is KtCallExpression && index != qualifiers.lastIndex) return null
qualifier.referenceExpression() as? KtNameReferenceExpression ?: return null
}
return qualifyingReferences.map { it.getReferencedName() }
}
@@ -960,6 +960,76 @@ public class FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated extends Ab
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects")
@TestDataPath("$PROJECT_ROOT")
public class InvokeOnObjects {
@Test
public void testAllFilesPresentInInvokeOnObjects() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("companionObject1.kt")
public void testCompanionObject1() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/companionObject1.kt");
}
@Test
@TestMetadata("companionObject2.kt")
public void testCompanionObject2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/companionObject2.kt");
}
@Test
@TestMetadata("companionObjectWithName1.kt")
public void testCompanionObjectWithName1() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/companionObjectWithName1.kt");
}
@Test
@TestMetadata("companionObjectWithName2.kt")
public void testCompanionObjectWithName2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/companionObjectWithName2.kt");
}
@Test
@TestMetadata("nestedObject1.kt")
public void testNestedObject1() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/nestedObject1.kt");
}
@Test
@TestMetadata("nestedObject2.kt")
public void testNestedObject2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/nestedObject2.kt");
}
@Test
@TestMetadata("nestedObject3.kt")
public void testNestedObject3() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/nestedObject3.kt");
}
@Test
@TestMetadata("nestedObject4.kt")
public void testNestedObject4() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/nestedObject4.kt");
}
@Test
@TestMetadata("simpleObject1.kt")
public void testSimpleObject1() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/simpleObject1.kt");
}
@Test
@TestMetadata("simpleObject2.kt")
public void testSimpleObject2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/simpleObject2.kt");
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls")
@TestDataPath("$PROJECT_ROOT")
@@ -1075,6 +1075,76 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex
runTest("analysis/analysis-api/testData/referenceResolve/invoke/oneParamRPar.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/referenceResolve/invoke/onObjects")
@TestDataPath("$PROJECT_ROOT")
public class OnObjects {
@Test
public void testAllFilesPresentInOnObjects() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/invoke/onObjects"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("companionObject1.kt")
public void testCompanionObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObject1.kt");
}
@Test
@TestMetadata("companionObject2.kt")
public void testCompanionObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObject2.kt");
}
@Test
@TestMetadata("companionObjectWithName1.kt")
public void testCompanionObjectWithName1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObjectWithName1.kt");
}
@Test
@TestMetadata("companionObjectWithName2.kt")
public void testCompanionObjectWithName2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObjectWithName2.kt");
}
@Test
@TestMetadata("nestedObject1.kt")
public void testNestedObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject1.kt");
}
@Test
@TestMetadata("nestedObject2.kt")
public void testNestedObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject2.kt");
}
@Test
@TestMetadata("nestedObject3.kt")
public void testNestedObject3() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject3.kt");
}
@Test
@TestMetadata("nestedObject4.kt")
public void testNestedObject4() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject4.kt");
}
@Test
@TestMetadata("simpleObject1.kt")
public void testSimpleObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/simpleObject1.kt");
}
@Test
@TestMetadata("simpleObject2.kt")
public void testSimpleObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/simpleObject2.kt");
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/referenceResolve/invoke/withErrors")
@TestDataPath("$PROJECT_ROOT")
@@ -998,6 +998,76 @@ public class FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerate
public void testOneParamRPar() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/oneParamRPar.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/referenceResolve/invoke/onObjects")
@TestDataPath("$PROJECT_ROOT")
public class OnObjects {
@Test
public void testAllFilesPresentInOnObjects() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/invoke/onObjects"), Pattern.compile("^([^.]+)\\.kt$"), null, true, "withErrors");
}
@Test
@TestMetadata("companionObject1.kt")
public void testCompanionObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObject1.kt");
}
@Test
@TestMetadata("companionObject2.kt")
public void testCompanionObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObject2.kt");
}
@Test
@TestMetadata("companionObjectWithName1.kt")
public void testCompanionObjectWithName1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObjectWithName1.kt");
}
@Test
@TestMetadata("companionObjectWithName2.kt")
public void testCompanionObjectWithName2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObjectWithName2.kt");
}
@Test
@TestMetadata("nestedObject1.kt")
public void testNestedObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject1.kt");
}
@Test
@TestMetadata("nestedObject2.kt")
public void testNestedObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject2.kt");
}
@Test
@TestMetadata("nestedObject3.kt")
public void testNestedObject3() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject3.kt");
}
@Test
@TestMetadata("nestedObject4.kt")
public void testNestedObject4() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject4.kt");
}
@Test
@TestMetadata("simpleObject1.kt")
public void testSimpleObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/simpleObject1.kt");
}
@Test
@TestMetadata("simpleObject2.kt")
public void testSimpleObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/simpleObject2.kt");
}
}
}
@Nested
@@ -1075,6 +1075,76 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten
runTest("analysis/analysis-api/testData/referenceResolve/invoke/oneParamRPar.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/referenceResolve/invoke/onObjects")
@TestDataPath("$PROJECT_ROOT")
public class OnObjects {
@Test
public void testAllFilesPresentInOnObjects() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/invoke/onObjects"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("companionObject1.kt")
public void testCompanionObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObject1.kt");
}
@Test
@TestMetadata("companionObject2.kt")
public void testCompanionObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObject2.kt");
}
@Test
@TestMetadata("companionObjectWithName1.kt")
public void testCompanionObjectWithName1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObjectWithName1.kt");
}
@Test
@TestMetadata("companionObjectWithName2.kt")
public void testCompanionObjectWithName2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObjectWithName2.kt");
}
@Test
@TestMetadata("nestedObject1.kt")
public void testNestedObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject1.kt");
}
@Test
@TestMetadata("nestedObject2.kt")
public void testNestedObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject2.kt");
}
@Test
@TestMetadata("nestedObject3.kt")
public void testNestedObject3() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject3.kt");
}
@Test
@TestMetadata("nestedObject4.kt")
public void testNestedObject4() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject4.kt");
}
@Test
@TestMetadata("simpleObject1.kt")
public void testSimpleObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/simpleObject1.kt");
}
@Test
@TestMetadata("simpleObject2.kt")
public void testSimpleObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/simpleObject2.kt");
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/referenceResolve/invoke/withErrors")
@TestDataPath("$PROJECT_ROOT")
@@ -960,6 +960,76 @@ public class FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated ext
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects")
@TestDataPath("$PROJECT_ROOT")
public class InvokeOnObjects {
@Test
public void testAllFilesPresentInInvokeOnObjects() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects"), Pattern.compile("^(.+)\\.kt$"), null, true, "withTestCompilerPluginEnabled");
}
@Test
@TestMetadata("companionObject1.kt")
public void testCompanionObject1() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/companionObject1.kt");
}
@Test
@TestMetadata("companionObject2.kt")
public void testCompanionObject2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/companionObject2.kt");
}
@Test
@TestMetadata("companionObjectWithName1.kt")
public void testCompanionObjectWithName1() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/companionObjectWithName1.kt");
}
@Test
@TestMetadata("companionObjectWithName2.kt")
public void testCompanionObjectWithName2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/companionObjectWithName2.kt");
}
@Test
@TestMetadata("nestedObject1.kt")
public void testNestedObject1() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/nestedObject1.kt");
}
@Test
@TestMetadata("nestedObject2.kt")
public void testNestedObject2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/nestedObject2.kt");
}
@Test
@TestMetadata("nestedObject3.kt")
public void testNestedObject3() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/nestedObject3.kt");
}
@Test
@TestMetadata("nestedObject4.kt")
public void testNestedObject4() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/nestedObject4.kt");
}
@Test
@TestMetadata("simpleObject1.kt")
public void testSimpleObject1() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/simpleObject1.kt");
}
@Test
@TestMetadata("simpleObject2.kt")
public void testSimpleObject2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invokeOnObjects/simpleObject2.kt");
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls")
@TestDataPath("$PROJECT_ROOT")
@@ -1075,6 +1075,76 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate
runTest("analysis/analysis-api/testData/referenceResolve/invoke/oneParamRPar.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/referenceResolve/invoke/onObjects")
@TestDataPath("$PROJECT_ROOT")
public class OnObjects {
@Test
public void testAllFilesPresentInOnObjects() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/invoke/onObjects"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("companionObject1.kt")
public void testCompanionObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObject1.kt");
}
@Test
@TestMetadata("companionObject2.kt")
public void testCompanionObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObject2.kt");
}
@Test
@TestMetadata("companionObjectWithName1.kt")
public void testCompanionObjectWithName1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObjectWithName1.kt");
}
@Test
@TestMetadata("companionObjectWithName2.kt")
public void testCompanionObjectWithName2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/companionObjectWithName2.kt");
}
@Test
@TestMetadata("nestedObject1.kt")
public void testNestedObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject1.kt");
}
@Test
@TestMetadata("nestedObject2.kt")
public void testNestedObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject2.kt");
}
@Test
@TestMetadata("nestedObject3.kt")
public void testNestedObject3() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject3.kt");
}
@Test
@TestMetadata("nestedObject4.kt")
public void testNestedObject4() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/nestedObject4.kt");
}
@Test
@TestMetadata("simpleObject1.kt")
public void testSimpleObject1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/simpleObject1.kt");
}
@Test
@TestMetadata("simpleObject2.kt")
public void testSimpleObject2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/invoke/onObjects/simpleObject2.kt");
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/referenceResolve/invoke/withErrors")
@TestDataPath("$PROJECT_ROOT")
@@ -0,0 +1,9 @@
class Foo private constructor() {
companion object {
operator fun invoke() {}
}
}
fun test() {
<expr>Foo</expr>()
}
@@ -0,0 +1,11 @@
package foo
class Foo private constructor() {
companion object {
operator fun invoke() {}
}
}
fun test() {
foo.<expr>Foo</expr>()
}
@@ -0,0 +1,9 @@
class Foo private constructor() {
companion object Helper {
operator fun invoke() {}
}
}
fun test() {
Foo.<expr>Helper</expr>()
}
@@ -0,0 +1,9 @@
class Foo private constructor() {
companion object Helper {
operator fun invoke() {}
}
}
fun test() {
<expr>Foo</expr>()
}
@@ -0,0 +1,9 @@
object Foo {
object Helper {
operator fun invoke() {}
}
}
fun test() {
<expr>Foo</expr>.Helper()
}
@@ -0,0 +1,9 @@
object Foo {
object Helper {
operator fun invoke() {}
}
}
fun test() {
Foo.<expr>Helper</expr>()
}
@@ -0,0 +1,11 @@
package foo.bar.baz
object Foo {
object Helper {
operator fun invoke() {}
}
}
fun test() {
foo.bar.baz.<expr>Foo</expr>.Helper()
}
@@ -0,0 +1,11 @@
package foo.bar.baz
object Foo {
object Helper {
operator fun invoke() {}
}
}
fun test() {
foo.bar.baz.Foo.<expr>Helper</expr>()
}
@@ -0,0 +1,7 @@
object Foo {
operator fun invoke() {}
}
fun test() {
<expr>Foo</expr>()
}
@@ -0,0 +1,9 @@
package foo
object Foo {
operator fun invoke() {}
}
fun test() {
foo.<expr>Foo</expr>()
}
@@ -1,2 +0,0 @@
Resolved to:
0: (in test) object Conflict
@@ -1,2 +1,2 @@
Resolved to:
0: (in test.Conflict) operator fun invoke()
0: (in test) object Conflict
@@ -1,2 +0,0 @@
Resolved to:
0: (in test) object Conflict
@@ -1,2 +1,2 @@
Resolved to:
0: (in test) operator fun test.Conflict.invoke()
0: (in test) object Conflict
@@ -0,0 +1,9 @@
class Foo private constructor() {
companion object {
operator fun invoke() {}
}
}
fun test() {
Fo<caret>o()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in Foo) companion object
@@ -0,0 +1,11 @@
package foo
class Foo(i: Int) {
companion object {
operator fun invoke() {}
}
}
fun test() {
foo.Fo<caret>o()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in foo.Foo) companion object
@@ -0,0 +1,9 @@
class Foo private constructor() {
companion object Helper {
operator fun invoke() {}
}
}
fun test() {
Foo.He<caret>lper()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in Foo) companion object Helper
@@ -0,0 +1,9 @@
class Foo private constructor() {
companion object Helper {
operator fun invoke() {}
}
}
fun test() {
Fo<caret>o()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in Foo) companion object Helper
@@ -0,0 +1,9 @@
object Foo {
object Helper {
operator fun invoke() {}
}
}
fun test() {
Fo<caret>o.Helper()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in ROOT) object Foo
@@ -0,0 +1,9 @@
object Foo {
object Helper {
operator fun invoke() {}
}
}
fun test() {
Foo.He<caret>lper()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in Foo) object Helper
@@ -0,0 +1,11 @@
package foo.bar.baz
object Foo {
object Helper {
operator fun invoke() {}
}
}
fun test() {
foo.bar.baz.Fo<caret>o.Helper()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in foo.bar.baz) object Foo
@@ -0,0 +1,11 @@
package foo.bar.baz
object Foo {
object Helper {
operator fun invoke() {}
}
}
fun test() {
foo.bar.baz.Foo.He<caret>lper()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in foo.bar.baz.Foo) object Helper
@@ -0,0 +1,7 @@
object Foo {
operator fun invoke() {}
}
fun test() {
Fo<caret>o()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in ROOT) object Foo
@@ -0,0 +1,9 @@
package foo
object Foo {
operator fun invoke() {}
}
fun test() {
foo.Fo<caret>o()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in foo) object Foo
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.resolve.calls.tower
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
@@ -286,7 +287,10 @@ private fun BodyResolveComponents.createExplicitReceiverForInvoke(
is FirCallableSymbol<*> -> createExplicitReceiverForInvokeByCallable(
candidate, info, invokeBuiltinExtensionMode, extensionReceiverExpression, symbol
)
is FirRegularClassSymbol -> buildResolvedQualifierForClass(symbol, sourceElement = null)
is FirRegularClassSymbol -> buildResolvedQualifierForClass(
symbol,
sourceElement = info.fakeSourceForImplicitInvokeCallReceiver
)
is FirTypeAliasSymbol -> {
val type = symbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>().fullyExpandedType(session)
val expansionRegularClassSymbol = type.lookupTag.toSymbolOrError(session)
@@ -321,12 +325,15 @@ private fun BodyResolveComponents.createExplicitReceiverForInvokeByCallable(
if (candidate.currentApplicability == CandidateApplicability.K2_PROPERTY_AS_OPERATOR) {
nonFatalDiagnostics.add(ConePropertyAsOperator(candidate.symbol as FirPropertySymbol))
}
source = (info.callSite as? FirFunctionCall)?.calleeReference?.source?.fakeElement(KtFakeSourceElementKind.ImplicitInvokeCall)
source = info.fakeSourceForImplicitInvokeCallReceiver
}.build().let {
transformQualifiedAccessUsingSmartcastInfo(it)
}
}
private val CallInfo.fakeSourceForImplicitInvokeCallReceiver: KtSourceElement?
get() = (callSite as? FirFunctionCall)?.calleeReference?.source?.fakeElement(KtFakeSourceElementKind.ImplicitInvokeCall)
private class InvokeReceiverResolveTask(
components: BodyResolveComponents,
manager: TowerResolveManager,