From 8095aabd42c4e13c82a9c2fd54bf35d4fb64f324 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Tue, 12 May 2015 13:53:27 +0300 Subject: [PATCH] Refactored intentions to replace special name calls with operators --- .../kotlin/idea/JetBundle.properties | 16 -- .../jetbrains/kotlin/idea/intentions/Utils.kt | 16 +- .../AttributeCallReplacementIntention.kt | 137 ------------------ .../ReplaceBinaryInfixIntention.kt | 54 +++---- .../ReplaceContainsIntention.kt | 45 +++--- .../ReplaceGetIntention.kt | 42 ++++-- .../ReplaceInvokeIntention.kt | 25 ++-- .../ReplaceUnaryPrefixIntention.kt | 44 +++--- .../replaceBinaryInfixIntention/.intention | 2 +- .../missingDefaultArgument.kt | 2 +- .../unacceptableVararg1.kt | 2 +- .../replaceContainsIntention/.intention | 2 +- .../invalidArgument.kt | 2 +- .../missingArgument.kt | 2 +- .../missingDefaultArgument.kt | 2 +- .../unacceptableVararg1.kt | 2 +- .../replaceGetIntention/.intention | 2 +- .../replaceGetIntention/duplicateArguments.kt | 2 +- .../replaceGetIntention/invalidArgument.kt | 2 +- .../replaceGetIntention/missingArgument.kt | 9 -- .../missingDefaultArgument.kt | 2 +- .../replaceGetIntention/namedAndFunction.kt | 9 -- .../namedAndFunction.kt.after | 9 -- .../singleNamedArgument.kt | 7 - .../singleNamedArgument.kt.after | 7 - .../replaceGetIntention/unacceptableVararg.kt | 2 +- .../replaceGetIntention/unnamedAndNamed.kt | 1 + .../unnamedAndNamed.kt.after | 7 - .../replaceInvokeIntention/.intention | 2 +- .../expressionReceiver.kt | 7 + .../expressionReceiver.kt.after | 7 + .../replaceUnaryPrefixIntention/.intention | 2 +- .../minusSanityTest.kt | 2 +- .../minusSanityTest.kt.after | 2 +- .../notSanityTest.kt | 2 +- .../notSanityTest.kt.after | 2 +- .../plusSanityTest.kt | 2 +- .../plusSanityTest.kt.after | 2 +- .../intentions/AbstractIntentionTest.java | 3 - ...buteCallReplacementIntentionTestHelpers.kt | 32 ---- .../idea/intentions/IntentionTestException.kt | 19 --- .../intentions/IntentionTestGenerated.java | 24 +-- 42 files changed, 172 insertions(+), 390 deletions(-) delete mode 100644 idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/AttributeCallReplacementIntention.kt delete mode 100644 idea/testData/intentions/attributeCallReplacements/replaceGetIntention/missingArgument.kt delete mode 100644 idea/testData/intentions/attributeCallReplacements/replaceGetIntention/namedAndFunction.kt delete mode 100644 idea/testData/intentions/attributeCallReplacements/replaceGetIntention/namedAndFunction.kt.after delete mode 100644 idea/testData/intentions/attributeCallReplacements/replaceGetIntention/singleNamedArgument.kt delete mode 100644 idea/testData/intentions/attributeCallReplacements/replaceGetIntention/singleNamedArgument.kt.after delete mode 100644 idea/testData/intentions/attributeCallReplacements/replaceGetIntention/unnamedAndNamed.kt.after create mode 100644 idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/expressionReceiver.kt create mode 100644 idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/expressionReceiver.kt.after delete mode 100644 idea/tests/org/jetbrains/kotlin/idea/intentions/AttributeCallReplacementIntentionTestHelpers.kt delete mode 100644 idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestException.kt diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties index 3c8d9110526..3c6ea7392fa 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties @@ -88,22 +88,6 @@ replace.call.error.invalid.arguments=Invalid arguments included. replace.call.error.vararg.not.last=Cannot handle named arguments after a vararg. replace.call.error.contains.returns_boolean=Contains must return a Boolean. -replace.get.with.index=Replace 'get' call with index operator -replace.get.with.index.family=Replace Get - -replace.contains.with.in=Replace 'contains' call with in operator -replace.contains.with.in.family=Replace Contains - -replace.invoke.with.call=Replace 'invoke' with direct call -replace.invoke.with.call.family=Replace Invoke - -replace.unary.operator.with.prefix=Replace with ''{0}'' prefix -replace.unary.operator.with.prefix.family=Replace Unary Operator - -replace.binary.operator.with.infix=Replace with ''{0}'' operator -replace.binary.operator.with.infix.family=Replace Binary Operator - - add.kotlin.signature.action.family.name=Specify Custom Kotlin Signature add.kotlin.signature.action.text=Specify custom Kotlin signature edit.kotlin.signature.action.text=Edit custom Kotlin signature diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/Utils.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/Utils.kt index 7b4012f0076..98a1da0d82d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/Utils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/Utils.kt @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.openapi.util.TextRange import org.jetbrains.kotlin.JetNodeTypes -import org.jetbrains.kotlin.analyzer.analyzeInContext import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor @@ -31,8 +30,9 @@ import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.typeRefHelpers.setReceiverTypeReference import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.types.JetType -import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf fun JetCallableDeclaration.setType(type: JetType) { if (type.isError()) return @@ -102,3 +102,15 @@ fun splitPropertyDeclaration(property: JetProperty): JetBinaryExpression { return assignment } + +val JetQualifiedExpression.callExpression: JetCallExpression? + get() = getSelectorExpression() as? JetCallExpression + +val JetQualifiedExpression.functionName: String? + get() = (callExpression?.getCalleeExpression() as? JetSimpleNameExpression)?.getText() + +fun JetQualifiedExpression.toResolvedCall(): ResolvedCall? { + val callExpression = callExpression ?: return null + return callExpression.getResolvedCall(callExpression.analyze()) ?: return null +} + diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/AttributeCallReplacementIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/AttributeCallReplacementIntention.kt deleted file mode 100644 index d4f2431e9b6..00000000000 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/AttributeCallReplacementIntention.kt +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.idea.intentions.attributeCallReplacements - -import com.intellij.codeInsight.hint.HintManager -import com.intellij.openapi.editor.Editor -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.idea.JetBundle -import org.jetbrains.kotlin.idea.caches.resolve.analyze -import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingOffsetIndependentIntention -import org.jetbrains.kotlin.idea.util.Maybe -import org.jetbrains.kotlin.idea.util.MaybeError -import org.jetbrains.kotlin.idea.util.MaybeValue -import org.jetbrains.kotlin.psi.JetCallExpression -import org.jetbrains.kotlin.psi.JetDotQualifiedExpression -import org.jetbrains.kotlin.psi.JetQualifiedExpression -import org.jetbrains.kotlin.psi.ValueArgument -import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument -import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall -import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument - -// Internal because you shouldn't construct this manually. You can end up with an inconsistant CallDescription. -public class CallDescription internal ( - public val element: JetQualifiedExpression, - public val callElement: JetCallExpression, - public val resolved: ResolvedCall -) { - public val functionName: String? - get() = callElement.getCalleeExpression()?.getText() - - public val argumentCount: Int - get() = callElement.getValueArguments().size - - public val hasTypeArguments: Boolean - get() = callElement.getTypeArgumentList() != null - - public val hasEmptyArguments: Boolean - get() = callElement.getValueArguments().any { it?.getArgumentExpression() == null } - - public fun getPositionalArguments(): Maybe, String> { - - val resolvedValueArguments = resolved.getValueArgumentsByIndex() - ?: return MaybeError("duplicate.or.missing.arguments") - - // Check for mixed default and passed arguments and return the passed parameters (or fail) - val indexOfFirstDefaultArgument = resolvedValueArguments.indexOf(DefaultValueArgument.DEFAULT) - val valueArgumentGroups = if (indexOfFirstDefaultArgument >= 0) { - if (resolvedValueArguments.listIterator(indexOfFirstDefaultArgument).any { it != DefaultValueArgument.DEFAULT }) { - return MaybeError("skipped.defaults") - } - resolvedValueArguments.subList(0, indexOfFirstDefaultArgument) - } else { - resolvedValueArguments - } - - // The vararg must be the last (passed) argument - if (valueArgumentGroups.size > 0) { - val vararg = valueArgumentGroups.find { it is VarargValueArgument } - if (vararg != null && vararg != valueArgumentGroups.last) { - return MaybeError("vararg.not.last") - } - } - - val valueArguments = valueArgumentGroups.flatMap { it.getArguments() } - if (valueArguments.size < argumentCount) { - // Only happens if invalid arguments were thrown away. - return MaybeError("invalid.arguments") - } - - return MaybeValue(valueArguments) - } -} - -public fun JetQualifiedExpression.toCallDescription(): CallDescription? { - val callExpression = getSelectorExpression() as? JetCallExpression ?: return null - - val bindingContext = callExpression.analyze() - // This should work. Nothing that returns a CallableDescriptor returns null and (out T is T) - val resolvedCall = callExpression.getResolvedCall(bindingContext) ?: - return null - - return CallDescription(this, callExpression, resolvedCall) -} - -public abstract class AttributeCallReplacementIntention(private val name: String) : JetSelfTargetingOffsetIndependentIntention(name, javaClass()) { - - protected abstract fun isApplicableToCall(call: CallDescription): Boolean - - protected abstract fun replaceCall(call: CallDescription, editor: Editor): Unit - protected open fun formatArgumentsFor(call: CallDescription): Array = array() - - final override fun isApplicableTo(element: JetDotQualifiedExpression): Boolean { - val callDescription = element.toCallDescription() - if (callDescription != null && isApplicableToCall(callDescription)) { - setText(JetBundle.message(name, *formatArgumentsFor(callDescription))) - return true - } else { - return false - } - } - - final override fun applyTo(element: JetDotQualifiedExpression, editor: Editor) { - // If this doesn't work, something is very wrong (isApplicableTo failed). - replaceCall(element.toCallDescription()!!, editor) - } - - protected open fun intentionFailed(editor: Editor, messageId: String, vararg values: Any?) { - val message = "Intention failed: ${JetBundle.message("replace.call.error.${messageId}", *values)}" - HintManager.getInstance().showErrorHint(editor, message) - } - - protected fun handleErrors(editor: Editor, maybeValue: Maybe): V? { - return when (maybeValue) { - is MaybeValue -> maybeValue.value - is MaybeError -> { - intentionFailed(editor, maybeValue.error) - null - } - else -> throw NoWhenBranchMatchedException() - } - } -} diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceBinaryInfixIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceBinaryInfixIntention.kt index 965644a1d8d..5b0d322941d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceBinaryInfixIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceBinaryInfixIntention.kt @@ -17,13 +17,37 @@ package org.jetbrains.kotlin.idea.intentions.attributeCallReplacements import com.intellij.openapi.editor.Editor +import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingOffsetIndependentIntention +import org.jetbrains.kotlin.idea.intentions.callExpression +import org.jetbrains.kotlin.idea.intentions.functionName +import org.jetbrains.kotlin.idea.intentions.toResolvedCall +import org.jetbrains.kotlin.psi.JetDotQualifiedExpression import org.jetbrains.kotlin.psi.JetPsiFactory import org.jetbrains.kotlin.psi.createExpressionByPattern +import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch -public open class ReplaceBinaryInfixIntention : AttributeCallReplacementIntention("replace.binary.operator.with.infix") { +public class ReplaceBinaryInfixIntention : JetSelfTargetingOffsetIndependentIntention(javaClass(), "Replace call with binary operator") { + override fun isApplicableTo(element: JetDotQualifiedExpression): Boolean { + val operation = operation(element.functionName) ?: return false + val resolvedCall = element.toResolvedCall() ?: return false + if (!resolvedCall.getStatus().isSuccess()) return false + if (resolvedCall.getCall().getTypeArgumentList() != null) return false + val argument = resolvedCall.getCall().getValueArguments().singleOrNull() ?: return false + if ((resolvedCall.getArgumentMapping(argument) as ArgumentMatch).valueParameter.getIndex() != 0) return false + setText("Replace with '$operation' operator") + return true + } - private fun lookup(name: String?): String? { - return when (name) { + override fun applyTo(element: JetDotQualifiedExpression, editor: Editor) { + val operation = operation(element.functionName)!! + val argument = element.callExpression!!.getValueArguments().single().getArgumentExpression()!! + val receiver = element.getReceiverExpression() + + element.replace(JetPsiFactory(element).createExpressionByPattern("$0 $operation $1", receiver, argument)) + } + + private fun operation(functionName: String?): String? { + return when (functionName) { "plus" -> "+" "minus" -> "-" "div" -> "/" @@ -33,28 +57,4 @@ public open class ReplaceBinaryInfixIntention : AttributeCallReplacementIntentio else -> null } } - - override fun formatArgumentsFor(call: CallDescription): Array { - return array(lookup(call.functionName)) - } - - override fun isApplicableToCall(call: CallDescription): Boolean { - return ( - lookup(call.functionName) != null && - call.argumentCount == 1 && - !call.hasTypeArguments && - !call.hasEmptyArguments - ) - } - - override fun replaceCall(call: CallDescription, editor: Editor) { - val argument = (handleErrors(editor, call.getPositionalArguments()) ?: return)[0].getArgumentExpression() - - val operation = lookup(call.functionName)!! // Lookup must succeed - call.element.replace( - JetPsiFactory(call.element).createExpressionByPattern("$0 $operation $1", - call.element.getReceiverExpression(), argument - ) - ) - } } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceContainsIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceContainsIntention.kt index 264ebb4010f..6cbd3b978c2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceContainsIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceContainsIntention.kt @@ -16,34 +16,38 @@ package org.jetbrains.kotlin.idea.intentions.attributeCallReplacements -import org.jetbrains.kotlin.lexer.JetTokens import com.intellij.openapi.editor.Editor -import org.jetbrains.kotlin.types.checker.JetTypeChecker -import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingOffsetIndependentIntention +import org.jetbrains.kotlin.idea.intentions.callExpression +import org.jetbrains.kotlin.idea.intentions.functionName +import org.jetbrains.kotlin.idea.intentions.toResolvedCall +import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns +import org.jetbrains.kotlin.types.expressions.OperatorConventions -public open class ReplaceContainsIntention : AttributeCallReplacementIntention("replace.contains.with.in") { +public class ReplaceContainsIntention : JetSelfTargetingOffsetIndependentIntention(javaClass(), "Replace 'contains' call with 'in' operator") { + override fun isApplicableTo(element: JetDotQualifiedExpression): Boolean { + if (element.functionName != OperatorConventions.CONTAINS.asString()) return false + val resolvedCall = element.toResolvedCall() ?: return false + if (!resolvedCall.getStatus().isSuccess()) return false + val argument = resolvedCall.getCall().getValueArguments().singleOrNull() ?: return false + if ((resolvedCall.getArgumentMapping(argument) as ArgumentMatch).valueParameter.getIndex() != 0) return false - override fun isApplicableToCall(call: CallDescription): Boolean { - return call.functionName == "contains" && call.argumentCount == 1 && !call.hasEmptyArguments + val target = resolvedCall.getResultingDescriptor() + val returnType = target.getReturnType() ?: return false + return target.builtIns.isBooleanOrSubtype(returnType) } - override fun replaceCall(call: CallDescription, editor: Editor) { - val resultingDescriptor = call.resolved.getResultingDescriptor() - val ret = resultingDescriptor.getReturnType() - ?: return intentionFailed(editor, "undefined.returntype") - - if (!resultingDescriptor.builtIns.isBooleanOrSubtype(ret)) { - return intentionFailed(editor, "contains.returns.boolean") - } - - val argument = (handleErrors(editor, call.getPositionalArguments()) ?: return)[0].getArgumentExpression() + override fun applyTo(element: JetDotQualifiedExpression, editor: Editor) { + val argument = element.callExpression!!.getValueArguments().single().getArgumentExpression()!! + val receiver = element.getReceiverExpression() // Append semicolon to previous statement if needed - val psiFactory = JetPsiFactory(call.element) + val psiFactory = JetPsiFactory(element) if (argument is JetFunctionLiteralExpression) { - val previousElement = JetPsiUtil.skipSiblingsBackwardByPredicate(call.element) { + val previousElement = JetPsiUtil.skipSiblingsBackwardByPredicate(element) { // I checked, it can't be null. it!!.getNode()?.getElementType() in JetTokens.WHITE_SPACE_OR_COMMENT_BIT_SET } @@ -53,9 +57,6 @@ public open class ReplaceContainsIntention : AttributeCallReplacementIntention(" } } - call.element.replace(psiFactory.createExpressionByPattern("$0 in $1", - argument, - call.element.getReceiverExpression() - )) + element.replace(psiFactory.createExpressionByPattern("$0 in $1", argument, receiver)) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceGetIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceGetIntention.kt index 35f9a477e40..4e7e9a7f70c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceGetIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceGetIntention.kt @@ -17,21 +17,41 @@ package org.jetbrains.kotlin.idea.intentions.attributeCallReplacements import com.intellij.openapi.editor.Editor +import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingOffsetIndependentIntention +import org.jetbrains.kotlin.idea.intentions.callExpression +import org.jetbrains.kotlin.idea.intentions.functionName +import org.jetbrains.kotlin.psi.JetDotQualifiedExpression import org.jetbrains.kotlin.psi.JetPsiFactory +import org.jetbrains.kotlin.psi.buildExpression +import org.jetbrains.kotlin.psi.createExpressionByPattern -public open class ReplaceGetIntention : AttributeCallReplacementIntention("replace.get.with.index") { - - override fun isApplicableToCall(call: CallDescription): Boolean { - return (call.functionName == "get" && !call.hasTypeArguments && call.argumentCount > 0) +public class ReplaceGetIntention : JetSelfTargetingOffsetIndependentIntention(javaClass(), "Replace 'get' call with index operator") { + override fun isApplicableTo(element: JetDotQualifiedExpression): Boolean { + if (element.functionName != "get") return false + val call = element.callExpression ?: return false + if (call.getTypeArgumentList() != null) return false + val arguments = call.getValueArguments() + if (arguments.isEmpty()) return false + if (arguments.any { it.isNamed() }) return false + return true } - override fun replaceCall(call: CallDescription, editor: Editor) { - val argumentString = (handleErrors(editor, call.getPositionalArguments()) ?: return).map { - it.getArgumentExpression()?.getText() ?: "" - }.makeString(", ") + override fun applyTo(element: JetDotQualifiedExpression, editor: Editor) { + val expression = JetPsiFactory(element).buildExpression { + appendExpression(element.getReceiverExpression()) - call.element.replace(JetPsiFactory(call.element).createExpression( - "${call.element.getReceiverExpression().getText()}[${argumentString}]" - )) + appendFixedText("[") + + val call = element.callExpression!! + for ((index, argument) in call.getValueArguments().withIndex()) { + if (index > 0) { + appendFixedText(",") + } + appendExpression(argument.getArgumentExpression()) + } + + appendFixedText("]") + } + element.replace(expression) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceInvokeIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceInvokeIntention.kt index ace56492d2a..7ddbe70e13b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceInvokeIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceInvokeIntention.kt @@ -17,21 +17,22 @@ package org.jetbrains.kotlin.idea.intentions.attributeCallReplacements import com.intellij.openapi.editor.Editor -import org.jetbrains.kotlin.psi.JetPsiFactory +import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingOffsetIndependentIntention +import org.jetbrains.kotlin.idea.intentions.callExpression +import org.jetbrains.kotlin.idea.intentions.functionName +import org.jetbrains.kotlin.psi.JetCallExpression +import org.jetbrains.kotlin.psi.JetDotQualifiedExpression import org.jetbrains.kotlin.types.expressions.OperatorConventions -public open class ReplaceInvokeIntention : AttributeCallReplacementIntention("replace.invoke.with.call") { - - override fun isApplicableToCall(call: CallDescription): Boolean { - return call.functionName == OperatorConventions.INVOKE.asString() +public class ReplaceInvokeIntention : JetSelfTargetingOffsetIndependentIntention(javaClass(), "Replace 'invoke' with direct call") { + override fun isApplicableTo(element: JetDotQualifiedExpression): Boolean { + return element.functionName == OperatorConventions.INVOKE.asString() } - override fun replaceCall(call: CallDescription, editor: Editor) { - call.element.replace(JetPsiFactory(call.element).createExpression( - call.element.getReceiverExpression().getText() + - (call.callElement.getTypeArgumentList()?.getText() ?: "") + - (call.callElement.getValueArgumentList()?.getText() ?: "") + - (call.callElement.getFunctionLiteralArguments().fold("") { a, b -> a + " " + b.getText() }) - )) + override fun applyTo(element: JetDotQualifiedExpression, editor: Editor) { + val receiver = element.getReceiverExpression() + val callExpression = element.callExpression!! + callExpression.getCalleeExpression()!!.replace(receiver) + element.replace(callExpression) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceUnaryPrefixIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceUnaryPrefixIntention.kt index 298bf6a3fa1..2f1925db378 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceUnaryPrefixIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/attributeCallReplacements/ReplaceUnaryPrefixIntention.kt @@ -17,35 +17,35 @@ package org.jetbrains.kotlin.idea.intentions.attributeCallReplacements import com.intellij.openapi.editor.Editor +import org.jetbrains.kotlin.idea.intentions.JetSelfTargetingOffsetIndependentIntention +import org.jetbrains.kotlin.idea.intentions.callExpression +import org.jetbrains.kotlin.idea.intentions.functionName +import org.jetbrains.kotlin.psi.JetDotQualifiedExpression import org.jetbrains.kotlin.psi.JetPsiFactory +import org.jetbrains.kotlin.psi.createExpressionByPattern -public open class ReplaceUnaryPrefixIntention : AttributeCallReplacementIntention("replace.unary.operator.with.prefix") { +public class ReplaceUnaryPrefixIntention : JetSelfTargetingOffsetIndependentIntention(javaClass(), "Replace call with unary operator") { + override fun isApplicableTo(element: JetDotQualifiedExpression): Boolean { + val operation = operation(element.functionName) ?: return false + val call = element.callExpression ?: return false + if (call.getTypeArgumentList() != null) return false + if (!call.getValueArguments().isEmpty()) return false + setText("Replace with '$operation' operator") + return true + } - private fun lookup(name: String?) : String? { - return when (name) { + override fun applyTo(element: JetDotQualifiedExpression, editor: Editor) { + val operation = operation(element.functionName)!! + val receiver = element.getReceiverExpression() + element.replace(JetPsiFactory(element).createExpressionByPattern("$0$1", operation, receiver)) + } + + private fun operation(functionName: String?) : String? { + return when (functionName) { "plus" -> "+" "minus" -> "-" "not" -> "!" else -> null } } - - override fun formatArgumentsFor(call: CallDescription): Array { - return array(lookup(call.functionName)) - } - - override fun isApplicableToCall(call: CallDescription): Boolean { - return ( - lookup(call.functionName) != null && - !call.hasTypeArguments && - call.argumentCount == 0 && - call.callElement.getValueArgumentList() != null // Has argument expression - ) - } - - override fun replaceCall(call: CallDescription, editor: Editor) { - call.element.replace(JetPsiFactory(call.element).createExpression( - lookup(call.functionName)!! + call.element.getReceiverExpression().getText() - )) - } } diff --git a/idea/testData/intentions/attributeCallReplacements/replaceBinaryInfixIntention/.intention b/idea/testData/intentions/attributeCallReplacements/replaceBinaryInfixIntention/.intention index 39eaf87b972..f3775b2cb33 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceBinaryInfixIntention/.intention +++ b/idea/testData/intentions/attributeCallReplacements/replaceBinaryInfixIntention/.intention @@ -1 +1 @@ -org.jetbrains.kotlin.idea.intentions.TestableReplaceBinaryInfixIntention +org.jetbrains.kotlin.idea.intentions.attributeCallReplacements.ReplaceBinaryInfixIntention diff --git a/idea/testData/intentions/attributeCallReplacements/replaceBinaryInfixIntention/missingDefaultArgument.kt b/idea/testData/intentions/attributeCallReplacements/replaceBinaryInfixIntention/missingDefaultArgument.kt index 208a6934658..74c439d9c9c 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceBinaryInfixIntention/missingDefaultArgument.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceBinaryInfixIntention/missingDefaultArgument.kt @@ -1,4 +1,4 @@ -// SHOULD_FAIL_WITH: skipped.defaults +// IS_APPLICABLE: false fun test() { class Test{ fun plus(a: Int=1, b: Int=2) : Int = 0 diff --git a/idea/testData/intentions/attributeCallReplacements/replaceBinaryInfixIntention/unacceptableVararg1.kt b/idea/testData/intentions/attributeCallReplacements/replaceBinaryInfixIntention/unacceptableVararg1.kt index eacd3ae2b63..1f35db9a9dc 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceBinaryInfixIntention/unacceptableVararg1.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceBinaryInfixIntention/unacceptableVararg1.kt @@ -1,4 +1,4 @@ -// SHOULD_FAIL_WITH: vararg.not.last +// IS_APPLICABLE: false fun test() { class Test{ fun plus(vararg b: Int, c: Int = 0): Int = 0 diff --git a/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/.intention b/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/.intention index 623313ace82..ff0a202579b 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/.intention +++ b/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/.intention @@ -1 +1 @@ -org.jetbrains.kotlin.idea.intentions.TestableReplaceContainsIntention +org.jetbrains.kotlin.idea.intentions.attributeCallReplacements.ReplaceContainsIntention diff --git a/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/invalidArgument.kt b/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/invalidArgument.kt index 345f4b7a247..416db198712 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/invalidArgument.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/invalidArgument.kt @@ -1,4 +1,4 @@ -// SHOULD_FAIL_WITH: invalid.arguments +// IS_APPLICABLE: false // ERROR: Cannot find a parameter with this name: c fun test() { class Test{ diff --git a/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/missingArgument.kt b/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/missingArgument.kt index 2ba79491ec8..7e17ef74646 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/missingArgument.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/missingArgument.kt @@ -1,4 +1,4 @@ -// SHOULD_FAIL_WITH: duplicate.or.missing.arguments +// IS_APPLICABLE: false // ERROR: No value passed for parameter b fun test() { class Test{ diff --git a/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/missingDefaultArgument.kt b/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/missingDefaultArgument.kt index f832a3252ca..0b39ef3b252 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/missingDefaultArgument.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/missingDefaultArgument.kt @@ -1,4 +1,4 @@ -// SHOULD_FAIL_WITH: skipped.defaults +// IS_APPLICABLE: false fun test() { class Test{ fun contains(a: Int=1, b: Int=2) : Boolean = true diff --git a/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/unacceptableVararg1.kt b/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/unacceptableVararg1.kt index 28f06c033ab..07ab808e147 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/unacceptableVararg1.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceContainsIntention/unacceptableVararg1.kt @@ -1,4 +1,4 @@ -// SHOULD_FAIL_WITH: vararg.not.last +// IS_APPLICABLE: false fun test() { class Test{ fun contains(vararg b: Int, c: Int = 0): Boolean = true diff --git a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/.intention b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/.intention index 1ddcfc1d8e6..f3429fda20d 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/.intention +++ b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/.intention @@ -1 +1 @@ -org.jetbrains.kotlin.idea.intentions.TestableReplaceGetIntention +org.jetbrains.kotlin.idea.intentions.attributeCallReplacements.ReplaceGetIntention diff --git a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/duplicateArguments.kt b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/duplicateArguments.kt index 7d2ad08f496..08a23a6918d 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/duplicateArguments.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/duplicateArguments.kt @@ -1,4 +1,4 @@ -// SHOULD_FAIL_WITH: duplicate.or.missing.arguments +// IS_APPLICABLE: false // ERROR: An argument is already passed for this parameter // ERROR: No value passed for parameter b fun test() { diff --git a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/invalidArgument.kt b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/invalidArgument.kt index 97662b9c8da..fae3a7228b3 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/invalidArgument.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/invalidArgument.kt @@ -1,4 +1,4 @@ -// SHOULD_FAIL_WITH: invalid.arguments +// IS_APPLICABLE: false // ERROR: Cannot find a parameter with this name: c fun test() { class Test{ diff --git a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/missingArgument.kt b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/missingArgument.kt deleted file mode 100644 index 5f1efffb0c8..00000000000 --- a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/missingArgument.kt +++ /dev/null @@ -1,9 +0,0 @@ -// SHOULD_FAIL_WITH: duplicate.or.missing.arguments -// ERROR: No value passed for parameter b -fun test() { - class Test{ - fun get(a: Int, b: Int) : Int = 0 - } - val test = Test() - test.get(0) -} diff --git a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/missingDefaultArgument.kt b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/missingDefaultArgument.kt index 380f44662b4..effd2a05ed1 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/missingDefaultArgument.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/missingDefaultArgument.kt @@ -1,4 +1,4 @@ -// SHOULD_FAIL_WITH: skipped.defaults +// IS_APPLICABLE: false fun test() { class Test{ fun get(a: Int=1, b: Int=2) : Int = 0 diff --git a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/namedAndFunction.kt b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/namedAndFunction.kt deleted file mode 100644 index 6ff77e55489..00000000000 --- a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/namedAndFunction.kt +++ /dev/null @@ -1,9 +0,0 @@ -fun test() { - class Test{ - fun get(a: Int, b: Int, c: Int = 1, d: Int = 1, fn: (i: Int) -> Int) : Int = 0 - } - val test = Test() - test.get(a=1, c=3, b=2, d=4) { i -> - i - } -} diff --git a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/namedAndFunction.kt.after b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/namedAndFunction.kt.after deleted file mode 100644 index 6d2b6938019..00000000000 --- a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/namedAndFunction.kt.after +++ /dev/null @@ -1,9 +0,0 @@ -fun test() { - class Test{ - fun get(a: Int, b: Int, c: Int = 1, d: Int = 1, fn: (i: Int) -> Int) : Int = 0 - } - val test = Test() - test[1, 2, 3, 4, { i -> - i - }] -} diff --git a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/singleNamedArgument.kt b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/singleNamedArgument.kt deleted file mode 100644 index d9053a2d5e6..00000000000 --- a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/singleNamedArgument.kt +++ /dev/null @@ -1,7 +0,0 @@ -fun test() { - class Test{ - fun get(a: Int) : Int = 0 - } - val test = Test() - test.get(a=1) -} diff --git a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/singleNamedArgument.kt.after b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/singleNamedArgument.kt.after deleted file mode 100644 index 2af31855c25..00000000000 --- a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/singleNamedArgument.kt.after +++ /dev/null @@ -1,7 +0,0 @@ -fun test() { - class Test{ - fun get(a: Int) : Int = 0 - } - val test = Test() - test[1] -} diff --git a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/unacceptableVararg.kt b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/unacceptableVararg.kt index 9934d4c2f15..7e73e0d5d53 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/unacceptableVararg.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/unacceptableVararg.kt @@ -1,4 +1,4 @@ -// SHOULD_FAIL_WITH: vararg.not.last +// IS_APPLICABLE: false fun test() { class Test{ fun get(a: Int, vararg b: Int, c: Int = 0) : Int = 0 diff --git a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/unnamedAndNamed.kt b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/unnamedAndNamed.kt index 15ff47bc460..5e787a3ff16 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/unnamedAndNamed.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/unnamedAndNamed.kt @@ -1,3 +1,4 @@ +// IS_APPLICABLE: false fun test() { class Test{ fun get(a: Int = 0, b: Int = 1, c: Int = 2, d: Int = 3) : Int = 0 diff --git a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/unnamedAndNamed.kt.after b/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/unnamedAndNamed.kt.after deleted file mode 100644 index 24494f9a21a..00000000000 --- a/idea/testData/intentions/attributeCallReplacements/replaceGetIntention/unnamedAndNamed.kt.after +++ /dev/null @@ -1,7 +0,0 @@ -fun test() { - class Test{ - fun get(a: Int = 0, b: Int = 1, c: Int = 2, d: Int = 3) : Int = 0 - } - val test = Test() - test[1, 2, 3] -} diff --git a/idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/.intention b/idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/.intention index 35c627f86e1..356a056cad2 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/.intention +++ b/idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/.intention @@ -1 +1 @@ -org.jetbrains.kotlin.idea.intentions.TestableReplaceInvokeIntention +org.jetbrains.kotlin.idea.intentions.attributeCallReplacements.ReplaceInvokeIntention diff --git a/idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/expressionReceiver.kt b/idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/expressionReceiver.kt new file mode 100644 index 00000000000..2f428435004 --- /dev/null +++ b/idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/expressionReceiver.kt @@ -0,0 +1,7 @@ +fun test() { + class Test(val v: Int) + + fun Test.invoke(): Unit = Unit + + Test(1).invoke() +} diff --git a/idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/expressionReceiver.kt.after b/idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/expressionReceiver.kt.after new file mode 100644 index 00000000000..0d5b4518311 --- /dev/null +++ b/idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/expressionReceiver.kt.after @@ -0,0 +1,7 @@ +fun test() { + class Test(val v: Int) + + fun Test.invoke(): Unit = Unit + + Test(1)() +} diff --git a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/.intention b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/.intention index 624b88be701..5f14587eb83 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/.intention +++ b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/.intention @@ -1 +1 @@ -org.jetbrains.kotlin.idea.intentions.TestableReplaceUnaryPrefixIntention +org.jetbrains.kotlin.idea.intentions.attributeCallReplacements.ReplaceUnaryPrefixIntention diff --git a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/minusSanityTest.kt b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/minusSanityTest.kt index e1444ef9b23..e7c688262f8 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/minusSanityTest.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/minusSanityTest.kt @@ -1,4 +1,4 @@ -// INTENTION_TEXT: Replace with '-' prefix +// INTENTION_TEXT: Replace with '-' operator fun test() { class Test { fun minus(): Test = Test() diff --git a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/minusSanityTest.kt.after b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/minusSanityTest.kt.after index 67a51f3adbf..65d3c74b0d9 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/minusSanityTest.kt.after +++ b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/minusSanityTest.kt.after @@ -1,4 +1,4 @@ -// INTENTION_TEXT: Replace with '-' prefix +// INTENTION_TEXT: Replace with '-' operator fun test() { class Test { fun minus(): Test = Test() diff --git a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/notSanityTest.kt b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/notSanityTest.kt index 5e7e28f86a2..06f2029ed0d 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/notSanityTest.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/notSanityTest.kt @@ -1,4 +1,4 @@ -// INTENTION_TEXT: Replace with '!' prefix +// INTENTION_TEXT: Replace with '!' operator fun test() { class Test { fun not(): Test = Test() diff --git a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/notSanityTest.kt.after b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/notSanityTest.kt.after index 12911afe6cd..6696a902dec 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/notSanityTest.kt.after +++ b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/notSanityTest.kt.after @@ -1,4 +1,4 @@ -// INTENTION_TEXT: Replace with '!' prefix +// INTENTION_TEXT: Replace with '!' operator fun test() { class Test { fun not(): Test = Test() diff --git a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/plusSanityTest.kt b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/plusSanityTest.kt index 9698dda4932..5d3c231b2b2 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/plusSanityTest.kt +++ b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/plusSanityTest.kt @@ -1,4 +1,4 @@ -// INTENTION_TEXT: Replace with '+' prefix +// INTENTION_TEXT: Replace with '+' operator fun test() { class Test { fun plus(): Test = Test() diff --git a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/plusSanityTest.kt.after b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/plusSanityTest.kt.after index d3ca91bb988..84088da876c 100644 --- a/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/plusSanityTest.kt.after +++ b/idea/testData/intentions/attributeCallReplacements/replaceUnaryPrefixIntention/plusSanityTest.kt.after @@ -1,4 +1,4 @@ -// INTENTION_TEXT: Replace with '+' prefix +// INTENTION_TEXT: Replace with '+' operator fun test() { class Test { fun plus(): Test = Test() diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/AbstractIntentionTest.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/AbstractIntentionTest.java index 1c3d764395a..a23b5d30a44 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/AbstractIntentionTest.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/AbstractIntentionTest.java @@ -174,9 +174,6 @@ public abstract class AbstractIntentionTest extends KotlinCodeInsightTestCase { } assertNull("Expected test to fail.", shouldFailString); } - catch (IntentionTestException e) { - assertEquals("Failure message mismatch.", shouldFailString, e.getMessage()); - } catch (BaseRefactoringProcessor.ConflictsInTestsException e) { assertEquals("Failure message mismatch.", shouldFailString, StringUtil.join(e.getMessages(), ", ")); } diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/AttributeCallReplacementIntentionTestHelpers.kt b/idea/tests/org/jetbrains/kotlin/idea/intentions/AttributeCallReplacementIntentionTestHelpers.kt deleted file mode 100644 index 14318f8ed60..00000000000 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/AttributeCallReplacementIntentionTestHelpers.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.idea.intentions - -import com.intellij.openapi.editor.Editor -import org.jetbrains.kotlin.idea.intentions.attributeCallReplacements.* - -trait AttributeCallReplacementIntentionTestMixin : AttributeCallReplacementIntention { - protected override fun intentionFailed(editor: Editor, messageId: String, vararg values: Any?) { - throw IntentionTestException(messageId) - } -} - -class TestableReplaceGetIntention() : ReplaceGetIntention(), AttributeCallReplacementIntentionTestMixin -class TestableReplaceContainsIntention() : ReplaceContainsIntention(), AttributeCallReplacementIntentionTestMixin -class TestableReplaceBinaryInfixIntention() : ReplaceBinaryInfixIntention(), AttributeCallReplacementIntentionTestMixin -class TestableReplaceUnaryPrefixIntention() : ReplaceUnaryPrefixIntention(), AttributeCallReplacementIntentionTestMixin -class TestableReplaceInvokeIntention() : ReplaceInvokeIntention(), AttributeCallReplacementIntentionTestMixin diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestException.kt b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestException.kt deleted file mode 100644 index 7067bc36ce7..00000000000 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestException.kt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.idea.intentions - -public class IntentionTestException(message: String) : RuntimeException(message) diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index c6c391a9bbe..382508c65e9 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -372,12 +372,6 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } - @TestMetadata("missingArgument.kt") - public void testMissingArgument() throws Exception { - String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/attributeCallReplacements/replaceGetIntention/missingArgument.kt"); - doTest(fileName); - } - @TestMetadata("missingDefaultArgument.kt") public void testMissingDefaultArgument() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/attributeCallReplacements/replaceGetIntention/missingDefaultArgument.kt"); @@ -390,12 +384,6 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } - @TestMetadata("namedAndFunction.kt") - public void testNamedAndFunction() throws Exception { - String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/attributeCallReplacements/replaceGetIntention/namedAndFunction.kt"); - doTest(fileName); - } - @TestMetadata("noArgument.kt") public void testNoArgument() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/attributeCallReplacements/replaceGetIntention/noArgument.kt"); @@ -414,12 +402,6 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } - @TestMetadata("singleNamedArgument.kt") - public void testSingleNamedArgument() throws Exception { - String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/attributeCallReplacements/replaceGetIntention/singleNamedArgument.kt"); - doTest(fileName); - } - @TestMetadata("unacceptableVararg.kt") public void testUnacceptableVararg() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/attributeCallReplacements/replaceGetIntention/unacceptableVararg.kt"); @@ -442,6 +424,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("expressionReceiver.kt") + public void testExpressionReceiver() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/expressionReceiver.kt"); + doTest(fileName); + } + @TestMetadata("extensionFunction.kt") public void testExtensionFunction() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/attributeCallReplacements/replaceInvokeIntention/extensionFunction.kt");