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 7bbe197e6ef..842cd318930 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 @@ -308,6 +308,21 @@ public class FirReferenceResolveTestGenerated extends AbstractFirReferenceResolv runTest("idea/testData/resolve/references/ResolvePackageInProperty.kt"); } + @TestMetadata("ResolvePackageInTheEndInProperty.kt") + public void testResolvePackageInTheEndInProperty() throws Exception { + runTest("idea/testData/resolve/references/ResolvePackageInTheEndInProperty.kt"); + } + + @TestMetadata("ResolvePackageInTheMiddleInProperty.kt") + public void testResolvePackageInTheMiddleInProperty() throws Exception { + runTest("idea/testData/resolve/references/ResolvePackageInTheMiddleInProperty.kt"); + } + + @TestMetadata("ResolvePackageInTheTypeNameInProperty.kt") + public void testResolvePackageInTheTypeNameInProperty() throws Exception { + runTest("idea/testData/resolve/references/ResolvePackageInTheTypeNameInProperty.kt"); + } + @TestMetadata("SamAdapter.kt") public void testSamAdapter() throws Exception { runTest("idea/testData/resolve/references/SamAdapter.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 47869edf61c..b6cba3b3fa9 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 @@ -86,8 +86,16 @@ internal object FirReferenceResolveHelper { } } - private fun getPackageSymbolFor(expression: KtSimpleNameExpression, symbolBuilder: KtSymbolByFirBuilder): KtFirPackageSymbol? { - val fqName = when (val qualified = expression.getQualifiedExpressionForSelector()) { + private fun getPackageSymbolFor( + expression: KtSimpleNameExpression, + symbolBuilder: KtSymbolByFirBuilder, + forQualifiedType: Boolean + ): KtFirPackageSymbol? { + val qualified = when { + forQualifiedType -> expression.parent?.takeIf { it is KtUserType && it.referenceExpression === expression } + else -> expression.getQualifiedExpressionForSelector() + } + val fqName = when (qualified) { null -> FqName(expression.getReferencedName()) else -> { qualified @@ -96,10 +104,28 @@ internal object FirReferenceResolveHelper { .let(::FqName) } } - return symbolBuilder.createPackageSymbolIfOneExists(fqName) } + private fun KtSimpleNameExpression.isPartOfQualifiedExpression(): Boolean { + var parent = parent + while (parent is KtDotQualifiedExpression) { + if (parent.selectorExpression !== this) return true + parent = parent.parent + } + return false + } + + private fun KtSimpleNameExpression.isPartOfUserTypeRefQualifier(): Boolean { + var parent = parent + while (parent is KtUserType) { + if (parent.referenceExpression !== this) return true + parent = parent.parent + } + return false + } + + internal fun resolveSimpleNameReference( ref: KtFirSimpleNameReference, analysisSession: KtFirAnalysisSession @@ -124,6 +150,9 @@ internal object FirReferenceResolveHelper { return listOfNotNull(calleeReference.toTargetSymbol(session, symbolBuilder)) } is FirResolvedTypeRef -> { + if (expression.isPartOfUserTypeRefQualifier()) { + return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder, forQualifiedType = true)) + } return listOfNotNull(fir.toTargetSymbol(session, symbolBuilder)) } is FirResolvedQualifier -> { @@ -150,14 +179,8 @@ internal object FirReferenceResolveHelper { return listOfNotNull(type.toTargetSymbol(session, symbolBuilder)) } is FirResolvedImport -> { - var parent = expression.parent - while (parent is KtDotQualifiedExpression) { - if (parent.selectorExpression !== expression) { - // Special: package reference in the middle of import directive - // import a.b.c.SomeClass - return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder)?.let { return listOf(it) }) - } - parent = parent.parent + if (expression.isPartOfQualifiedExpression()) { + return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder, forQualifiedType = false)) } val classId = fir.resolvedClassId @@ -181,7 +204,7 @@ internal object FirReferenceResolveHelper { is FirFile -> { if (expression.getNonStrictParentOfType() != null) { // Special: package reference in the middle of package directive - return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder)) + return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder, forQualifiedType = false)) } return listOf(symbolBuilder.buildSymbol(fir)) } diff --git a/idea/testData/resolve/references/ResolvePackageInProperty.kt b/idea/testData/resolve/references/ResolvePackageInProperty.kt index dd6b0d7da05..d908e10591a 100644 --- a/idea/testData/resolve/references/ResolvePackageInProperty.kt +++ b/idea/testData/resolve/references/ResolvePackageInProperty.kt @@ -1,5 +1,3 @@ -// IGNORE_FIR - package test1.test2 class Some() diff --git a/idea/testData/resolve/references/ResolvePackageInTheEndInProperty.kt b/idea/testData/resolve/references/ResolvePackageInTheEndInProperty.kt new file mode 100644 index 00000000000..2db3a0f03ff --- /dev/null +++ b/idea/testData/resolve/references/ResolvePackageInTheEndInProperty.kt @@ -0,0 +1,7 @@ +package test1.test2.test3 + +class Some() + +val test : test1.test2.test3.Some = Some() + +// REF: test3 \ No newline at end of file diff --git a/idea/testData/resolve/references/ResolvePackageInTheMiddleInProperty.kt b/idea/testData/resolve/references/ResolvePackageInTheMiddleInProperty.kt new file mode 100644 index 00000000000..31a40c19112 --- /dev/null +++ b/idea/testData/resolve/references/ResolvePackageInTheMiddleInProperty.kt @@ -0,0 +1,7 @@ +package test1.test2.test3 + +class Some() + +val test : test1.test2.test3.Some = Some() + +// REF: test2 \ No newline at end of file diff --git a/idea/testData/resolve/references/ResolvePackageInTheTypeNameInProperty.kt b/idea/testData/resolve/references/ResolvePackageInTheTypeNameInProperty.kt new file mode 100644 index 00000000000..17246c9452b --- /dev/null +++ b/idea/testData/resolve/references/ResolvePackageInTheTypeNameInProperty.kt @@ -0,0 +1,7 @@ +package test1.test2.test3 + +class Some() + +val test : test1.test2.test3.Some = Some() + +// REF: (test1.test2.test3).Some \ No newline at end of file diff --git a/idea/testData/resolve/references/invoke/lambdaAndParens.kt b/idea/testData/resolve/references/invoke/lambdaAndParens.kt index 6b4d7f881cd..ce83fad9711 100644 --- a/idea/testData/resolve/references/invoke/lambdaAndParens.kt +++ b/idea/testData/resolve/references/invoke/lambdaAndParens.kt @@ -1,5 +1,3 @@ -// IGNORE_FIR - class Foo { operator fun invoke(a: Any) {} } diff --git a/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java index 0f4c123841a..27463ca5dfa 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java @@ -308,6 +308,21 @@ public class ReferenceResolveTestGenerated extends AbstractReferenceResolveTest runTest("idea/testData/resolve/references/ResolvePackageInProperty.kt"); } + @TestMetadata("ResolvePackageInTheEndInProperty.kt") + public void testResolvePackageInTheEndInProperty() throws Exception { + runTest("idea/testData/resolve/references/ResolvePackageInTheEndInProperty.kt"); + } + + @TestMetadata("ResolvePackageInTheMiddleInProperty.kt") + public void testResolvePackageInTheMiddleInProperty() throws Exception { + runTest("idea/testData/resolve/references/ResolvePackageInTheMiddleInProperty.kt"); + } + + @TestMetadata("ResolvePackageInTheTypeNameInProperty.kt") + public void testResolvePackageInTheTypeNameInProperty() throws Exception { + runTest("idea/testData/resolve/references/ResolvePackageInTheTypeNameInProperty.kt"); + } + @TestMetadata("SamAdapter.kt") public void testSamAdapter() throws Exception { runTest("idea/testData/resolve/references/SamAdapter.kt");