From 38e2d474b7dc5ca1125ea5ea6d3abb499a6eee45 Mon Sep 17 00:00:00 2001 From: Nicolay Mitropolsky Date: Thu, 5 Jul 2018 21:52:50 +0300 Subject: [PATCH] Uast: create `KotlinULambdaExpression` for in-place lambdas (KT-25297) and provide appropriate functionalInterface --- .../uast/kotlin/KotlinUastLanguagePlugin.kt | 5 ++++- .../uast/kotlin/KotlinUastLanguagePlugin.kt.172 | 5 ++++- .../uast/kotlin/KotlinUastLanguagePlugin.kt.173 | 5 ++++- plugins/uast-kotlin/testData/Lambdas.kt | 5 +++++ plugins/uast-kotlin/tests/KotlinUastApiTest.kt | 15 +++++++++++++++ .../uast-kotlin/tests/KotlinUastApiTest.kt.172 | 13 +++++++++++++ .../uast-kotlin/tests/KotlinUastApiTest.kt.173 | 15 +++++++++++++++ 7 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 plugins/uast-kotlin/testData/Lambdas.kt diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt index ef6dab21c84..05b4723c75e 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt @@ -184,7 +184,10 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { is KtFunction -> if (original.isLocal) { el { - if (original.name.isNullOrEmpty() || original.parent is KtLambdaExpression) { + val parent = original.parent + if (parent is KtLambdaExpression) { + KotlinULambdaExpression(parent, givenParent) // your parent is the ULambdaExpression + } else if (original.name.isNullOrEmpty()) { createLocalFunctionLambdaExpression(original, givenParent) } else { diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.172 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.172 index 1c02130282e..778ec161668 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.172 +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.172 @@ -179,7 +179,10 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { is KtFunction -> if (original.isLocal) { el { - if (original.name.isNullOrEmpty() || original.parent is KtLambdaExpression) { + val parent = original.parent + if (parent is KtLambdaExpression) { + KotlinULambdaExpression(parent, givenParent) // your parent is the ULambdaExpression + } else if (original.name.isNullOrEmpty()) { createLocalFunctionLambdaExpression(original, givenParent) } else { diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.173 b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.173 index 19e19208ff7..7095d4394f5 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.173 +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastLanguagePlugin.kt.173 @@ -183,7 +183,10 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin { is KtFunction -> if (original.isLocal) { el { - if (original.name.isNullOrEmpty() || original.parent is KtLambdaExpression) { + val parent = original.parent + if (parent is KtLambdaExpression) { + KotlinULambdaExpression(parent, givenParent) // your parent is the ULambdaExpression + } else if (original.name.isNullOrEmpty()) { createLocalFunctionLambdaExpression(original, givenParent) } else { diff --git a/plugins/uast-kotlin/testData/Lambdas.kt b/plugins/uast-kotlin/testData/Lambdas.kt new file mode 100644 index 00000000000..59905883327 --- /dev/null +++ b/plugins/uast-kotlin/testData/Lambdas.kt @@ -0,0 +1,5 @@ +import java.util.stream.Stream + +fun foo() { + Stream.empty().filter { it.isEmpty() } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/tests/KotlinUastApiTest.kt b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt index 8783d6455d4..d6196ce62f7 100644 --- a/plugins/uast-kotlin/tests/KotlinUastApiTest.kt +++ b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt @@ -7,6 +7,7 @@ import org.jetbrains.kotlin.asJava.toLightAnnotation import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase +import org.jetbrains.kotlin.utils.addToStdlib.assertedCast import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.sure import org.jetbrains.uast.* @@ -360,6 +361,20 @@ class KotlinUastApiTest : AbstractKotlinUastTest() { barMethod.assertResolveCall("contains(2 as Int)", "longRangeContains") barMethod.assertResolveCall("IntRange(1, 2)") } + + @Test + fun testUtilsStreamLambda() { + doTest("Lambdas") { _, file -> + val lambda = file.findElementByTextFromPsi("{ it.isEmpty() }") + assertEquals( + "kotlin.jvm.functions.Function1", + lambda.getExpressionType()?.canonicalText + ) + val uCallExpression = lambda.uastParent.assertedCast { "UCallExpression expected" } + assertTrue(uCallExpression.valueArguments.contains(lambda)) + } + } + } fun Iterable.assertedFind(value: R, transform: (T) -> R): T = diff --git a/plugins/uast-kotlin/tests/KotlinUastApiTest.kt.172 b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt.172 index 908a756d096..cfae9202d30 100644 --- a/plugins/uast-kotlin/tests/KotlinUastApiTest.kt.172 +++ b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt.172 @@ -7,6 +7,7 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase +import org.jetbrains.kotlin.utils.addToStdlib.assertedCast import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.sure import org.jetbrains.uast.* @@ -214,4 +215,16 @@ class KotlinUastApiTest : AbstractKotlinUastTest() { barMethod.assertResolveCall("joinToString()") barMethod.assertResolveCall("last()") } + + @Test + fun testUtilsStreamLambda() { + doTest("Lambdas") { _, file -> + val lambda = file.findElementByTextFromPsi("{ it.isEmpty() }") + assertEquals( + "kotlin.jvm.functions.Function1", + lambda.getExpressionType()?.canonicalText + ) + val uCallExpression = lambda.uastParent.assertedCast { "UCallExpression expected" } + assertTrue(uCallExpression.valueArguments.contains(lambda)) + } } diff --git a/plugins/uast-kotlin/tests/KotlinUastApiTest.kt.173 b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt.173 index 18eb64a27c9..8688555176d 100644 --- a/plugins/uast-kotlin/tests/KotlinUastApiTest.kt.173 +++ b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt.173 @@ -8,6 +8,7 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase +import org.jetbrains.kotlin.utils.addToStdlib.assertedCast import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.sure import org.jetbrains.uast.* @@ -324,6 +325,20 @@ class KotlinUastApiTest : AbstractKotlinUastTest() { barMethod.assertResolveCall("joinToString()") barMethod.assertResolveCall("last()") } + + @Test + fun testUtilsStreamLambda() { + doTest("Lambdas") { _, file -> + val lambda = file.findElementByTextFromPsi("{ it.isEmpty() }") + assertEquals( + "kotlin.jvm.functions.Function1", + lambda.getExpressionType()?.canonicalText + ) + val uCallExpression = lambda.uastParent.assertedCast { "UCallExpression expected" } + assertTrue(uCallExpression.valueArguments.contains(lambda)) + } + } + } fun Iterable.assertedFind(value: R, transform: (T) -> R): T = find { transform(it) == value } ?: throw AssertionError("'$value' not found, only ${this.joinToString { transform(it).toString() }}")