[Analysis API] move ShortenCommand.invokeShortening to the IDE repository

as Analysis API should not modify the code

^KT-58992 fixed
This commit is contained in:
Ilya Kirillov
2023-05-31 11:27:16 +02:00
committed by Space Team
parent 95cf892eec
commit d9cb7b67d4
4 changed files with 1 additions and 135 deletions
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtUserType
@@ -46,8 +45,6 @@ internal class KtFe10ReferenceShortener(
override val qualifiersToShorten: List<SmartPsiElementPointer<KtDotQualifiedExpression>> get() = emptyList()
override val isEmpty: Boolean get() = true
override fun invokeShortening(): List<KtElement> = emptyList()
}
}
}
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.analysis.api.components.ShortenCommand
import org.jetbrains.kotlin.analysis.api.components.ShortenOption
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.utils.addImportToFile
import org.jetbrains.kotlin.analysis.api.fir.utils.computeImportableName
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
@@ -1065,37 +1064,7 @@ private class ShortenCommandImpl(
override val starImportsToAdd: List<FqName>,
override val typesToShorten: List<SmartPsiElementPointer<KtUserType>>,
override val qualifiersToShorten: List<SmartPsiElementPointer<KtDotQualifiedExpression>>,
) : ShortenCommand {
override fun invokeShortening(): List<KtElement> {
// if the file has been invalidated, there's nothing we can shorten
val targetFile = targetFile.element ?: return emptyList()
for (nameToImport in importsToAdd) {
addImportToFile(targetFile.project, targetFile, nameToImport)
}
for (nameToImport in starImportsToAdd) {
addImportToFile(targetFile.project, targetFile, nameToImport, allUnder = true)
}
val shorteningResults = mutableListOf<KtElement>()
//todo
// PostprocessReformattingAspect.getInstance(targetFile.project).disablePostprocessFormattingInside {
for (typePointer in typesToShorten) {
val type = typePointer.element ?: continue
type.deleteQualifier()
shorteningResults.add(type)
}
for (callPointer in qualifiersToShorten) {
val call = callPointer.element ?: continue
call.deleteQualifier()?.let { shorteningResults.add(it) }
}
// }
return shorteningResults
}
}
) : ShortenCommand
private fun KtUserType.hasFakeRootPrefix(): Boolean =
qualifier?.referencedName == ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE
@@ -1106,11 +1075,6 @@ private fun KtDotQualifiedExpression.hasFakeRootPrefix(): Boolean =
internal fun KtElement.getDotQualifiedExpressionForSelector(): KtDotQualifiedExpression? =
getQualifiedExpressionForSelector() as? KtDotQualifiedExpression
private fun KtDotQualifiedExpression.deleteQualifier(): KtExpression? {
val selectorExpression = selectorExpression ?: return null
return this.replace(selectorExpression) as KtExpression
}
private fun KtElement.getQualifier(): KtElement? = when (this) {
is KtUserType -> qualifier
is KtDotQualifiedExpression -> receiverExpression
@@ -1,93 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.api.fir.utils
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.resolve.ImportPath
private val SimpleImportPathComparator: Comparator<ImportPath> = compareBy(ImportPath::toString)
fun addImportToFile(
project: Project,
file: KtFile,
callableId: CallableId,
allUnder: Boolean = false,
alias: Name? = null
) {
addImportToFile(project, file, callableId.asSingleFqName(), allUnder, alias)
}
/**
* This is a partial copy from `org.jetbrains.kotlin.idea.util.ImportInsertHelperImpl.Companion.addImport`.
*
* We want it as a copy because we do not yet care about imports ordering, so we do not need a fancy comparator.
*/
fun addImportToFile(
project: Project,
file: KtFile,
fqName: FqName,
allUnder: Boolean = false,
alias: Name? = null
) {
val importPath = ImportPath(fqName, allUnder, alias)
// Already imported.
if (file.importDirectives.any { it.importPath == importPath && it.alias?.name == alias?.identifierOrNullIfSpecial }) return
val psiFactory = KtPsiFactory(project)
if (file is KtCodeFragment) {
val newDirective = psiFactory.createImportDirective(importPath)
file.addImportsFromString(newDirective.text)
return
}
if (allUnder) {
file.importDirectives.filter { it.alias == null && it.importPath?.fqName?.parent() == fqName }.forEach { it.delete() }
}
val importList = file.importList
?: error("Trying to insert import $fqName into a file ${file.name} of type ${file::class.java} with no import list.")
val newDirective = psiFactory.createImportDirective(importPath)
val imports = importList.imports
if (imports.isEmpty()) {
val packageDirective = file.packageDirective?.takeIf { it.packageKeyword != null }
packageDirective?.let {
file.addAfter(psiFactory.createNewLine(2), it)
}
importList.add(newDirective)
if (packageDirective == null) {
val whiteSpace = importList.nextSibling
if (whiteSpace is PsiWhiteSpace) {
val newLineBreak = if (whiteSpace.textContains('\n')) {
psiFactory.createWhiteSpace("\n" + whiteSpace.text)
} else {
psiFactory.createWhiteSpace("\n\n" + whiteSpace.text)
}
whiteSpace.replace(newLineBreak)
} else {
file.addAfter(psiFactory.createNewLine(2), importList)
}
}
} else {
val insertAfter = imports.lastOrNull {
val directivePath = it.importPath
directivePath != null && SimpleImportPathComparator.compare(directivePath, importPath) <= 0
}
importList.addAfter(newDirective, insertAfter).also {
importList.addBefore(psiFactory.createNewLine(1), it)
}
}
}
@@ -127,6 +127,4 @@ public interface ShortenCommand {
public val isEmpty: Boolean
get() = typesToShorten.isEmpty() && qualifiersToShorten.isEmpty()
public fun invokeShortening(): List<KtElement>
}