K2: Update reference shortener to handle import alias
The existing reference shortener does not use import alias when it
shortens a symbol. Instead, it adds a new import directive for the
symbol that is already imported. This commit updates reference shortener
to let it reuse the existing import alias rather than adding a new one:
1. When shortening a symbol, check whether the symbol is already
imported.
2. If it is already imported by an import alias, keep the symbol
reference expression and the import alias as a string together in
`ShortenCommand`.
The actual PSI update (shortening) based on the ShortenCommand is done
by IntelliJ.
^KTIJ-27205
This commit is contained in:
+3
-8
@@ -8,10 +8,7 @@ package org.jetbrains.kotlin.analysis.api.descriptors.components
|
|||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.psi.SmartPointerManager
|
import com.intellij.psi.SmartPointerManager
|
||||||
import com.intellij.psi.SmartPsiElementPointer
|
import com.intellij.psi.SmartPsiElementPointer
|
||||||
import org.jetbrains.kotlin.analysis.api.components.KtReferenceShortener
|
import org.jetbrains.kotlin.analysis.api.components.*
|
||||||
import org.jetbrains.kotlin.analysis.api.components.ShortenCommand
|
|
||||||
import org.jetbrains.kotlin.analysis.api.components.ShortenOptions
|
|
||||||
import org.jetbrains.kotlin.analysis.api.components.ShortenStrategy
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.components.base.Fe10KtAnalysisSessionComponent
|
import org.jetbrains.kotlin.analysis.api.descriptors.components.base.Fe10KtAnalysisSessionComponent
|
||||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
||||||
@@ -19,9 +16,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
|||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
|
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtUserType
|
|
||||||
|
|
||||||
internal class KtFe10ReferenceShortener(
|
internal class KtFe10ReferenceShortener(
|
||||||
override val analysisSession: KtFe10AnalysisSession,
|
override val analysisSession: KtFe10AnalysisSession,
|
||||||
@@ -44,8 +39,8 @@ internal class KtFe10ReferenceShortener(
|
|||||||
override val targetFile: SmartPsiElementPointer<KtFile> get() = ktFilePointer
|
override val targetFile: SmartPsiElementPointer<KtFile> get() = ktFilePointer
|
||||||
override val importsToAdd: Set<FqName> get() = emptySet()
|
override val importsToAdd: Set<FqName> get() = emptySet()
|
||||||
override val starImportsToAdd: Set<FqName> get() = emptySet()
|
override val starImportsToAdd: Set<FqName> get() = emptySet()
|
||||||
override val typesToShorten: List<SmartPsiElementPointer<KtUserType>> get() = emptyList()
|
override val listOfTypeToShortenInfo: List<TypeToShortenInfo> get() = emptyList()
|
||||||
override val qualifiersToShorten: List<SmartPsiElementPointer<KtDotQualifiedExpression>> get() = emptyList()
|
override val listOfQualifierToShortenInfo: List<QualifierToShortenInfo> get() = emptyList()
|
||||||
override val kDocQualifiersToShorten: List<SmartPsiElementPointer<KDocName>> get() = emptyList()
|
override val kDocQualifiersToShorten: List<SmartPsiElementPointer<KDocName>> get() = emptyList()
|
||||||
|
|
||||||
override val isEmpty: Boolean get() = true
|
override val isEmpty: Boolean get() = true
|
||||||
|
|||||||
+56
-20
@@ -10,10 +10,7 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.SmartPsiElementPointer
|
import com.intellij.psi.SmartPsiElementPointer
|
||||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.analysis.api.components.KtReferenceShortener
|
import org.jetbrains.kotlin.analysis.api.components.*
|
||||||
import org.jetbrains.kotlin.analysis.api.components.ShortenCommand
|
|
||||||
import org.jetbrains.kotlin.analysis.api.components.ShortenOptions
|
|
||||||
import org.jetbrains.kotlin.analysis.api.components.ShortenStrategy
|
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.components.ElementsToShortenCollector.PartialOrderOfScope.Companion.toPartialOrder
|
import org.jetbrains.kotlin.analysis.api.fir.components.ElementsToShortenCollector.PartialOrderOfScope.Companion.toPartialOrder
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.isImplicitDispatchReceiver
|
import org.jetbrains.kotlin.analysis.api.fir.isImplicitDispatchReceiver
|
||||||
@@ -92,8 +89,8 @@ internal class KtFirReferenceShortener(
|
|||||||
file.createSmartPointer(),
|
file.createSmartPointer(),
|
||||||
importsToAdd = emptySet(),
|
importsToAdd = emptySet(),
|
||||||
starImportsToAdd = emptySet(),
|
starImportsToAdd = emptySet(),
|
||||||
typesToShorten = emptyList(),
|
listOfTypeToShortenInfo = emptyList(),
|
||||||
qualifiersToShorten = emptyList(),
|
listOfQualifierToShortenInfo = emptyList(),
|
||||||
kDocQualifiersToShorten = emptyList(),
|
kDocQualifiersToShorten = emptyList(),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -134,9 +131,10 @@ internal class KtFirReferenceShortener(
|
|||||||
file.createSmartPointer(),
|
file.createSmartPointer(),
|
||||||
additionalImports.simpleImports,
|
additionalImports.simpleImports,
|
||||||
additionalImports.starImports,
|
additionalImports.starImports,
|
||||||
collector.typesToShorten.map { it.element }.distinct().map { it.createSmartPointer() },
|
collector.typesToShorten.distinctBy { it.element }.map { TypeToShortenInfo(it.element.createSmartPointer(), it.shortenedRef) },
|
||||||
collector.qualifiersToShorten.map { it.element }.distinct().map { it.createSmartPointer() },
|
collector.qualifiersToShorten.distinctBy { it.element }
|
||||||
kDocCollector.kDocQualifiersToShorten.map { it.element }.distinct().map { it.createSmartPointer() },
|
.map { QualifierToShortenInfo(it.element.createSmartPointer(), it.shortenedRef) },
|
||||||
|
kDocCollector.kDocQualifiersToShorten.distinctBy { it.element }.map { it.element.createSmartPointer() },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,12 +386,14 @@ private sealed class ElementToShorten {
|
|||||||
|
|
||||||
private class ShortenType(
|
private class ShortenType(
|
||||||
val element: KtUserType,
|
val element: KtUserType,
|
||||||
|
val shortenedRef: String? = null,
|
||||||
override val nameToImport: FqName? = null,
|
override val nameToImport: FqName? = null,
|
||||||
override val importAllInParent: Boolean = false,
|
override val importAllInParent: Boolean = false,
|
||||||
) : ElementToShorten()
|
) : ElementToShorten()
|
||||||
|
|
||||||
private class ShortenQualifier(
|
private class ShortenQualifier(
|
||||||
val element: KtDotQualifiedExpression,
|
val element: KtDotQualifiedExpression,
|
||||||
|
val shortenedRef: String? = null,
|
||||||
override val nameToImport: FqName? = null,
|
override val nameToImport: FqName? = null,
|
||||||
override val importAllInParent: Boolean = false
|
override val importAllInParent: Boolean = false
|
||||||
) : ElementToShorten()
|
) : ElementToShorten()
|
||||||
@@ -774,6 +774,19 @@ private class ElementsToShortenCollector(
|
|||||||
return !element.containingFile.hasImportDirectiveForDifferentSymbolWithSameName(classId)
|
return !element.containingFile.hasImportDirectiveForDifferentSymbolWithSameName(classId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun shortenIfAlreadyImportedAsAlias(referenceExpression: KtElement, referencedSymbolFqName: FqName): ElementToShorten? {
|
||||||
|
val importDirectiveForReferencedSymbol = referenceExpression.containingKtFile.importDirectives.firstOrNull {
|
||||||
|
it.importedFqName == referencedSymbolFqName && it.alias != null
|
||||||
|
} ?: return null
|
||||||
|
return when (referenceExpression) {
|
||||||
|
is KtUserType -> ShortenType(referenceExpression, shortenedRef = importDirectiveForReferencedSymbol.alias?.name)
|
||||||
|
is KtDotQualifiedExpression -> ShortenQualifier(
|
||||||
|
referenceExpression, shortenedRef = importDirectiveForReferencedSymbol.alias?.name
|
||||||
|
)
|
||||||
|
else -> error("Unexpected ${referenceExpression::class}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun findClassifierElementsToShorten(
|
private fun findClassifierElementsToShorten(
|
||||||
positionScopes: List<FirScope>,
|
positionScopes: List<FirScope>,
|
||||||
allClassIds: Sequence<ClassId>,
|
allClassIds: Sequence<ClassId>,
|
||||||
@@ -787,6 +800,8 @@ private class ElementsToShortenCollector(
|
|||||||
// If its parent has a type parameter, we do not shorten it ATM because it will lose its type parameter. See KTIJ-26072
|
// If its parent has a type parameter, we do not shorten it ATM because it will lose its type parameter. See KTIJ-26072
|
||||||
if (classSymbol.hasTypeParameterFromParent()) continue
|
if (classSymbol.hasTypeParameterFromParent()) continue
|
||||||
|
|
||||||
|
shortenIfAlreadyImportedAsAlias(element, classId.asSingleFqName())?.let { return it }
|
||||||
|
|
||||||
if (shortenClassifierIfAlreadyImported(classId, element, classSymbol, positionScopes)) {
|
if (shortenClassifierIfAlreadyImported(classId, element, classSymbol, positionScopes)) {
|
||||||
return createElementToShorten(element, null, false)
|
return createElementToShorten(element, null, false)
|
||||||
}
|
}
|
||||||
@@ -829,8 +844,8 @@ private class ElementsToShortenCollector(
|
|||||||
|
|
||||||
private fun createElementToShorten(element: KtElement, nameToImport: FqName?, importAllInParent: Boolean): ElementToShorten {
|
private fun createElementToShorten(element: KtElement, nameToImport: FqName?, importAllInParent: Boolean): ElementToShorten {
|
||||||
return when (element) {
|
return when (element) {
|
||||||
is KtUserType -> ShortenType(element, nameToImport, importAllInParent)
|
is KtUserType -> ShortenType(element, shortenedRef = null, nameToImport, importAllInParent)
|
||||||
is KtDotQualifiedExpression -> ShortenQualifier(element, nameToImport, importAllInParent)
|
is KtDotQualifiedExpression -> ShortenQualifier(element, shortenedRef = null, nameToImport, importAllInParent)
|
||||||
else -> error("Unexpected ${element::class}")
|
else -> error("Unexpected ${element::class}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1039,6 +1054,11 @@ private class ElementsToShortenCollector(
|
|||||||
val option = callableShortenStrategy(propertySymbol)
|
val option = callableShortenStrategy(propertySymbol)
|
||||||
if (option == ShortenStrategy.DO_NOT_SHORTEN) return
|
if (option == ShortenStrategy.DO_NOT_SHORTEN) return
|
||||||
|
|
||||||
|
shortenIfAlreadyImportedAsAlias(qualifiedProperty, propertySymbol.callableId.asSingleFqName())?.let {
|
||||||
|
addElementToShorten(it)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val scopes = shorteningContext.findScopesAtPosition(qualifiedProperty, getNamesToImport(), towerContextProvider) ?: return
|
val scopes = shorteningContext.findScopesAtPosition(qualifiedProperty, getNamesToImport(), towerContextProvider) ?: return
|
||||||
val availableCallables = shorteningContext.findPropertiesInScopes(scopes, propertySymbol.name)
|
val availableCallables = shorteningContext.findPropertiesInScopes(scopes, propertySymbol.name)
|
||||||
if (availableCallables.isNotEmpty() && shortenIfAlreadyImported(firPropertyAccess, propertySymbol, qualifiedProperty)) {
|
if (availableCallables.isNotEmpty() && shortenIfAlreadyImported(firPropertyAccess, propertySymbol, qualifiedProperty)) {
|
||||||
@@ -1085,6 +1105,11 @@ private class ElementsToShortenCollector(
|
|||||||
val option = callableShortenStrategy(calledSymbol)
|
val option = callableShortenStrategy(calledSymbol)
|
||||||
if (option == ShortenStrategy.DO_NOT_SHORTEN) return
|
if (option == ShortenStrategy.DO_NOT_SHORTEN) return
|
||||||
|
|
||||||
|
shortenIfAlreadyImportedAsAlias(qualifiedCallExpression, calledSymbol.callableId.asSingleFqName())?.let {
|
||||||
|
addElementToShorten(it)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val scopes = shorteningContext.findScopesAtPosition(callExpression, getNamesToImport(), towerContextProvider) ?: return
|
val scopes = shorteningContext.findScopesAtPosition(callExpression, getNamesToImport(), towerContextProvider) ?: return
|
||||||
val availableCallables = shorteningContext.findFunctionsInScopes(scopes, calledSymbol.name)
|
val availableCallables = shorteningContext.findFunctionsInScopes(scopes, calledSymbol.name)
|
||||||
if (availableCallables.isNotEmpty() && shortenIfAlreadyImported(functionCall, calledSymbol, callExpression)) {
|
if (availableCallables.isNotEmpty() && shortenIfAlreadyImported(functionCall, calledSymbol, callExpression)) {
|
||||||
@@ -1123,13 +1148,14 @@ private class ElementsToShortenCollector(
|
|||||||
if (nameToImport == null || option == ShortenStrategy.SHORTEN_IF_ALREADY_IMPORTED) return
|
if (nameToImport == null || option == ShortenStrategy.SHORTEN_IF_ALREADY_IMPORTED) return
|
||||||
ShortenQualifier(
|
ShortenQualifier(
|
||||||
qualifiedCallExpression,
|
qualifiedCallExpression,
|
||||||
|
shortenedRef = null,
|
||||||
nameToImport,
|
nameToImport,
|
||||||
importAllInParent = option == ShortenStrategy.SHORTEN_AND_STAR_IMPORT
|
importAllInParent = option == ShortenStrategy.SHORTEN_AND_STAR_IMPORT
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// Respect caller's request to star import this symbol.
|
// Respect caller's request to star import this symbol.
|
||||||
matchedCallables.any { it.importKind == ImportKind.EXPLICIT } && option == ShortenStrategy.SHORTEN_AND_STAR_IMPORT ->
|
matchedCallables.any { it.importKind == ImportKind.EXPLICIT } && option == ShortenStrategy.SHORTEN_AND_STAR_IMPORT ->
|
||||||
ShortenQualifier(qualifiedCallExpression, nameToImport, importAllInParent = true)
|
ShortenQualifier(qualifiedCallExpression, null, nameToImport, importAllInParent = true)
|
||||||
else -> ShortenQualifier(qualifiedCallExpression)
|
else -> ShortenQualifier(qualifiedCallExpression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1201,13 +1227,17 @@ private class ElementsToShortenCollector(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addElementToShorten(element: KtElement, nameToImport: FqName?, isImportWithStar: Boolean) {
|
private fun addElementToShorten(element: KtElement, shortenedRef: String?, nameToImport: FqName?, isImportWithStar: Boolean) {
|
||||||
val qualifier = element.getQualifier() ?: return
|
val qualifier = element.getQualifier() ?: return
|
||||||
if (!qualifier.isAlreadyCollected()) {
|
if (!qualifier.isAlreadyCollected()) {
|
||||||
removeRedundantElements(qualifier)
|
removeRedundantElements(qualifier)
|
||||||
when (element) {
|
when (element) {
|
||||||
is KtUserType -> typesToShorten.add(ShortenType(element, nameToImport, isImportWithStar))
|
is KtUserType -> typesToShorten.add(ShortenType(element, shortenedRef, nameToImport, isImportWithStar))
|
||||||
is KtDotQualifiedExpression -> qualifiersToShorten.add(ShortenQualifier(element, nameToImport, isImportWithStar))
|
is KtDotQualifiedExpression -> qualifiersToShorten.add(
|
||||||
|
ShortenQualifier(
|
||||||
|
element, shortenedRef, nameToImport, isImportWithStar
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1219,9 +1249,15 @@ private class ElementsToShortenCollector(
|
|||||||
elementInfoToShorten.nameToImport to false
|
elementInfoToShorten.nameToImport to false
|
||||||
}
|
}
|
||||||
when (elementInfoToShorten) {
|
when (elementInfoToShorten) {
|
||||||
is ShortenType -> addElementToShorten(elementInfoToShorten.element, nameToImport, isImportWithStar)
|
is ShortenType -> addElementToShorten(
|
||||||
is ShortenQualifier -> addElementToShorten(elementInfoToShorten.element, nameToImport, isImportWithStar)
|
elementInfoToShorten.element, elementInfoToShorten.shortenedRef, nameToImport, isImportWithStar
|
||||||
is ShortenKDocQualifier -> addElementToShorten(elementInfoToShorten.element, nameToImport, isImportWithStar)
|
)
|
||||||
|
is ShortenQualifier -> addElementToShorten(
|
||||||
|
elementInfoToShorten.element, elementInfoToShorten.shortenedRef, nameToImport, isImportWithStar
|
||||||
|
)
|
||||||
|
is ShortenKDocQualifier -> addElementToShorten(
|
||||||
|
elementInfoToShorten.element, shortenedRef = null, nameToImport, isImportWithStar
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1366,8 +1402,8 @@ private class ShortenCommandImpl(
|
|||||||
override val targetFile: SmartPsiElementPointer<KtFile>,
|
override val targetFile: SmartPsiElementPointer<KtFile>,
|
||||||
override val importsToAdd: Set<FqName>,
|
override val importsToAdd: Set<FqName>,
|
||||||
override val starImportsToAdd: Set<FqName>,
|
override val starImportsToAdd: Set<FqName>,
|
||||||
override val typesToShorten: List<SmartPsiElementPointer<KtUserType>>,
|
override val listOfTypeToShortenInfo: List<TypeToShortenInfo>,
|
||||||
override val qualifiersToShorten: List<SmartPsiElementPointer<KtDotQualifiedExpression>>,
|
override val listOfQualifierToShortenInfo: List<QualifierToShortenInfo>,
|
||||||
override val kDocQualifiersToShorten: List<SmartPsiElementPointer<KDocName>>,
|
override val kDocQualifiersToShorten: List<SmartPsiElementPointer<KDocName>>,
|
||||||
) : ShortenCommand
|
) : ShortenCommand
|
||||||
|
|
||||||
|
|||||||
+48
@@ -274,6 +274,36 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/functionalType_parameterPosition.kt");
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/functionalType_parameterPosition.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("importAliasAndStarImport.kt")
|
||||||
|
public void testImportAliasAndStarImport() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/importAliasAndStarImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("importAliasForFunction.kt")
|
||||||
|
public void testImportAliasForFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/importAliasForFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("importAliasForProperty.kt")
|
||||||
|
public void testImportAliasForProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/importAliasForProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("importAliasForType.kt")
|
||||||
|
public void testImportAliasForType() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/importAliasForType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("importAliasForTypeQualifier.kt")
|
||||||
|
public void testImportAliasForTypeQualifier() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/importAliasForTypeQualifier.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kdoc.kt")
|
@TestMetadata("kdoc.kt")
|
||||||
public void testKdoc() throws Exception {
|
public void testKdoc() throws Exception {
|
||||||
@@ -310,6 +340,18 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/multipleImport.kt");
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/multipleImport.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("multipleImportAlias.kt")
|
||||||
|
public void testMultipleImportAlias() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/multipleImportAlias.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("multipleImportAlias2.kt")
|
||||||
|
public void testMultipleImportAlias2() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/multipleImportAlias2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nestedClass.kt")
|
@TestMetadata("nestedClass.kt")
|
||||||
public void testNestedClass() throws Exception {
|
public void testNestedClass() throws Exception {
|
||||||
@@ -490,6 +532,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/shortenAlreadyImportedFunction4.kt");
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/shortenAlreadyImportedFunction4.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("starImport.kt")
|
||||||
|
public void testStarImport() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/starImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("staticMethodFromBaseClassConflict.kt")
|
@TestMetadata("staticMethodFromBaseClassConflict.kt")
|
||||||
public void testStaticMethodFromBaseClassConflict() throws Exception {
|
public void testStaticMethodFromBaseClassConflict() throws Exception {
|
||||||
|
|||||||
+1
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.test.services.assertions
|
|||||||
* Note that it tests shortening only a single expression between <expr> and </expr> in the first file.
|
* Note that it tests shortening only a single expression between <expr> and </expr> in the first file.
|
||||||
*/
|
*/
|
||||||
abstract class AbstractReferenceShortenerTest : AbstractAnalysisApiBasedSingleModuleTest() {
|
abstract class AbstractReferenceShortenerTest : AbstractAnalysisApiBasedSingleModuleTest() {
|
||||||
|
|
||||||
override fun doTestByFileStructure(ktFiles: List<KtFile>, module: TestModule, testServices: TestServices) {
|
override fun doTestByFileStructure(ktFiles: List<KtFile>, module: TestModule, testServices: TestServices) {
|
||||||
val element = testServices.expressionMarkerProvider.getSelectedElementOfType<KtElement>(ktFiles.first())
|
val element = testServices.expressionMarkerProvider.getSelectedElementOfType<KtElement>(ktFiles.first())
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -14,14 +14,14 @@ internal object ShorteningResultsRenderer {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
shortening.typesToShorten.forEach { userType ->
|
shortening.listOfTypeToShortenInfo.forEach { (userType, shortenedRef) ->
|
||||||
userType.element?.text?.let {
|
userType.element?.text?.let {
|
||||||
appendLine("[type] $it")
|
appendLine("[type] $it${shortenedRef?.let { ref -> " -> $ref" } ?: ""}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
shortening.qualifiersToShorten.forEach { qualifier ->
|
shortening.listOfQualifierToShortenInfo.forEach { (qualifier, shortenedRef) ->
|
||||||
qualifier.element?.text?.let {
|
qualifier.element?.text?.let {
|
||||||
appendLine("[qualifier] $it")
|
appendLine("[qualifier] $it${shortenedRef?.let { ref -> " -> $ref" } ?: ""}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
shortening.kDocQualifiersToShorten.forEach { kdoc ->
|
shortening.kDocQualifiersToShorten.forEach { kdoc ->
|
||||||
|
|||||||
+48
@@ -274,6 +274,36 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/functionalType_parameterPosition.kt");
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/functionalType_parameterPosition.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("importAliasAndStarImport.kt")
|
||||||
|
public void testImportAliasAndStarImport() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/importAliasAndStarImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("importAliasForFunction.kt")
|
||||||
|
public void testImportAliasForFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/importAliasForFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("importAliasForProperty.kt")
|
||||||
|
public void testImportAliasForProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/importAliasForProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("importAliasForType.kt")
|
||||||
|
public void testImportAliasForType() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/importAliasForType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("importAliasForTypeQualifier.kt")
|
||||||
|
public void testImportAliasForTypeQualifier() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/importAliasForTypeQualifier.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kdoc.kt")
|
@TestMetadata("kdoc.kt")
|
||||||
public void testKdoc() throws Exception {
|
public void testKdoc() throws Exception {
|
||||||
@@ -310,6 +340,18 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/multipleImport.kt");
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/multipleImport.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("multipleImportAlias.kt")
|
||||||
|
public void testMultipleImportAlias() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/multipleImportAlias.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("multipleImportAlias2.kt")
|
||||||
|
public void testMultipleImportAlias2() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/multipleImportAlias2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nestedClass.kt")
|
@TestMetadata("nestedClass.kt")
|
||||||
public void testNestedClass() throws Exception {
|
public void testNestedClass() throws Exception {
|
||||||
@@ -490,6 +532,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/shortenAlreadyImportedFunction4.kt");
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/shortenAlreadyImportedFunction4.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("starImport.kt")
|
||||||
|
public void testStarImport() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/starImport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("staticMethodFromBaseClassConflict.kt")
|
@TestMetadata("staticMethodFromBaseClassConflict.kt")
|
||||||
public void testStaticMethodFromBaseClassConflict() throws Exception {
|
public void testStaticMethodFromBaseClassConflict() throws Exception {
|
||||||
|
|||||||
+30
-3
@@ -152,14 +152,41 @@ public interface KtReferenceShortenerMixIn : KtAnalysisSessionMixIn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to keep a [KtUserType] to shorten and what shape the shortened result has to be. [shortenedReference] is the expected result of
|
||||||
|
* shortening in a string form. If [shortenedReference] is null, it means the shortening will simply delete the qualifier. Note that
|
||||||
|
* currently the only usage of [shortenedReference] is the case we have the import-alias. For example, [shortenedReference] will be
|
||||||
|
* "AliasType" when we shorten:
|
||||||
|
* ```
|
||||||
|
* import my.package.NewType as AliasType
|
||||||
|
* ... my.package.Ne<caret>wType ... // -> we can replace this with `AliasType`.
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public data class TypeToShortenInfo(val typeToShorten: SmartPsiElementPointer<KtUserType>, val shortenedReference: String?)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to keep a [KtDotQualifiedExpression] to shorten and what shape the shortened result has to be. [shortenedReference] is the
|
||||||
|
* expected result of shortening in a string form. If [shortenedReference] is null, it means the shortening will simply delete the
|
||||||
|
* qualifier. Note that currently the only usage of [shortenedReference] is the case we have the import-alias. For example,
|
||||||
|
* [shortenedReference] will be "bar" when we shorten:
|
||||||
|
* ```
|
||||||
|
* import my.package.foo as bar
|
||||||
|
* ... my.package.fo<caret>o ... // -> we can replace this with `bar`.
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public data class QualifierToShortenInfo(
|
||||||
|
val qualifierToShorten: SmartPsiElementPointer<KtDotQualifiedExpression>,
|
||||||
|
val shortenedReference: String?,
|
||||||
|
)
|
||||||
|
|
||||||
public interface ShortenCommand {
|
public interface ShortenCommand {
|
||||||
public val targetFile: SmartPsiElementPointer<KtFile>
|
public val targetFile: SmartPsiElementPointer<KtFile>
|
||||||
public val importsToAdd: Set<FqName>
|
public val importsToAdd: Set<FqName>
|
||||||
public val starImportsToAdd: Set<FqName>
|
public val starImportsToAdd: Set<FqName>
|
||||||
public val typesToShorten: List<SmartPsiElementPointer<KtUserType>>
|
public val listOfTypeToShortenInfo: List<TypeToShortenInfo>
|
||||||
public val qualifiersToShorten: List<SmartPsiElementPointer<KtDotQualifiedExpression>>
|
public val listOfQualifierToShortenInfo: List<QualifierToShortenInfo>
|
||||||
public val kDocQualifiersToShorten: List<SmartPsiElementPointer<KDocName>>
|
public val kDocQualifiersToShorten: List<SmartPsiElementPointer<KDocName>>
|
||||||
|
|
||||||
public val isEmpty: Boolean
|
public val isEmpty: Boolean
|
||||||
get() = typesToShorten.isEmpty() && qualifiersToShorten.isEmpty() && kDocQualifiersToShorten.isEmpty()
|
get() = listOfTypeToShortenInfo.isEmpty() && listOfQualifierToShortenInfo.isEmpty() && kDocQualifiersToShorten.isEmpty()
|
||||||
}
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// FILE: main.kt
|
||||||
|
package test
|
||||||
|
|
||||||
|
import com.dependency.bar as bar1
|
||||||
|
import com.dependency.*
|
||||||
|
|
||||||
|
fun foo() = <expr>com.dependency.bar</expr>
|
||||||
|
|
||||||
|
// FILE: dependency.kt
|
||||||
|
package com.dependency
|
||||||
|
|
||||||
|
val bar = 3
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
Before shortening: com.dependency.bar
|
||||||
|
with DO_NOT_SHORTEN:
|
||||||
|
with SHORTEN_IF_ALREADY_IMPORTED:
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
|
with SHORTEN_AND_IMPORT:
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
|
with SHORTEN_AND_STAR_IMPORT:
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// FILE: main.kt
|
||||||
|
package test
|
||||||
|
|
||||||
|
import com.dependency.bar as bar1
|
||||||
|
|
||||||
|
fun foo() = <expr>com.dependency.bar()</expr>
|
||||||
|
|
||||||
|
// FILE: dependency.kt
|
||||||
|
package com.dependency
|
||||||
|
|
||||||
|
fun bar() = 3
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
Before shortening: com.dependency.bar()
|
||||||
|
with DO_NOT_SHORTEN:
|
||||||
|
with SHORTEN_IF_ALREADY_IMPORTED:
|
||||||
|
[qualifier] com.dependency.bar() -> bar1
|
||||||
|
with SHORTEN_AND_IMPORT:
|
||||||
|
[qualifier] com.dependency.bar() -> bar1
|
||||||
|
with SHORTEN_AND_STAR_IMPORT:
|
||||||
|
[qualifier] com.dependency.bar() -> bar1
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// FILE: main.kt
|
||||||
|
package test
|
||||||
|
|
||||||
|
import com.dependency.bar as bar1
|
||||||
|
|
||||||
|
fun foo() = <expr>com.dependency.bar</expr>
|
||||||
|
|
||||||
|
// FILE: dependency.kt
|
||||||
|
package com.dependency
|
||||||
|
|
||||||
|
val bar = 3
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
Before shortening: com.dependency.bar
|
||||||
|
with DO_NOT_SHORTEN:
|
||||||
|
with SHORTEN_IF_ALREADY_IMPORTED:
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
|
with SHORTEN_AND_IMPORT:
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
|
with SHORTEN_AND_STAR_IMPORT:
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// FILE: main.kt
|
||||||
|
package test
|
||||||
|
|
||||||
|
import com.dependency.Bar as Bar1
|
||||||
|
|
||||||
|
fun foo(): <expr>com.dependency.Bar</expr> = Bar1()
|
||||||
|
|
||||||
|
// FILE: dependency.kt
|
||||||
|
package com.dependency
|
||||||
|
|
||||||
|
class Bar
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
Before shortening: com.dependency.Bar
|
||||||
|
with DO_NOT_SHORTEN:
|
||||||
|
with SHORTEN_IF_ALREADY_IMPORTED:
|
||||||
|
[type] com.dependency.Bar -> Bar1
|
||||||
|
with SHORTEN_AND_IMPORT:
|
||||||
|
[type] com.dependency.Bar -> Bar1
|
||||||
|
with SHORTEN_AND_STAR_IMPORT:
|
||||||
|
[type] com.dependency.Bar -> Bar1
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// FILE: main.kt
|
||||||
|
package test
|
||||||
|
|
||||||
|
import com.dependency.Bar as Bar1
|
||||||
|
|
||||||
|
fun foo() = <expr>com.dependency.Bar.bar()</expr>
|
||||||
|
|
||||||
|
// FILE: dependency.kt
|
||||||
|
package com.dependency
|
||||||
|
|
||||||
|
class Bar {
|
||||||
|
companion object
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Bar.bar(): Bar {
|
||||||
|
return this
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
Before shortening: com.dependency.Bar.bar()
|
||||||
|
with DO_NOT_SHORTEN:
|
||||||
|
with SHORTEN_IF_ALREADY_IMPORTED:
|
||||||
|
[qualifier] com.dependency.Bar -> Bar1
|
||||||
|
with SHORTEN_AND_IMPORT:
|
||||||
|
[qualifier] com.dependency.Bar -> Bar1
|
||||||
|
with SHORTEN_AND_STAR_IMPORT:
|
||||||
|
[qualifier] com.dependency.Bar -> Bar1
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
// FILE: main.kt
|
||||||
|
package test
|
||||||
|
|
||||||
|
import com.dependency.*
|
||||||
|
import com.dependency.bar as bar1
|
||||||
|
import com.dependency.bar as bar2
|
||||||
|
import com.dependency.bar as bar3
|
||||||
|
import com.dependency.bar
|
||||||
|
|
||||||
|
fun foo(a: Int) = <expr>when (a) {
|
||||||
|
1 -> bar1
|
||||||
|
2 -> bar2
|
||||||
|
3 -> bar3
|
||||||
|
else -> com.dependency.bar
|
||||||
|
}</expr>
|
||||||
|
|
||||||
|
// FILE: dependency.kt
|
||||||
|
package com.dependency
|
||||||
|
|
||||||
|
val bar = 3
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
Before shortening: when (a) {
|
||||||
|
1 -> bar1
|
||||||
|
2 -> bar2
|
||||||
|
3 -> bar3
|
||||||
|
else -> com.dependency.bar
|
||||||
|
}
|
||||||
|
with DO_NOT_SHORTEN:
|
||||||
|
with SHORTEN_IF_ALREADY_IMPORTED:
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
|
with SHORTEN_AND_IMPORT:
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
|
with SHORTEN_AND_STAR_IMPORT:
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// FILE: main.kt
|
||||||
|
package test
|
||||||
|
|
||||||
|
import com.dependency.bar as bar1
|
||||||
|
import com.dependency.bar as bar2
|
||||||
|
import com.dependency.bar as bar3
|
||||||
|
|
||||||
|
fun foo(a: Int) = <expr>when (a) {
|
||||||
|
1 -> bar1
|
||||||
|
2 -> com.dependency.bar
|
||||||
|
3 -> bar3
|
||||||
|
else -> com.dependency.bar
|
||||||
|
}</expr>
|
||||||
|
|
||||||
|
// FILE: dependency.kt
|
||||||
|
package com.dependency
|
||||||
|
|
||||||
|
val bar = 3
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
Before shortening: when (a) {
|
||||||
|
1 -> bar1
|
||||||
|
2 -> com.dependency.bar
|
||||||
|
3 -> bar3
|
||||||
|
else -> com.dependency.bar
|
||||||
|
}
|
||||||
|
with DO_NOT_SHORTEN:
|
||||||
|
with SHORTEN_IF_ALREADY_IMPORTED:
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
|
with SHORTEN_AND_IMPORT:
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
|
with SHORTEN_AND_STAR_IMPORT:
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
|
[qualifier] com.dependency.bar -> bar1
|
||||||
Vendored
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// FILE: main.kt
|
||||||
|
package test
|
||||||
|
|
||||||
|
import com.dependency.*
|
||||||
|
|
||||||
|
fun foo() = <expr>com.dependency.bar()</expr>
|
||||||
|
|
||||||
|
// FILE: dependency.kt
|
||||||
|
package com.dependency
|
||||||
|
|
||||||
|
fun bar() = 3
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
Before shortening: com.dependency.bar()
|
||||||
|
with DO_NOT_SHORTEN:
|
||||||
|
with SHORTEN_IF_ALREADY_IMPORTED:
|
||||||
|
[qualifier] com.dependency.bar()
|
||||||
|
with SHORTEN_AND_IMPORT:
|
||||||
|
[qualifier] com.dependency.bar()
|
||||||
|
with SHORTEN_AND_STAR_IMPORT:
|
||||||
|
[qualifier] com.dependency.bar()
|
||||||
+1
-4
@@ -52,10 +52,7 @@ import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typePro
|
|||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeProvider.AbstractHasCommonSubtypeTest
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeProvider.AbstractHasCommonSubtypeTest
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeProvider.AbstractTypeReferenceTest
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeProvider.AbstractTypeReferenceTest
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractReferenceImportAliasTest
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractReferenceImportAliasTest
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractReferenceResolveTest
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.*
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractReferenceResolveWithResolveExtensionTest
|
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractReferenceShortenerForWholeFileTest
|
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractReferenceShortenerTest
|
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.*
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.*
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.types.AbstractAnalysisApiSubstitutorsTest
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.types.AbstractAnalysisApiSubstitutorsTest
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.types.AbstractBuiltInTypeTest
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.types.AbstractBuiltInTypeTest
|
||||||
|
|||||||
Reference in New Issue
Block a user