From f4e8242a2278bcc708f58d634b4e3bb35f9b7f7a Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 1 Nov 2016 15:47:53 +0300 Subject: [PATCH] Convert Property to Function Intention: Search occurrences using progress dialog #KT-14569 Fixed --- ChangeLog.md | 8 ++ .../ConvertPropertyToFunctionIntention.kt | 119 +++++++++--------- 2 files changed, 69 insertions(+), 58 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 6828ee171f0..60fd4ec0b85 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -216,6 +216,14 @@ These artifacts include extensions for the types available in the latter JDKs, s + [`KT-12389`](https://youtrack.jetbrains.com/issue/KT-12389) Do not exit from REPL when toString() of user class throws an exception + [`KT-12129`](https://youtrack.jetbrains.com/issue/KT-12129) Fixed link on api reference page in KDoc +## 1.0.6 + +### IDE + +#### Intention actions, inspections and quickfixes + +- [`KT-14569`](https://youtrack.jetbrains.com/issue/KT-14569) Convert Property to Function Intention: Search occurrences using progress dialog + ## 1.0.5 ### IDE diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyToFunctionIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyToFunctionIntention.kt index d30f6256528..cf532958ee3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyToFunctionIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyToFunctionIntention.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.codeInsight.intention.LowPriorityAction import com.intellij.openapi.editor.Editor +import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.Project import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.* @@ -28,11 +29,7 @@ import org.jetbrains.kotlin.asJava.namedUnwrappedElement import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde -import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively -import org.jetbrains.kotlin.idea.refactoring.reportDeclarationConflict -import org.jetbrains.kotlin.idea.refactoring.CallableRefactoring -import org.jetbrains.kotlin.idea.refactoring.getAffectedCallables -import org.jetbrains.kotlin.idea.refactoring.getContainingScope +import org.jetbrains.kotlin.idea.refactoring.* import org.jetbrains.kotlin.idea.references.KtReference import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.idea.util.application.executeWriteCommand @@ -93,66 +90,72 @@ class ConvertPropertyToFunctionIntention : SelfTargetingIntention(Kt val kotlinRefsToReplaceWithCall = ArrayList() val refsToRename = ArrayList() val javaRefsToReplaceWithCall = ArrayList() - for (callable in callables) { - if (callable !is PsiNamedElement) continue - if (!checkModifiable(callable)) { - val renderedCallable = RefactoringUIUtil.getDescription(callable, true).capitalize() - conflicts.putValue(callable, "Can't modify $renderedCallable") - } + project.runSynchronouslyWithProgress("Looking for usages and conflicts...", true) { + val progressStep = 1.0/callables.size + for ((i, callable) in callables.withIndex()) { + ProgressManager.getInstance().progressIndicator.fraction = (i + 1)*progressStep - if (callable is KtProperty) { - callableDescriptor.getContainingScope() - ?.findFunction(callableDescriptor.name, NoLookupLocation.FROM_IDE) { it.valueParameters.isEmpty() } - ?.let { DescriptorToSourceUtilsIde.getAnyDeclaration(project, it) } - ?.let { reportDeclarationConflict(conflicts, it) { "$it already exists" } } - } - else if (callable is PsiMethod) { - callable.containingClass - ?.findMethodsByName(propertyName, true) - // as is necessary here: see KT-10386 - ?.firstOrNull { it.parameterList.parametersCount == 0 && !callables.contains(it.namedUnwrappedElement as PsiElement?) } - ?.let { reportDeclarationConflict(conflicts, it) { "$it already exists" } } - } + if (callable !is PsiNamedElement) continue - val usages = ReferencesSearch.search(callable) - for (usage in usages) { - if (usage is KtReference) { - if (usage is KtSimpleNameReference) { - val expression = usage.expression - if (expression.getCall(expression.analyze(BodyResolveMode.PARTIAL)) != null - && expression.getStrictParentOfType() == null) { - kotlinRefsToReplaceWithCall.add(expression) - } - else if (nameChanged) { - refsToRename.add(usage) - } - } - else { - val refElement = usage.element - conflicts.putValue( - refElement, - "Unrecognized reference will be skipped: " + StringUtil.htmlEmphasize(refElement.text) - ) - } - continue + if (!checkModifiable(callable)) { + val renderedCallable = RefactoringUIUtil.getDescription(callable, true).capitalize() + conflicts.putValue(callable, "Can't modify $renderedCallable") } - val refElement = usage.element - - if (refElement.text.endsWith(getterName)) continue - - if (usage is PsiJavaReference) { - if (usage.resolve() is PsiField && usage is PsiReferenceExpression) { - javaRefsToReplaceWithCall.add(usage) - } - continue + if (callable is KtProperty) { + callableDescriptor.getContainingScope() + ?.findFunction(callableDescriptor.name, NoLookupLocation.FROM_IDE) { it.valueParameters.isEmpty() } + ?.let { DescriptorToSourceUtilsIde.getAnyDeclaration(project, it) } + ?.let { reportDeclarationConflict(conflicts, it) { "$it already exists" } } + } + else if (callable is PsiMethod) { + callable.containingClass + ?.findMethodsByName(propertyName, true) + // as is necessary here: see KT-10386 + ?.firstOrNull { it.parameterList.parametersCount == 0 && !callables.contains(it.namedUnwrappedElement as PsiElement?) } + ?.let { reportDeclarationConflict(conflicts, it) { "$it already exists" } } } - conflicts.putValue( - refElement, - "Can't replace foreign reference with call expression: " + StringUtil.htmlEmphasize(refElement.text) - ) + val usages = ReferencesSearch.search(callable) + for (usage in usages) { + if (usage is KtReference) { + if (usage is KtSimpleNameReference) { + val expression = usage.expression + if (expression.getCall(expression.analyze(BodyResolveMode.PARTIAL)) != null + && expression.getStrictParentOfType() == null) { + kotlinRefsToReplaceWithCall.add(expression) + } + else if (nameChanged) { + refsToRename.add(usage) + } + } + else { + val refElement = usage.element + conflicts.putValue( + refElement, + "Unrecognized reference will be skipped: " + StringUtil.htmlEmphasize(refElement.text) + ) + } + continue + } + + val refElement = usage.element + + if (refElement.text.endsWith(getterName)) continue + + if (usage is PsiJavaReference) { + if (usage.resolve() is PsiField && usage is PsiReferenceExpression) { + javaRefsToReplaceWithCall.add(usage) + } + continue + } + + conflicts.putValue( + refElement, + "Can't replace foreign reference with call expression: " + StringUtil.htmlEmphasize(refElement.text) + ) + } } }