Convert lambda to callable reference intention / inspection #KT-10903 Fixed
(cherry picked from commit b620099)
This commit is contained in:
committed by
Mikhail Glukhikh
parent
b5bdb070a0
commit
220141ab2b
@@ -262,6 +262,8 @@ class KtPsiFactory(private val project: Project) {
|
||||
return createDeclaration(funDecl)
|
||||
}
|
||||
|
||||
fun createCallableReferenceExpression(text: String) = createExpression(text) as? KtCallableReferenceExpression
|
||||
|
||||
fun createSecondaryConstructor(decl: String): KtSecondaryConstructor {
|
||||
return createClass("class Foo {\n $decl \n}").getSecondaryConstructors().first()
|
||||
}
|
||||
|
||||
@@ -33,6 +33,9 @@ import java.util.*
|
||||
fun KtPsiFactory.createExpressionByPattern(pattern: String, vararg args: Any): KtExpression
|
||||
= createByPattern(pattern, *args) { createExpression(it) }
|
||||
|
||||
fun KtPsiFactory.createValueArgumentListByPattern(pattern: String, vararg args: Any): KtValueArgumentList
|
||||
= createByPattern(pattern, *args) { createCallArguments(it) }
|
||||
|
||||
fun <TDeclaration : KtDeclaration> KtPsiFactory.createDeclarationByPattern(pattern: String, vararg args: Any): TDeclaration
|
||||
= createByPattern(pattern, *args) { createDeclaration<TDeclaration>(it) }
|
||||
|
||||
@@ -314,6 +317,10 @@ fun KtPsiFactory.buildExpression(build: BuilderByPattern<KtExpression>.() -> Uni
|
||||
return buildByPattern({ pattern, args -> this.createExpressionByPattern(pattern, *args) }, build)
|
||||
}
|
||||
|
||||
fun KtPsiFactory.buildValueArgumentList(build: BuilderByPattern<KtValueArgumentList>.() -> Unit): KtValueArgumentList {
|
||||
return buildByPattern({ pattern, args -> this.createValueArgumentListByPattern(pattern, *args) }, build)
|
||||
}
|
||||
|
||||
fun KtPsiFactory.buildDeclaration(build: BuilderByPattern<KtDeclaration>.() -> Unit): KtDeclaration {
|
||||
return buildByPattern({ pattern, args -> this.createDeclarationByPattern(pattern, *args) }, build)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This inspection reports a lambda (function literal) expression that can be replaced with function reference expression
|
||||
</body>
|
||||
</html>
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class Person(val name: String)
|
||||
|
||||
val persons = listOf("Jack", "Tom").map(::Person)
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class Person(val name: String)
|
||||
|
||||
val persons = listOf("Jack", "Tom").map { Person(it) }
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention converts a lambda (function literal) expression calling a single function to the function reference
|
||||
</body>
|
||||
</html>
|
||||
@@ -1260,6 +1260,11 @@
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.ConvertLambdaToReferenceIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaInspection"
|
||||
displayName="Object literal can be converted to lambda"
|
||||
groupName="Kotlin"
|
||||
@@ -1607,6 +1612,14 @@
|
||||
language="kotlin"
|
||||
/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.ConvertLambdaToReferenceInspection"
|
||||
displayName="Can be replaced with function reference"
|
||||
groupName="Kotlin"
|
||||
enabledByDefault="true"
|
||||
level="WEAK WARNING"
|
||||
language="kotlin"
|
||||
/>
|
||||
|
||||
<referenceImporter implementation="org.jetbrains.kotlin.idea.quickfix.KotlinReferenceImporter"/>
|
||||
|
||||
<fileType.fileViewProviderFactory filetype="KJSM" implementationClass="com.intellij.psi.ClassFileViewProviderFactory"/>
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.builtins.getReturnTypeFromFunctionType
|
||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.core.isVisible
|
||||
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.REFERENCE_TARGET
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
|
||||
class ConvertLambdaToReferenceInspection : IntentionBasedInspection<KtLambdaExpression>(ConvertLambdaToReferenceIntention())
|
||||
|
||||
class ConvertLambdaToReferenceIntention : SelfTargetingOffsetIndependentIntention<KtLambdaExpression>(
|
||||
KtLambdaExpression::class.java, "Convert lambda to reference"
|
||||
) {
|
||||
override fun isApplicableTo(element: KtLambdaExpression): Boolean {
|
||||
val body = element.bodyExpression ?: return false
|
||||
val statement = body.statements.singleOrNull() ?: return false
|
||||
val lambdaParent = element.parent
|
||||
val context: BindingContext
|
||||
var lambdaMustReturnUnit = false
|
||||
if (lambdaParent is KtLambdaArgument) {
|
||||
val outerCallExpression = lambdaParent.parent as? KtCallExpression ?: return false
|
||||
context = outerCallExpression.analyze()
|
||||
val outerCallee = outerCallExpression.calleeExpression as? KtReferenceExpression ?: return false
|
||||
val outerCalleeDescriptor = context[REFERENCE_TARGET, outerCallee] as? FunctionDescriptor ?: return false
|
||||
// No function parameter predecessors with default value
|
||||
if (outerCalleeDescriptor.valueParameters.any { it.hasDefaultValue() }) return false
|
||||
val lambdaParameterType = outerCalleeDescriptor.valueParameters.lastOrNull()?.type
|
||||
if (lambdaParameterType != null && lambdaParameterType.isFunctionType) {
|
||||
// Special Unit case (non-Unit returning lambda is accepted here, but non-Unit returning reference is not)
|
||||
lambdaMustReturnUnit = getReturnTypeFromFunctionType(lambdaParameterType).isUnit()
|
||||
}
|
||||
}
|
||||
else {
|
||||
context = statement.analyze()
|
||||
}
|
||||
|
||||
fun isConvertableCallInLambda(
|
||||
callableExpression: KtExpression,
|
||||
explicitReceiver: KtExpression? = null,
|
||||
lambdaExpression: KtLambdaExpression
|
||||
): Boolean {
|
||||
val calleeReferenceExpression = when (callableExpression) {
|
||||
is KtCallExpression -> callableExpression.calleeExpression as? KtNameReferenceExpression ?: return false
|
||||
is KtNameReferenceExpression -> callableExpression
|
||||
else -> return false
|
||||
}
|
||||
val calleeDescriptor = context[REFERENCE_TARGET, calleeReferenceExpression] as? CallableMemberDescriptor ?: return false
|
||||
// No references with type parameters
|
||||
if (calleeDescriptor.typeParameters.isNotEmpty()) return false
|
||||
// No references to Java synthetic properties
|
||||
if (calleeDescriptor is SyntheticJavaPropertyDescriptor) return false
|
||||
val descriptorHasReceiver = with (calleeDescriptor) {
|
||||
// No references to both member / extension
|
||||
if (dispatchReceiverParameter != null && extensionReceiverParameter != null) return false
|
||||
dispatchReceiverParameter != null || extensionReceiverParameter != null
|
||||
}
|
||||
val callHasReceiver = explicitReceiver != null
|
||||
if (descriptorHasReceiver != callHasReceiver) return false
|
||||
val callableArgumentsCount = if (callableExpression is KtCallExpression) callableExpression.valueArguments.size else 0
|
||||
if (calleeDescriptor.valueParameters.size != callableArgumentsCount) return false
|
||||
if (lambdaMustReturnUnit) {
|
||||
calleeDescriptor.returnType.let {
|
||||
// If Unit required, no references to non-Unit callables
|
||||
if (it == null || !it.isUnit()) return false
|
||||
}
|
||||
}
|
||||
|
||||
val hasSpecification = lambdaExpression.functionLiteral.hasParameterSpecification()
|
||||
val receiverShift = if (callHasReceiver) 1 else 0
|
||||
val parametersCount = if (hasSpecification) lambdaExpression.valueParameters.size else 1
|
||||
if (parametersCount != callableArgumentsCount + receiverShift) return false
|
||||
if (explicitReceiver != null) {
|
||||
if (explicitReceiver !is KtNameReferenceExpression) return false
|
||||
val callReceiverDescriptor = context[REFERENCE_TARGET, explicitReceiver] as? ParameterDescriptor ?: return false
|
||||
val receiverType = callReceiverDescriptor.type
|
||||
// No exotic receiver types
|
||||
if (receiverType.isTypeParameter() || receiverType.isError || receiverType.isDynamic() ||
|
||||
receiverType.isFlexibleRecursive() || !receiverType.constructor.isDenotable || receiverType.isFunctionType) return false
|
||||
val receiverDeclarationDescriptor = receiverType.constructor.declarationDescriptor
|
||||
if (receiverDeclarationDescriptor is ClassDescriptor) {
|
||||
// No references to object members
|
||||
if (receiverDeclarationDescriptor.kind == ClassKind.OBJECT) return false
|
||||
// No invisible receiver types
|
||||
if (!receiverDeclarationDescriptor.isVisible(
|
||||
explicitReceiver, null, context, explicitReceiver.getResolutionFacade()
|
||||
)) return false
|
||||
}
|
||||
|
||||
val parameterName = if (hasSpecification) lambdaExpression.valueParameters[0].name else "it"
|
||||
if (explicitReceiver.getReferencedName() != parameterName) return false
|
||||
}
|
||||
// Same lambda / references function parameter order
|
||||
if (callableExpression is KtCallExpression) {
|
||||
callableExpression.valueArguments.forEachIndexed { i, argument ->
|
||||
val argumentExpression = argument.getArgumentExpression() as? KtNameReferenceExpression ?: return false
|
||||
val parameterName = if (hasSpecification) lambdaExpression.valueParameters[i + receiverShift].name else "it"
|
||||
if (argumentExpression.getReferencedName() != parameterName) return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return when (statement) {
|
||||
is KtCallExpression -> {
|
||||
isConvertableCallInLambda(callableExpression = statement, lambdaExpression = element)
|
||||
}
|
||||
is KtNameReferenceExpression -> false // Global property reference is not possible (?!)
|
||||
is KtDotQualifiedExpression -> {
|
||||
val selector = statement.selectorExpression ?: return false
|
||||
isConvertableCallInLambda(callableExpression = selector, explicitReceiver = statement.receiverExpression,
|
||||
lambdaExpression = element)
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtCallExpression.getCallReferencedName() = (calleeExpression as? KtNameReferenceExpression)?.getReferencedName()
|
||||
|
||||
private fun buildReferenceText(expression: KtExpression): String? {
|
||||
return when (expression) {
|
||||
is KtCallExpression -> "::${expression.getCallReferencedName()}"
|
||||
is KtDotQualifiedExpression -> {
|
||||
val selector = expression.selectorExpression
|
||||
val selectorReferenceName = when (selector) {
|
||||
is KtCallExpression -> selector.getCallReferencedName() ?: return null
|
||||
is KtNameReferenceExpression -> selector.getReferencedName()
|
||||
else -> return null
|
||||
}
|
||||
val receiver = expression.receiverExpression as? KtNameReferenceExpression ?: return null
|
||||
val context = receiver.analyze()
|
||||
val receiverDescriptor = context[REFERENCE_TARGET, receiver] as? ParameterDescriptor ?: return null
|
||||
val receiverType = receiverDescriptor.type
|
||||
"$receiverType::$selectorReferenceName"
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtLambdaExpression, editor: Editor?) {
|
||||
val body = element.bodyExpression ?: return
|
||||
val referenceName = buildReferenceText(body.statements.singleOrNull() ?: return) ?: return
|
||||
val factory = KtPsiFactory(editor?.project)
|
||||
val lambdaArgument = element.parent as? KtLambdaArgument
|
||||
if (lambdaArgument == null) {
|
||||
// Without lambda argument syntax, just replace lambda with reference
|
||||
val callableReferenceExpr = factory.createCallableReferenceExpression(referenceName) ?: return
|
||||
element.replace(callableReferenceExpr)
|
||||
}
|
||||
else {
|
||||
// Otherwise, replace the whole argument list for lambda argument-using call
|
||||
val outerCallExpression = lambdaArgument.parent as? KtCallExpression ?: return
|
||||
val arguments = outerCallExpression.valueArguments.filter { it !is KtLambdaArgument }
|
||||
val newArgumentList = factory.buildValueArgumentList {
|
||||
appendFixedText("(")
|
||||
for (argument in arguments) {
|
||||
appendExpression(argument.getArgumentExpression())
|
||||
appendFixedText(", ")
|
||||
}
|
||||
appendFixedText(referenceName)
|
||||
appendFixedText(")")
|
||||
}
|
||||
val argumentList = outerCallExpression.valueArgumentList
|
||||
if (argumentList == null) {
|
||||
lambdaArgument.replace(newArgumentList)
|
||||
}
|
||||
else {
|
||||
argumentList.replace(newArgumentList)
|
||||
lambdaArgument.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,11 +49,6 @@ class SpecifyTypeExplicitlyIntention :
|
||||
SelfTargetingRangeIntention<KtCallableDeclaration>(KtCallableDeclaration::class.java, "Specify type explicitly"),
|
||||
LowPriorityAction {
|
||||
|
||||
private fun KotlinType.isFlexibleRecursive(): Boolean {
|
||||
if (isFlexible()) return true
|
||||
return arguments.any { !it.isStarProjection && it.type.isFlexibleRecursive() }
|
||||
}
|
||||
|
||||
fun dangerousFlexibleTypeOrNull(declaration: KtCallableDeclaration, publicAPIOnly: Boolean): KotlinType? {
|
||||
when (declaration) {
|
||||
is KtFunction -> if (declaration.isLocal || declaration.hasDeclaredReturnType()) return null
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.isFlexible
|
||||
|
||||
fun KtCallableDeclaration.setType(type: KotlinType, shortenReferences: Boolean = true) {
|
||||
if (type.isError) return
|
||||
@@ -203,3 +204,10 @@ private fun getNegatedOperatorText(token: IElementType): String {
|
||||
else -> throw IllegalArgumentException("The token $token does not have a negated equivalent.")
|
||||
}
|
||||
}
|
||||
|
||||
internal fun KotlinType.isFlexibleRecursive(): Boolean {
|
||||
if (isFlexible()) return true
|
||||
return arguments.any { !it.isStarProjection && it.type.isFlexibleRecursive() }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.idea.intentions.ConvertLambdaToReferenceIntention
|
||||
@@ -0,0 +1,5 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Person(val name: String)
|
||||
|
||||
val x = listOf("Jack", "Tom").map <caret>{ Person(it) }
|
||||
@@ -0,0 +1,5 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Person(val name: String)
|
||||
|
||||
val x = listOf("Jack", "Tom").map(::Person)
|
||||
@@ -0,0 +1,3 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
val x = listOf("123", "4567").map <caret>{ it.toInt() }
|
||||
@@ -0,0 +1,3 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
val x = listOf("123", "4567").map(String::toInt)
|
||||
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun foo(z: Int, y: Int = 0) = y + z
|
||||
|
||||
val x = { arg: Int <caret>-> foo(arg) }
|
||||
@@ -0,0 +1,8 @@
|
||||
// IS_APPLICABLE: false
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun List<Int>.transform(x: Int = 0, f: (Int) -> Int) = map { f(it + x) }
|
||||
|
||||
fun bar(x: Int) = x * x
|
||||
|
||||
val y = listOf(1, 2, 3).transform { <caret>bar(it) }
|
||||
@@ -0,0 +1,11 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
interface Transformer {
|
||||
fun transform(x: Int = 0, f: (Int) -> Int) = f(x)
|
||||
}
|
||||
|
||||
class TransformerImpl : Transformer
|
||||
|
||||
fun bar(x: Int) = x * x
|
||||
|
||||
val y = TransformerImpl().transform { <caret>bar(it) }
|
||||
@@ -0,0 +1,5 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun bar(s: String) = s.length
|
||||
|
||||
val x = listOf("Jack", "Tom").map() <caret>{ w -> bar(w) }
|
||||
@@ -0,0 +1,5 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun bar(s: String) = s.length
|
||||
|
||||
val x = listOf("Jack", "Tom").map(::bar)
|
||||
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
class Generic<T : Any> {
|
||||
val y = { arg: T <caret>-> arg.hashCode() }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
class Owner(val z: Int) {
|
||||
// Possible only in 1.1 with bound references (this::foo)
|
||||
val x = { arg: Int <caret> -> foo(arg) }
|
||||
}
|
||||
|
||||
fun Owner.foo(y: Int) = y + z
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
val Any.name: String get() = toString()
|
||||
|
||||
val converted = { x: Any -> <caret>x.name }
|
||||
@@ -0,0 +1,3 @@
|
||||
val Any.name: String get() = toString()
|
||||
|
||||
val converted = Any::name
|
||||
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun <T> id(y: T) = y
|
||||
|
||||
val x = { arg: Int <caret>-> id<Int>(arg) }
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
val name = "Kotlin"
|
||||
val x = { obj: Any -> <caret>name }
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
val name = "Kotlin"
|
||||
val x = { -> <caret>name }
|
||||
@@ -0,0 +1,5 @@
|
||||
class Owner {
|
||||
inner class Inner
|
||||
|
||||
val x = { <caret>o: Owner -> o.Inner() }
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class Owner {
|
||||
inner class Inner
|
||||
|
||||
val x = Owner::Inner
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun bar(s: String) = s.length
|
||||
|
||||
val x = listOf("Jack", "Tom").mapTo(hashSetOf<Int>()) <caret>{ w -> bar(w) }
|
||||
@@ -0,0 +1,5 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun bar(s: String) = s.length
|
||||
|
||||
val x = listOf("Jack", "Tom").mapTo(hashSetOf<Int>(), ::bar)
|
||||
@@ -0,0 +1,7 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
class Owner(val z: Int) {
|
||||
fun foo(y: Int) = y + z
|
||||
// Possible only in 1.1 with bound references (this::foo)
|
||||
val x = { arg: Int <caret> -> foo(arg) }
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
class Their {
|
||||
fun Int.foo() = "x"
|
||||
|
||||
val x = { arg: Int -> <caret>arg.foo() }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class Person(val name: String)
|
||||
|
||||
val reader = { p: Person -> p.name<caret> }
|
||||
@@ -0,0 +1,3 @@
|
||||
class Person(val name: String)
|
||||
|
||||
val reader = Person::name
|
||||
@@ -0,0 +1,3 @@
|
||||
fun Int?.foo() = this?.hashCode() ?: 0
|
||||
|
||||
val x = { arg: Int? -> arg.foo() <caret>}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun Int?.foo() = this?.hashCode() ?: 0
|
||||
|
||||
val x = Int?::foo
|
||||
@@ -0,0 +1,7 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
object Object {
|
||||
fun foo() = 42
|
||||
}
|
||||
|
||||
val x = { o: Object -> o.foo()<caret> }
|
||||
@@ -0,0 +1,3 @@
|
||||
fun Int.foo(x: Int) = this - x
|
||||
|
||||
val x = { a: Int, b: Int <caret>-> a.foo(b) }
|
||||
@@ -0,0 +1,3 @@
|
||||
fun Int.foo(x: Int) = this - x
|
||||
|
||||
val x = Int::foo
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun Int.foo(x: Int) = this - x
|
||||
|
||||
val x = { a: Int, b: Int <caret>-> b.foo(a) }
|
||||
@@ -0,0 +1,3 @@
|
||||
fun foo(y: Int) = y
|
||||
|
||||
val x = { arg: Int <caret>-> foo(arg) }
|
||||
@@ -0,0 +1,3 @@
|
||||
fun foo(y: Int) = y
|
||||
|
||||
val x = ::foo
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: false
|
||||
// WITH_RUNTIME
|
||||
|
||||
val x = listOf(java.lang.String("")).map { <caret>it.bytes }
|
||||
@@ -0,0 +1,3 @@
|
||||
fun foo(x: Int, y: Int, z: Int) = x - y / z
|
||||
|
||||
val x = { a: Int, b: Int, c: Int <caret>-> foo(a, b, c) }
|
||||
@@ -0,0 +1,3 @@
|
||||
fun foo(x: Int, y: Int, z: Int) = x - y / z
|
||||
|
||||
val x = ::foo
|
||||
@@ -0,0 +1 @@
|
||||
val x = { arg: Int -> <caret>arg.toString() }
|
||||
@@ -0,0 +1 @@
|
||||
val x = Int::toString
|
||||
@@ -0,0 +1,9 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun Int.exec(f: (Int) -> Unit) = f(this)
|
||||
|
||||
fun bar(x: Int) = x
|
||||
|
||||
fun foo() {
|
||||
2.exec {<caret> bar(it) }
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Wrapper<T>(private val x: T) {
|
||||
fun unwrap() = x
|
||||
}
|
||||
|
||||
val unwrapped = listOf(Wrapper(1), Wrapper("B")).map { <caret>it.unwrap() }
|
||||
@@ -0,0 +1,7 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class Wrapper<T>(private val x: T) {
|
||||
fun unwrap() = x
|
||||
}
|
||||
|
||||
val unwrapped = listOf(Wrapper(1), Wrapper("B")).map(Wrapper<out Any>::unwrap)
|
||||
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun foo() = 42
|
||||
|
||||
val x = { arg: Int <caret>-> foo() }
|
||||
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun foo(y: Int, z: Int) = y - z
|
||||
|
||||
val x = { second: Int, first: Int -> foo(first, second) }
|
||||
@@ -3713,6 +3713,189 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/convertLambdaToReference")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ConvertLambdaToReference extends AbstractIntentionTest {
|
||||
public void testAllFilesPresentInConvertLambdaToReference() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/convertLambdaToReference"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("constructor.kt")
|
||||
public void testConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/constructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("conversion.kt")
|
||||
public void testConversion() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/conversion.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultArgument.kt")
|
||||
public void testDefaultArgument() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/defaultArgument.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultBeforeLambda.kt")
|
||||
public void testDefaultBeforeLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/defaultBeforeLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultOverridden.kt")
|
||||
public void testDefaultOverridden() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/defaultOverridden.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("emptyBrackets.kt")
|
||||
public void testEmptyBrackets() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/emptyBrackets.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("erasedReceiver.kt")
|
||||
public void testErasedReceiver() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/erasedReceiver.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("extension.kt")
|
||||
public void testExtension() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/extension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("extensionProperty.kt")
|
||||
public void testExtensionProperty() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/extensionProperty.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("generic.kt")
|
||||
public void testGeneric() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/generic.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("globalProperty.kt")
|
||||
public void testGlobalProperty() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/globalProperty.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("globalPropertyNoArgs.kt")
|
||||
public void testGlobalPropertyNoArgs() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/globalPropertyNoArgs.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inner.kt")
|
||||
public void testInner() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/inner.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("mapTo.kt")
|
||||
public void testMapTo() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/mapTo.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("member.kt")
|
||||
public void testMember() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/member.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("memberExtension.kt")
|
||||
public void testMemberExtension() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/memberExtension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("name.kt")
|
||||
public void testName() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/name.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nullable.kt")
|
||||
public void testNullable() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/nullable.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("object.kt")
|
||||
public void testObject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/object.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("receiverParameter.kt")
|
||||
public void testReceiverParameter() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/receiverParameter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("receiverParameterReversed.kt")
|
||||
public void testReceiverParameterReversed() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/receiverParameterReversed.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("syntheticProperty.kt")
|
||||
public void testSyntheticProperty() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/syntheticProperty.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("threeParameters.kt")
|
||||
public void testThreeParameters() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/threeParameters.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("toString.kt")
|
||||
public void testToString() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/toString.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("unit.kt")
|
||||
public void testUnit() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/unit.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("unwrap.kt")
|
||||
public void testUnwrap() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/unwrap.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("wrongParameterNumber.kt")
|
||||
public void testWrongParameterNumber() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/wrongParameterNumber.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("wrongParameterOrder.kt")
|
||||
public void testWrongParameterOrder() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/wrongParameterOrder.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/convertNegatedBooleanSequence")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user