Refactored intentions to replace special name calls with operators

This commit is contained in:
Valentin Kipyatkov
2015-05-12 13:53:27 +03:00
parent fbc3fa2b09
commit 8095aabd42
42 changed files with 172 additions and 390 deletions
@@ -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
@@ -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<out CallableDescriptor>? {
val callExpression = callExpression ?: return null
return callExpression.getResolvedCall(callExpression.analyze()) ?: return 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<out CallableDescriptor>
) {
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<List<ValueArgument>, 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<JetDotQualifiedExpression>(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<Any?> = 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<V: Any>(editor: Editor, maybeValue: Maybe<V, String>): V? {
return when (maybeValue) {
is MaybeValue -> maybeValue.value
is MaybeError -> {
intentionFailed(editor, maybeValue.error)
null
}
else -> throw NoWhenBranchMatchedException()
}
}
}
@@ -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<JetDotQualifiedExpression>(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<Any?> {
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
)
)
}
}
@@ -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<JetDotQualifiedExpression>(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))
}
}
@@ -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<JetDotQualifiedExpression>(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)
}
}
@@ -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<JetDotQualifiedExpression>(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)
}
}
@@ -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<JetDotQualifiedExpression>(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<Any?> {
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()
))
}
}
@@ -1 +1 @@
org.jetbrains.kotlin.idea.intentions.TestableReplaceBinaryInfixIntention
org.jetbrains.kotlin.idea.intentions.attributeCallReplacements.ReplaceBinaryInfixIntention
@@ -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
@@ -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
@@ -1 +1 @@
org.jetbrains.kotlin.idea.intentions.TestableReplaceContainsIntention
org.jetbrains.kotlin.idea.intentions.attributeCallReplacements.ReplaceContainsIntention
@@ -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{
@@ -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{
@@ -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
@@ -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
@@ -1 +1 @@
org.jetbrains.kotlin.idea.intentions.TestableReplaceGetIntention
org.jetbrains.kotlin.idea.intentions.attributeCallReplacements.ReplaceGetIntention
@@ -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() {
@@ -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{
@@ -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.g<caret>et(0)
}
@@ -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
@@ -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.g<caret>et(a=1, c=3, b=2, d=4) { i ->
i
}
}
@@ -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
}]
}
@@ -1,7 +0,0 @@
fun test() {
class Test{
fun get(a: Int) : Int = 0
}
val test = Test()
test.g<caret>et(a=1)
}
@@ -1,7 +0,0 @@
fun test() {
class Test{
fun get(a: Int) : Int = 0
}
val test = Test()
test[1]
}
@@ -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
@@ -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
@@ -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]
}
@@ -1 +1 @@
org.jetbrains.kotlin.idea.intentions.TestableReplaceInvokeIntention
org.jetbrains.kotlin.idea.intentions.attributeCallReplacements.ReplaceInvokeIntention
@@ -0,0 +1,7 @@
fun test() {
class Test(val v: Int)
fun Test.invoke(): Unit = Unit
Test(1).i<caret>nvoke()
}
@@ -0,0 +1,7 @@
fun test() {
class Test(val v: Int)
fun Test.invoke(): Unit = Unit
Test(1)<caret>()
}
@@ -1 +1 @@
org.jetbrains.kotlin.idea.intentions.TestableReplaceUnaryPrefixIntention
org.jetbrains.kotlin.idea.intentions.attributeCallReplacements.ReplaceUnaryPrefixIntention
@@ -1,4 +1,4 @@
// INTENTION_TEXT: Replace with '-' prefix
// INTENTION_TEXT: Replace with '-' operator
fun test() {
class Test {
fun minus(): Test = Test()
@@ -1,4 +1,4 @@
// INTENTION_TEXT: Replace with '-' prefix
// INTENTION_TEXT: Replace with '-' operator
fun test() {
class Test {
fun minus(): Test = Test()
@@ -1,4 +1,4 @@
// INTENTION_TEXT: Replace with '!' prefix
// INTENTION_TEXT: Replace with '!' operator
fun test() {
class Test {
fun not(): Test = Test()
@@ -1,4 +1,4 @@
// INTENTION_TEXT: Replace with '!' prefix
// INTENTION_TEXT: Replace with '!' operator
fun test() {
class Test {
fun not(): Test = Test()
@@ -1,4 +1,4 @@
// INTENTION_TEXT: Replace with '+' prefix
// INTENTION_TEXT: Replace with '+' operator
fun test() {
class Test {
fun plus(): Test = Test()
@@ -1,4 +1,4 @@
// INTENTION_TEXT: Replace with '+' prefix
// INTENTION_TEXT: Replace with '+' operator
fun test() {
class Test {
fun plus(): Test = Test()
@@ -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(), ", "));
}
@@ -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
@@ -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)
@@ -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");