[LL FIR] Add multi-module resolve extension reference resolve tests

- To test the reference resolution of declarations provided through
  resolve extensions of module dependencies, we need support for
  multimodule resolve extension tests.
This commit is contained in:
Marco Pennekamp
2023-05-09 16:59:11 +02:00
committed by Space Team
parent 915c412929
commit a50e839660
10 changed files with 177 additions and 19 deletions
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.kotlin.analysis.api.fir.test.cases.generated.cases.references;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.AnalysisApiFirTestConfiguratorFactory;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactoryData;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode;
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractMultiModuleReferenceResolveWithResolveExtensionTest;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.analysis.api.GenerateAnalysisApiTestsKt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve")
@TestDataPath("$PROJECT_ROOT")
public class FirIdeNormalAnalysisSourceModuleMultiModuleReferenceResolveWithResolveExtensionTestGenerated extends AbstractMultiModuleReferenceResolveWithResolveExtensionTest {
@NotNull
@Override
public AnalysisApiTestConfigurator getConfigurator() {
return AnalysisApiFirTestConfiguratorFactory.INSTANCE.createConfigurator(
new AnalysisApiTestConfiguratorFactoryData(
FrontendKind.Fir,
TestModuleKind.Source,
AnalysisSessionMode.Normal,
AnalysisApiMode.Ide
)
);
}
@Test
public void testAllFilesPresentInReferenceResolve() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
}
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModul
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind; import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode; import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode; import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode;
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractReferenceResolveWithResolveExtensionTest; import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractSingleModuleReferenceResolveWithResolveExtensionTest;
import org.jetbrains.kotlin.test.TestMetadata; import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -27,7 +27,7 @@ import java.util.regex.Pattern;
@SuppressWarnings("all") @SuppressWarnings("all")
@TestMetadata("analysis/analysis-api/testData/resolveExtensions/referenceResolve") @TestMetadata("analysis/analysis-api/testData/resolveExtensions/referenceResolve")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
public class FirIdeNormalAnalysisSourceModuleReferenceResolveWithResolveExtensionTestGenerated extends AbstractReferenceResolveWithResolveExtensionTest { public class FirIdeNormalAnalysisSourceModuleSingleModuleReferenceResolveWithResolveExtensionTestGenerated extends AbstractSingleModuleReferenceResolveWithResolveExtensionTest {
@NotNull @NotNull
@Override @Override
public AnalysisApiTestConfigurator getConfigurator() { public AnalysisApiTestConfigurator getConfigurator() {
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.kotlin.analysis.api.impl.base.test.cases.references
import org.jetbrains.kotlin.analysis.api.impl.base.test.util.KtMultiModuleResolveExtensionProviderForTest
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionFile
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.name.FqName
abstract class AbstractMultiModuleReferenceResolveWithResolveExtensionTest : AbstractReferenceResolveWithResolveExtensionTest() {
override fun createResolveExtensionProvider(files: List<KtResolveExtensionFile>, packages: Set<FqName>): KtResolveExtensionProvider =
KtMultiModuleResolveExtensionProviderForTest(files, packages) { it is KtSourceModule && it.moduleName == "extendedModule" }
}
@@ -12,7 +12,8 @@ import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KtDeclaratio
import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.callables.KtPropertyAccessorsRenderer import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.callables.KtPropertyAccessorsRenderer
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestDirectives import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestDirectives
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedSingleModuleTest import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedTest
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
import org.jetbrains.kotlin.analysis.test.framework.utils.unwrapMultiReferences import org.jetbrains.kotlin.analysis.test.framework.utils.unwrapMultiReferences
import org.jetbrains.kotlin.idea.references.KtReference import org.jetbrains.kotlin.idea.references.KtReference
@@ -21,10 +22,11 @@ import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions import org.jetbrains.kotlin.test.services.assertions
abstract class AbstractReferenceResolveTest : AbstractAnalysisApiBasedSingleModuleTest() { abstract class AbstractReferenceResolveTest : AbstractAnalysisApiBasedTest() {
override fun configureTest(builder: TestConfigurationBuilder) { override fun configureTest(builder: TestConfigurationBuilder) {
super.configureTest(builder) super.configureTest(builder)
with(builder) { with(builder) {
@@ -41,7 +43,16 @@ abstract class AbstractReferenceResolveTest : AbstractAnalysisApiBasedSingleModu
} }
} }
override fun doTestByFileStructure(ktFiles: List<KtFile>, module: TestModule, testServices: TestServices) { final override fun doTestByModuleStructure(moduleStructure: TestModuleStructure, testServices: TestServices) {
val mainModule = moduleStructure.modules.singleOrNull() ?: findMainModule(moduleStructure)
val ktFiles = testServices.ktModuleProvider.getModuleFiles(mainModule).filterIsInstance<KtFile>()
doTestByFileStructure(ktFiles, mainModule, testServices)
}
private fun findMainModule(moduleStructure: TestModuleStructure): TestModule =
moduleStructure.modules.find { it.name == "main" } ?: error("There should be a module named 'main' in the multi-module test.")
fun doTestByFileStructure(ktFiles: List<KtFile>, mainModule: TestModule, testServices: TestServices) {
val mainKtFile = ktFiles.singleOrNull() ?: ktFiles.firstOrNull { it.name == "main.kt" } ?: ktFiles.first() val mainKtFile = ktFiles.singleOrNull() ?: ktFiles.firstOrNull { it.name == "main.kt" } ?: ktFiles.first()
val caretPosition = testServices.expressionMarkerProvider.getCaretPosition(mainKtFile) val caretPosition = testServices.expressionMarkerProvider.getCaretPosition(mainKtFile)
val ktReferences = findReferencesAtCaret(mainKtFile, caretPosition) val ktReferences = findReferencesAtCaret(mainKtFile, caretPosition)
@@ -52,11 +63,11 @@ abstract class AbstractReferenceResolveTest : AbstractAnalysisApiBasedSingleModu
val resolvedTo = val resolvedTo =
analyseForTest(ktReferences.first().element) { analyseForTest(ktReferences.first().element) {
val symbols = ktReferences.flatMap { it.resolveToSymbols() } val symbols = ktReferences.flatMap { it.resolveToSymbols() }
checkReferenceResultForValidity(ktReferences, module, testServices, symbols) checkReferenceResultForValidity(ktReferences, mainModule, testServices, symbols)
renderResolvedTo(symbols, renderingOptions) renderResolvedTo(symbols, renderingOptions)
} }
if (Directives.UNRESOLVED_REFERENCE in module.directives) { if (Directives.UNRESOLVED_REFERENCE in mainModule.directives) {
return return
} }
@@ -5,17 +5,23 @@
package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references
import org.jetbrains.kotlin.analysis.api.impl.base.test.util.KtResolveExtensionProviderForTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.util.KtResolveExtensionProviderForTestPreAnalysisHandler
import org.jetbrains.kotlin.analysis.api.impl.base.test.util.KtResolveExtensionFileForTests import org.jetbrains.kotlin.analysis.api.impl.base.test.util.KtResolveExtensionFileForTests
import org.jetbrains.kotlin.analysis.api.impl.base.test.util.KtResolveExtensionProviderForTestPreAnalysisHandler
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionFile
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.test.bind import org.jetbrains.kotlin.test.bind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
abstract class AbstractReferenceResolveWithResolveExtensionTest : AbstractReferenceResolveTest() { abstract class AbstractReferenceResolveWithResolveExtensionTest : AbstractReferenceResolveTest() {
abstract fun createResolveExtensionProvider(
files: List<KtResolveExtensionFile>,
packages: Set<FqName>,
): KtResolveExtensionProvider
override fun configureTest(builder: TestConfigurationBuilder) { override fun configureTest(builder: TestConfigurationBuilder) {
super.configureTest(builder) super.configureTest(builder)
val provider = KtResolveExtensionProviderForTest( val provider = createResolveExtensionProvider(
listOf( listOf(
KtResolveExtensionFileForTests( KtResolveExtensionFileForTests(
"extension1.kt", "extension1.kt",
@@ -0,0 +1,16 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.kotlin.analysis.api.impl.base.test.cases.references
import org.jetbrains.kotlin.analysis.api.impl.base.test.util.KtSingleModuleResolveExtensionProviderForTest
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionFile
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider
import org.jetbrains.kotlin.name.FqName
abstract class AbstractSingleModuleReferenceResolveWithResolveExtensionTest : AbstractReferenceResolveWithResolveExtensionTest() {
override fun createResolveExtensionProvider(files: List<KtResolveExtensionFile>, packages: Set<FqName>): KtResolveExtensionProvider =
KtSingleModuleResolveExtensionProviderForTest(files, packages)
}
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.test.services.PreAnalysisHandler
import org.jetbrains.kotlin.test.services.TestModuleStructure import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.TestServices
class KtResolveExtensionProviderForTest( class KtSingleModuleResolveExtensionProviderForTest(
private val files: List<KtResolveExtensionFile>, private val files: List<KtResolveExtensionFile>,
private val packages: Set<FqName>, private val packages: Set<FqName>,
) : KtResolveExtensionProvider() { ) : KtResolveExtensionProvider() {
@@ -31,9 +31,20 @@ class KtResolveExtensionProviderForTest(
} }
} }
class KtMultiModuleResolveExtensionProviderForTest(
private val files: List<KtResolveExtensionFile>,
private val packages: Set<FqName>,
private val hasResolveExtension: (KtModule) -> Boolean,
) : KtResolveExtensionProvider() {
override fun provideExtensionsFor(module: KtModule): List<KtResolveExtension> {
if (!hasResolveExtension(module)) return emptyList()
return listOf(KtResolveExtensionForTest(files, packages))
}
}
class KtResolveExtensionProviderForTestPreAnalysisHandler( class KtResolveExtensionProviderForTestPreAnalysisHandler(
testServices: TestServices, testServices: TestServices,
private val providers: List<KtResolveExtensionProviderForTest>, private val providers: List<KtResolveExtensionProvider>,
) : PreAnalysisHandler(testServices) { ) : PreAnalysisHandler(testServices) {
override fun preprocessModuleStructure(moduleStructure: TestModuleStructure) { override fun preprocessModuleStructure(moduleStructure: TestModuleStructure) {
val project = testServices.environmentManager.getProject() as MockProject val project = testServices.environmentManager.getProject() as MockProject
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.kotlin.analysis.api.standalone.fir.test.cases.generated.cases.references;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.analysis.api.standalone.fir.test.AnalysisApiFirStandaloneModeTestConfiguratorFactory;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactoryData;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode;
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractMultiModuleReferenceResolveWithResolveExtensionTest;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.analysis.api.GenerateAnalysisApiTestsKt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve")
@TestDataPath("$PROJECT_ROOT")
public class FirStandaloneNormalAnalysisSourceModuleMultiModuleReferenceResolveWithResolveExtensionTestGenerated extends AbstractMultiModuleReferenceResolveWithResolveExtensionTest {
@NotNull
@Override
public AnalysisApiTestConfigurator getConfigurator() {
return AnalysisApiFirStandaloneModeTestConfiguratorFactory.INSTANCE.createConfigurator(
new AnalysisApiTestConfiguratorFactoryData(
FrontendKind.Fir,
TestModuleKind.Source,
AnalysisSessionMode.Normal,
AnalysisApiMode.Standalone
)
);
}
@Test
public void testAllFilesPresentInReferenceResolve() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/resolveExtensions/multiModule/referenceResolve"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
}
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModul
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind; import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode; import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode;
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode; import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode;
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractReferenceResolveWithResolveExtensionTest; import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractSingleModuleReferenceResolveWithResolveExtensionTest;
import org.jetbrains.kotlin.test.TestMetadata; import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -27,7 +27,7 @@ import java.util.regex.Pattern;
@SuppressWarnings("all") @SuppressWarnings("all")
@TestMetadata("analysis/analysis-api/testData/resolveExtensions/referenceResolve") @TestMetadata("analysis/analysis-api/testData/resolveExtensions/referenceResolve")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveWithResolveExtensionTestGenerated extends AbstractReferenceResolveWithResolveExtensionTest { public class FirStandaloneNormalAnalysisSourceModuleSingleModuleReferenceResolveWithResolveExtensionTestGenerated extends AbstractSingleModuleReferenceResolveWithResolveExtensionTest {
@NotNull @NotNull
@Override @Override
public AnalysisApiTestConfigurator getConfigurator() { public AnalysisApiTestConfigurator getConfigurator() {
@@ -42,10 +42,7 @@ import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeInf
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeProvider.AbstractAnalysisApiGetSuperTypesTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeProvider.AbstractAnalysisApiGetSuperTypesTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeProvider.AbstractHasCommonSubtypeTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeProvider.AbstractHasCommonSubtypeTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeProvider.AbstractTypeReferenceTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.typeProvider.AbstractTypeReferenceTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractReferenceResolveTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.*
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractReferenceResolveWithResolveExtensionTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractReferenceShortenerForWholeFileTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractReferenceShortenerTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.* import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.*
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.types.AbstractAnalysisApiSubstitutorsTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.types.AbstractAnalysisApiSubstitutorsTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.types.AbstractTypeByDeclarationReturnTypeTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.types.AbstractTypeByDeclarationReturnTypeTest
@@ -92,9 +89,13 @@ private fun AnalysisApiTestGroup.generateResolveExtensionsTests() {
frontendIs(FrontendKind.Fir) and frontendIs(FrontendKind.Fir) and
testModuleKindIs(TestModuleKind.Source) testModuleKindIs(TestModuleKind.Source)
) { ) {
test(AbstractReferenceResolveWithResolveExtensionTest::class) { test(AbstractSingleModuleReferenceResolveWithResolveExtensionTest::class) {
model("referenceResolve") model("referenceResolve")
} }
test(AbstractMultiModuleReferenceResolveWithResolveExtensionTest::class) {
model("multiModule/referenceResolve")
}
} }
} }