diff --git a/idea/idea-fir/tests/org/jetbrains/kotlin/shortenRefs/FirShortenRefsTestGenerated.java b/idea/idea-fir/tests/org/jetbrains/kotlin/shortenRefs/FirShortenRefsTestGenerated.java index 33a57420cff..ed61781103a 100644 --- a/idea/idea-fir/tests/org/jetbrains/kotlin/shortenRefs/FirShortenRefsTestGenerated.java +++ b/idea/idea-fir/tests/org/jetbrains/kotlin/shortenRefs/FirShortenRefsTestGenerated.java @@ -66,6 +66,11 @@ public class FirShortenRefsTestGenerated extends AbstractFirShortenRefsTest { runTest("idea/testData/shortenRefsFir/types/ParameterTypeGenericTypes.kt"); } + @TestMetadata("ParameterTypeImplicitImportBeatsStarImport.kt") + public void testParameterTypeImplicitImportBeatsStarImport() throws Exception { + runTest("idea/testData/shortenRefsFir/types/ParameterTypeImplicitImportBeatsStarImport.kt"); + } + @TestMetadata("ParameterTypeImportedNestedClass.kt") public void testParameterTypeImportedNestedClass() throws Exception { runTest("idea/testData/shortenRefsFir/types/ParameterTypeImportedNestedClass.kt"); diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirReferenceShortener.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirReferenceShortener.kt index de77008cae5..86b85116b44 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirReferenceShortener.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirReferenceShortener.kt @@ -15,12 +15,15 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvedImport import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.scopes.FirScope +import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractStarImportingScope import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope +import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope import org.jetbrains.kotlin.fir.scopes.processClassifiersByName import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.classId +import org.jetbrains.kotlin.fir.types.lowerBoundIfFlexible import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFir @@ -60,12 +63,17 @@ internal class KtFirReferenceShortener( ) } - private fun findFirstClassifierInScopesByName(positionScopes: List, targetClassName: Name): ClassId? { + private data class AvailableClassifier(val classId: ClassId, val isFromStarOrPackageImport: Boolean) + + private fun findFirstClassifierInScopesByName(positionScopes: List, targetClassName: Name): AvailableClassifier? { for (scope in positionScopes) { val classifierSymbol = scope.findFirstClassifierByName(targetClassName) ?: continue val classifierLookupTag = classifierSymbol.toLookupTag() as? ConeClassLikeLookupTag ?: continue - return classifierLookupTag.classId + return AvailableClassifier( + classifierLookupTag.classId, + isFromStarOrPackageImport = scope is FirAbstractStarImportingScope || scope is FirPackageMemberScope + ) } return null @@ -137,7 +145,7 @@ internal class KtFirReferenceShortener( private fun processTypeRef(resolvedTypeRef: FirResolvedTypeRef) { val wholeTypeReference = resolvedTypeRef.psi as? KtTypeReference ?: return - val wholeClassifierId = resolvedTypeRef.type.classId ?: return + val wholeClassifierId = resolvedTypeRef.type.lowerBoundIfFlexible().classId ?: return val wholeTypeElement = wholeTypeReference.typeElement.unwrapNullable() as? KtUserType ?: return if (wholeTypeElement.qualifier == null) return @@ -152,7 +160,7 @@ internal class KtFirReferenceShortener( val positionScopes = findScopesAtPosition(wholeTypeElement, typesToImport) ?: return for ((classId, typeElement) in allClassIds.zip(allTypeElements)) { - val firstFoundClass = findFirstClassifierInScopesByName(positionScopes, classId.shortClassName) + val firstFoundClass = findFirstClassifierInScopesByName(positionScopes, classId.shortClassName)?.classId if (firstFoundClass == classId) { addTypeToShorten(typeElement) @@ -162,11 +170,11 @@ internal class KtFirReferenceShortener( // none class matched val (mostTopLevelClassId, mostTopLevelTypeElement) = allClassIds.zip(allTypeElements).last() - val firstFoundClass = findFirstClassifierInScopesByName(positionScopes, mostTopLevelClassId.shortClassName) + val availableClassifier = findFirstClassifierInScopesByName(positionScopes, mostTopLevelClassId.shortClassName) - check(firstFoundClass != mostTopLevelClassId) { "This should not be true" } + check(availableClassifier?.classId != mostTopLevelClassId) { "This should not be true" } - if (firstFoundClass == null) { + if (availableClassifier == null || availableClassifier.isFromStarOrPackageImport) { addTypeToImportAndShorten(mostTopLevelClassId.asSingleFqName(), mostTopLevelTypeElement) } } diff --git a/idea/testData/shortenRefsFir/types/ParameterTypeImplicitImportBeatsStarImport.dependency1.kt b/idea/testData/shortenRefsFir/types/ParameterTypeImplicitImportBeatsStarImport.dependency1.kt new file mode 100644 index 00000000000..e868126b897 --- /dev/null +++ b/idea/testData/shortenRefsFir/types/ParameterTypeImplicitImportBeatsStarImport.dependency1.kt @@ -0,0 +1,3 @@ +package dependency1 + +class T \ No newline at end of file diff --git a/idea/testData/shortenRefsFir/types/ParameterTypeImplicitImportBeatsStarImport.dependency2.kt b/idea/testData/shortenRefsFir/types/ParameterTypeImplicitImportBeatsStarImport.dependency2.kt new file mode 100644 index 00000000000..83d8674a6c4 --- /dev/null +++ b/idea/testData/shortenRefsFir/types/ParameterTypeImplicitImportBeatsStarImport.dependency2.kt @@ -0,0 +1,3 @@ +package dependency2 + +class T \ No newline at end of file diff --git a/idea/testData/shortenRefsFir/types/ParameterTypeImplicitImportBeatsStarImport.kt b/idea/testData/shortenRefsFir/types/ParameterTypeImplicitImportBeatsStarImport.kt new file mode 100644 index 00000000000..1e419001dc4 --- /dev/null +++ b/idea/testData/shortenRefsFir/types/ParameterTypeImplicitImportBeatsStarImport.kt @@ -0,0 +1,6 @@ +// FIR_COMPARISON +package test + +import dependency1.* + +fun foo(t: dependency2.T) {} diff --git a/idea/testData/shortenRefsFir/types/ParameterTypeImplicitImportBeatsStarImport.kt.after b/idea/testData/shortenRefsFir/types/ParameterTypeImplicitImportBeatsStarImport.kt.after new file mode 100644 index 00000000000..31166417872 --- /dev/null +++ b/idea/testData/shortenRefsFir/types/ParameterTypeImplicitImportBeatsStarImport.kt.after @@ -0,0 +1,7 @@ +// FIR_COMPARISON +package test + +import dependency1.* +import dependency2.T + +fun foo(t: T) {} diff --git a/idea/testData/shortenRefsFir/types/ParameterTypeStarImportedTypeLoses.kt.after b/idea/testData/shortenRefsFir/types/ParameterTypeStarImportedTypeLoses.kt.after index bcab9592b0e..7b5abce0f79 100644 --- a/idea/testData/shortenRefsFir/types/ParameterTypeStarImportedTypeLoses.kt.after +++ b/idea/testData/shortenRefsFir/types/ParameterTypeStarImportedTypeLoses.kt.after @@ -2,7 +2,8 @@ package test import dependency.* +import dependency.T class T -fun foo(t: dependency.T) {} \ No newline at end of file +fun foo(t: T) {} \ No newline at end of file