diff --git a/compiler/fir/resolve/build.gradle.kts b/compiler/fir/resolve/build.gradle.kts index 16a0cb9f451..7c4bf38f27a 100644 --- a/compiler/fir/resolve/build.gradle.kts +++ b/compiler/fir/resolve/build.gradle.kts @@ -14,9 +14,10 @@ dependencies { api(project(":compiler:fir:tree")) api(kotlinxCollectionsImmutable()) implementation(project(":core:util.runtime")) + implementation(project(":compiler:psi")) compileOnly(project(":kotlin-reflect-api")) - compileOnly(intellijCoreDep()) { includeJars("guava", rootProject = rootProject) } + compileOnly(intellijCoreDep()) { includeJars("intellij-core", "guava", rootProject = rootProject) } } sourceSets { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt index 879929932a0..9c9c0f7e46b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.resolve.typeForQualifier import org.jetbrains.kotlin.fir.types.FirTypeProjection import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf const val ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE = "_root_ide_package_" @@ -91,7 +92,7 @@ class FirQualifiedNameResolver(private val components: BodyResolveComponents) { } return buildResolvedQualifier { - this.source = source + this.source = getWholeQualifierSource(source, qualifierPartsToDrop) packageFqName = resolved.packageFqName relativeClassFqName = resolved.relativeClassFqName symbol = resolved.classSymbol @@ -104,4 +105,11 @@ class FirQualifiedNameResolver(private val components: BodyResolveComponents) { return null } + private fun getWholeQualifierSource(qualifierStartSource: FirSourceElement?, stepsToWholeQualifier: Int): FirSourceElement? { + if (qualifierStartSource !is FirRealPsiSourceElement<*>) return qualifierStartSource + + val qualifierStart = qualifierStartSource.psi + val wholeQualifier = qualifierStart.parentsWithSelf.drop(stepsToWholeQualifier).first() + return wholeQualifier.toFirPsiSourceElement() + } } diff --git a/idea/idea-fir/tests/org/jetbrains/kotlin/idea/resolve/FirReferenceResolveTestGenerated.java b/idea/idea-fir/tests/org/jetbrains/kotlin/idea/resolve/FirReferenceResolveTestGenerated.java index 7cfd514a251..9b5670d96b6 100644 --- a/idea/idea-fir/tests/org/jetbrains/kotlin/idea/resolve/FirReferenceResolveTestGenerated.java +++ b/idea/idea-fir/tests/org/jetbrains/kotlin/idea/resolve/FirReferenceResolveTestGenerated.java @@ -144,6 +144,11 @@ public class FirReferenceResolveTestGenerated extends AbstractFirReferenceResolv runTest("idea/testData/resolve/references/EnumValues.kt"); } + @TestMetadata("ExternalCompanionObject.kt") + public void testExternalCompanionObject() throws Exception { + runTest("idea/testData/resolve/references/ExternalCompanionObject.kt"); + } + @TestMetadata("FakeJavaLang1.kt") public void testFakeJavaLang1() throws Exception { runTest("idea/testData/resolve/references/FakeJavaLang1.kt"); diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt index 83693dea8f7..1887b75d494 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.references import com.intellij.psi.tree.TokenSet import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.expressions.* @@ -121,6 +122,7 @@ internal object FirReferenceResolveHelper { else -> { qualified .collectDescendantsOfType() + .dropWhile { it.getReferencedName() == ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE } .joinToString(separator = ".") { it.getReferencedName() } .let(::FqName) } diff --git a/idea/testData/resolve/references/ExternalCompanionObject.Data.kt b/idea/testData/resolve/references/ExternalCompanionObject.Data.kt new file mode 100644 index 00000000000..fea28614468 --- /dev/null +++ b/idea/testData/resolve/references/ExternalCompanionObject.Data.kt @@ -0,0 +1,5 @@ +package dependency + +class C { + companion object +} \ No newline at end of file diff --git a/idea/testData/resolve/references/ExternalCompanionObject.kt b/idea/testData/resolve/references/ExternalCompanionObject.kt new file mode 100644 index 00000000000..c7740b22449 --- /dev/null +++ b/idea/testData/resolve/references/ExternalCompanionObject.kt @@ -0,0 +1,5 @@ +fun usage() { + dependency.C.Companion +} + +// REF: companion object of (dependency).C diff --git a/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java index b5fcd41ad55..22c4ccf8944 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java @@ -144,6 +144,11 @@ public class ReferenceResolveTestGenerated extends AbstractReferenceResolveTest runTest("idea/testData/resolve/references/EnumValues.kt"); } + @TestMetadata("ExternalCompanionObject.kt") + public void testExternalCompanionObject() throws Exception { + runTest("idea/testData/resolve/references/ExternalCompanionObject.kt"); + } + @TestMetadata("FakeJavaLang1.kt") public void testFakeJavaLang1() throws Exception { runTest("idea/testData/resolve/references/FakeJavaLang1.kt");