[kotlin] Add reference resolution tests for both decompiled libraries and libraries with sources

GitOrigin-RevId: f01d179d985ab1a831b0a172908c0152f71dcb6a
This commit is contained in:
Yan Zhulanow
2023-04-12 00:01:41 +09:00
committed by intellij-monorepo-bot
parent 9826bce842
commit 960afa503c
15 changed files with 288 additions and 26 deletions

View File

@@ -2,8 +2,13 @@
package org.jetbrains.kotlin.idea.fir.resolve
import org.jetbrains.kotlin.idea.resolve.AbstractReferenceResolveWithCompiledLibTest
import org.jetbrains.kotlin.idea.resolve.AbstractReferenceResolveWithLibTest
abstract class AbstractFirReferenceResolveWithLibTest : AbstractReferenceResolveWithLibTest() {
override fun isFirPlugin(): Boolean = true
}
abstract class AbstractFirReferenceResolveWithCompiledLibTest : AbstractReferenceResolveWithCompiledLibTest() {
override fun isFirPlugin(): Boolean = true
}

View File

@@ -0,0 +1,105 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.fir.resolve;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.idea.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.idea.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TestMetadata;
import org.jetbrains.kotlin.idea.base.test.TestRoot;
import org.junit.runner.RunWith;
/**
* This class is generated by {@link org.jetbrains.kotlin.testGenerator.generator.TestGenerator}.
* DO NOT MODIFY MANUALLY.
*/
@SuppressWarnings("all")
@TestRoot("fir")
@TestDataPath("$CONTENT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../idea/tests/testData/resolve/referenceWithLib")
public class FirReferenceResolveWithCompiledLibTestGenerated extends AbstractFirReferenceResolveWithCompiledLibTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@TestMetadata("dataClassSyntheticMethods")
public void testDataClassSyntheticMethods() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/dataClassSyntheticMethods/");
}
@TestMetadata("delegatedPropertyWithTypeParameters")
public void testDelegatedPropertyWithTypeParameters() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/delegatedPropertyWithTypeParameters/");
}
@TestMetadata("enumSyntheticMethods")
public void testEnumSyntheticMethods() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/enumSyntheticMethods/");
}
@TestMetadata("fakeOverride")
public void testFakeOverride() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/fakeOverride/");
}
@TestMetadata("fakeOverride2")
public void testFakeOverride2() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/fakeOverride2/");
}
@TestMetadata("infinityAndNanInJavaAnnotation")
public void testInfinityAndNanInJavaAnnotation() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/infinityAndNanInJavaAnnotation/");
}
@TestMetadata("innerClassFromLib")
public void testInnerClassFromLib() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/innerClassFromLib/");
}
@TestMetadata("iteratorWithTypeParameter")
public void testIteratorWithTypeParameter() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/iteratorWithTypeParameter/");
}
@TestMetadata("multiDeclarationWithTypeParameters")
public void testMultiDeclarationWithTypeParameters() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/multiDeclarationWithTypeParameters/");
}
@TestMetadata("nestedClassFromLib")
public void testNestedClassFromLib() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/nestedClassFromLib/");
}
@TestMetadata("overloadFun")
public void testOverloadFun() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/overloadFun/");
}
@TestMetadata("overridingFunctionWithSamAdapter")
public void testOverridingFunctionWithSamAdapter() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/overridingFunctionWithSamAdapter/");
}
@TestMetadata("packageOfLibDeclaration")
public void testPackageOfLibDeclaration() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/packageOfLibDeclaration/");
}
@TestMetadata("referenceToRootJavaClassFromLib")
public void testReferenceToRootJavaClassFromLib() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/referenceToRootJavaClassFromLib/");
}
@TestMetadata("sameNameInLib")
public void testSameNameInLib() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/sameNameInLib/");
}
@TestMetadata("setWithTypeParameters")
public void testSetWithTypeParameters() throws Exception {
runTest("../idea/tests/testData/resolve/referenceWithLib/setWithTypeParameters/");
}
}

View File

@@ -48,8 +48,9 @@ abstract class AbstractReferenceToCompiledKotlinResolveInJavaTest : AbstractRefe
)
}
override val refMarkerText: String
get() = "CLS_REF"
override fun getExpectedReferences(text: String, index: Int): List<String> {
return getExpectedReferences(text, index, "CLS_REF")
}
override fun checkResolvedTo(element: PsiElement) {
val navigationElement = element.navigationElement

View File

@@ -36,7 +36,9 @@ abstract class AbstractReferenceResolveInLibrarySourcesTest : KotlinLightCodeIns
fixture.configureByFile(fileName())
val expectedResolveData = AbstractReferenceResolveTest.readResolveData(fixture.file!!.text, 0)
val fileText = fixture.file!!.text
val expectedReferences = AbstractReferenceResolveTest.getExpectedReferences(fileText, 0, "REF")
val expectedResolveData = AbstractReferenceResolveTest.readResolveData(fileText, expectedReferences)
val gotoData = NavigationTestUtils.invokeGotoImplementations(fixture.editor, fixture.file)!!
Assert.assertEquals("Single target expected for original file", 1, gotoData.targets.size)
@@ -44,7 +46,7 @@ abstract class AbstractReferenceResolveInLibrarySourcesTest : KotlinLightCodeIns
val testedPsiElement = gotoData.targets[0].navigationElement
val testedElementFile = testedPsiElement.containingFile!!
val lineContext = InTextDirectivesUtils.findStringWithPrefixes(fixture.file!!.text, "CONTEXT:")
val lineContext = InTextDirectivesUtils.findStringWithPrefixes(fileText, "CONTEXT:")
?: throw AssertionFailedError("'CONTEXT: ' directive is expected to set up position in library file: ${testedElementFile.name}")
val inContextOffset = lineContext.indexOf(REF_CARET_MARKER)

View File

@@ -56,7 +56,8 @@ abstract class AbstractReferenceResolveTest : KotlinLightCodeInsightFixtureTestC
private fun doSingleResolveTest() {
forEachCaret { index, offset ->
val expectedResolveData = readResolveData(myFixture.file.text, index, refMarkerText)
val fileText = myFixture.file.text
val expectedResolveData = readResolveData(fileText, getExpectedReferences(fileText, index))
val psiReference = wrapReference(myFixture.file.findReferenceAt(offset))
checkReferenceResolve(expectedResolveData, offset, psiReference, render = { this.render(it) }) { resolveTo ->
checkResolvedTo(resolveTo)
@@ -78,7 +79,7 @@ abstract class AbstractReferenceResolveTest : KotlinLightCodeInsightFixtureTestC
private fun doMultiResolveTest() {
forEachCaret { index, offset ->
val expectedReferences = getExpectedReferences(myFixture.file.text, index, refMarkerText)
val expectedReferences = getExpectedReferences(myFixture.file.text, index)
val psiReference = myFixture.file.findReferenceAt(offset)
assertTrue(psiReference is PsiPolyVariantReference)
@@ -112,37 +113,38 @@ abstract class AbstractReferenceResolveTest : KotlinLightCodeInsightFixtureTestC
override fun getDefaultProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.getInstanceNoSources()
open val refMarkerText: String = "REF"
protected open fun getExpectedReferences(text: String, index: Int): List<String> {
return getExpectedReferences(text, index, "REF")
}
companion object {
const val MULTIRESOLVE: String = "MULTIRESOLVE"
const val REF_EMPTY: String = "REF_EMPTY"
fun readResolveData(fileText: String, index: Int, refMarkerText: String = "REF"): ExpectedResolveData {
fun readResolveData(fileText: String, expectedReferences: List<String>): ExpectedResolveData {
val shouldBeUnresolved = InTextDirectivesUtils.isDirectiveDefined(fileText, REF_EMPTY)
val refs = getExpectedReferences(fileText, index, refMarkerText)
val referenceToString: String
if (shouldBeUnresolved) {
Assert.assertTrue("REF: directives will be ignored for $REF_EMPTY test: $refs", refs.isEmpty())
Assert.assertTrue("REF: directives will be ignored for $REF_EMPTY test: $expectedReferences", expectedReferences.isEmpty())
referenceToString = "<empty>"
} else {
assertTrue(
refs.size == 1,
"Must be a single ref: $refs.\nUse $MULTIRESOLVE if you need multiple refs\nUse $REF_EMPTY for an unresolved reference"
expectedReferences.size == 1,
"Must be a single ref: $expectedReferences.\n" +
"Use $MULTIRESOLVE if you need multiple refs\nUse $REF_EMPTY for an unresolved reference"
)
referenceToString = refs[0]
referenceToString = expectedReferences[0]
Assert.assertNotNull("Test data wasn't found, use \"// REF: \" directive", referenceToString)
}
return ExpectedResolveData(shouldBeUnresolved, referenceToString)
}
// purpose of this helper is to deal with the case when navigation element is a file
// see ReferenceResolveInJavaTestGenerated.testPackageFacade()
private fun getExpectedReferences(text: String, index: Int, refMarkerText: String): List<String> {
fun getExpectedReferences(fileText: String, index: Int, refMarkerText: String): List<String> {
// Navigation element might be a file (see ReferenceResolveInJavaTestGenerated.testPackageFacade())
val prefix = if (index > 0) "// $refMarkerText$index:" else "// $refMarkerText:"
return InTextDirectivesUtils.findLinesWithPrefixesRemoved(text, prefix)
return InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, prefix)
}
fun checkReferenceResolve(

View File

@@ -16,6 +16,9 @@ abstract class AbstractReferenceResolveWithLibTest : AbstractReferenceResolveTes
protected val testDirectoryPath: String
get() = KotlinTestUtils.getTestDataFileName(this::class.java, this.name)!!
protected open val attachLibrarySources: Boolean
get() = true
override fun fileName(): String {
return KotlinTestUtils.getTestDataFileName(this::class.java, this.name) + "/src/" + getTestName(true) + ".kt"
}
@@ -24,7 +27,7 @@ abstract class AbstractReferenceResolveWithLibTest : AbstractReferenceResolveTes
super.setUp()
val libraryDir = testDataDirectory.resolve(testDirectoryPath).resolve("lib")
mockLibraryFacility = MockLibraryFacility(libraryDir, attachSources = false).apply { setUp(module) }
mockLibraryFacility = MockLibraryFacility(libraryDir, attachLibrarySources).apply { setUp(module) }
}
override fun tearDown() {
@@ -53,4 +56,20 @@ abstract class AbstractReferenceResolveWithLibTest : AbstractReferenceResolveTes
}
}
}
override fun getExpectedReferences(text: String, index: Int): List<String> {
if (!attachLibrarySources) {
val decompiledReferences = getExpectedReferences(text, index, "CLS_REF")
if (decompiledReferences.isNotEmpty()) {
return decompiledReferences
}
}
return super.getExpectedReferences(text, index)
}
}
abstract class AbstractReferenceResolveWithCompiledLibTest : AbstractReferenceResolveWithLibTest() {
override val attachLibrarySources: Boolean
get() = false
}

View File

@@ -0,0 +1,105 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.resolve;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.idea.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.idea.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TestMetadata;
import org.jetbrains.kotlin.idea.base.test.TestRoot;
import org.junit.runner.RunWith;
/**
* This class is generated by {@link org.jetbrains.kotlin.testGenerator.generator.TestGenerator}.
* DO NOT MODIFY MANUALLY.
*/
@SuppressWarnings("all")
@TestRoot("idea/tests")
@TestDataPath("$CONTENT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("testData/resolve/referenceWithLib")
public class ReferenceResolveWithCompiledLibTestGenerated extends AbstractReferenceResolveWithCompiledLibTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@TestMetadata("dataClassSyntheticMethods")
public void testDataClassSyntheticMethods() throws Exception {
runTest("testData/resolve/referenceWithLib/dataClassSyntheticMethods/");
}
@TestMetadata("delegatedPropertyWithTypeParameters")
public void testDelegatedPropertyWithTypeParameters() throws Exception {
runTest("testData/resolve/referenceWithLib/delegatedPropertyWithTypeParameters/");
}
@TestMetadata("enumSyntheticMethods")
public void testEnumSyntheticMethods() throws Exception {
runTest("testData/resolve/referenceWithLib/enumSyntheticMethods/");
}
@TestMetadata("fakeOverride")
public void testFakeOverride() throws Exception {
runTest("testData/resolve/referenceWithLib/fakeOverride/");
}
@TestMetadata("fakeOverride2")
public void testFakeOverride2() throws Exception {
runTest("testData/resolve/referenceWithLib/fakeOverride2/");
}
@TestMetadata("infinityAndNanInJavaAnnotation")
public void testInfinityAndNanInJavaAnnotation() throws Exception {
runTest("testData/resolve/referenceWithLib/infinityAndNanInJavaAnnotation/");
}
@TestMetadata("innerClassFromLib")
public void testInnerClassFromLib() throws Exception {
runTest("testData/resolve/referenceWithLib/innerClassFromLib/");
}
@TestMetadata("iteratorWithTypeParameter")
public void testIteratorWithTypeParameter() throws Exception {
runTest("testData/resolve/referenceWithLib/iteratorWithTypeParameter/");
}
@TestMetadata("multiDeclarationWithTypeParameters")
public void testMultiDeclarationWithTypeParameters() throws Exception {
runTest("testData/resolve/referenceWithLib/multiDeclarationWithTypeParameters/");
}
@TestMetadata("nestedClassFromLib")
public void testNestedClassFromLib() throws Exception {
runTest("testData/resolve/referenceWithLib/nestedClassFromLib/");
}
@TestMetadata("overloadFun")
public void testOverloadFun() throws Exception {
runTest("testData/resolve/referenceWithLib/overloadFun/");
}
@TestMetadata("overridingFunctionWithSamAdapter")
public void testOverridingFunctionWithSamAdapter() throws Exception {
runTest("testData/resolve/referenceWithLib/overridingFunctionWithSamAdapter/");
}
@TestMetadata("packageOfLibDeclaration")
public void testPackageOfLibDeclaration() throws Exception {
runTest("testData/resolve/referenceWithLib/packageOfLibDeclaration/");
}
@TestMetadata("referenceToRootJavaClassFromLib")
public void testReferenceToRootJavaClassFromLib() throws Exception {
runTest("testData/resolve/referenceWithLib/referenceToRootJavaClassFromLib/");
}
@TestMetadata("sameNameInLib")
public void testSameNameInLib() throws Exception {
runTest("testData/resolve/referenceWithLib/sameNameInLib/");
}
@TestMetadata("setWithTypeParameters")
public void testSetWithTypeParameters() throws Exception {
runTest("testData/resolve/referenceWithLib/setWithTypeParameters/");
}
}

View File

@@ -9,5 +9,9 @@ class B {
}
// MULTIRESOLVE
// REF: (for T in dependency).getValue(R, kotlin.reflect.KProperty<*>)
// REF: (for T in dependency).setValue(R, kotlin.reflect.KProperty<*>, kotlin.Int)
// REF: (for T in dependency).getValue(R, KProperty<*>)
// REF: (for T in dependency).setValue(R, KProperty<*>, Int)
// CLS_REF: (for T in dependency).getValue(R, kotlin.reflect.KProperty<*>)
// CLS_REF: (for T in dependency).setValue(R, kotlin.reflect.KProperty<*>, kotlin.Int)

View File

@@ -12,6 +12,7 @@ fun foo() {
}
// ALLOW_AST_ACCESS
// REF1: (dependency).LibraryEnum
// REF2: (dependency).LibraryEnum
// REF3: (dependency).LibraryEnum

View File

@@ -8,6 +8,11 @@ fun foo(f: Foo<Int>) {
}
// MULTIRESOLVE
// REF: (for dependency.Foo<T> in dependency).iterator()
// REF: (for dependency.FooIterator<T> in dependency).hasNext()
// REF: (for dependency.FooIterator<T> in dependency).next()
// REF: (for Foo<T> in dependency).iterator()
// REF: (for FooIterator<T> in dependency).hasNext()
// REF: (for FooIterator<T> in dependency).next()
// CLS_REF: (for dependency.Foo<T> in dependency).iterator()
// CLS_REF: (for dependency.FooIterator<T> in dependency).hasNext()
// CLS_REF: (for dependency.FooIterator<T> in dependency).next()

View File

@@ -7,5 +7,5 @@ fun <Int> f(l: List<Int>) {
}
// ALLOW_AST_ACCESS
// REF: el1
// REF: el1

View File

@@ -7,4 +7,7 @@ fun foo() {
}
// ALLOW_AST_ACCESS
// REF: (dependency).test(kotlin.String)
// REF: (dependency).test(String)
// CLS_REF: (dependency).test(kotlin.String)

View File

@@ -6,4 +6,6 @@ fun foo(a: List<Int>) {
a[<caret>"bar"] = 3
}
// REF: (for kotlin.collections.List<T> in dependency).set(kotlin.String, T)
// REF: (for List<T> in dependency).set(String, T)
// CLS_REF: (for kotlin.collections.List<T> in dependency).set(kotlin.String, T)

View File

@@ -642,6 +642,10 @@ private fun assembleWorkspace(): TWorkspace = workspace {
model("resolve/referenceWithLib", pattern = DIRECTORY, isRecursive = false)
}
testClass<AbstractReferenceResolveWithCompiledLibTest> {
model("resolve/referenceWithLib", pattern = DIRECTORY, isRecursive = false)
}
testClass<AbstractReferenceResolveInLibrarySourcesTest> {
model("resolve/referenceInLib", isRecursive = false)
}

View File

@@ -85,6 +85,10 @@ private fun assembleWorkspace(): TWorkspace = workspace {
model("resolve/referenceWithLib", pattern = DIRECTORY, isRecursive = false)
}
testClass<AbstractFirReferenceResolveWithCompiledLibTest> {
model("resolve/referenceWithLib", pattern = DIRECTORY, isRecursive = false)
}
testClass<AbstractFirReferenceResolveInJavaTest> {
model("resolve/referenceInJava/binaryAndSource", pattern = JAVA)
model("resolve/referenceInJava/sourceOnly", pattern = JAVA)