From d5d49c65b4fe6da37444ed8910ae16df5eb2dd26 Mon Sep 17 00:00:00 2001 From: Nicolay Mitropolsky Date: Thu, 18 Jan 2018 18:48:55 +0300 Subject: [PATCH] Uast: tests for `UClass.uastSuperTypes` --- plugins/uast-kotlin/testData/Anonymous.kt | 10 +++++ .../uast-kotlin/testData/Anonymous.log.txt | 36 +++++++++++++++++ .../uast-kotlin/testData/Anonymous.render.txt | 11 +++++ .../uast-kotlin/tests/KotlinUastApiTest.kt | 40 ++++++++++++++++--- .../tests/SimpleKotlinRenderLogTest.kt | 6 +++ .../uast/test/env/AbstractUastTest.kt | 16 ++++---- 6 files changed, 106 insertions(+), 13 deletions(-) create mode 100644 plugins/uast-kotlin/testData/Anonymous.kt create mode 100644 plugins/uast-kotlin/testData/Anonymous.log.txt create mode 100644 plugins/uast-kotlin/testData/Anonymous.render.txt diff --git a/plugins/uast-kotlin/testData/Anonymous.kt b/plugins/uast-kotlin/testData/Anonymous.kt new file mode 100644 index 00000000000..b9b1a5bff64 --- /dev/null +++ b/plugins/uast-kotlin/testData/Anonymous.kt @@ -0,0 +1,10 @@ +import java.io.Closeable +import java.io.InputStream + + +fun foo() { + val runnable = object : Runnable { override fun run() {} } + runnable.run() + val closeableRunnable = object : Runnable, Closeable { override fun close() {} override fun run() {} } + val runnableIs = object : InputStream(), Runnable { override fun read(): Int = 0; override fun run() {} } +} \ No newline at end of file diff --git a/plugins/uast-kotlin/testData/Anonymous.log.txt b/plugins/uast-kotlin/testData/Anonymous.log.txt new file mode 100644 index 00000000000..a32d211c109 --- /dev/null +++ b/plugins/uast-kotlin/testData/Anonymous.log.txt @@ -0,0 +1,36 @@ +UFile (package = ) + UImportStatement (isOnDemand = false) + UImportStatement (isOnDemand = false) + UClass (name = AnonymousKt) + UAnnotationMethod (name = foo) + UBlockExpression + UDeclarationsExpression + ULocalVariable (name = runnable) + UObjectLiteralExpression + UClass (name = null) + UAnnotationMethod (name = run) + UBlockExpression + UAnnotationMethod (name = AnonymousKt$foo$runnable$1) + UQualifiedReferenceExpression + USimpleNameReferenceExpression (identifier = runnable) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (run)) + USimpleNameReferenceExpression (identifier = run) + UDeclarationsExpression + ULocalVariable (name = closeableRunnable) + UObjectLiteralExpression + UClass (name = null) + UAnnotationMethod (name = close) + UBlockExpression + UAnnotationMethod (name = run) + UBlockExpression + UAnnotationMethod (name = AnonymousKt$foo$closeableRunnable$1) + UDeclarationsExpression + ULocalVariable (name = runnableIs) + UObjectLiteralExpression + UClass (name = null) + UAnnotationMethod (name = read) + ULiteralExpression (value = 0) + UAnnotationMethod (name = run) + UBlockExpression + UAnnotationMethod (name = AnonymousKt$foo$runnableIs$1) diff --git a/plugins/uast-kotlin/testData/Anonymous.render.txt b/plugins/uast-kotlin/testData/Anonymous.render.txt new file mode 100644 index 00000000000..ae3c8e5ed6a --- /dev/null +++ b/plugins/uast-kotlin/testData/Anonymous.render.txt @@ -0,0 +1,11 @@ +import java.io.Closeable +import java.io.InputStream + +public final class AnonymousKt { + public static final fun foo() : void { + var runnable: = anonymous object : Runnable { override fun run() {} } + runnable.run() + var closeableRunnable: = anonymous object : Runnable, Closeable { override fun close() {} override fun run() {} } + var runnableIs: = anonymous object : InputStream(), Runnable { override fun read(): Int = 0; override fun run() {} } + } +} diff --git a/plugins/uast-kotlin/tests/KotlinUastApiTest.kt b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt index 368818d347d..6c960a677ce 100644 --- a/plugins/uast-kotlin/tests/KotlinUastApiTest.kt +++ b/plugins/uast-kotlin/tests/KotlinUastApiTest.kt @@ -3,11 +3,7 @@ package org.jetbrains.uast.test.kotlin import com.intellij.psi.PsiModifier import com.intellij.testFramework.UsefulTestCase import org.jetbrains.kotlin.asJava.toLightAnnotation -import org.jetbrains.kotlin.psi.KtAnnotationEntry -import org.jetbrains.kotlin.psi.KtBinaryExpression -import org.jetbrains.kotlin.psi.KtLiteralStringTemplateEntry -import org.jetbrains.kotlin.psi.KtStringTemplateExpression -import org.jetbrains.kotlin.psi.KtUserType +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.cast @@ -227,6 +223,40 @@ class KotlinUastApiTest : AbstractKotlinUastTest() { } } } + + + fun UFile.checkUastSuperTypes(refText: String, superTypes: List) { + findElementByTextFromPsi(refText, false).let { + assertEquals("base classes", superTypes, it.uastSuperTypes.map { it.getQualifiedName() }) + } + } + + + @Test + fun testSuperTypes() { + doTest("SuperCalls") { _, file -> + file.checkUastSuperTypes("B", listOf("A")) + file.checkUastSuperTypes("O", listOf("A")) + file.checkUastSuperTypes("innerObject ", listOf("A")) + file.checkUastSuperTypes("InnerClass", listOf("A")) + file.checkUastSuperTypes("object : A(\"textForAnon\")", listOf("A")) + } + } + + @Test + fun testAnonymousSuperTypes() { + doTest("Anonymous") { _, file -> + file.checkUastSuperTypes("object : Runnable { override fun run() {} }", listOf("java.lang.Runnable")) + file.checkUastSuperTypes( + "object : Runnable, Closeable { override fun close() {} override fun run() {} }", + listOf("java.lang.Runnable", "java.io.Closeable") + ) + file.checkUastSuperTypes( + "object : InputStream(), Runnable { override fun read(): Int = 0; override fun run() {} }", + listOf("java.io.InputStream", "java.lang.Runnable") + ) + } + } } fun Iterable.assertedFind(value: R, transform: (T) -> R): T = find { transform(it) == value } ?: throw AssertionError("'$value' not found, only ${this.joinToString { transform(it).toString() }}") diff --git a/plugins/uast-kotlin/tests/SimpleKotlinRenderLogTest.kt b/plugins/uast-kotlin/tests/SimpleKotlinRenderLogTest.kt index aaec47ab04c..d4cea81061d 100644 --- a/plugins/uast-kotlin/tests/SimpleKotlinRenderLogTest.kt +++ b/plugins/uast-kotlin/tests/SimpleKotlinRenderLogTest.kt @@ -67,4 +67,10 @@ class SimpleKotlinRenderLogTest : AbstractKotlinRenderLogTest() { @Test fun testReceiverFun() = doTest("ReceiverFun") + + @Test + fun testAnonymous() = doTest("Anonymous") { testName, file -> + //Disabled because cant convert IMPORT_DIRECTIVE + check(testName, file, false) + } } diff --git a/plugins/uast-kotlin/tests/org/jetbrains/uast/test/env/AbstractUastTest.kt b/plugins/uast-kotlin/tests/org/jetbrains/uast/test/env/AbstractUastTest.kt index 4292f11a9f1..45d13c4df79 100644 --- a/plugins/uast-kotlin/tests/org/jetbrains/uast/test/env/AbstractUastTest.kt +++ b/plugins/uast-kotlin/tests/org/jetbrains/uast/test/env/AbstractUastTest.kt @@ -65,16 +65,16 @@ fun UElement.findElementByText(refText: String, cls: Class): T { inline fun UElement.findElementByText(refText: String): T = findElementByText(refText, T::class.java) -inline fun UElement.findElementByTextFromPsi(refText: String): T = (this.psi ?: fail("no psi for $this")).findUElementByTextFromPsi(refText) +inline fun UElement.findElementByTextFromPsi(refText: String, strict: Boolean = true): T = + (this.psi ?: fail("no psi for $this")).findUElementByTextFromPsi(refText, strict) -inline fun PsiElement.findUElementByTextFromPsi(refText: String): T { +inline fun PsiElement.findUElementByTextFromPsi(refText: String, strict: Boolean = true): T { val elementAtStart = this.findElementAt(this.text.indexOf(refText)) - ?: throw AssertionError("requested text '$refText' was not found in $this") - val uElementContainingText = elementAtStart.parentsWithSelf. - dropWhile { !it.text.contains(refText) }. - mapNotNull { it.toUElementOfType() }. - first() - if (uElementContainingText.psi != null && uElementContainingText.psi?.text != refText) { + ?: throw AssertionError("requested text '$refText' was not found in $this") + val uElementContainingText = elementAtStart.parentsWithSelf.let { + if (strict) it.dropWhile { !it.text.contains(refText) } else it + }.mapNotNull { it.toUElementOfType() }.first() + if (strict && uElementContainingText.psi != null && uElementContainingText.psi?.text != refText) { throw AssertionError("requested text '$refText' found as '${uElementContainingText.psi?.text}' in $uElementContainingText") } return uElementContainingText;