Files
kotlin-fork/plugins/uast-kotlin/tests/KotlinUastResolveApiTest.kt
T
Vyacheslav Gerasimov d84c5b1608 Switch to 183 platform
2018-12-06 20:16:58 +03:00

294 lines
11 KiB
Kotlin

/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.uast.test.kotlin
import com.intellij.openapi.util.registry.Registry
import com.intellij.psi.PsiClassType
import com.intellij.psi.PsiType
import com.intellij.testFramework.LightProjectDescriptor
import junit.framework.TestCase
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UQualifiedReferenceExpression
import org.jetbrains.uast.getContainingUMethod
import org.jetbrains.uast.kotlin.KotlinUFunctionCallExpression
import org.jetbrains.uast.test.env.findElementByText
import org.jetbrains.uast.test.env.findElementByTextFromPsi
import org.jetbrains.uast.test.env.findUElementByTextFromPsi
import org.jetbrains.uast.toUElement
class KotlinUastResolveApiTest : KotlinLightCodeInsightFixtureTestCase() {
override fun getProjectDescriptor(): LightProjectDescriptor =
KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
override fun setUp() {
super.setUp()
Registry.get("kotlin.uast.multiresolve.enabled").setValue(true, testRootDisposable)
}
fun testResolveStringFromUast() {
val file = myFixture.addFileToProject(
"s.kt", """fun foo(){
val s = "abc"
s.toUpperCase()
}
""${'"'}"""
)
val refs = file.findUElementByTextFromPsi<UQualifiedReferenceExpression>("s.toUpperCase()")
TestCase.assertNotNull((refs.receiver.getExpressionType() as PsiClassType).resolve())
}
fun testMultiResolve() {
val file = myFixture.configureByText(
"s.kt", """
fun foo(): Int = TODO()
fun foo(a: Int): Int = TODO()
fun foo(a: Int, b: Int): Int = TODO()
fun main(args: Array<String>) {
foo(1<caret>
}"""
)
val main = file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
val functionCall =
main.findElementByText<UElement>("foo").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"fun foo(): Int = TODO()",
"fun foo(a: Int): Int = TODO()",
"fun foo(a: Int, b: Int): Int = TODO()"
)
TestCase.assertEquals(PsiType.INT, functionCall.getExpressionType())
val firstArgument = main.findElementByText<UElement>("1")
val firstParameter = functionCall.getArgumentForParameter(0)
TestCase.assertEquals(firstArgument, firstParameter)
}
fun testMultiResolveJava() {
val file = myFixture.configureByText(
"s.kt", """
fun main(args: Array<String>) {
System.out.print(""
}
"""
)
val main = file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
val functionCall = main.findElementByText<UElement>("print").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"public void print(char c) { /* compiled code */ }",
"public void print(int i) { /* compiled code */ }",
"public void print(long l) { /* compiled code */ }",
"public void print(float f) { /* compiled code */ }",
"public void print(double d) { /* compiled code */ }",
"public void print(char[] s) { /* compiled code */ }",
"public void print(java.lang.String s) { /* compiled code */ }",
"public void print(java.lang.Object obj) { /* compiled code */ }"
)
TestCase.assertEquals(PsiType.VOID, functionCall.getExpressionType())
val firstArgument = main.findElementByText<UElement>("\"\"")
val firstParameter = functionCall.getArgumentForParameter(0)
TestCase.assertEquals(firstArgument, firstParameter)
}
fun testMultiResolveJavaAmbiguous() {
myFixture.addClass(
"""
public class JavaClass {
public void setParameter(String name, int value){}
public void setParameter(String name, double value){}
public void setParameter(String name, String value){}
}
"""
)
val file = myFixture.configureByText(
"s.kt", """
fun main(args: Array<String>) {
JavaClass().setParameter(""
}
"""
)
val main = file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
val functionCall = main.findElementByText<UElement>("setParameter").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"public void setParameter(String name, int value){}",
"public void setParameter(String name, double value){}",
"public void setParameter(String name, String value){}"
)
TestCase.assertEquals(PsiType.VOID, functionCall.getExpressionType())
val firstArgument = main.findElementByText<UElement>("\"\"")
val firstParameter = functionCall.getArgumentForParameter(0)
TestCase.assertEquals(firstArgument, firstParameter)
}
fun testMultiResolveInClass() {
val file = myFixture.configureByText(
"s.kt", """
class MyClass {
fun foo(): Int = TODO()
fun foo(a: Int): Int = TODO()
fun foo(a: Int, b: Int): Int = TODO()
}
fun foo(string: String) = TODO()
fun main(args: Array<String>) {
MyClass().foo(
}
"""
)
val functionCall =
file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
.findElementByText<UElement>("foo").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"fun foo(): Int = TODO()",
"fun foo(a: Int): Int = TODO()",
"fun foo(a: Int, b: Int): Int = TODO()"
)
assertDoesntContain(resolvedDeclarationsStrings, "fun foo(string: String) = TODO()")
TestCase.assertEquals(PsiType.INT, functionCall.getExpressionType())
}
fun testMultiConstructorResolve() {
val file = myFixture.configureByText(
"s.kt", """
class MyClass(int: Int) {
constructor(int: Int, int1: Int) : this(int + int1)
fun foo(): Int = TODO()
}
fun MyClass(string: String): MyClass = MyClass(1)
fun main(args: Array<String>) {
MyClass(
}
"""
)
val functionCall =
file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
.findElementByText<UElement>("MyClass").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"(int: Int)",
"constructor(int: Int, int1: Int) : this(int + int1)",
"fun MyClass(string: String): MyClass = MyClass(1)"
)
assertDoesntContain(resolvedDeclarationsStrings, "fun foo(): Int = TODO()")
TestCase.assertEquals(PsiType.getTypeByName("MyClass", project, file.resolveScope), functionCall.getExpressionType())
}
fun testMultiInvokableObjectResolve() {
val file = myFixture.configureByText(
"s.kt", """
object Foo {
operator fun invoke(i: Int): Int = TODO()
operator fun invoke(i1: Int, i2: Int): Int = TODO()
operator fun invoke(i1: Int, i2: Int, i3: Int): Int = TODO()
}
fun main(args: Array<String>) {
Foo(
}
"""
)
val functionCall =
file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
.findElementByText<UElement>("Foo").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"operator fun invoke(i: Int): Int = TODO()",
"operator fun invoke(i1: Int, i2: Int): Int = TODO()",
"operator fun invoke(i1: Int, i2: Int, i3: Int): Int = TODO()"
)
TestCase.assertEquals(PsiType.INT, functionCall.getExpressionType())
}
fun testMultiResolveJvmOverloads() {
val file = myFixture.configureByText(
"s.kt", """
class MyClass {
@JvmOverloads
fun foo(i1: Int = 1, i2: Int = 2): Int = TODO()
}
fun main(args: Array<String>) {
MyClass().foo(
}"""
)
val functionCall =
file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
.findElementByText<UElement>("foo").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"@JvmOverloads\n fun foo(i1: Int = 1, i2: Int = 2): Int = TODO()"
)
TestCase.assertEquals(PsiType.INT, functionCall.getExpressionType())
}
}