Refactor KotlinShortenReferencesRefactringHelper
Rename refactoring helper and its infrastructure Add support for different request types
This commit is contained in:
+28
-24
@@ -31,50 +31,54 @@ import org.jetbrains.kotlin.psi.CopyableUserDataProperty
|
||||
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
|
||||
import java.util.*
|
||||
|
||||
class ShorteningRequest(val pointer: SmartPsiElementPointer<KtElement>, val options: Options)
|
||||
interface DelayedRefactoringRequest
|
||||
|
||||
private var Project.elementsToShorten: MutableSet<ShorteningRequest>?
|
||||
by UserDataProperty(Key.create("ELEMENTS_TO_SHORTEN_KEY"))
|
||||
class ShorteningRequest(val pointer: SmartPsiElementPointer<KtElement>, val options: Options) : DelayedRefactoringRequest
|
||||
|
||||
private var Project.delayedRefactoringRequests: MutableSet<DelayedRefactoringRequest>?
|
||||
by UserDataProperty(Key.create("DELAYED_REFACTORING_REQUESTS"))
|
||||
|
||||
/*
|
||||
* When one refactoring invokes another this value must be set to false so that shortening wait-set is not cleared
|
||||
* and previously collected references are processed correctly. Afterwards it must be reset to original value
|
||||
*/
|
||||
var Project.ensureElementsToShortenIsEmptyBeforeRefactoring: Boolean
|
||||
by NotNullableUserDataProperty(Key.create("ENSURE_ELEMENTS_TO_SHORTEN_IS_EMPTY"), true)
|
||||
var Project.ensureNoRefactoringRequestsBeforeRefactoring: Boolean
|
||||
by NotNullableUserDataProperty(Key.create("ENSURE_NO_REFACTORING_REQUESTS_BEFORE_REFACTORING"), true)
|
||||
|
||||
fun Project.runWithElementsToShortenIsEmptyIgnored(action: () -> Unit) {
|
||||
val ensureElementsToShortenIsEmpty = ensureElementsToShortenIsEmptyBeforeRefactoring
|
||||
fun Project.runRefactoringAndKeepDelayedRequests(action: () -> Unit) {
|
||||
val ensureNoRefactoringRequests = ensureNoRefactoringRequestsBeforeRefactoring
|
||||
|
||||
try {
|
||||
ensureElementsToShortenIsEmptyBeforeRefactoring = false
|
||||
ensureNoRefactoringRequestsBeforeRefactoring = false
|
||||
action()
|
||||
} finally {
|
||||
ensureElementsToShortenIsEmptyBeforeRefactoring = ensureElementsToShortenIsEmpty
|
||||
ensureNoRefactoringRequestsBeforeRefactoring = ensureNoRefactoringRequests
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.getOrCreateElementsToShorten(): MutableSet<ShorteningRequest> {
|
||||
var elements = elementsToShorten
|
||||
if (elements == null) {
|
||||
elements = LinkedHashSet()
|
||||
elementsToShorten = elements
|
||||
private fun Project.getOrCreateRefactoringRequests(): MutableSet<DelayedRefactoringRequest> {
|
||||
var requests = delayedRefactoringRequests
|
||||
if (requests == null) {
|
||||
requests = LinkedHashSet()
|
||||
delayedRefactoringRequests = requests
|
||||
}
|
||||
|
||||
return elements
|
||||
return requests
|
||||
}
|
||||
|
||||
fun KtElement.addToShorteningWaitSet(options: Options = Options.DEFAULT) {
|
||||
assert(ApplicationManager.getApplication()!!.isWriteAccessAllowed) { "Write access needed" }
|
||||
val project = project
|
||||
val elementPointer = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(this)
|
||||
project.getOrCreateElementsToShorten().add(ShorteningRequest(elementPointer, options))
|
||||
project.getOrCreateRefactoringRequests().add(ShorteningRequest(elementPointer, options))
|
||||
}
|
||||
|
||||
fun performDelayedShortening(project: Project) {
|
||||
project.elementsToShorten?.let { requests ->
|
||||
project.elementsToShorten = null
|
||||
val elementToOptions = requests.mapNotNull { req -> req.pointer.element?.let { it to req.options } }.toMap()
|
||||
fun performDelayedRefactoringRequests(project: Project) {
|
||||
project.delayedRefactoringRequests?.let { requests ->
|
||||
project.delayedRefactoringRequests = null
|
||||
|
||||
val shorteningRequests = requests.filterIsInstance<ShorteningRequest>()
|
||||
val elementToOptions = shorteningRequests.mapNotNull { req -> req.pointer.element?.let { it to req.options } }.toMap()
|
||||
val elements = elementToOptions.keys
|
||||
//TODO: this is not correct because it should not shorten deep into the elements!
|
||||
ShortenReferences({ elementToOptions[it] ?: Options.DEFAULT }).process(elements)
|
||||
@@ -83,11 +87,11 @@ fun performDelayedShortening(project: Project) {
|
||||
|
||||
private val LOG = Logger.getInstance(Project::class.java.canonicalName)
|
||||
|
||||
fun prepareElementsToShorten(project: Project) {
|
||||
val elementsToShorten = project.elementsToShorten
|
||||
if (project.ensureElementsToShortenIsEmptyBeforeRefactoring && elementsToShorten != null && !elementsToShorten.isEmpty()) {
|
||||
fun prepareDelayedRequests(project: Project) {
|
||||
val requests = project.delayedRefactoringRequests
|
||||
if (project.ensureNoRefactoringRequestsBeforeRefactoring && requests != null && !requests.isEmpty()) {
|
||||
LOG.warn("Waiting set for reference shortening is not empty")
|
||||
project.elementsToShorten = null
|
||||
project.delayedRefactoringRequests = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,7 +357,7 @@
|
||||
implementationClass="org.jetbrains.kotlin.idea.codeInsight.surroundWith.statement.KotlinStatementSurroundDescriptor"/>
|
||||
<lang.unwrapDescriptor language="kotlin" implementationClass="org.jetbrains.kotlin.idea.codeInsight.unwrap.KotlinUnwrapDescriptor"/>
|
||||
<quoteHandler fileType="Kotlin" className="org.jetbrains.kotlin.idea.editor.KotlinQuoteHandler"/>
|
||||
<refactoring.helper implementation="org.jetbrains.kotlin.idea.codeInsight.KotlinShortenReferencesRefactoringHelper"/>
|
||||
<refactoring.helper implementation="org.jetbrains.kotlin.idea.codeInsight.KotlinRefactoringHelperForDelayedRequests"/>
|
||||
<refactoring.helper implementation="org.jetbrains.kotlin.idea.codeInsight.KotlinOptimizeImportsRefactoringHelper"/>
|
||||
<refactoring.moveHandler
|
||||
id="kotlin.moveFilesOrDirectories"
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedShortening
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedRefactoringRequests
|
||||
import org.jetbrains.kotlin.idea.conversion.copy.end
|
||||
import org.jetbrains.kotlin.idea.conversion.copy.range
|
||||
import org.jetbrains.kotlin.idea.conversion.copy.start
|
||||
@@ -334,7 +334,7 @@ class KotlinCopyPasteReferenceProcessor : CopyPastePostProcessor<KotlinReference
|
||||
val reference = pointer.element!!.mainReference
|
||||
reference.bindToFqName(fqName, KtSimpleNameReference.ShorteningMode.DELAYED_SHORTENING)
|
||||
}
|
||||
performDelayedShortening(file.project)
|
||||
performDelayedRefactoringRequests(file.project)
|
||||
}
|
||||
|
||||
private fun KotlinReferenceData.Kind.isExtension()
|
||||
|
||||
+3
-3
@@ -24,16 +24,16 @@ import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.*
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
|
||||
class KotlinShortenReferencesRefactoringHelper: RefactoringHelper<Any> {
|
||||
class KotlinRefactoringHelperForDelayedRequests : RefactoringHelper<Any> {
|
||||
override fun prepareOperation(usages: Array<out UsageInfo>?): Any? {
|
||||
if (usages != null && usages.isNotEmpty()) {
|
||||
val project = usages[0].project
|
||||
prepareElementsToShorten(project)
|
||||
prepareDelayedRequests(project)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun performOperation(project: Project, operationData: Any?) {
|
||||
runWriteAction { performDelayedShortening(project) }
|
||||
runWriteAction { performDelayedRefactoringRequests(project) }
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.runWithElementsToShortenIsEmptyIgnored
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.runRefactoringAndKeepDelayedRequests
|
||||
import org.jetbrains.kotlin.idea.core.CollectingNameValidator
|
||||
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||
import org.jetbrains.kotlin.idea.core.appendElement
|
||||
@@ -201,7 +201,7 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() {
|
||||
}
|
||||
}
|
||||
|
||||
project.runWithElementsToShortenIsEmptyIgnored {
|
||||
project.runRefactoringAndKeepDelayedRequests {
|
||||
processConstructors(project, propertyDescriptor, constructorDescriptors.iterator())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedShortening
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedRefactoringRequests
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.idea.refactoring.addTypeArgumentsIfNeeded
|
||||
@@ -212,7 +212,7 @@ class KotlinInlineValHandler : InlineActionHandler() {
|
||||
highlightElements(project, editor, inlinedExpressions)
|
||||
}
|
||||
}
|
||||
performDelayedShortening(project)
|
||||
performDelayedRefactoringRequests(project)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedShortening
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedRefactoringRequests
|
||||
import org.jetbrains.kotlin.idea.core.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.insertDeclaration
|
||||
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo
|
||||
@@ -320,7 +320,7 @@ class ExtractSuperRefactoring(
|
||||
extractInfo.docPolicy
|
||||
).moveMembersToBase()
|
||||
|
||||
performDelayedShortening(project)
|
||||
performDelayedRefactoringRequests(project)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiDirectory
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.runWithElementsToShortenIsEmptyIgnored
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.runRefactoringAndKeepDelayedRequests
|
||||
import org.jetbrains.kotlin.idea.refactoring.move.ContainerChangeInfo
|
||||
import org.jetbrains.kotlin.idea.refactoring.move.ContainerInfo
|
||||
import org.jetbrains.kotlin.idea.refactoring.move.getInternalReferencesToUpdateOnPackageNameChange
|
||||
@@ -69,7 +69,7 @@ class KotlinChangePackageRefactoring(val file: KtFile) {
|
||||
project.executeWriteCommand("Change file's package to '${newFqName.asString()}'") {
|
||||
packageDirective.fqName = newFqName.quoteIfNeeded()
|
||||
postProcessMoveUsages(internalUsages)
|
||||
project.runWithElementsToShortenIsEmptyIgnored { declarationProcessor.execute(declarationUsages) }
|
||||
project.runRefactoringAndKeepDelayedRequests { declarationProcessor.execute(declarationUsages) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.runWithElementsToShortenIsEmptyIgnored
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.runRefactoringAndKeepDelayedRequests
|
||||
import org.jetbrains.kotlin.idea.core.getPackage
|
||||
import org.jetbrains.kotlin.idea.core.packageMatchesDirectory
|
||||
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
|
||||
@@ -145,7 +145,7 @@ class MoveKotlinFileHandler : MoveFileHandler() {
|
||||
|
||||
fun retargetUsages(usageInfos: List<UsageInfo>?, moveDeclarationsProcessor: MoveKotlinDeclarationsProcessor) {
|
||||
postProcessMoveUsages(usageInfos?.firstIsInstanceOrNull<InternalUsagesWrapper>()?.usages ?: emptyList())
|
||||
moveDeclarationsProcessor.project.runWithElementsToShortenIsEmptyIgnored {
|
||||
moveDeclarationsProcessor.project.runRefactoringAndKeepDelayedRequests {
|
||||
usageInfos?.let { moveDeclarationsProcessor.execute(it) }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user