Add replacement intentions for operator functions

Add intentions for replacing attribute calls that correspond to
overloadable operators with their respective operators.

This commit includes call replacements for:
 * Binary Infix Operators: plus, minus, times, rangeTo, mod, div
 * Unary Prefix Operators: plus, minus, not
 * Array Index Operator: get
 * In Operator: contains
This commit is contained in:
Steven Allen
2014-02-27 15:57:51 -05:00
parent 08a8d17e97
commit 84a8911822
152 changed files with 1922 additions and 1 deletions
@@ -379,6 +379,11 @@ fun main(args: Array<String>) {
model("intentions/replaceItWithExplicitFunctionLiteralParam", testMethod = "doTestReplaceItWithExplicitFunctionLiteralParam")
model("intentions/removeBraces", testMethod = "doTestRemoveBraces")
model("intentions/addBraces", testMethod = "doTestAddBraces")
model("intentions/attributeCallReplacements/replaceGetIntention", testMethod = "doTestReplaceGetIntention")
model("intentions/attributeCallReplacements/replaceContainsIntention", testMethod = "doTestReplaceContainsIntention")
model("intentions/attributeCallReplacements/replaceBinaryInfixIntention", testMethod = "doTestReplaceBinaryInfixIntention")
model("intentions/attributeCallReplacements/replaceUnaryPrefixIntention", testMethod = "doTestReplaceUnaryPrefixIntention")
model("intentions/attributeCallReplacements/replaceInvokeIntention", testMethod = "doTestReplaceInvokeIntention")
}
testClass(javaClass<AbstractHierarchyTest>()) {
@@ -0,0 +1,6 @@
a + b
a - b
a * b
a / b
a % b
a .. b
@@ -0,0 +1,6 @@
a.plus(b)
a.minus(b)
a.times(b)
a.div(b)
a.mod(b)
a.rangeTo(b)
@@ -0,0 +1,6 @@
<html>
<body>
This intention replaces any calls to infix operators
(<code>plus</code>, <code>minus</code>, <code>div</code>, <code>times</code>, <code>mod</code>, <code>rangeTo</code>) with their respective infixes.
</body>
</html>
@@ -0,0 +1 @@
a.contains(b)
@@ -0,0 +1,5 @@
<html>
<body>
This intention replaces <code>contains</code> member calls with the <code>in</code> operator.
</body>
</html>
@@ -0,0 +1 @@
inst[a, b]
@@ -0,0 +1 @@
inst.get(a, b)
@@ -0,0 +1,5 @@
<html>
<body>
This intention replaces <code>get</code> member calls with the array index operator (<code>[]</code>).
</body>
</html>
@@ -0,0 +1 @@
inst(a, b)
@@ -0,0 +1 @@
inst.invoke(a, b)
@@ -0,0 +1,5 @@
<html>
<body>
This intention replaces <code>invoke</code> member calls with a receiver call.
</body>
</html>
@@ -0,0 +1,3 @@
!inst
+inst
-inst
@@ -0,0 +1,3 @@
inst.not()
inst.plus()
inst.minus()
@@ -0,0 +1,5 @@
<html>
<body>
This intention replaces prefix member calls (<code>plus</code>, <code>minus</code>, <code>not</code>) with their respective prefixes.
</body>
</html>
+25
View File
@@ -399,6 +399,31 @@
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.jet.plugin.intentions.attributeCallReplacements.ReplaceGetIntention</className>
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.jet.plugin.intentions.attributeCallReplacements.ReplaceContainsIntention</className>
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.jet.plugin.intentions.attributeCallReplacements.ReplaceInvokeIntention</className>
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.jet.plugin.intentions.attributeCallReplacements.ReplaceUnaryPrefixIntention</className>
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.jet.plugin.intentions.attributeCallReplacements.ReplaceBinaryInfixIntention</className>
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.FoldIfToReturnAsymmetricallyIntention</className>
<category>Kotlin</category>
@@ -82,6 +82,30 @@ change.signature.family=Change signature of function/constructor
cast.expression.to.type=Cast expression ''{0}'' to ''{1}''
cast.expression.family=Cast Expression
replace.call.error.skipped.defaults=Cannot skip default arguments.
replace.call.error.undefined.returntype=Unable to determine the return type.
replace.call.error.duplicate.or.missing.arguments=Duplicate or missing arguments.
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
@@ -0,0 +1,140 @@
/*
* Copyright 2010-2014 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.jet.plugin.intentions.attributeCallReplacements
import org.jetbrains.jet.lang.psi.JetCallExpression
import com.intellij.openapi.editor.Editor
import org.jetbrains.jet.lang.psi.JetQualifiedExpression
import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression
import org.jetbrains.jet.plugin.intentions.JetSelfTargetingIntention
import com.intellij.openapi.ui.popup.JBPopupFactory
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.psi.ValueArgument
import org.jetbrains.jet.plugin.JetBundle
import org.jetbrains.jet.lang.resolve.calls.model.DefaultValueArgument
import org.jetbrains.jet.lang.resolve.calls.model.VarargValueArgument
abstract class Maybe<out V, out E>
public class Value<V, E>(public val value: V) : Maybe<V, E>()
public class Error<V, E>(public val error: E) : Maybe<V, E>()
// 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 + callElement.getFunctionLiteralArguments().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 Error("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 Error("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 Error("vararg.not.last")
}
}
val valueArguments = valueArgumentGroups.flatMap { it.getArguments() }
if (valueArguments.size < argumentCount) {
// Only happens if invalid arguments were thrown away.
return Error("invalid.arguments")
}
return Value(valueArguments)
}
}
public fun JetQualifiedExpression.toCallDescription(): CallDescription? {
val call = getSelectorExpression()
if (call !is JetCallExpression) return null
val bindingContext = AnalyzerFacadeWithCache.getContextForElement(call)
// This should work. Nothing that returns a CallableDescriptor returns null and (out T is T)
val resolvedCall = bindingContext[BindingContext.RESOLVED_CALL, call.getCalleeExpression()] ?:
return null
return CallDescription(this, call, resolvedCall)
}
public abstract class AttributeCallReplacementIntention(name: String) : JetSelfTargetingIntention<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(key, *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?) {
JBPopupFactory.getInstance()!!
.createMessage("Intention Failed: ${JetBundle.message("replace.call.error.${messageId}", *values)}")
.showInBestPositionFor(editor)
}
protected fun handleErrors<V: Any>(editor: Editor, maybeValue: Maybe<V, String>): V? {
return when (maybeValue) {
is Value -> maybeValue.value
is Error -> {
intentionFailed(editor, maybeValue.error)
null
}
else -> throw NoWhenBranchMatchedException()
}
}
}
@@ -0,0 +1,61 @@
/*
* Copyright 2010-2014 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.jet.plugin.intentions.attributeCallReplacements
import com.intellij.openapi.editor.Editor
import org.jetbrains.jet.lang.psi.JetPsiFactory
public open class ReplaceBinaryInfixIntention : AttributeCallReplacementIntention("replace.binary.operator.with.infix") {
private fun lookup(name: String?): String? {
return when (name) {
"plus" -> "+"
"minus" -> "-"
"div" -> "/"
"times" -> "*"
"mod" -> "%"
"rangeTo" -> ".."
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()
call.element.replace(
JetPsiFactory.createBinaryExpression(
call.element.getProject(),
call.element.getReceiverExpression(),
lookup(call.functionName)!!, // Lookup must succeed
argument
)
)
}
}
@@ -0,0 +1,63 @@
/*
* Copyright 2010-2014 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.jet.plugin.intentions.attributeCallReplacements
import org.jetbrains.jet.lang.psi.JetExpression
import org.jetbrains.jet.lexer.JetTokens
import com.intellij.openapi.editor.Editor
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.psi.JetPsiFactory
import org.jetbrains.jet.lang.psi.JetPsiUtil
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression
public open class ReplaceContainsIntention : AttributeCallReplacementIntention("replace.contains.with.in") {
override fun isApplicableToCall(call: CallDescription): Boolean {
return call.functionName == "contains" && call.argumentCount == 1 && !call.hasEmptyArguments
}
override fun replaceCall(call: CallDescription, editor: Editor) {
val ret = call.resolved.getResultingDescriptor().getReturnType()
?: return intentionFailed(editor, "undefined.returntype")
if (!JetTypeChecker.INSTANCE.isSubtypeOf(ret, KotlinBuiltIns.getInstance().getBooleanType())) {
return intentionFailed(editor, "contains.returns.boolean")
}
val argument = (handleErrors(editor, call.getPositionalArguments()) ?: return)[0].getArgumentExpression()
// Append semicolon to previous statement if needed
if (argument is JetFunctionLiteralExpression) {
val previousElement = JetPsiUtil.skipSiblingsBackwardByPredicate(call.element) {
// I checked, it can't be null.
it!!.getNode()?.getElementType() in JetTokens.WHITE_SPACE_OR_COMMENT_BIT_SET
}
if (previousElement != null && previousElement is JetExpression) {
// If the parent is null, something is very wrong.
previousElement.getParent()!!.addAfter(JetPsiFactory.createSemicolon(call.element.getProject()), previousElement)
}
}
call.element.replace(JetPsiFactory.createBinaryExpression(
call.element.getProject(),
argument,
"in",
call.element.getReceiverExpression()
))
}
}
@@ -0,0 +1,37 @@
/*
* Copyright 2014 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.jet.plugin.intentions.attributeCallReplacements
import com.intellij.openapi.editor.Editor
import org.jetbrains.jet.lang.psi.JetPsiFactory
public open class ReplaceGetIntention : AttributeCallReplacementIntention("replace.get.with.index") {
override fun isApplicableToCall(call: CallDescription): Boolean {
return (call.functionName == "get" && !call.hasTypeArguments && call.argumentCount > 0)
}
override fun replaceCall(call: CallDescription, editor: Editor) {
val argumentString = (handleErrors(editor, call.getPositionalArguments()) ?: return).map {
it.getArgumentExpression()?.getText() ?: ""
}.makeString(", ")
call.element.replace(JetPsiFactory.createExpression(
call.element.getProject(),
"${call.element.getReceiverExpression().getText()}[${argumentString}]"
))
}
}
@@ -0,0 +1,37 @@
/*
* Copyright 2010-2014 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.jet.plugin.intentions.attributeCallReplacements
import com.intellij.openapi.editor.Editor
import org.jetbrains.jet.lang.psi.JetPsiFactory
public open class ReplaceInvokeIntention : AttributeCallReplacementIntention("replace.invoke.with.call") {
override fun isApplicableToCall(call: CallDescription): Boolean {
return call.functionName == "invoke"
}
override fun replaceCall(call: CallDescription, editor: Editor) {
call.element.replace(JetPsiFactory.createExpression(
call.element.getProject(),
call.element.getReceiverExpression().getText() +
(call.callElement.getTypeArgumentList()?.getText() ?: "") +
(call.callElement.getValueArgumentList()?.getText() ?: "") +
(call.callElement.getFunctionLiteralArguments().fold("") { a, b -> a + " " + b.getText() })
))
}
}
@@ -0,0 +1,52 @@
/*
* Copyright 2010-2014 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.jet.plugin.intentions.attributeCallReplacements
import com.intellij.openapi.editor.Editor
import org.jetbrains.jet.lang.psi.JetPsiFactory
public open class ReplaceUnaryPrefixIntention : AttributeCallReplacementIntention("replace.unary.operator.with.prefix") {
private fun lookup(name: String?) : String? {
return when (name) {
"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.createExpression(
call.element.getProject(),
lookup(call.functionName)!! + call.element.getReceiverExpression().getText()
))
}
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun plus(a: Int, vararg b: Int, c: Int = 0) : Int = 0
}
val test = Test()
test.p<caret>lus(1)
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun plus(a: Int, vararg b: Int, c: Int = 0) : Int = 0
}
val test = Test()
test + 1
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun plus(vararg b: Int, c: Int = 0) : Int = 0
}
val test = Test()
test.p<caret>lus(1)
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun plus(vararg b: Int, c: Int = 0) : Int = 0
}
val test = Test()
test + 1
}
@@ -0,0 +1,7 @@
fun test() {
class Test {
fun plus(a: Int, b: Int=5): Test = Test()
}
val test = Test()
test.pl<caret>us(1)
}
@@ -0,0 +1,7 @@
fun test() {
class Test {
fun plus(a: Int, b: Int=5): Test = Test()
}
val test = Test()
test + 1
}
@@ -0,0 +1,8 @@
// INTENTION_TEXT: Replace with '/' operator
fun test() {
class Test {
fun div(a: Int): Test = Test()
}
val test = Test()
test.div<caret>(1)
}
@@ -0,0 +1,8 @@
// INTENTION_TEXT: Replace with '/' operator
fun test() {
class Test {
fun div(a: Int): Test = Test()
}
val test = Test()
test / 1
}
@@ -0,0 +1,6 @@
fun test() {
class Test()
fun Test.div(a: Int): Test = Test()
val test = Test()
test.div<caret>(1)
}
@@ -0,0 +1,6 @@
fun test() {
class Test()
fun Test.div(a: Int): Test = Test()
val test = Test()
test / 1
}
@@ -0,0 +1,9 @@
fun test() {
class Test {
fun plus(fn: () -> Test): Test = fn()
}
val test = Test()
test.pl<caret>us {
Test()
}
}
@@ -0,0 +1,9 @@
fun test() {
class Test {
fun plus(fn: () -> Test): Test = fn()
}
val test = Test()
test + {
Test()
}
}
@@ -0,0 +1,8 @@
// INTENTION_TEXT: Replace with '-' operator
fun test() {
class Test {
fun minus(a: Int): Test = Test()
}
val test = Test()
test.min<caret>us(1)
}
@@ -0,0 +1,8 @@
// INTENTION_TEXT: Replace with '-' operator
fun test() {
class Test {
fun minus(a: Int): Test = Test()
}
val test = Test()
test - 1
}
@@ -0,0 +1,8 @@
// SHOULD_FAIL_WITH: skipped.defaults
fun test() {
class Test{
fun plus(a: Int=1, b: Int=2) : Int = 0
}
val test = Test()
test.p<caret>lus(b=3)
}
@@ -0,0 +1,8 @@
// INTENTION_TEXT: Replace with '%' operator
fun test() {
class Test {
fun mod(a: Int): Test = Test()
}
val test = Test()
test.mod<caret>(1)
}
@@ -0,0 +1,8 @@
// INTENTION_TEXT: Replace with '%' operator
fun test() {
class Test {
fun mod(a: Int): Test = Test()
}
val test = Test()
test % 1
}
@@ -0,0 +1,8 @@
// IS_APPLICABLE: false
fun test() {
class Test {
fun plus(a: Int, b: Int): Test = Test()
}
val test = Test()
test.pl<caret>us(1, 2)
}
@@ -0,0 +1,8 @@
// INTENTION_TEXT: Replace with '+' operator
fun test() {
class Test {
fun plus(a: Int): Test = Test()
}
val test = Test()
test.pl<caret>us(1)
}
@@ -0,0 +1,8 @@
// INTENTION_TEXT: Replace with '+' operator
fun test() {
class Test {
fun plus(a: Int): Test = Test()
}
val test = Test()
test + 1
}
@@ -0,0 +1,8 @@
// INTENTION_TEXT: Replace with '..' operator
fun test() {
class Test {
fun rangeTo(a: Int): Test = Test()
}
val test = Test()
test.rangeTo<caret>(1)
}
@@ -0,0 +1,8 @@
// INTENTION_TEXT: Replace with '..' operator
fun test() {
class Test {
fun rangeTo(a: Int): Test = Test()
}
val test = Test()
test..1
}
@@ -0,0 +1,8 @@
// INTENTION_TEXT: Replace with '*' operator
fun test() {
class Test {
fun times(a: Int): Test = Test()
}
val test = Test()
test.time<caret>s(1)
}
@@ -0,0 +1,8 @@
// INTENTION_TEXT: Replace with '*' operator
fun test() {
class Test {
fun times(a: Int): Test = Test()
}
val test = Test()
test * 1
}
@@ -0,0 +1,8 @@
// IS_APPLICABLE: false
fun test() {
class Test {
fun div<T>(a: Test): T? = a as? T
}
val test = Test()
test.div<caret><Int>(Test())
}
@@ -0,0 +1,8 @@
// SHOULD_FAIL_WITH: vararg.not.last
fun test() {
class Test{
fun plus(vararg b: Int, c: Int = 0): Int = 0
}
val test = Test()
test.plus<caret>(c=5)
}
@@ -0,0 +1,8 @@
// IS_APPLICABLE: false
fun test() {
class Test{
fun plus(vararg b: Int, c: Int = 0): Int = 0
}
val test = Test()
test.plus<caret>(0, 1)
}
@@ -0,0 +1,7 @@
fun test() {
class Test {
fun plus(a: Int): Test = Test()
}
val test = Test()
test.pl<caret>us(a=1)
}
@@ -0,0 +1,7 @@
fun test() {
class Test {
fun plus(a: Int): Test = Test()
}
val test = Test()
test + 1
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(vararg a: Int, b: Int = 0): Boolean = true
}
val test = Test()
test.contai<caret>ns(1)
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(vararg a: Int, b: Int = 0): Boolean = true
}
val test = Test()
1 in test
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(c: Int, vararg a: Int, b: Int = 0): Boolean = true
}
val test = Test()
test.contai<caret>ns(1)
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(c: Int, vararg a: Int, b: Int = 0): Boolean = true
}
val test = Test()
1 in test
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(a: Int, b: Int=5) : Boolean = true
}
val test = Test()
test.c<caret>ontains(1)
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(a: Int, b: Int=5) : Boolean = true
}
val test = Test()
1 in test
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(a: Int) : Boolean = true
}
val test = Test()
println(test.c<caret>ontains(0).toString())
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(a: Int) : Boolean = true
}
val test = Test()
println((0 in test).toString())
}
@@ -0,0 +1,6 @@
fun test() {
class Test()
fun Test.contains(a: Int) : Boolean = true
val test = Test()
test.c<caret>ontains(1)
}
@@ -0,0 +1,6 @@
fun test() {
class Test()
fun Test.contains(a: Int) : Boolean = true
val test = Test()
1 in test
}
@@ -0,0 +1,9 @@
fun test() {
class Test{
fun contains(fn: () -> Boolean) : Boolean = true
}
val test = Test()
test.c<caret>ontains {
true
}
}
@@ -0,0 +1,9 @@
fun test() {
class Test{
fun contains(fn: () -> Boolean) : Boolean = true
}
val test = Test();
{
true
} in test
}
@@ -0,0 +1,9 @@
fun test() {
class Test{
fun contains(fn: () -> Boolean) : Boolean = true
}
val test = Test();
test.c<caret>ontains {
true
}
}
@@ -0,0 +1,9 @@
fun test() {
class Test{
fun contains(fn: () -> Boolean) : Boolean = true
}
val test = Test();
{
true
} in test
}
@@ -0,0 +1,11 @@
fun test() {
class Test{
fun contains(fn: () -> Boolean) : Boolean = true
}
val test = Test()
if (true) {
test.c<caret>ontains {
true
}
}
}
@@ -0,0 +1,11 @@
fun test() {
class Test{
fun contains(fn: () -> Boolean) : Boolean = true
}
val test = Test()
if (true) {
{
true
} in test
}
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(fn: () -> Boolean) : Boolean = true
}
val test = Test()
println(test.c<caret>ontains { true }.toString())
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(fn: () -> Boolean) : Boolean = true
}
val test = Test()
println(({ true } in test).toString())
}
@@ -0,0 +1,8 @@
// SHOULD_FAIL_WITH: invalid.arguments
fun test() {
class Test{
fun contains(a: Int=1, b: Int=2): Boolean = true
}
val test = Test()
test.c<caret>ontains(c=3)
}
@@ -0,0 +1,8 @@
// SHOULD_FAIL_WITH: duplicate.or.missing.arguments
fun test() {
class Test{
fun contains(a: Int, b: Int): Boolean = true
}
val test = Test()
test.cont<caret>ains(0)
}
@@ -0,0 +1,8 @@
// SHOULD_FAIL_WITH: skipped.defaults
fun test() {
class Test{
fun contains(a: Int=1, b: Int=2) : Boolean = true
}
val test = Test()
test.contai<caret>ns(b=3)
}
@@ -0,0 +1,8 @@
// IS_APPLICABLE: false
fun test() {
class Test{
fun contains(a: Int, b: Int) : Boolean = true
}
val test = Test()
test.c<caret>ontains(1, 2)
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(a: Int) : Boolean = true
}
val test = Test()
test.c<caret>ontains(1)
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(a: Int) : Boolean = true
}
val test = Test()
1 in test
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains<T>(a: T): Boolean = false
}
val test = Test()
test.contai<caret>ns<Int>(1)
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains<T>(a: T): Boolean = false
}
val test = Test()
1 in test
}
@@ -0,0 +1,8 @@
// SHOULD_FAIL_WITH: vararg.not.last
fun test() {
class Test{
fun contains(vararg b: Int, c: Int = 0): Boolean = true
}
val test = Test()
test.contains<caret>(c=5)
}
@@ -0,0 +1,8 @@
// IS_APPLICABLE: false
fun test() {
class Test{
fun contains(vararg b: Int, c: Int = 0): Boolean = true
}
val test = Test()
test.contains<caret>(0, 1)
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(a: Int=1, b: Int=2) : Boolean = true
}
val test = Test()
test.c<caret>ontains(a=5)
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun contains(a: Int=1, b: Int=2) : Boolean = true
}
val test = Test()
5 in test
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun get(a: Int, vararg b: Int, c: Int = 0) : Int = 0
}
val test = Test()
test.g<caret>et(1, 3, 4, 5)
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun get(a: Int, vararg b: Int, c: Int = 0) : Int = 0
}
val test = Test()
test[1, 3, 4, 5]
}
@@ -0,0 +1,9 @@
fun test() {
class Test{
fun get(a: Int, b: Int, fn: (i: Int) -> Int) : Int = 0
}
val test = Test()
test.g<caret>et(1, 2) { i ->
i
}
}
@@ -0,0 +1,9 @@
fun test() {
class Test{
fun get(a: Int, b: Int, fn: (i: Int) -> Int) : Int = 0
}
val test = Test()
test[1, 2, { i ->
i
}]
}
@@ -0,0 +1,8 @@
// SHOULD_FAIL_WITH: duplicate.or.missing.arguments
fun test() {
class Test{
fun get(a: Int, b: Int) : Int = 0
}
val test = Test()
test.g<caret>et(a=0, a=1)
}
@@ -0,0 +1,7 @@
fun test() {
class Test()
fun Test.get(i: Int) : Int = 0
val test = Test()
test.g<caret>et(0)
}
@@ -0,0 +1,7 @@
fun test() {
class Test()
fun Test.get(i: Int) : Int = 0
val test = Test()
test[0]
}
@@ -0,0 +1,9 @@
fun test() {
class Test{
fun get(fn: (i: Int) -> Int) : Int = 0
}
val test = Test()
test.g<caret>et() { i ->
i
}
}
@@ -0,0 +1,9 @@
fun test() {
class Test{
fun get(fn: (i: Int) -> Int) : Int = 0
}
val test = Test()
test[{ i ->
i
}]
}
@@ -0,0 +1,8 @@
// SHOULD_FAIL_WITH: invalid.arguments
fun test() {
class Test{
fun get(a: Int=1, b: Int=2) : Int = 0
}
val test = Test()
test.g<caret>et(c=3)
}
@@ -0,0 +1,8 @@
// SHOULD_FAIL_WITH: duplicate.or.missing.arguments
fun test() {
class Test{
fun get(a: Int, b: Int) : Int = 0
}
val test = Test()
test.g<caret>et(0)
}
@@ -0,0 +1,8 @@
// SHOULD_FAIL_WITH: skipped.defaults
fun test() {
class Test{
fun get(a: Int=1, b: Int=2) : Int = 0
}
val test = Test()
test.g<caret>et(b=3)
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun get(a: Int, b: Int) : Int = 0
}
val test = Test()
test.g<caret>et(1, 2)
}
@@ -0,0 +1,7 @@
fun test() {
class Test{
fun get(a: Int, b: Int) : Int = 0
}
val test = Test()
test[1, 2]
}
@@ -0,0 +1,9 @@
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(1, c=3, b=2) { i ->
i
}
}
@@ -0,0 +1,9 @@
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, { i ->
i
}]
}
@@ -0,0 +1,8 @@
// IS_APPLICABLE: false
fun test() {
class Test{
fun get() : Int = 0
}
val test = Test()
test.g<caret>et()
}

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