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.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<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()) {
@@ -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<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()
}
}