Analysis API FIR: introduce library resolve tests

This commit is contained in:
Ilya Kirillov
2022-01-25 16:46:43 +01:00
parent 96e1f1e7d4
commit caddbda01b
22 changed files with 1784 additions and 128 deletions
@@ -29,7 +29,11 @@ dependencies {
testApi(projectTests(":compiler:tests-common-new"))
testApi(projectTests(":compiler:fir:analysis-tests:legacy-fir-tests"))
testApi(projectTests(":analysis:analysis-api-impl-base"))
testApi(projectTests(":analysis:decompiled:decompiler-to-file-stubs"))
testApi(project(":analysis:decompiled:decompiler-to-file-stubs"))
testApi(project(":analysis:decompiled:decompiler-to-psi"))
testApi(project(":kotlin-test:kotlin-test-junit"))
testApi(toolsJar())
testApiJUnit5()
testApi(project(":analysis:symbol-light-classes"))
@@ -22,7 +22,7 @@ import java.util.regex.Pattern;
@SuppressWarnings("all")
@TestMetadata("analysis/analysis-api/testData/referenceResolve")
@TestDataPath("$PROJECT_ROOT")
public class FirReferenceResolveTestGenerated extends AbstractReferenceResolveTest {
public class FirSourceReferenceResolveTestGenerated extends AbstractReferenceResolveTest {
@NotNull
@Override
public FrontendApiTestConfiguratorService getConfigurator() {
@@ -0,0 +1,60 @@
/*
* Copyright 2010-2021 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.utils.libraries.binary
import com.intellij.ide.highlighter.JavaClassFileType
import com.intellij.mock.MockApplication
import com.intellij.mock.MockProject
import com.intellij.openapi.Disposable
import com.intellij.openapi.extensions.LoadingOrder
import com.intellij.psi.ClassFileViewProviderFactory
import com.intellij.psi.FileTypeFileViewProviders
import com.intellij.psi.compiled.ClassFileDecompilers
import org.jetbrains.kotlin.analysis.api.fir.FirFrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.impl.base.test.utils.libraries.LibraryEnvironmentConfigurator
import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinBuiltInDecompiler
import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinClassFileDecompiler
import org.jetbrains.kotlin.analysis.decompiler.stub.file.ClsKotlinBinaryClassCache
import org.jetbrains.kotlin.analysis.decompiler.stub.file.FileAttributeService
import org.jetbrains.kotlin.analysis.decompiler.stub.files.DummyFileAttributeService
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
object LibraryFrontendApiTestConfiguratorService : FrontendApiTestConfiguratorService {
override val allowDependedAnalysisSession: Boolean get() = false
override fun TestConfigurationBuilder.configureTest(disposable: Disposable) {
useConfigurators(::LibraryEnvironmentConfigurator)
usePreAnalysisHandlers(::LibraryModuleRegistrarPreAnalysisHandler)
}
override fun registerProjectServices(project: MockProject) {
}
override fun registerApplicationServices(application: MockApplication) {
FirFrontendApiTestConfiguratorService.registerApplicationServices(application)
if (application.getServiceIfCreated(ClsKotlinBinaryClassCache::class.java) != null) return
application.registerService(ClsKotlinBinaryClassCache::class.java)
application.registerService(FileAttributeService::class.java, DummyFileAttributeService)
FileTypeFileViewProviders.INSTANCE.addExplicitExtension(
JavaClassFileType.INSTANCE,
ClassFileViewProviderFactory()
)
@Suppress("DEPRECATION")
ClassFileDecompilers.getInstance().EP_NAME.point.apply {
registerExtension(KotlinClassFileDecompiler(), LoadingOrder.FIRST)
registerExtension(KotlinBuiltInDecompiler(), LoadingOrder.FIRST)
}
}
override fun doOutOfBlockModification(file: KtFile) {
FirFrontendApiTestConfiguratorService.doOutOfBlockModification(file)
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2022 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.utils.libraries.binary
import com.intellij.mock.MockProject
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.TestKtLibraryModule
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.projectModuleProvider
import org.jetbrains.kotlin.analysis.api.impl.base.test.utils.libraries.TestLibraryUtils
import org.jetbrains.kotlin.analysis.api.impl.base.test.utils.libraries.compiledLibraryProvider
import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based.registerTestServices
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.PreAnalysisHandler
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
class LibraryModuleRegistrarPreAnalysisHandler(
testServices: TestServices
) : PreAnalysisHandler(testServices) {
private val moduleInfoProvider = testServices.projectModuleProvider
override fun preprocessModuleStructure(moduleStructure: TestModuleStructure) {
val testModule = moduleStructure.modules.single()
val project = testServices.compilerConfigurationProvider.getProject(testModule)
val decompiledKtFiles = getDecompiledVirtualFilesFromLibrary(testModule, project)
moduleInfoProvider.registerModuleInfo(testModule, TestKtLibraryModule(project, testModule, decompiledKtFiles, testServices))
(project as MockProject).registerTestServices(testModule, decompiledKtFiles, testServices)
}
private fun getDecompiledVirtualFilesFromLibrary(module: TestModule, project: Project): List<KtClsFile> {
val library = testServices.compiledLibraryProvider.getCompiledLibrary(module).jar
val virtualFiles = TestLibraryUtils.getAllVirtualFilesFromJar(library)
return virtualFiles.mapNotNull { virtualFile ->
PsiManager.getInstance(project).findFile(virtualFile) as? KtClsFile
}
}
}
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2021 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.utils.libraries.source
import com.intellij.mock.MockApplication
import com.intellij.mock.MockProject
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.analysis.api.fir.FirFrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.impl.base.test.utils.libraries.CompiledLibraryProvider
import org.jetbrains.kotlin.analysis.api.impl.base.test.utils.libraries.LibraryEnvironmentConfigurator
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.services.ServiceRegistrationData
object LibrarySourceFrontendApiTestConfiguratorService : FrontendApiTestConfiguratorService {
override val allowDependedAnalysisSession: Boolean get() = false
override fun TestConfigurationBuilder.configureTest(disposable: Disposable) {
useConfigurators(::LibraryEnvironmentConfigurator)
usePreAnalysisHandlers(::LibrarySourceModuleRegistrarPreAnalysisHandler)
useAdditionalServices(ServiceRegistrationData(CompiledLibraryProvider::class, ::CompiledLibraryProvider))
}
override fun registerProjectServices(project: MockProject) {
}
override fun registerApplicationServices(application: MockApplication) {
FirFrontendApiTestConfiguratorService.registerApplicationServices(application)
}
override fun doOutOfBlockModification(file: KtFile) {
FirFrontendApiTestConfiguratorService.doOutOfBlockModification(file)
}
}
@@ -0,0 +1,82 @@
/*
* Copyright 2010-2022 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.utils.libraries.source
import com.intellij.mock.MockProject
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiManager
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.TestKtLibrarySourceModule
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.projectModuleProvider
import org.jetbrains.kotlin.analysis.api.impl.base.test.utils.libraries.TestLibraryUtils
import org.jetbrains.kotlin.analysis.api.impl.base.test.utils.libraries.compiledLibraryProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based.registerTestServices
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
import org.jetbrains.kotlin.analysis.project.structure.KtLibrarySourceModule
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.test.frontend.fir.getAnalyzerServices
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.PreAnalysisHandler
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
import java.nio.file.Path
class LibrarySourceModuleRegistrarPreAnalysisHandler(
testServices: TestServices
) : PreAnalysisHandler(testServices) {
private val moduleInfoProvider = testServices.projectModuleProvider
override fun preprocessModuleStructure(moduleStructure: TestModuleStructure) {
val testModule = moduleStructure.modules.single()
val project = testServices.compilerConfigurationProvider.getProject(testModule)
val (libraryJar, librarySourcesJar) = testServices.compiledLibraryProvider.getCompiledLibrary(testModule)
val libraryKtModule = KtTestLibraryModule(project, testModule, libraryJar)
val librarySourceKtFiles = TestLibraryUtils
.getAllVirtualFilesFromJar(librarySourcesJar)
.mapNotNull { PsiManager.getInstance(project).findFile(it) as? KtFile }
val sourcesKtModule = TestKtLibrarySourceModule(
project,
testModule,
librarySourceKtFiles.toSet(),
testServices,
libraryKtModule
)
libraryKtModule.librarySources = sourcesKtModule
moduleInfoProvider.registerModuleInfo(testModule, sourcesKtModule)
(project as MockProject).registerTestServices(testModule, librarySourceKtFiles, testServices)
}
}
private class KtTestLibraryModule(
override val project: Project,
private val testModule: TestModule,
private val jar: Path
) : KtLibraryModule {
override val directRegularDependencies: List<KtModule> get() = emptyList()
override val directRefinementDependencies: List<KtModule> get() = emptyList()
override val directFriendDependencies: List<KtModule> get() = emptyList()
override val contentScope: GlobalSearchScope by lazy {
GlobalSearchScope.filesScope(project, TestLibraryUtils.getAllVirtualFilesFromJar(jar))
}
override fun getBinaryRoots(): Collection<Path> = listOf(jar)
override val libraryName: String get() = testModule.name
override lateinit var librarySources: KtLibrarySourceModule
override val platform: TargetPlatform get() = testModule.targetPlatform
override val analyzerServices: PlatformDependentAnalyzerServices get() = testModule.targetPlatform.getAnalyzerServices()
}