diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt index 9fd52b182b1..8f5742f7b19 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt @@ -33,10 +33,12 @@ import com.intellij.refactoring.HelpID import com.intellij.refactoring.RefactoringBundle import com.intellij.refactoring.util.CommonRefactoringUtil import com.intellij.refactoring.util.RefactoringMessageDialog +import com.intellij.util.containers.MultiMap 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.core.refactoring.checkConflictsInteractively import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.resolve.ResolutionFacade 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.types.ErrorUtils import org.jetbrains.kotlin.types.expressions.OperatorConventions +import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.sure +import java.util.* class KotlinInlineValHandler : InlineActionHandler() { override fun isEnabledForLanguage(l: Language) = l == KotlinLanguage.INSTANCE @@ -67,8 +71,16 @@ class KotlinInlineValHandler : InlineActionHandler() { val file = declaration.getContainingKtFile() val name = declaration.name ?: return - val referenceExpressions = ReferencesSearch.search(declaration).mapNotNull() { - (it.element as? KtExpression)?.getQualifiedExpressionForSelectorOrThis() + val references = ReferencesSearch.search(declaration) + val referenceExpressions = ArrayList() + val foreignUsages = ArrayList() + 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()) { @@ -108,32 +120,45 @@ class KotlinInlineValHandler : InlineActionHandler() { highlightExpressions(project, editor, referenceExpressions) } - if (!showDialog(project, name, declaration, referenceExpressions)) { - if (canHighlight) { - val statusBar = WindowManager.getInstance().getStatusBar(project) - statusBar?.info = RefactoringBundle.message("press.escape.to.remove.the.highlighting") + fun performRefactoring() { + if (!showDialog(project, name, declaration, referenceExpressions)) { + if (canHighlight) { + val statusBar = WindowManager.getInstance().getStatusBar(project) + statusBar?.info = RefactoringBundle.message("press.escape.to.remove.the.highlighting") + } + return + } + + project.executeWriteCommand(RefactoringBundle.message("inline.command", name)) { + val inlinedExpressions = referenceExpressions.mapNotNull { referenceExpression -> + if (assignments.contains(referenceExpression.parent)) return@mapNotNull null + referenceExpression.replaced(initializer) + } + + assignments.forEach { it.delete() } + declaration.delete() + + if (inlinedExpressions.isEmpty()) return@executeWriteCommand + + typeArgumentsForCall?.let { addTypeArguments(it, inlinedExpressions) } + + parametersForFunctionLiteral?.let { addFunctionLiteralParameterTypes(it, inlinedExpressions) } + + if (canHighlight) { + highlightExpressions(project, editor, inlinedExpressions) + } } - return } - project.executeWriteCommand(RefactoringBundle.message("inline.command", name)) { - val inlinedExpressions = referenceExpressions.mapNotNull { referenceExpression -> - if (assignments.contains(referenceExpression.parent)) return@mapNotNull null - referenceExpression.replaced(initializer) - } - - assignments.forEach { it.delete() } - declaration.delete() - - if (inlinedExpressions.isEmpty()) return@executeWriteCommand - - typeArgumentsForCall?.let { addTypeArguments(it, inlinedExpressions) } - - parametersForFunctionLiteral?.let { addFunctionLiteralParameterTypes(it, inlinedExpressions) } - - if (canHighlight) { - highlightExpressions(project, editor, inlinedExpressions) + if (foreignUsages.isNotEmpty()) { + val conflicts = MultiMap().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() } }