editor is nullable in SelfTargetingIntention.applyTo()

This commit is contained in:
Dmitry Jemerov
2016-01-11 19:45:56 +01:00
parent 9bfa90dc0e
commit 7390e0ac66
101 changed files with 179 additions and 155 deletions
@@ -25,8 +25,8 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.EditorFactory import com.intellij.openapi.editor.EditorFactory
import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiDocumentManager
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
@@ -118,13 +118,12 @@ abstract class IntentionBasedInspection<TElement : KtElement>(
assert(startElement == endElement) assert(startElement == endElement)
if (!isAvailable(project, file, startElement, endElement)) return if (!isAvailable(project, file, startElement, endElement)) return
startElement.getOrCreateEditor()?.let { editor -> val editor = startElement.findExistingEditor()
editor.caretModel.moveToOffset(startElement.textOffset) editor?.caretModel?.moveToOffset(startElement.textOffset)
intention.applyTo(startElement as TElement, editor) intention.applyTo(startElement as TElement, editor)
}
} }
private fun PsiElement.getOrCreateEditor(): Editor? { private fun PsiElement.findExistingEditor(): Editor? {
val file = containingFile?.virtualFile ?: return null val file = containingFile?.virtualFile ?: return null
val document = FileDocumentManager.getInstance().getDocument(file) ?: return null val document = FileDocumentManager.getInstance().getDocument(file) ?: return null
@@ -263,7 +263,7 @@ class OperatorToFunctionIntention : SelfTargetingIntention<KtExpression>(KtExpre
} }
} }
override fun applyTo(element: KtExpression, editor: Editor) { override fun applyTo(element: KtExpression, editor: Editor?) {
convert(element) convert(element)
} }
} }
@@ -51,7 +51,7 @@ abstract class SelfTargetingIntention<TElement : KtElement>(
abstract fun isApplicableTo(element: TElement, caretOffset: Int): Boolean abstract fun isApplicableTo(element: TElement, caretOffset: Int): Boolean
abstract fun applyTo(element: TElement, editor: Editor) abstract fun applyTo(element: TElement, editor: Editor?)
private fun getTarget(editor: Editor, file: PsiFile): TElement? { private fun getTarget(editor: Editor, file: PsiFile): TElement? {
val offset = editor.caretModel.offset val offset = editor.caretModel.offset
@@ -98,6 +98,12 @@ private fun moveCaretIntoGeneratedElementDocumentUnblocked(editor: Editor, eleme
return false return false
} }
fun Editor.unblockDocument() {
project?.let {
PsiDocumentManager.getInstance(it).doPostponedOperationsAndUnblockDocument(document)
}
}
fun Editor.moveCaret(offset: Int, scrollType: ScrollType = ScrollType.RELATIVE) { fun Editor.moveCaret(offset: Int, scrollType: ScrollType = ScrollType.RELATIVE) {
caretModel.moveToOffset(offset) caretModel.moveToOffset(offset)
scrollingModel.scrollToCaret(scrollType) scrollingModel.scrollToCaret(scrollType)
@@ -31,7 +31,8 @@ class AddBracesIntention : SelfTargetingIntention<KtExpression>(KtExpression::cl
return true return true
} }
override fun applyTo(element: KtExpression, editor: Editor) { override fun applyTo(element: KtExpression, editor: Editor?) {
if (editor == null) throw IllegalArgumentException("This intention requires an editor")
val expression = element.getTargetExpression(editor.caretModel.offset)!! val expression = element.getTargetExpression(editor.caretModel.offset)!!
if (element.nextSibling?.text == ";") { if (element.nextSibling?.text == ";") {
@@ -24,8 +24,8 @@ import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.idea.analysis.analyzeInContext import org.jetbrains.kotlin.idea.analysis.analyzeInContext
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.util.getResolutionScope
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset
@@ -56,7 +56,8 @@ class AddForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpression>(
return TextRange(element.startOffset, element.body?.startOffset ?: element.endOffset) return TextRange(element.startOffset, element.body?.startOffset ?: element.endOffset)
} }
override fun applyTo(element: KtForExpression, editor: Editor) { override fun applyTo(element: KtForExpression, editor: Editor?) {
if (editor == null) throw IllegalArgumentException("This intention requires an editor")
val loopRange = element.loopRange!! val loopRange = element.loopRange!!
val loopParameter = element.loopParameter!! val loopParameter = element.loopParameter!!
val psiFactory = KtPsiFactory(element) val psiFactory = KtPsiFactory(element)
@@ -50,7 +50,7 @@ class AddNameToArgumentIntention
override fun allowCaretInsideElement(element: PsiElement) override fun allowCaretInsideElement(element: PsiElement)
= element !is KtValueArgumentList && element !is KtContainerNode = element !is KtValueArgumentList && element !is KtContainerNode
override fun applyTo(element: KtValueArgument, editor: Editor) { override fun applyTo(element: KtValueArgument, editor: Editor?) {
val name = detectNameToAdd(element)!! val name = detectNameToAdd(element)!!
val newArgument = KtPsiFactory(element).createArgument(element.getArgumentExpression()!!, name, element.getSpreadElement() != null) val newArgument = KtPsiFactory(element).createArgument(element.getArgumentExpression()!!, name, element.getSpreadElement() != null)
element.replace(newArgument) element.replace(newArgument)
@@ -32,7 +32,7 @@ class AddOperatorModifierIntention : SelfTargetingRangeIntention<KtNamedFunction
return nameIdentifier.textRange return nameIdentifier.textRange
} }
override fun applyTo(element: KtNamedFunction, editor: Editor) { override fun applyTo(element: KtNamedFunction, editor: Editor?) {
applyTo(element) applyTo(element)
} }
@@ -71,7 +71,7 @@ interface AddValVarToConstructorParameterAction {
return element.nameIdentifier?.textRange return element.nameIdentifier?.textRange
} }
override fun applyTo(element: KtParameter, editor: Editor) = invoke(element, editor) override fun applyTo(element: KtParameter, editor: Editor?) = invoke(element, editor)
} }
class QuickFix(parameter: KtParameter) : class QuickFix(parameter: KtParameter) :
@@ -47,7 +47,7 @@ class AnonymousFunctionToLambdaIntention : SelfTargetingRangeIntention<KtNamedFu
return element.funKeyword!!.textRange return element.funKeyword!!.textRange
} }
override fun applyTo(element: KtNamedFunction, editor: Editor) { override fun applyTo(element: KtNamedFunction, editor: Editor?) {
applyTo(element) applyTo(element)
} }
@@ -83,7 +83,7 @@ open class ChangeVisibilityModifierIntention protected constructor(
return descriptor return descriptor
} }
override fun applyTo(element: KtDeclaration, editor: Editor) { override fun applyTo(element: KtDeclaration, editor: Editor?) {
element.setVisibility(modifier) element.setVisibility(modifier)
} }
@@ -45,7 +45,7 @@ class ConvertAssertToIfWithThrowIntention : SelfTargetingIntention<KtCallExpress
return DescriptorUtils.getFqName(resolvedCall.resultingDescriptor).asString() == "kotlin.assert" return DescriptorUtils.getFqName(resolvedCall.resultingDescriptor).asString() == "kotlin.assert"
} }
override fun applyTo(element: KtCallExpression, editor: Editor) { override fun applyTo(element: KtCallExpression, editor: Editor?) {
val args = element.valueArguments val args = element.valueArguments
val conditionText = args[0]?.getArgumentExpression()?.text ?: return val conditionText = args[0]?.getArgumentExpression()?.text ?: return
val functionLiteralArgument = element.lambdaArguments.singleOrNull() val functionLiteralArgument = element.lambdaArguments.singleOrNull()
@@ -39,7 +39,7 @@ class ConvertForEachToForLoopIntention : SelfTargetingOffsetIndependentIntention
return true return true
} }
override fun applyTo(element: KtSimpleNameExpression, editor: Editor) { override fun applyTo(element: KtSimpleNameExpression, editor: Editor?) {
val (expressionToReplace, receiver, functionLiteral) = extractData(element)!! val (expressionToReplace, receiver, functionLiteral) = extractData(element)!!
val commentSaver = CommentSaver(expressionToReplace) val commentSaver = CommentSaver(expressionToReplace)
@@ -211,7 +211,7 @@ class ConvertFunctionToPropertyIntention : SelfTargetingIntention<KtNamedFunctio
return !KotlinBuiltIns.isUnit(returnType) && !KotlinBuiltIns.isNothing(returnType) return !KotlinBuiltIns.isUnit(returnType) && !KotlinBuiltIns.isNothing(returnType)
} }
override fun applyTo(element: KtNamedFunction, editor: Editor) { override fun applyTo(element: KtNamedFunction, editor: Editor?) {
val context = element.analyze(BodyResolveMode.PARTIAL) val context = element.analyze(BodyResolveMode.PARTIAL)
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, element] as FunctionDescriptor val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, element] as FunctionDescriptor
Converter(element.project, descriptor).run() Converter(element.project, descriptor).run()
@@ -40,7 +40,7 @@ class ConvertIfWithThrowToAssertIntention : SelfTargetingOffsetIndependentIntent
return DescriptorUtils.getFqName(resolvedCall.resultingDescriptor).toString() == "java.lang.AssertionError.<init>" return DescriptorUtils.getFqName(resolvedCall.resultingDescriptor).toString() == "java.lang.AssertionError.<init>"
} }
override fun applyTo(element: KtIfExpression, editor: Editor) { override fun applyTo(element: KtIfExpression, editor: Editor?) {
val condition = element.condition ?: return val condition = element.condition ?: return
val thenExpr = element.then?.unwrapBlockOrParenthesis() as KtThrowExpression val thenExpr = element.then?.unwrapBlockOrParenthesis() as KtThrowExpression
@@ -32,7 +32,7 @@ class ConvertNegatedBooleanSequenceIntention : SelfTargetingOffsetIndependentInt
return splitBooleanSequence(element) != null return splitBooleanSequence(element) != null
} }
override fun applyTo(element: KtBinaryExpression, editor: Editor) { override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
val operatorText = when(element.operationToken) { val operatorText = when(element.operationToken) {
KtTokens.ANDAND -> KtTokens.OROR.value KtTokens.ANDAND -> KtTokens.OROR.value
KtTokens.OROR -> KtTokens.ANDAND.value KtTokens.OROR -> KtTokens.ANDAND.value
@@ -38,7 +38,7 @@ class ConvertNegatedExpressionWithDemorgansLawIntention : SelfTargetingOffsetInd
return splitBooleanSequence(baseExpression) != null return splitBooleanSequence(baseExpression) != null
} }
override fun applyTo(element: KtPrefixExpression, editor: Editor) { override fun applyTo(element: KtPrefixExpression, editor: Editor?) {
applyTo(element) applyTo(element)
} }
@@ -50,7 +50,7 @@ class ConvertParameterToReceiverIntention : SelfTargetingIntention<KtParameter>(
override fun startInWriteAction() = false override fun startInWriteAction() = false
override fun applyTo(element: KtParameter, editor: Editor) { override fun applyTo(element: KtParameter, editor: Editor?) {
val function = element.getStrictParentOfType<KtNamedFunction>() ?: return val function = element.getStrictParentOfType<KtNamedFunction>() ?: return
val parameterIndex = function.valueParameters.indexOf(element) val parameterIndex = function.valueParameters.indexOf(element)
val context = function.analyze() val context = function.analyze()
@@ -30,7 +30,7 @@ class ConvertPropertyInitializerToGetterIntention : SelfTargetingIntention<KtPro
&& !element.isLocal && !element.isLocal
} }
override fun applyTo(element: KtProperty, editor: Editor) { override fun applyTo(element: KtProperty, editor: Editor?) {
convertPropertyInitializerToGetter(element, editor) convertPropertyInitializerToGetter(element, editor)
} }
@@ -187,7 +187,7 @@ class ConvertPropertyToFunctionIntention : SelfTargetingIntention<KtProperty>(Kt
return element.delegate == null && !element.isVar && !element.isLocal return element.delegate == null && !element.isVar && !element.isLocal
} }
override fun applyTo(element: KtProperty, editor: Editor) { override fun applyTo(element: KtProperty, editor: Editor?) {
val context = element.analyze() val context = element.analyze()
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, element] as? CallableDescriptor ?: return val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, element] as? CallableDescriptor ?: return
Converter(element.project, descriptor).run() Converter(element.project, descriptor).run()
@@ -43,7 +43,7 @@ class ConvertReceiverToParameterIntention : SelfTargetingOffsetIndependentIntent
override fun startInWriteAction() = false override fun startInWriteAction() = false
override fun applyTo(element: KtTypeReference, editor: Editor) { override fun applyTo(element: KtTypeReference, editor: Editor?) {
val function = element.parent as? KtNamedFunction ?: return val function = element.parent as? KtNamedFunction ?: return
val context = function.analyze() val context = function.analyze()
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, function] as? FunctionDescriptor ?: return val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, function] as? FunctionDescriptor ?: return
@@ -47,7 +47,7 @@ class ConvertToBlockBodyIntention : SelfTargetingIntention<KtDeclarationWithBody
override fun allowCaretInsideElement(element: PsiElement) = element !is KtDeclaration override fun allowCaretInsideElement(element: PsiElement) = element !is KtDeclaration
override fun applyTo(element: KtDeclarationWithBody, editor: Editor) { override fun applyTo(element: KtDeclarationWithBody, editor: Editor?) {
convert(element) convert(element)
} }
@@ -29,7 +29,7 @@ class ConvertToConcatenatedStringIntention : SelfTargetingOffsetIndependentInten
return element.entries.any { it is KtStringTemplateEntryWithExpression } return element.entries.any { it is KtStringTemplateEntryWithExpression }
} }
override fun applyTo(element: KtStringTemplateExpression, editor: Editor) { override fun applyTo(element: KtStringTemplateExpression, editor: Editor?) {
val tripleQuoted = isTripleQuoted(element.text!!) val tripleQuoted = isTripleQuoted(element.text!!)
val quote = if (tripleQuoted) "\"\"\"" else "\"" val quote = if (tripleQuoted) "\"\"\"" else "\""
val entries = element.entries val entries = element.entries
@@ -20,9 +20,9 @@ import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.util.CommentSaver
import org.jetbrains.kotlin.idea.core.canOmitDeclaredType import org.jetbrains.kotlin.idea.core.canOmitDeclaredType
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.util.CommentSaver
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
@@ -42,12 +42,14 @@ class ConvertToExpressionBodyIntention : SelfTargetingOffsetIndependentIntention
override fun allowCaretInsideElement(element: PsiElement) = element !is KtDeclaration override fun allowCaretInsideElement(element: PsiElement) = element !is KtDeclaration
override fun applyTo(element: KtDeclarationWithBody, editor: Editor) { override fun applyTo(element: KtDeclarationWithBody, editor: Editor?) {
applyTo(element) { applyTo(element) {
val typeRef = it.typeReference!! val typeRef = it.typeReference!!
val colon = it.colon!! val colon = it.colon!!
editor.selectionModel.setSelection(colon.startOffset, typeRef.endOffset) editor?.apply {
editor.caretModel.moveToOffset(typeRef.endOffset) selectionModel.setSelection(colon.startOffset, typeRef.endOffset)
caretModel.moveToOffset(typeRef.endOffset)
}
} }
} }
@@ -32,7 +32,7 @@ class ConvertToForEachFunctionCallIntention : SelfTargetingIntention<KtForExpres
return element.loopRange != null && element.loopParameter != null && element.body != null return element.loopRange != null && element.loopParameter != null && element.body != null
} }
override fun applyTo(element: KtForExpression, editor: Editor) { override fun applyTo(element: KtForExpression, editor: Editor?) {
val commentSaver = CommentSaver(element) val commentSaver = CommentSaver(element)
val body = element.body!! val body = element.body!!
@@ -42,7 +42,7 @@ class ConvertToStringTemplateIntention : SelfTargetingOffsetIndependentIntention
return true return true
} }
override fun applyTo(element: KtBinaryExpression, editor: Editor) { override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
applyTo(element) applyTo(element)
} }
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.intentions
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.codeStyle.CodeStyleManager import com.intellij.psi.codeStyle.CodeStyleManager
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
@@ -29,6 +28,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
import org.jetbrains.kotlin.idea.quickfix.moveCaret import org.jetbrains.kotlin.idea.quickfix.moveCaret
import org.jetbrains.kotlin.idea.quickfix.unblockDocument
import org.jetbrains.kotlin.idea.util.ImportInsertHelper import org.jetbrains.kotlin.idea.util.ImportInsertHelper
import org.jetbrains.kotlin.idea.util.ShortenReferences import org.jetbrains.kotlin.idea.util.ShortenReferences
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
@@ -55,7 +55,7 @@ class DeprecatedCallableAddReplaceWithIntention : SelfTargetingRangeIntention<Kt
return annotationEntry.textRange return annotationEntry.textRange
} }
override fun applyTo(element: KtCallableDeclaration, editor: Editor) { override fun applyTo(element: KtCallableDeclaration, editor: Editor?) {
val replaceWith = element.suggestReplaceWith()!! val replaceWith = element.suggestReplaceWith()!!
assert('\n' !in replaceWith.expression && '\r' !in replaceWith.expression) { "Formatted expression text should not contain \\n or \\r" } assert('\n' !in replaceWith.expression && '\r' !in replaceWith.expression) { "Formatted expression text should not contain \\n or \\r" }
@@ -98,8 +98,10 @@ class DeprecatedCallableAddReplaceWithIntention : SelfTargetingRangeIntention<Kt
argument = annotationEntry.valueArgumentList!!.addArgument(argument) argument = annotationEntry.valueArgumentList!!.addArgument(argument)
argument = ShortenReferences.DEFAULT.process(argument) as KtValueArgument argument = ShortenReferences.DEFAULT.process(argument) as KtValueArgument
PsiDocumentManager.getInstance(argument.project).doPostponedOperationsAndUnblockDocument(editor.document) editor?.apply {
editor.moveCaret(argument.textOffset) unblockDocument()
moveCaret(argument.textOffset)
}
} }
private fun KtCallableDeclaration.deprecatedAnnotationWithNoReplaceWith(): KtAnnotationEntry? { private fun KtCallableDeclaration.deprecatedAnnotationWithNoReplaceWith(): KtAnnotationEntry? {
@@ -47,9 +47,9 @@ class IfNullToElvisIntention : SelfTargetingRangeIntention<KtIfExpression>(KtIfE
return TextRange(element.startOffset, rParen.endOffset) return TextRange(element.startOffset, rParen.endOffset)
} }
override fun applyTo(element: KtIfExpression, editor: Editor) { override fun applyTo(element: KtIfExpression, editor: Editor?) {
val newElvis = applyTo(element) val newElvis = applyTo(element)
editor.caretModel.moveToOffset(newElvis.right!!.textOffset) editor?.caretModel?.moveToOffset(newElvis.right!!.textOffset)
} }
fun applyTo(element: KtIfExpression): KtBinaryExpression { fun applyTo(element: KtIfExpression): KtBinaryExpression {
@@ -200,7 +200,8 @@ abstract class ImplementAbstractMemberIntentionBase :
} }
} }
override fun applyTo(element: KtNamedDeclaration, editor: Editor) { override fun applyTo(element: KtNamedDeclaration, editor: Editor?) {
if (editor == null) throw IllegalArgumentException("This intention requires an editor")
val project = element.project val project = element.project
val classesToProcess = project.runSynchronouslyWithProgress( val classesToProcess = project.runSynchronouslyWithProgress(
@@ -56,7 +56,7 @@ class ImportAllMembersIntention : SelfTargetingIntention<KtDotQualifiedExpressio
return true return true
} }
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor) { override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) {
val target = target(element)!! val target = target(element)!!
val classFqName = target.importableFqName!!.parent() val classFqName = target.importableFqName!!.parent()
@@ -46,7 +46,7 @@ class ImportMemberIntention : SelfTargetingOffsetIndependentIntention<KtNameRefe
return true return true
} }
override fun applyTo(element: KtNameReferenceExpression, editor: Editor) { override fun applyTo(element: KtNameReferenceExpression, editor: Editor?) {
val bindingContext = element.analyze(BodyResolveMode.PARTIAL) val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
val targets = element.mainReference.resolveToDescriptors(bindingContext) val targets = element.mainReference.resolveToDescriptors(bindingContext)
val fqName = targets.map { it.importableFqName!! }.single() val fqName = targets.map { it.importableFqName!! }.single()
@@ -26,7 +26,7 @@ class InfixCallToOrdinaryIntention : SelfTargetingIntention<KtBinaryExpression>(
return element.operationReference.textRange.containsOffset(caretOffset) return element.operationReference.textRange.containsOffset(caretOffset)
} }
override fun applyTo(element: KtBinaryExpression, editor: Editor) { override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
convert(element) convert(element)
} }
@@ -26,7 +26,7 @@ class InsertCurlyBracesToTemplateIntention : SelfTargetingOffsetIndependentInten
override fun isApplicableTo(element: KtSimpleNameStringTemplateEntry): Boolean = true override fun isApplicableTo(element: KtSimpleNameStringTemplateEntry): Boolean = true
override fun applyTo(element: KtSimpleNameStringTemplateEntry, editor: Editor) { override fun applyTo(element: KtSimpleNameStringTemplateEntry, editor: Editor?) {
val expression = element.expression ?: return val expression = element.expression ?: return
element.replace(KtPsiFactory(element).createBlockStringTemplateEntry(expression)) element.replace(KtPsiFactory(element).createBlockStringTemplateEntry(expression))
} }
@@ -34,7 +34,7 @@ class InsertExplicitTypeArgumentsIntention : SelfTargetingRangeIntention<KtCallE
return if (isApplicableTo(element, element.analyze())) element.calleeExpression!!.textRange else null return if (isApplicableTo(element, element.analyze())) element.calleeExpression!!.textRange else null
} }
override fun applyTo(element: KtCallExpression, editor: Editor) { override fun applyTo(element: KtCallExpression, editor: Editor?) {
val argumentList = createTypeArguments(element, element.analyze())!! val argumentList = createTypeArguments(element, element.analyze())!!
val callee = element.calleeExpression!! val callee = element.calleeExpression!!
@@ -32,7 +32,7 @@ class IntroduceBackingPropertyIntention(): SelfTargetingIntention<KtProperty>(Kt
return element.nameIdentifier?.textRange?.containsOffset(caretOffset) == true return element.nameIdentifier?.textRange?.containsOffset(caretOffset) == true
} }
override fun applyTo(element: KtProperty, editor: Editor) { override fun applyTo(element: KtProperty, editor: Editor?) {
introduceBackingProperty(element) introduceBackingProperty(element)
} }
@@ -17,11 +17,11 @@
package org.jetbrains.kotlin.idea.intentions package org.jetbrains.kotlin.idea.intentions
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.quickfix.moveCaret import org.jetbrains.kotlin.idea.quickfix.moveCaret
import org.jetbrains.kotlin.idea.quickfix.unblockDocument
import org.jetbrains.kotlin.idea.util.psi.patternMatching.matches import org.jetbrains.kotlin.idea.util.psi.patternMatching.matches
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.psiUtil.*
@@ -35,7 +35,7 @@ class InvertIfConditionIntention : SelfTargetingIntention<KtIfExpression>(KtIfEx
return element.condition != null && element.then != null return element.condition != null && element.then != null
} }
override fun applyTo(element: KtIfExpression, editor: Editor) { override fun applyTo(element: KtIfExpression, editor: Editor?) {
val newCondition = element.condition!!.negate() val newCondition = element.condition!!.negate()
val newIf = handleSpecialCases(element, newCondition) val newIf = handleSpecialCases(element, newCondition)
@@ -47,8 +47,10 @@ class InvertIfConditionIntention : SelfTargetingIntention<KtIfExpression>(KtIfEx
simplifyIntention.applyTo(newIfCondition) simplifyIntention.applyTo(newIfCondition)
} }
PsiDocumentManager.getInstance(newIf.project).doPostponedOperationsAndUnblockDocument(editor.document) editor?.apply {
editor.moveCaret(newIf.textOffset) unblockDocument()
moveCaret(newIf.textOffset)
}
} }
private fun handleStandardCase(ifExpression: KtIfExpression, newCondition: KtExpression): KtIfExpression { private fun handleStandardCase(ifExpression: KtIfExpression, newCondition: KtExpression): KtIfExpression {
@@ -28,9 +28,7 @@ import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.chooseA
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.suggestNamesForComponent import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.suggestNamesForComponent
import org.jetbrains.kotlin.idea.resolve.ideService import org.jetbrains.kotlin.idea.resolve.ideService
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.idea.util.application.executeCommand
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.siblings import org.jetbrains.kotlin.psi.psiUtil.siblings
@@ -62,7 +60,8 @@ class IterateExpressionIntention : SelfTargetingIntention<KtExpression>(KtExpres
override fun startInWriteAction() = false override fun startInWriteAction() = false
override fun applyTo(element: KtExpression, editor: Editor) { override fun applyTo(element: KtExpression, editor: Editor?) {
if (editor == null) throw IllegalArgumentException("This intention requires an editor")
val elementType = data(element)!!.elementType val elementType = data(element)!!.elementType
val nameValidator = NewDeclarationNameValidator(element, element.siblings(), NewDeclarationNameValidator.Target.VARIABLES) val nameValidator = NewDeclarationNameValidator(element, element.siblings(), NewDeclarationNameValidator.Target.VARIABLES)
val bindingContext = element.analyze(BodyResolveMode.PARTIAL) val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
@@ -18,12 +18,12 @@ package org.jetbrains.kotlin.idea.intentions
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.ScrollType import com.intellij.openapi.editor.ScrollType
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReferenceService import com.intellij.psi.PsiReferenceService
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.idea.core.canOmitDeclaredType import org.jetbrains.kotlin.idea.core.canOmitDeclaredType
import org.jetbrains.kotlin.idea.quickfix.moveCaret import org.jetbrains.kotlin.idea.quickfix.moveCaret
import org.jetbrains.kotlin.idea.quickfix.unblockDocument
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.psiUtil.*
@@ -49,7 +49,7 @@ class MoveAssignmentToInitializerIntention :
} }
override fun applyTo(element: KtBinaryExpression, editor: Editor) { override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
val property = findTargetProperty(element) ?: return val property = findTargetProperty(element) ?: return
val initializer = element.right ?: return val initializer = element.right ?: return
val newInitializer = property.setInitializer(initializer)!! val newInitializer = property.setInitializer(initializer)!!
@@ -60,16 +60,18 @@ class MoveAssignmentToInitializerIntention :
initializerBlock.delete() initializerBlock.delete()
} }
PsiDocumentManager.getInstance(property.project).doPostponedOperationsAndUnblockDocument(editor.document) editor?.apply {
unblockDocument()
val typeRef = property.typeReference val typeRef = property.typeReference
if (typeRef != null && property.canOmitDeclaredType(newInitializer, canChangeTypeToSubtype = !property.isVar)) { if (typeRef != null && property.canOmitDeclaredType(newInitializer, canChangeTypeToSubtype = !property.isVar)) {
val colon = property.colon!! val colon = property.colon!!
editor.selectionModel.setSelection(colon.startOffset, typeRef.endOffset) selectionModel.setSelection(colon.startOffset, typeRef.endOffset)
editor.moveCaret(typeRef.endOffset, ScrollType.CENTER) moveCaret(typeRef.endOffset, ScrollType.CENTER)
} }
else { else {
editor.moveCaret(newInitializer.startOffset, ScrollType.CENTER) moveCaret(newInitializer.startOffset, ScrollType.CENTER)
}
} }
} }
@@ -29,7 +29,7 @@ class MoveLambdaInsideParenthesesIntention : SelfTargetingIntention<KtLambdaArgu
return !body.textRange.containsInside(caretOffset) return !body.textRange.containsInside(caretOffset)
} }
override fun applyTo(element: KtLambdaArgument, editor: Editor) { override fun applyTo(element: KtLambdaArgument, editor: Editor?) {
element.moveInsideParentheses(element.analyze()) element.moveInsideParentheses(element.analyze())
} }
} }
@@ -57,7 +57,7 @@ class MoveLambdaOutsideParenthesesIntention : SelfTargetingIntention<KtCallExpre
return !bodyRange.containsInside(caretOffset) return !bodyRange.containsInside(caretOffset)
} }
override fun applyTo(element: KtCallExpression, editor: Editor) { override fun applyTo(element: KtCallExpression, editor: Editor?) {
element.moveFunctionLiteralOutsideParentheses() element.moveFunctionLiteralOutsideParentheses()
} }
@@ -68,7 +68,7 @@ class ObjectLiteralToLambdaIntention : SelfTargetingRangeIntention<KtObjectLiter
return TextRange(element.objectDeclaration.getObjectKeyword().startOffset, baseTypeRef.endOffset) return TextRange(element.objectDeclaration.getObjectKeyword().startOffset, baseTypeRef.endOffset)
} }
override fun applyTo(element: KtObjectLiteralExpression, editor: Editor) { override fun applyTo(element: KtObjectLiteralExpression, editor: Editor?) {
applyTo(element) applyTo(element)
} }
@@ -51,7 +51,7 @@ class ReconstructTypeInCastOrIsIntention : SelfTargetingOffsetIndependentIntenti
return true return true
} }
override fun applyTo(element: KtTypeReference, editor: Editor) { override fun applyTo(element: KtTypeReference, editor: Editor?) {
val type = getReconstructedType(element)!! val type = getReconstructedType(element)!!
val newType = KtPsiFactory(element).createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type)) val newType = KtPsiFactory(element).createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type))
ShortenReferences.DEFAULT.process(element.replaced(newType)) ShortenReferences.DEFAULT.process(element.replaced(newType))
@@ -47,7 +47,7 @@ class RemoveArgumentNameIntention
return TextRange(element.startOffset, expression.startOffset) return TextRange(element.startOffset, expression.startOffset)
} }
override fun applyTo(element: KtValueArgument, editor: Editor) { override fun applyTo(element: KtValueArgument, editor: Editor?) {
val newArgument = KtPsiFactory(element).createArgument(element.getArgumentExpression()!!, null, element.getSpreadElement() != null) val newArgument = KtPsiFactory(element).createArgument(element.getArgumentExpression()!!, null, element.getSpreadElement() != null)
element.replace(newArgument) element.replace(newArgument)
} }
@@ -36,7 +36,7 @@ class RemoveBracesIntention : SelfTargetingIntention<KtBlockExpression>(KtBlockE
return true return true
} }
override fun applyTo(element: KtBlockExpression, editor: Editor) { override fun applyTo(element: KtBlockExpression, editor: Editor?) {
val statement = element.statements.single() val statement = element.statements.single()
val containerNode = element.parent as KtContainerNode val containerNode = element.parent as KtContainerNode
@@ -33,7 +33,7 @@ class RemoveCurlyBracesFromTemplateIntention : SelfTargetingOffsetIndependentInt
return canPlaceAfterSimpleNameEntry(element.nextSibling) return canPlaceAfterSimpleNameEntry(element.nextSibling)
} }
override fun applyTo(element: KtBlockStringTemplateEntry, editor: Editor) { override fun applyTo(element: KtBlockStringTemplateEntry, editor: Editor?) {
applyTo(element) applyTo(element)
} }
@@ -28,7 +28,7 @@ class RemoveExplicitLambdaParameterTypesIntention : SelfTargetingIntention<KtLam
return caretOffset <= arrow.endOffset return caretOffset <= arrow.endOffset
} }
override fun applyTo(element: KtLambdaExpression, editor: Editor) { override fun applyTo(element: KtLambdaExpression, editor: Editor?) {
val oldParameterList = element.functionLiteral.valueParameterList!! val oldParameterList = element.functionLiteral.valueParameterList!!
val parameterString = oldParameterList.parameters.map { it.name }.joinToString(", ") val parameterString = oldParameterList.parameters.map { it.name }.joinToString(", ")
@@ -65,7 +65,7 @@ class RemoveExplicitSuperQualifierIntention : SelfTargetingRangeIntention<KtSupe
return TextRange(element.instanceReference.endOffset, element.labelQualifier?.startOffset ?: element.endOffset) return TextRange(element.instanceReference.endOffset, element.labelQualifier?.startOffset ?: element.endOffset)
} }
override fun applyTo(element: KtSuperExpression, editor: Editor) { override fun applyTo(element: KtSuperExpression, editor: Editor?) {
element.replace(toNonQualified(element)) element.replace(toNonQualified(element))
} }
@@ -102,7 +102,7 @@ class RemoveExplicitTypeArgumentsIntention : SelfTargetingOffsetIndependentInten
override fun getTypeArgumentList() = null override fun getTypeArgumentList() = null
} }
override fun applyTo(element: KtTypeArgumentList, editor: Editor) { override fun applyTo(element: KtTypeArgumentList, editor: Editor?) {
element.delete() element.delete()
} }
} }
@@ -35,7 +35,7 @@ class RemoveExplicitTypeIntention : SelfTargetingIntention<KtCallableDeclaration
} }
} }
override fun applyTo(element: KtCallableDeclaration, editor: Editor) { override fun applyTo(element: KtCallableDeclaration, editor: Editor?) {
element.setTypeReference(null) element.setTypeReference(null)
} }
} }
@@ -60,7 +60,7 @@ class RemoveForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpressio
return indexVar.nameIdentifier?.range return indexVar.nameIdentifier?.range
} }
override fun applyTo(element: KtForExpression, editor: Editor) { override fun applyTo(element: KtForExpression, editor: Editor?) {
val multiParameter = element.destructuringParameter!! val multiParameter = element.destructuringParameter!!
val loopRange = element.loopRange as KtDotQualifiedExpression val loopRange = element.loopRange as KtDotQualifiedExpression
@@ -28,7 +28,7 @@ class RemoveUnnecessaryParenthesesIntention : SelfTargetingRangeIntention<KtPare
return element.textRange return element.textRange
} }
override fun applyTo(element: KtParenthesizedExpression, editor: Editor) { override fun applyTo(element: KtParenthesizedExpression, editor: Editor?) {
applyTo(element) applyTo(element)
} }
@@ -34,7 +34,8 @@ class ReplaceItWithExplicitFunctionLiteralParamIntention() : SelfTargetingOffset
override fun isApplicableTo(element: KtNameReferenceExpression) override fun isApplicableTo(element: KtNameReferenceExpression)
= isAutoCreatedItUsage(element) = isAutoCreatedItUsage(element)
override fun applyTo(element: KtNameReferenceExpression, editor: Editor) { override fun applyTo(element: KtNameReferenceExpression, editor: Editor?) {
if (editor == null) throw IllegalArgumentException("This intention requires an editor")
val target = element.mainReference.resolveToDescriptors(element.analyze()).single() val target = element.mainReference.resolveToDescriptors(element.analyze()).single()
val functionLiteral = DescriptorToSourceUtils.descriptorToDeclaration(target.containingDeclaration!!) as KtFunctionLiteral val functionLiteral = DescriptorToSourceUtils.descriptorToDeclaration(target.containingDeclaration!!) as KtFunctionLiteral
@@ -78,7 +78,7 @@ class ReplaceWithOperatorAssignmentIntention : SelfTargetingOffsetIndependentInt
operationToken == KtTokens.DIV || operationToken == KtTokens.DIV ||
operationToken == KtTokens.PERC operationToken == KtTokens.PERC
override fun applyTo(element: KtBinaryExpression, editor: Editor) { override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
val replacement = buildOperatorAssignmentText( val replacement = buildOperatorAssignmentText(
element.left as KtNameReferenceExpression, element.left as KtNameReferenceExpression,
element.right as KtBinaryExpression, element.right as KtBinaryExpression,
@@ -32,7 +32,7 @@ class ReplaceWithOrdinaryAssignmentIntention : SelfTargetingIntention<KtBinaryEx
return element.operationReference.textRange.containsOffset(caretOffset) return element.operationReference.textRange.containsOffset(caretOffset)
} }
override fun applyTo(element: KtBinaryExpression, editor: Editor) { override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
val left = element.left!! val left = element.left!!
val right = element.right!! val right = element.right!!
val factory = KtPsiFactory(element) val factory = KtPsiFactory(element)
@@ -52,7 +52,7 @@ class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentInte
return element.canBeReducedToBooleanConstant(null) return element.canBeReducedToBooleanConstant(null)
} }
override fun applyTo(element: KtBinaryExpression, editor: Editor) { override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
val topBinary = PsiTreeUtil.getTopmostParentOfType(element, KtBinaryExpression::class.java) ?: element val topBinary = PsiTreeUtil.getTopmostParentOfType(element, KtBinaryExpression::class.java) ?: element
val simplified = toSimplifiedExpression(topBinary) val simplified = toSimplifiedExpression(topBinary)
topBinary.replace(KtPsiUtil.safeDeparenthesize(simplified)) topBinary.replace(KtPsiUtil.safeDeparenthesize(simplified))
@@ -68,7 +68,7 @@ class SimplifyNegatedBinaryExpressionIntention : SelfTargetingRangeIntention<KtP
return true return true
} }
override fun applyTo(element: KtPrefixExpression, editor: Editor) { override fun applyTo(element: KtPrefixExpression, editor: Editor?) {
applyTo(element) applyTo(element)
} }
@@ -43,7 +43,7 @@ class SpecifyExplicitLambdaSignatureIntention : SelfTargetingIntention<KtLambdaE
return functionDescriptor.valueParameters.none { it.type.isError } return functionDescriptor.valueParameters.none { it.type.isError }
} }
override fun applyTo(element: KtLambdaExpression, editor: Editor) { override fun applyTo(element: KtLambdaExpression, editor: Editor?) {
val psiFactory = KtPsiFactory(element) val psiFactory = KtPsiFactory(element)
val functionLiteral = element.functionLiteral val functionLiteral = element.functionLiteral
val functionDescriptor = element.analyze()[BindingContext.FUNCTION, functionLiteral]!! val functionDescriptor = element.analyze()[BindingContext.FUNCTION, functionLiteral]!!
@@ -52,7 +52,7 @@ class SpecifyTypeExplicitlyIntention : SelfTargetingIntention<KtCallableDeclarat
return true return true
} }
override fun applyTo(element: KtCallableDeclaration, editor: Editor) { override fun applyTo(element: KtCallableDeclaration, editor: Editor?) {
val type = getTypeForDeclaration(element) val type = getTypeForDeclaration(element)
addTypeAnnotation(editor, element, type) addTypeAnnotation(editor, element, type)
} }
@@ -38,7 +38,7 @@ class SplitIfIntention : SelfTargetingIntention<KtExpression>(KtExpression::clas
} }
} }
override fun applyTo(element: KtExpression, editor: Editor) { override fun applyTo(element: KtExpression, editor: Editor?) {
val operator = when (element) { val operator = when (element) {
is KtIfExpression -> getFirstValidOperator(element)!! is KtIfExpression -> getFirstValidOperator(element)!!
else -> element as KtOperationReferenceExpression else -> element as KtOperationReferenceExpression
@@ -53,7 +53,7 @@ class SwapBinaryExpressionIntention : SelfTargetingIntention<KtBinaryExpression>
return false return false
} }
override fun applyTo(element: KtBinaryExpression, editor: Editor) { override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
// Have to use text here to preserve names like "plus" // Have to use text here to preserve names like "plus"
val operator = element.operationReference.text!! val operator = element.operationReference.text!!
val convertedOperator = when (operator) { val convertedOperator = when (operator) {
@@ -48,7 +48,7 @@ class ToInfixCallIntention : SelfTargetingIntention<KtCallExpression>(KtCallExpr
return true return true
} }
override fun applyTo(element: KtCallExpression, editor: Editor) { override fun applyTo(element: KtCallExpression, editor: Editor?) {
val dotQualified = element.parent as KtDotQualifiedExpression val dotQualified = element.parent as KtDotQualifiedExpression
val receiver = dotQualified.receiverExpression val receiver = dotQualified.receiverExpression
val argument = element.valueArguments.single().getArgumentExpression()!! val argument = element.valueArguments.single().getArgumentExpression()!!
@@ -61,7 +61,7 @@ class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention
return detectPropertyNameToUse(element) != null return detectPropertyNameToUse(element) != null
} }
override fun applyTo(element: KtCallExpression, editor: Editor) { override fun applyTo(element: KtCallExpression, editor: Editor?) {
applyTo(element, detectPropertyNameToUse(element)!!) applyTo(element, detectPropertyNameToUse(element)!!)
} }
@@ -17,12 +17,12 @@
package org.jetbrains.kotlin.idea.intentions.branchedTransformations package org.jetbrains.kotlin.idea.intentions.branchedTransformations
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.idea.core.copied import org.jetbrains.kotlin.idea.core.copied
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis
object BranchedUnfoldingUtils { object BranchedUnfoldingUtils {
fun unfoldAssignmentToIf(assignment: KtBinaryExpression, editor: Editor) { fun unfoldAssignmentToIf(assignment: KtBinaryExpression, editor: Editor?) {
val op = assignment.operationReference.text val op = assignment.operationReference.text
val left = assignment.left!! val left = assignment.left!!
val ifExpression = assignment.right as KtIfExpression val ifExpression = assignment.right as KtIfExpression
@@ -38,10 +38,10 @@ object BranchedUnfoldingUtils {
val resultIf = assignment.replace(newIfExpression) val resultIf = assignment.replace(newIfExpression)
editor.caretModel.moveToOffset(resultIf.textOffset) editor?.caretModel?.moveToOffset(resultIf.textOffset)
} }
fun unfoldAssignmentToWhen(assignment: KtBinaryExpression, editor: Editor) { fun unfoldAssignmentToWhen(assignment: KtBinaryExpression, editor: Editor?) {
val op = assignment.operationReference.text val op = assignment.operationReference.text
val left = assignment.left!! val left = assignment.left!!
val whenExpression = assignment.right as KtWhenExpression val whenExpression = assignment.right as KtWhenExpression
@@ -55,6 +55,6 @@ object BranchedUnfoldingUtils {
val resultWhen = assignment.replace(newWhenExpression) val resultWhen = assignment.replace(newWhenExpression)
editor.caretModel.moveToOffset(resultWhen.textOffset) editor?.caretModel?.moveToOffset(resultWhen.textOffset)
} }
} }
@@ -94,7 +94,7 @@ fun KtExpression.convertToIfStatement(condition: KtExpression, thenClause: KtExp
return replaced(KtPsiFactory(this).createIf(condition, thenClause, elseClause)) return replaced(KtPsiFactory(this).createIf(condition, thenClause, elseClause))
} }
fun KtIfExpression.introduceValueForCondition(occurrenceInThenClause: KtExpression, editor: Editor) { fun KtIfExpression.introduceValueForCondition(occurrenceInThenClause: KtExpression, editor: Editor?) {
val project = this.project val project = this.project
val occurrenceInConditional = (this.condition as KtBinaryExpression).left!! val occurrenceInConditional = (this.condition as KtBinaryExpression).left!!
KotlinIntroduceVariableHandler.doRefactoring(project, KotlinIntroduceVariableHandler.doRefactoring(project,
@@ -104,7 +104,7 @@ fun KtIfExpression.introduceValueForCondition(occurrenceInThenClause: KtExpressi
null) null)
} }
fun KtNameReferenceExpression.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor: Editor) { fun KtNameReferenceExpression.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor: Editor?) {
val declaration = this.mainReference.resolve() as? KtProperty ?: return val declaration = this.mainReference.resolve() as? KtProperty ?: return
val enclosingElement = KtPsiUtil.getEnclosingElementForLocalDeclaration(declaration) val enclosingElement = KtPsiUtil.getEnclosingElementForLocalDeclaration(declaration)
@@ -119,15 +119,15 @@ fun KtNameReferenceExpression.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(e
} }
} }
fun KtSafeQualifiedExpression.inlineReceiverIfApplicableWithPrompt(editor: Editor) { fun KtSafeQualifiedExpression.inlineReceiverIfApplicableWithPrompt(editor: Editor?) {
(this.receiverExpression as? KtNameReferenceExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor) (this.receiverExpression as? KtNameReferenceExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor)
} }
fun KtBinaryExpression.inlineLeftSideIfApplicableWithPrompt(editor: Editor) { fun KtBinaryExpression.inlineLeftSideIfApplicableWithPrompt(editor: Editor?) {
(this.left as? KtNameReferenceExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor) (this.left as? KtNameReferenceExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor)
} }
fun KtPostfixExpression.inlineBaseExpressionIfApplicableWithPrompt(editor: Editor) { fun KtPostfixExpression.inlineBaseExpressionIfApplicableWithPrompt(editor: Editor?) {
(this.baseExpression as? KtNameReferenceExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor) (this.baseExpression as? KtNameReferenceExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor)
} }
@@ -47,7 +47,9 @@ class DoubleBangToIfThenIntention : SelfTargetingRangeIntention<KtPostfixExpress
null null
} }
override fun applyTo(element: KtPostfixExpression, editor: Editor) { override fun applyTo(element: KtPostfixExpression, editor: Editor?) {
if (editor == null) throw IllegalArgumentException("This intention requires an editor")
val base = KtPsiUtil.safeDeparenthesize(element.baseExpression!!) val base = KtPsiUtil.safeDeparenthesize(element.baseExpression!!)
val expressionText = formatForUseInExceptionArgument(base.text!!) val expressionText = formatForUseInExceptionArgument(base.text!!)
@@ -33,7 +33,7 @@ class EliminateWhenSubjectIntention : SelfTargetingIntention<KtWhenExpression>(K
return caretOffset <= lBrace.startOffset return caretOffset <= lBrace.startOffset
} }
override fun applyTo(element: KtWhenExpression, editor: Editor) { override fun applyTo(element: KtWhenExpression, editor: Editor?) {
val subject = element.subjectExpression!! val subject = element.subjectExpression!!
val whenExpression = KtPsiFactory(element).buildExpression { val whenExpression = KtPsiFactory(element).buildExpression {
@@ -35,7 +35,7 @@ class ElvisToIfThenIntention : SelfTargetingRangeIntention<KtBinaryExpression>(K
null null
} }
override fun applyTo(element: KtBinaryExpression, editor: Editor) { override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
val left = KtPsiUtil.safeDeparenthesize(element.left!!) val left = KtPsiUtil.safeDeparenthesize(element.left!!)
val right = KtPsiUtil.safeDeparenthesize(element.right!!) val right = KtPsiUtil.safeDeparenthesize(element.right!!)
@@ -42,7 +42,7 @@ class FlattenWhenIntention : SelfTargetingIntention<KtWhenExpression>(KtWhenExpr
return elseEntry.startOffset <= caretOffset && caretOffset <= innerWhen.whenKeyword.endOffset return elseEntry.startOffset <= caretOffset && caretOffset <= innerWhen.whenKeyword.endOffset
} }
override fun applyTo(element: KtWhenExpression, editor: Editor) { override fun applyTo(element: KtWhenExpression, editor: Editor?) {
val subjectExpression = element.subjectExpression val subjectExpression = element.subjectExpression
val nestedWhen = element.elseExpression as KtWhenExpression val nestedWhen = element.elseExpression as KtWhenExpression
@@ -72,6 +72,6 @@ class FlattenWhenIntention : SelfTargetingIntention<KtWhenExpression>(KtWhenExpr
val newWhen = element.replaced(whenExpression) val newWhen = element.replaced(whenExpression)
val firstNewEntry = newWhen.entries[outerEntries.size - 1] val firstNewEntry = newWhen.entries[outerEntries.size - 1]
editor.moveCaret(firstNewEntry.textOffset) editor?.moveCaret(firstNewEntry.textOffset)
} }
} }
@@ -32,7 +32,7 @@ class FoldIfToAssignmentIntention : SelfTargetingRangeIntention<KtIfExpression>(
return element.ifKeyword.textRange return element.ifKeyword.textRange
} }
override fun applyTo(element: KtIfExpression, editor: Editor) { override fun applyTo(element: KtIfExpression, editor: Editor?) {
var thenAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.then!!)!! var thenAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.then!!)!!
val elseAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.`else`!!)!! val elseAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.`else`!!)!!
@@ -33,7 +33,7 @@ class FoldIfToReturnAsymmetricallyIntention : SelfTargetingRangeIntention<KtIfEx
return element.ifKeyword.textRange return element.ifKeyword.textRange
} }
override fun applyTo(element: KtIfExpression, editor: Editor) { override fun applyTo(element: KtIfExpression, editor: Editor?) {
val condition = element.condition!! val condition = element.condition!!
val thenBranch = element.then!! val thenBranch = element.then!!
val elseBranch = KtPsiUtil.skipTrailingWhitespacesAndComments(element) as KtReturnExpression val elseBranch = KtPsiUtil.skipTrailingWhitespacesAndComments(element) as KtReturnExpression
@@ -31,7 +31,7 @@ class FoldIfToReturnIntention : SelfTargetingRangeIntention<KtIfExpression>(KtIf
return element.ifKeyword.textRange return element.ifKeyword.textRange
} }
override fun applyTo(element: KtIfExpression, editor: Editor) { override fun applyTo(element: KtIfExpression, editor: Editor?) {
val thenReturn = BranchedFoldingUtils.getFoldableBranchedReturn(element.then!!)!! val thenReturn = BranchedFoldingUtils.getFoldableBranchedReturn(element.then!!)!!
val elseReturn = BranchedFoldingUtils.getFoldableBranchedReturn(element.`else`!!)!! val elseReturn = BranchedFoldingUtils.getFoldableBranchedReturn(element.`else`!!)!!
@@ -47,7 +47,7 @@ class FoldWhenToAssignmentIntention : SelfTargetingRangeIntention<KtWhenExpressi
return element.whenKeyword.textRange return element.whenKeyword.textRange
} }
override fun applyTo(element: KtWhenExpression, editor: Editor) { override fun applyTo(element: KtWhenExpression, editor: Editor?) {
assert(!element.entries.isEmpty()) assert(!element.entries.isEmpty())
val firstAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.entries.first().expression!!)!! val firstAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.entries.first().expression!!)!!
@@ -37,7 +37,7 @@ class FoldWhenToReturnIntention : SelfTargetingRangeIntention<KtWhenExpression>(
return element.whenKeyword.textRange return element.whenKeyword.textRange
} }
override fun applyTo(element: KtWhenExpression, editor: Editor) { override fun applyTo(element: KtWhenExpression, editor: Editor?) {
assert(!element.entries.isEmpty()) assert(!element.entries.isEmpty())
val newReturnExpression = KtPsiFactory(element).createExpressionByPattern("return $0", element) as KtReturnExpression val newReturnExpression = KtPsiFactory(element).createExpressionByPattern("return $0", element) as KtReturnExpression
@@ -66,7 +66,7 @@ class IfThenToDoubleBangIntention : SelfTargetingRangeIntention<KtIfExpression>(
return TextRange(element.startOffset, rParen.endOffset) return TextRange(element.startOffset, rParen.endOffset)
} }
override fun applyTo(element: KtIfExpression, editor: Editor) { override fun applyTo(element: KtIfExpression, editor: Editor?) {
val condition = element.condition as KtBinaryExpression val condition = element.condition as KtBinaryExpression
val expression = condition.expressionComparedToNull()!! val expression = condition.expressionComparedToNull()!!
val result = element.replace(KtPsiFactory(element).createExpressionByPattern("$0!!", expression)) as KtPostfixExpression val result = element.replace(KtPsiFactory(element).createExpressionByPattern("$0!!", expression)) as KtPostfixExpression
@@ -18,12 +18,12 @@ package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
import org.jetbrains.kotlin.idea.intentions.SelfTargetingOffsetIndependentIntention import org.jetbrains.kotlin.idea.intentions.SelfTargetingOffsetIndependentIntention
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.* import org.jetbrains.kotlin.idea.intentions.branchedTransformations.*
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.idea.core.replaced
class IfThenToElvisInspection : IntentionBasedInspection<KtIfExpression>(IfThenToElvisIntention()) class IfThenToElvisInspection : IntentionBasedInspection<KtIfExpression>(IfThenToElvisIntention())
@@ -56,7 +56,7 @@ class IfThenToElvisIntention : SelfTargetingOffsetIndependentIntention<KtIfExpre
return innerExpression !is KtBlockExpression && innerExpression.node.elementType != KtNodeTypes.NULL return innerExpression !is KtBlockExpression && innerExpression.node.elementType != KtNodeTypes.NULL
} }
override fun applyTo(element: KtIfExpression, editor: Editor) { override fun applyTo(element: KtIfExpression, editor: Editor?) {
val elvis = applyTo(element) val elvis = applyTo(element)
elvis.inlineLeftSideIfApplicableWithPrompt(editor) elvis.inlineLeftSideIfApplicableWithPrompt(editor)
} }
@@ -17,12 +17,12 @@
package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
import org.jetbrains.kotlin.idea.intentions.SelfTargetingOffsetIndependentIntention import org.jetbrains.kotlin.idea.intentions.SelfTargetingOffsetIndependentIntention
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.* import org.jetbrains.kotlin.idea.intentions.branchedTransformations.*
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.idea.core.replaced
class IfThenToSafeAccessInspection : IntentionBasedInspection<KtIfExpression>(IfThenToSafeAccessIntention()) class IfThenToSafeAccessInspection : IntentionBasedInspection<KtIfExpression>(IfThenToSafeAccessIntention())
@@ -50,7 +50,7 @@ class IfThenToSafeAccessIntention : SelfTargetingOffsetIndependentIntention<KtIf
} }
} }
override fun applyTo(element: KtIfExpression, editor: Editor) { override fun applyTo(element: KtIfExpression, editor: Editor?) {
val safeAccessExpr = applyTo(element) val safeAccessExpr = applyTo(element)
safeAccessExpr.inlineReceiverIfApplicableWithPrompt(editor) safeAccessExpr.inlineReceiverIfApplicableWithPrompt(editor)
} }
@@ -31,7 +31,7 @@ class IfToWhenIntention : SelfTargetingRangeIntention<KtIfExpression>(KtIfExpres
return element.ifKeyword.textRange return element.ifKeyword.textRange
} }
override fun applyTo(element: KtIfExpression, editor: Editor) { override fun applyTo(element: KtIfExpression, editor: Editor?) {
var whenExpression = KtPsiFactory(element).buildExpression { var whenExpression = KtPsiFactory(element).buildExpression {
appendFixedText("when {\n") appendFixedText("when {\n")
@@ -33,7 +33,7 @@ class IntroduceWhenSubjectIntention : SelfTargetingRangeIntention<KtWhenExpressi
return element.whenKeyword.textRange return element.whenKeyword.textRange
} }
override fun applyTo(element: KtWhenExpression, editor: Editor) { override fun applyTo(element: KtWhenExpression, editor: Editor?) {
element.introduceSubject() element.introduceSubject()
} }
} }
@@ -68,7 +68,7 @@ class MergeWhenIntention : SelfTargetingRangeIntention<KtWhenExpression>(KtWhenE
?.mapNotNull { it.name } ?.mapNotNull { it.name }
?.toSet() ?: emptySet() ?.toSet() ?: emptySet()
override fun applyTo(element: KtWhenExpression, editor: Editor) { override fun applyTo(element: KtWhenExpression, editor: Editor?) {
val nextWhen = PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace::class.java) as KtWhenExpression val nextWhen = PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace::class.java) as KtWhenExpression
for ((entry1, entry2) in element.entries.zip(nextWhen.entries)) { for ((entry1, entry2) in element.entries.zip(nextWhen.entries)) {
entry1.expression.mergeWith(entry2.expression) entry1.expression.mergeWith(entry2.expression)
@@ -33,7 +33,7 @@ class SafeAccessToIfThenIntention : SelfTargetingRangeIntention<KtSafeQualifiedE
return element.operationTokenNode.textRange return element.operationTokenNode.textRange
} }
override fun applyTo(element: KtSafeQualifiedExpression, editor: Editor) { override fun applyTo(element: KtSafeQualifiedExpression, editor: Editor?) {
val receiver = KtPsiUtil.safeDeparenthesize(element.receiverExpression) val receiver = KtPsiUtil.safeDeparenthesize(element.receiverExpression)
val selector = element.selectorExpression!! val selector = element.selectorExpression!!
@@ -35,7 +35,7 @@ class UnfoldAssignmentToIfIntention : SelfTargetingRangeIntention<KtBinaryExpres
return TextRange(element.startOffset, right.ifKeyword.endOffset) return TextRange(element.startOffset, right.ifKeyword.endOffset)
} }
override fun applyTo(element: KtBinaryExpression, editor: Editor) { override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
BranchedUnfoldingUtils.unfoldAssignmentToIf(element, editor) BranchedUnfoldingUtils.unfoldAssignmentToIf(element, editor)
} }
} }
@@ -38,7 +38,7 @@ class UnfoldAssignmentToWhenIntention : SelfTargetingRangeIntention<KtBinaryExpr
return TextRange(element.startOffset, right.whenKeyword.endOffset) return TextRange(element.startOffset, right.whenKeyword.endOffset)
} }
override fun applyTo(element: KtBinaryExpression, editor: Editor) { override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
BranchedUnfoldingUtils.unfoldAssignmentToWhen(element, editor) BranchedUnfoldingUtils.unfoldAssignmentToWhen(element, editor)
} }
} }
@@ -34,7 +34,7 @@ class UnfoldPropertyToIfIntention : SelfTargetingRangeIntention<KtProperty>(KtPr
return TextRange(element.startOffset, initializer.ifKeyword.endOffset) return TextRange(element.startOffset, initializer.ifKeyword.endOffset)
} }
override fun applyTo(element: KtProperty, editor: Editor) { override fun applyTo(element: KtProperty, editor: Editor?) {
val assignment = splitPropertyDeclaration(element) val assignment = splitPropertyDeclaration(element)
BranchedUnfoldingUtils.unfoldAssignmentToIf(assignment, editor) BranchedUnfoldingUtils.unfoldAssignmentToIf(assignment, editor)
} }
@@ -37,7 +37,7 @@ class UnfoldPropertyToWhenIntention : SelfTargetingRangeIntention<KtProperty>(Kt
return TextRange(element.startOffset, initializer.whenKeyword.endOffset) return TextRange(element.startOffset, initializer.whenKeyword.endOffset)
} }
override fun applyTo(element: KtProperty, editor: Editor) { override fun applyTo(element: KtProperty, editor: Editor?) {
val assignment = splitPropertyDeclaration(element) val assignment = splitPropertyDeclaration(element)
BranchedUnfoldingUtils.unfoldAssignmentToWhen(assignment, editor) BranchedUnfoldingUtils.unfoldAssignmentToWhen(assignment, editor)
} }
@@ -35,7 +35,7 @@ class UnfoldReturnToIfIntention : SelfTargetingRangeIntention<KtReturnExpression
return TextRange(element.startOffset, ifExpression.ifKeyword.endOffset) return TextRange(element.startOffset, ifExpression.ifKeyword.endOffset)
} }
override fun applyTo(element: KtReturnExpression, editor: Editor) { override fun applyTo(element: KtReturnExpression, editor: Editor?) {
val ifExpression = element.returnedExpression as KtIfExpression val ifExpression = element.returnedExpression as KtIfExpression
val newIfExpression = ifExpression.copied() val newIfExpression = ifExpression.copied()
val thenExpr = newIfExpression.then!!.lastBlockStatementOrThis() val thenExpr = newIfExpression.then!!.lastBlockStatementOrThis()
@@ -34,7 +34,7 @@ class UnfoldReturnToWhenIntention : SelfTargetingRangeIntention<KtReturnExpressi
return TextRange(element.startOffset, whenExpr.whenKeyword.endOffset) return TextRange(element.startOffset, whenExpr.whenKeyword.endOffset)
} }
override fun applyTo(element: KtReturnExpression, editor: Editor) { override fun applyTo(element: KtReturnExpression, editor: Editor?) {
val whenExpression = element.returnedExpression as KtWhenExpression val whenExpression = element.returnedExpression as KtWhenExpression
val newWhenExpression = whenExpression.copied() val newWhenExpression = whenExpression.copied()
@@ -32,7 +32,7 @@ class WhenToIfIntention : SelfTargetingRangeIntention<KtWhenExpression>(KtWhenEx
return element.whenKeyword.textRange return element.whenKeyword.textRange
} }
override fun applyTo(element: KtWhenExpression, editor: Editor) { override fun applyTo(element: KtWhenExpression, editor: Editor?) {
val factory = KtPsiFactory(element) val factory = KtPsiFactory(element)
val ifExpression = factory.buildExpression { val ifExpression = factory.buildExpression {
val entries = element.entries val entries = element.entries
@@ -45,7 +45,7 @@ class ReplaceCallWithBinaryOperatorIntention : SelfTargetingRangeIntention<KtDot
return element.callExpression!!.calleeExpression!!.textRange return element.callExpression!!.calleeExpression!!.textRange
} }
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor) { override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) {
val operation = operation(element.calleeName)!! val operation = operation(element.calleeName)!!
val argument = element.callExpression!!.valueArguments.single().getArgumentExpression()!! val argument = element.callExpression!!.valueArguments.single().getArgumentExpression()!!
val receiver = element.receiverExpression val receiver = element.receiverExpression
@@ -43,7 +43,7 @@ class ReplaceCallWithUnaryOperatorIntention : SelfTargetingRangeIntention<KtDotQ
return call.calleeExpression!!.textRange return call.calleeExpression!!.textRange
} }
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor) { override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) {
val operation = operation(element.calleeName)!! val operation = operation(element.calleeName)!!
val receiver = element.receiverExpression val receiver = element.receiverExpression
element.replace(KtPsiFactory(element).createExpressionByPattern("$0$1", operation, receiver)) element.replace(KtPsiFactory(element).createExpressionByPattern("$0$1", operation, receiver))
@@ -46,7 +46,7 @@ class ReplaceContainsIntention : SelfTargetingRangeIntention<KtDotQualifiedExpre
return element.callExpression!!.calleeExpression!!.textRange return element.callExpression!!.calleeExpression!!.textRange
} }
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor) { override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) {
val argument = element.callExpression!!.valueArguments.single().getArgumentExpression()!! val argument = element.callExpression!!.valueArguments.single().getArgumentExpression()!!
val receiver = element.receiverExpression val receiver = element.receiverExpression
@@ -86,7 +86,7 @@ class ReplaceGetOrSetIntention : SelfTargetingRangeIntention<KtDotQualifiedExpre
return callExpression.calleeExpression!!.textRange return callExpression.calleeExpression!!.textRange
} }
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor) { override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) {
applyTo(element) applyTo(element)
} }
@@ -32,7 +32,7 @@ class ReplaceInvokeIntention : SelfTargetingRangeIntention<KtDotQualifiedExpress
return element.callExpression!!.calleeExpression!!.textRange return element.callExpression!!.calleeExpression!!.textRange
} }
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor) { override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) {
val receiver = element.receiverExpression val receiver = element.receiverExpression
val callExpression = element.callExpression!!.copy() as KtCallExpression val callExpression = element.callExpression!!.copy() as KtCallExpression
callExpression.calleeExpression!!.replace(receiver) callExpression.calleeExpression!!.replace(receiver)
@@ -20,12 +20,12 @@ import com.intellij.codeInsight.intention.LowPriorityAction
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.ScrollType import com.intellij.openapi.editor.ScrollType
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
import org.jetbrains.kotlin.idea.intentions.setReceiverType import org.jetbrains.kotlin.idea.intentions.setReceiverType
import org.jetbrains.kotlin.idea.quickfix.moveCaret import org.jetbrains.kotlin.idea.quickfix.moveCaret
import org.jetbrains.kotlin.idea.quickfix.unblockDocument
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
@@ -44,7 +44,7 @@ class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtCallable
//TODO: local class //TODO: local class
override fun applyTo(element: KtCallableDeclaration, editor: Editor) { override fun applyTo(element: KtCallableDeclaration, editor: Editor?) {
val descriptor = element.resolveToDescriptor() val descriptor = element.resolveToDescriptor()
val containingClass = descriptor.containingDeclaration as ClassDescriptor val containingClass = descriptor.containingDeclaration as ClassDescriptor
@@ -125,15 +125,17 @@ class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtCallable
} }
} }
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.document) editor?.apply {
unblockDocument()
if (bodyToSelect != null) { if (bodyToSelect != null) {
val range = bodyToSelect!!.textRange val range = bodyToSelect!!.textRange
editor.moveCaret(range.startOffset, ScrollType.CENTER) moveCaret(range.startOffset, ScrollType.CENTER)
editor.selectionModel.setSelection(range.startOffset, range.endOffset) selectionModel.setSelection(range.startOffset, range.endOffset)
} }
else { else {
editor.moveCaret(extension.textOffset, ScrollType.CENTER) moveCaret(extension.textOffset, ScrollType.CENTER)
}
} }
} }
@@ -31,7 +31,7 @@ class SplitPropertyDeclarationIntention : SelfTargetingRangeIntention<KtProperty
return TextRange(element.startOffset, initializer.startOffset) return TextRange(element.startOffset, initializer.startOffset)
} }
override fun applyTo(element: KtProperty, editor: Editor) { override fun applyTo(element: KtProperty, editor: Editor?) {
splitPropertyDeclaration(element) splitPropertyDeclaration(element)
} }
} }
@@ -55,7 +55,7 @@ class AddConstModifierFix(val property: KtProperty) : AddModifierFix(property, K
} }
class AddConstModifierIntention : SelfTargetingIntention<KtProperty>(KtProperty::class.java, "Add 'const' modifier") { class AddConstModifierIntention : SelfTargetingIntention<KtProperty>(KtProperty::class.java, "Add 'const' modifier") {
override fun applyTo(element: KtProperty, editor: Editor) { override fun applyTo(element: KtProperty, editor: Editor?) {
AddConstModifierFix.addConstModifier(element) AddConstModifierFix.addConstModifier(element)
} }
@@ -41,10 +41,10 @@ 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.performDelayedShortening
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.refactoring.addTypeArgumentsIfNeeded import org.jetbrains.kotlin.idea.refactoring.addTypeArgumentsIfNeeded
import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively
import org.jetbrains.kotlin.idea.refactoring.getQualifiedTypeArgumentList import org.jetbrains.kotlin.idea.refactoring.getQualifiedTypeArgumentList
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.refactoring.move.PackageNameInfo import org.jetbrains.kotlin.idea.refactoring.move.PackageNameInfo
import org.jetbrains.kotlin.idea.refactoring.move.lazilyProcessInternalReferencesToUpdateOnPackageNameChange import org.jetbrains.kotlin.idea.refactoring.move.lazilyProcessInternalReferencesToUpdateOnPackageNameChange
import org.jetbrains.kotlin.idea.refactoring.move.postProcessMoveUsages import org.jetbrains.kotlin.idea.refactoring.move.postProcessMoveUsages
@@ -110,7 +110,7 @@ class KotlinInlineValHandler : InlineActionHandler() {
return expression.replaced(replacement).singletonList() return expression.replaced(replacement).singletonList()
} }
override fun inlineElement(project: Project, editor: Editor, element: PsiElement) { override fun inlineElement(project: Project, editor: Editor?, element: PsiElement) {
val declaration = element as KtProperty val declaration = element as KtProperty
val file = declaration.getContainingKtFile() val file = declaration.getContainingKtFile()
val name = declaration.name ?: return val name = declaration.name ?: return
@@ -243,13 +243,13 @@ class KotlinInlineValHandler : InlineActionHandler() {
} }
} }
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))
showErrorHint(project, editor, message) showErrorHint(project, editor, message)
} }
private fun showErrorHint(project: Project, editor: Editor, message: String) { private fun showErrorHint(project: Project, editor: Editor?, message: String) {
CommonRefactoringUtil.showErrorHint(project, editor, message, RefactoringBundle.message("inline.variable.title"), HelpID.INLINE_VARIABLE) CommonRefactoringUtil.showErrorHint(project, editor, message, RefactoringBundle.message("inline.variable.title"), HelpID.INLINE_VARIABLE)
} }
@@ -24,8 +24,8 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
import org.jetbrains.kotlin.idea.refactoring.hasIdentifiersOnly
import org.jetbrains.kotlin.idea.intentions.SelfTargetingOffsetIndependentIntention import org.jetbrains.kotlin.idea.intentions.SelfTargetingOffsetIndependentIntention
import org.jetbrains.kotlin.idea.refactoring.hasIdentifiersOnly
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.FqNameUnsafe
@@ -38,11 +38,13 @@ class ChangePackageIntention: SelfTargetingOffsetIndependentIntention<KtPackageD
override fun isApplicableTo(element: KtPackageDirective) = element.packageNameExpression != null override fun isApplicableTo(element: KtPackageDirective) = element.packageNameExpression != null
override fun applyTo(element: KtPackageDirective, editor: Editor) { override fun applyTo(element: KtPackageDirective, editor: Editor?) {
if (ApplicationManager.getApplication().isUnitTestMode) { if (ApplicationManager.getApplication().isUnitTestMode) {
throw UnsupportedOperationException("Do not call applyTo() in the test mode") throw UnsupportedOperationException("Do not call applyTo() in the test mode")
} }
if (editor == null) throw IllegalArgumentException("This intention requires an editor")
val file = element.getContainingKtFile() val file = element.getContainingKtFile()
val project = file.project val project = file.project
@@ -43,7 +43,7 @@ class ChangePackageToMatchDirectoryIntention : SelfTargetingOffsetIndependentInt
return true return true
} }
override fun applyTo(element: KtPackageDirective, editor: Editor) { override fun applyTo(element: KtPackageDirective, editor: Editor?) {
val file = element.getContainingKtFile() val file = element.getContainingKtFile()
val newFqName = file.getFqNameByDirectory() val newFqName = file.getFqNameByDirectory()
if (!newFqName.toUnsafe().hasIdentifiersOnly()) return if (!newFqName.toUnsafe().hasIdentifiersOnly()) return
@@ -38,7 +38,7 @@ class MoveFileToPackageMatchingDirectoryIntention : SelfTargetingOffsetIndepende
return true return true
} }
override fun applyTo(element: KtPackageDirective, editor: Editor) { override fun applyTo(element: KtPackageDirective, editor: Editor?) {
val file = element.getContainingKtFile() val file = element.getContainingKtFile()
val project = file.project val project = file.project
val targetDirectory = MoveClassesOrPackagesUtil.chooseDestinationPackage( val targetDirectory = MoveClassesOrPackagesUtil.chooseDestinationPackage(
@@ -24,9 +24,9 @@ import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.refactoring.move.MoveCallback import com.intellij.refactoring.move.MoveCallback
import com.intellij.refactoring.util.CommonRefactoringUtil import com.intellij.refactoring.util.CommonRefactoringUtil
import org.jetbrains.kotlin.idea.refactoring.createKotlinFile
import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
import org.jetbrains.kotlin.idea.quickfix.moveCaret import org.jetbrains.kotlin.idea.quickfix.moveCaret
import org.jetbrains.kotlin.idea.refactoring.createKotlinFile
import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.ui.MoveKotlinTopLevelDeclarationsDialog import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.ui.MoveKotlinTopLevelDeclarationsDialog
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClass
@@ -58,7 +58,8 @@ class MoveDeclarationToSeparateFileIntention :
return TextRange(startOffset, endOffset) return TextRange(startOffset, endOffset)
} }
override fun applyTo(element: KtClassOrObject, editor: Editor) { override fun applyTo(element: KtClassOrObject, editor: Editor?) {
if (editor == null) throw IllegalArgumentException("This intention requires an editor")
val file = element.getContainingKtFile() val file = element.getContainingKtFile()
val project = file.project val project = file.project
val originalOffset = editor.caretModel.offset - element.startOffset val originalOffset = editor.caretModel.offset - element.startOffset

Some files were not shown because too many files have changed in this diff Show More