Inline Variable: Warn about non-Kotlin usages

#KT-8885 Fixed
This commit is contained in:
Alexey Sedunov
2015-12-04 18:18:33 +03:00
parent ffb382e3bc
commit b5fad71b18
@@ -33,10 +33,12 @@ import com.intellij.refactoring.HelpID
import com.intellij.refactoring.RefactoringBundle import com.intellij.refactoring.RefactoringBundle
import com.intellij.refactoring.util.CommonRefactoringUtil import com.intellij.refactoring.util.CommonRefactoringUtil
import com.intellij.refactoring.util.RefactoringMessageDialog import com.intellij.refactoring.util.RefactoringMessageDialog
import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.diagnostics.Errors 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.core.refactoring.checkConflictsInteractively
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
@@ -52,7 +54,9 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.sure import org.jetbrains.kotlin.utils.sure
import java.util.*
class KotlinInlineValHandler : InlineActionHandler() { class KotlinInlineValHandler : InlineActionHandler() {
override fun isEnabledForLanguage(l: Language) = l == KotlinLanguage.INSTANCE override fun isEnabledForLanguage(l: Language) = l == KotlinLanguage.INSTANCE
@@ -67,8 +71,16 @@ class KotlinInlineValHandler : InlineActionHandler() {
val file = declaration.getContainingKtFile() val file = declaration.getContainingKtFile()
val name = declaration.name ?: return val name = declaration.name ?: return
val referenceExpressions = ReferencesSearch.search(declaration).mapNotNull() { val references = ReferencesSearch.search(declaration)
(it.element as? KtExpression)?.getQualifiedExpressionForSelectorOrThis() val referenceExpressions = ArrayList<KtExpression>()
val foreignUsages = ArrayList<PsiElement>()
for (ref in references) {
val refElement = ref.element ?: continue
if (refElement !is KtElement) {
foreignUsages.add(refElement)
continue
}
referenceExpressions.addIfNotNull((refElement as? KtExpression)?.getQualifiedExpressionForSelectorOrThis())
} }
if (referenceExpressions.isEmpty()) { if (referenceExpressions.isEmpty()) {
@@ -108,6 +120,7 @@ class KotlinInlineValHandler : InlineActionHandler() {
highlightExpressions(project, editor, referenceExpressions) highlightExpressions(project, editor, referenceExpressions)
} }
fun performRefactoring() {
if (!showDialog(project, name, declaration, referenceExpressions)) { if (!showDialog(project, name, declaration, referenceExpressions)) {
if (canHighlight) { if (canHighlight) {
val statusBar = WindowManager.getInstance().getStatusBar(project) val statusBar = WindowManager.getInstance().getStatusBar(project)
@@ -137,6 +150,18 @@ class KotlinInlineValHandler : InlineActionHandler() {
} }
} }
if (foreignUsages.isNotEmpty()) {
val conflicts = MultiMap<PsiElement, String>().apply {
putValue(null, "Property '$name' has non-Kotlin usages. They won't be processed by the Inline refactoring.")
foreignUsages.forEach { putValue(it, it.text) }
}
project.checkConflictsInteractively(conflicts) { performRefactoring() }
}
else {
performRefactoring()
}
}
private fun reportAmbiguousAssignment(project: Project, editor: Editor, name: String, assignments: Set<PsiElement>) { private fun reportAmbiguousAssignment(project: Project, editor: Editor, name: String, assignments: Set<PsiElement>) {
val key = if (assignments.isEmpty()) "variable.has.no.initializer" else "variable.has.no.dominating.definition" val key = if (assignments.isEmpty()) "variable.has.no.initializer" else "variable.has.no.dominating.definition"
val message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message(key, name)) val message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message(key, name))