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