AA: introduce static project structure provider by compiler configuration

Also add standalone mode utils to configure Application/Project environments
This commit is contained in:
Jinseong Jeon
2022-02-02 00:02:36 -08:00
committed by Ilya Kirillov
parent d219de0f88
commit 26e923e3ae
30 changed files with 713 additions and 88 deletions
@@ -1,4 +1,3 @@
plugins {
kotlin("jvm")
id("jps-compatible")
@@ -8,11 +8,8 @@ package org.jetbrains.kotlin.analysis.api.fir
import com.intellij.mock.MockApplication
import com.intellij.mock.MockProject
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.analysis.api.InvalidWayOfUsingAnalysisSession
import org.jetbrains.kotlin.analysis.api.KtAnalysisSessionProvider
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.impl.base.references.HLApiReferenceProviderService
import org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based.registerTestServices
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.FirLowLevelFrontendApiTestConfiguratorService
import org.jetbrains.kotlin.idea.references.KotlinFirReferenceContributor
import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor
@@ -48,4 +45,4 @@ object FirFrontendApiTestConfiguratorService : FrontendApiTestConfiguratorServic
override fun doOutOfBlockModification(file: KtFile) {
FirLowLevelFrontendApiTestConfiguratorService.doOutOfBlockModification(file)
}
}
}
@@ -10,8 +10,8 @@ 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.api.impl.base.util.LibraryUtils
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
@@ -38,7 +38,7 @@ class LibraryModuleRegistrarPreAnalysisHandler(
private fun getDecompiledVirtualFilesFromLibrary(module: TestModule, project: Project): List<KtClsFile> {
val library = testServices.compiledLibraryProvider.getCompiledLibrary(module).jar
val virtualFiles = TestLibraryUtils.getAllVirtualFilesFromJar(library)
val virtualFiles = LibraryUtils.getAllVirtualFilesFromJar(library)
return virtualFiles.mapNotNull { virtualFile ->
PsiManager.getInstance(project).findFile(virtualFile) as? KtClsFile
}
@@ -11,8 +11,8 @@ 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.api.impl.base.util.LibraryUtils
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
@@ -28,7 +28,6 @@ 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) {
@@ -41,7 +40,7 @@ class LibrarySourceModuleRegistrarPreAnalysisHandler(
val libraryKtModule = KtTestLibraryModule(project, testModule, libraryJar)
val librarySourceKtFiles = TestLibraryUtils
val librarySourceKtFiles = LibraryUtils
.getAllVirtualFilesFromJar(librarySourcesJar)
.mapNotNull { PsiManager.getInstance(project).findFile(it) as? KtFile }
@@ -69,7 +68,7 @@ private class KtTestLibraryModule(
override val directFriendDependencies: List<KtModule> get() = emptyList()
override val contentScope: GlobalSearchScope by lazy {
GlobalSearchScope.filesScope(project, TestLibraryUtils.getAllVirtualFilesFromJar(jar))
GlobalSearchScope.filesScope(project, LibraryUtils.getAllVirtualFilesFromJar(jar))
}
override fun getBinaryRoots(): Collection<Path> = listOf(jar)
@@ -79,4 +78,4 @@ private class KtTestLibraryModule(
override val platform: TargetPlatform get() = testModule.targetPlatform
override val analyzerServices: PlatformDependentAnalyzerServices get() = testModule.targetPlatform.getAnalyzerServices()
}
}
@@ -3,18 +3,18 @@
* 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.utils.libraries
package org.jetbrains.kotlin.analysis.api.impl.base.util
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem
import com.intellij.util.io.URLUtil.JAR_SEPARATOR
import java.nio.file.Path
import kotlin.io.path.absolutePathString
object TestLibraryUtils {
object LibraryUtils {
fun getAllVirtualFilesFromJar(jar: Path): Collection<VirtualFile> {
val jarFileSystem = CoreJarFileSystem()
val root = jarFileSystem.refreshAndFindFileByPath(jar.absolutePathString() + "!/")!!
val root = jarFileSystem.refreshAndFindFileByPath(jar.toAbsolutePath().toString() + JAR_SEPARATOR)!!
val files = mutableSetOf<VirtualFile>()
VfsUtilCore.iterateChildrenRecursively(
@@ -29,4 +29,4 @@ object TestLibraryUtils {
)
return files
}
}
}
@@ -5,19 +5,15 @@
package org.jetbrains.kotlin.analysis.api.impl.base.test
import com.intellij.psi.PsiReference
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions
import org.jetbrains.kotlin.analysis.api.components.RendererModifier
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.expressionMarkerProvider
import org.jetbrains.kotlin.analysis.api.impl.base.test.TestReferenceResolveResultRenderer.renderResolvedTo
import org.jetbrains.kotlin.analysis.api.impl.base.test.test.framework.AbstractHLApiSingleModuleTest
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtNamedSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
@@ -52,7 +48,7 @@ abstract class AbstractReferenceResolveTest : AbstractHLApiSingleModuleTest() {
) {
val symbols = ktReferences.flatMap { it.resolveToSymbols() }
checkReferenceResultForValidity(ktReferences, module, testServices, symbols)
renderResolvedTo(symbols)
renderResolvedTo(symbols, renderingOptions)
}
if (Directives.UNRESOLVED_REFERENCE in module.directives) {
@@ -83,49 +79,6 @@ abstract class AbstractReferenceResolveTest : AbstractHLApiSingleModuleTest() {
}
}
private fun KtAnalysisSession.renderResolvedTo(symbols: List<KtSymbol>) =
symbols.map { renderResolveResult(it) }
.sorted()
.withIndex()
.joinToString(separator = "\n") { "${it.index}: ${it.value}" }
private fun KtAnalysisSession.renderResolveResult(symbol: KtSymbol): String {
return buildString {
symbolContainerFqName(symbol)?.let { fqName ->
append("(in $fqName) ")
}
when (symbol) {
is KtDeclarationSymbol -> append(symbol.render(renderingOptions))
is KtPackageSymbol -> append("package ${symbol.fqName}")
is KtReceiverParameterSymbol -> {
append("extension receiver with type ")
append(symbol.type.render(renderingOptions.typeRendererOptions))
}
else -> error("Unexpected symbol ${symbol::class}")
}
}
}
@Suppress("unused")// KtAnalysisSession receiver
private fun KtAnalysisSession.symbolContainerFqName(symbol: KtSymbol): String? {
if (symbol is KtPackageSymbol || symbol is KtValueParameterSymbol) return null
val nonLocalFqName = when (symbol) {
is KtConstructorSymbol -> symbol.containingClassIdIfNonLocal?.asSingleFqName()
is KtCallableSymbol -> symbol.callableIdIfNonLocal?.asSingleFqName()?.parent()
is KtClassLikeSymbol -> symbol.classIdIfNonLocal?.asSingleFqName()?.parent()
else -> null
}
when (nonLocalFqName) {
null -> Unit
FqName.ROOT -> return "ROOT"
else -> return nonLocalFqName.asString()
}
val container = (symbol as? KtSymbolWithKind)?.getContainingSymbol() ?: return null
val parents = generateSequence(container) { it.getContainingSymbol() }.toList().asReversed()
return "<local>: " + parents.joinToString(separator = ".") { (it as? KtNamedSymbol)?.name?.asString() ?: "<no name>" }
}
private object Directives : SimpleDirectivesContainer() {
val UNRESOLVED_REFERENCE by directive(
"Reference should be unresolved",
@@ -137,9 +90,4 @@ abstract class AbstractReferenceResolveTest : AbstractHLApiSingleModuleTest() {
sortNestedDeclarations = true
)
private fun PsiReference.unwrapMultiReferences(): List<PsiReference> = when (this) {
is KtReference -> listOf(this)
is PsiMultiReference -> references.flatMap { it.unwrapMultiReferences() }
else -> error("Unexpected reference $this")
}
}
}
@@ -0,0 +1,63 @@
/*
* 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.impl.base.test
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtNamedSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind
import org.jetbrains.kotlin.name.FqName
object TestReferenceResolveResultRenderer {
fun KtAnalysisSession.renderResolvedTo(
symbols: List<KtSymbol>,
renderingOptions: KtDeclarationRendererOptions = KtDeclarationRendererOptions.DEFAULT
) =
symbols.map { renderResolveResult(it, renderingOptions) }
.sorted()
.withIndex()
.joinToString(separator = "\n") { "${it.index}: ${it.value}" }
private fun KtAnalysisSession.renderResolveResult(
symbol: KtSymbol,
renderingOptions: KtDeclarationRendererOptions
): String {
return buildString {
symbolContainerFqName(symbol)?.let { fqName ->
append("(in $fqName) ")
}
when (symbol) {
is KtDeclarationSymbol -> append(symbol.render(renderingOptions))
is KtPackageSymbol -> append("package ${symbol.fqName}")
is KtReceiverParameterSymbol -> {
append("extension receiver with type ")
append(symbol.type.render(renderingOptions.typeRendererOptions))
}
else -> error("Unexpected symbol ${symbol::class}")
}
}
}
@Suppress("unused")// KtAnalysisSession receiver
private fun KtAnalysisSession.symbolContainerFqName(symbol: KtSymbol): String? {
if (symbol is KtPackageSymbol || symbol is KtValueParameterSymbol) return null
val nonLocalFqName = when (symbol) {
is KtConstructorSymbol -> symbol.containingClassIdIfNonLocal?.asSingleFqName()
is KtCallableSymbol -> symbol.callableIdIfNonLocal?.asSingleFqName()?.parent()
is KtClassLikeSymbol -> symbol.classIdIfNonLocal?.asSingleFqName()?.parent()
else -> null
}
when (nonLocalFqName) {
null -> Unit
FqName.ROOT -> return "ROOT"
else -> return nonLocalFqName.asString()
}
val container = (symbol as? KtSymbolWithKind)?.getContainingSymbol() ?: return null
val parents = generateSequence(container) { it.getContainingSymbol() }.toList().asReversed()
return "<local>: " + parents.joinToString(separator = ".") { (it as? KtNamedSymbol)?.name?.asString() ?: "<no name>" }
}
}
@@ -8,14 +8,14 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.util.Computable
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.analyse
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils.offsetToLineAndColumn
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.psi.*
inline fun <T> runReadAction(crossinline runnable: () -> T): T {
return ApplicationManager.getApplication().runReadAction(Computable { runnable() })
@@ -51,3 +51,12 @@ fun String.indented(indent: Int): String {
fun KtDeclaration.getNameWithPositionString(): String {
return (presentation?.presentableText ?: name ?: this::class.simpleName) + "@" + position()
}
fun findReferencesAtCaret(mainKtFile: KtFile, caretPosition: Int): List<KtReference> =
mainKtFile.findReferenceAt(caretPosition)?.unwrapMultiReferences().orEmpty().filterIsInstance<KtReference>()
fun PsiReference.unwrapMultiReferences(): List<PsiReference> = when (this) {
is KtReference -> listOf(this)
is PsiMultiReference -> references.flatMap { it.unwrapMultiReferences() }
else -> error("Unexpected reference $this")
}
@@ -0,0 +1,45 @@
plugins {
kotlin("jvm")
id("jps-compatible")
}
kotlin {
explicitApiWarning()
}
dependencies {
implementation(intellijCore())
implementation(project(":compiler:psi"))
implementation(project(":compiler:cli"))
api(project(":analysis:analysis-api"))
api(project(":analysis:analysis-api-providers"))
api(project(":analysis:project-structure"))
api(project(":analysis:analysis-api-fir"))
api(project(":analysis:low-level-api-fir"))
api(project(":analysis:symbol-light-classes"))
testApi(projectTests(":analysis:analysis-api-impl-base"))
testApi(projectTests(":analysis:analysis-api-fir"))
testApi(project(":kotlin-test:kotlin-test-junit"))
testApi(toolsJar())
testApiJUnit5()
}
kotlin {
explicitApi()
}
sourceSets {
"main" { projectDefault() }
"test" { projectDefault() }
}
projectTest(jUnitMode = JUnitMode.JUnit5) {
dependsOn(":dist")
workingDir = rootDir
useJUnitPlatform()
}
testsJar()
@@ -0,0 +1,24 @@
/*
* 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.standalone;
import com.intellij.mock.MockProject;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirResolveStateService;
class RegisterComponentService {
static void registerLLFirResolveStateService(MockProject project) {
project.registerService(
LLFirResolveStateService.class,
new LLFirResolveStateService(project)
);
}
@TestOnly
static void unregisterLLFirResolveStateService(MockProject project) {
project.getPicoContainer().unregisterComponent(LLFirResolveStateService.class.getName());
}
}
@@ -0,0 +1,154 @@
/*
* 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.standalone
import com.intellij.mock.MockApplication
import com.intellij.mock.MockProject
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.api.InvalidWayOfUsingAnalysisSession
import org.jetbrains.kotlin.analysis.api.KtAnalysisSessionProvider
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSessionProvider
import org.jetbrains.kotlin.analysis.api.impl.base.references.HLApiReferenceProviderService
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.PackagePartProviderFactory
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProvider
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProviderImpl
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
import org.jetbrains.kotlin.analysis.project.structure.impl.ProjectStructureProviderByCompilerConfiguration
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProviderFactory
import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProviderFactory
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticDeclarationProviderFactory
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticModificationTrackerFactory
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticPackageProviderFactory
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProviderImpl
import org.jetbrains.kotlin.idea.references.KotlinFirReferenceContributor
import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor
import org.jetbrains.kotlin.light.classes.symbol.IDEKotlinAsJavaFirSupport
import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.psi.KotlinReferenceProvidersService
import org.jetbrains.kotlin.psi.KtFile
/**
* Configure Application environment for Analysis API standalone mode.
*
* In particular, this will register:
* * [KotlinReferenceProvidersService]
* * [KotlinReferenceProviderContributor]
*/
public fun configureApplicationEnvironment(app: MockApplication) {
if (app.getServiceIfCreated(KotlinReferenceProvidersService::class.java) == null) {
app.registerService(
KotlinReferenceProvidersService::class.java,
HLApiReferenceProviderService::class.java
)
}
if (app.getServiceIfCreated(KotlinReferenceProviderContributor::class.java) == null) {
app.registerService(
KotlinReferenceProviderContributor::class.java,
KotlinFirReferenceContributor::class.java
)
}
}
/**
* Configure Project environment for Analysis API standalone mode.
*
* In particular, this will register:
* * [KtAnalysisSessionProvider]
* * [KotlinAsJavaSupport] (a FIR version)
* * [SymbolLightClassFacadeCache] for FIR light class support
* * [KotlinModificationTrackerFactory]
* * [LLFirResolveStateService]
* * [FirSealedClassInheritorsProcessorFactory]
* * [KtModuleScopeProvider]
* * [ProjectStructureProvider]
* * [KotlinDeclarationProviderFactory]
* * [KotlinPackageProviderFactory]
* * [PackagePartProviderFactory]
*
* Note that [ProjectStructureProvider] is built by using
* * given [ktFiles] as Kotlin sources
* * other Java sources in [compilerConfig] (set via [addJavaSourceRoots])
* * JVM class paths in [compilerConfig] (set via [addJvmClasspathRoots]) as library.
*/
public fun configureProjectEnvironment(
project: MockProject,
compilerConfig: CompilerConfiguration,
ktFiles: List<KtFile>,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
) {
reRegisterJavaElementFinder(project)
// FIR LC
project.registerService(
SymbolLightClassFacadeCache::class.java
)
project.picoContainer.registerComponentInstance(
KotlinModificationTrackerFactory::class.qualifiedName,
KotlinStaticModificationTrackerFactory()
)
RegisterComponentService.registerLLFirResolveStateService(project)
project.picoContainer.registerComponentInstance(
FirSealedClassInheritorsProcessorFactory::class.qualifiedName,
object : FirSealedClassInheritorsProcessorFactory() {
override fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider {
return SealedClassInheritorsProviderImpl
}
}
)
project.picoContainer.registerComponentInstance(
KtModuleScopeProvider::class.qualifiedName,
KtModuleScopeProviderImpl()
)
project.picoContainer.registerComponentInstance(
ProjectStructureProvider::class.qualifiedName,
ProjectStructureProviderByCompilerConfiguration(compilerConfig, project, ktFiles)
)
project.picoContainer.registerComponentInstance(
KotlinDeclarationProviderFactory::class.qualifiedName,
KotlinStaticDeclarationProviderFactory(ktFiles)
)
project.picoContainer.registerComponentInstance(
KotlinPackageProviderFactory::class.qualifiedName,
KotlinStaticPackageProviderFactory(ktFiles)
)
project.picoContainer.registerComponentInstance(
PackagePartProviderFactory::class.qualifiedName,
object : PackagePartProviderFactory() {
override fun createPackagePartProviderForLibrary(scope: GlobalSearchScope): PackagePartProvider {
return packagePartProvider(scope)
}
}
)
}
@OptIn(InvalidWayOfUsingAnalysisSession::class)
private fun reRegisterJavaElementFinder(project: Project) {
PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java)
with(project as MockProject) {
picoContainer.registerComponentInstance(
KtAnalysisSessionProvider::class.qualifiedName,
KtFirAnalysisSessionProvider(this)
)
picoContainer.unregisterComponent(KotlinAsJavaSupport::class.qualifiedName)
picoContainer.registerComponentInstance(
KotlinAsJavaSupport::class.qualifiedName,
IDEKotlinAsJavaFirSupport(project)
)
}
@Suppress("DEPRECATION")
PsiElementFinder.EP.getPoint(project).registerExtension(JavaElementFinder(project))
}
@@ -0,0 +1,90 @@
/*
* 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.project.structure.impl
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.api.impl.base.util.LibraryUtils
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.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.jvm.JdkPlatform
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import java.nio.file.Path
internal abstract class BaseKtModuleByCompilerConfiguration(
private val compilerConfig: CompilerConfiguration,
val project: Project,
) {
val analyzerServices: PlatformDependentAnalyzerServices
get() = JvmPlatformAnalyzerServices
val directFriendDependencies: List<KtModule>
get() = emptyList()
val directRefinementDependencies: List<KtModule>
get() = emptyList()
val languageVersionSettings: LanguageVersionSettings
get() = LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST)
val moduleName: String
get() = compilerConfig.get(CommonConfigurationKeys.MODULE_NAME) ?: "<no module name provided>"
val platform: TargetPlatform
get() = TargetPlatform(setOf(JdkPlatform(JvmTarget.DEFAULT)))
}
internal class KtSourceModuleByCompilerConfiguration(
compilerConfig: CompilerConfiguration,
project: Project,
ktFiles: List<KtFile>,
) : BaseKtModuleByCompilerConfiguration(compilerConfig, project), KtSourceModule {
override val directRegularDependencies: List<KtModule> by lazy {
(compilerConfig.jvmModularRoots + compilerConfig.jvmClasspathRoots).map {
KtLibraryModuleByCompilerConfiguration(compilerConfig, project, it.toPath())
}
}
override val contentScope: GlobalSearchScope =
TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles)
}
internal class KtLibraryModuleByCompilerConfiguration(
compilerConfig: CompilerConfiguration,
project: Project,
private val jar: Path,
) : BaseKtModuleByCompilerConfiguration(compilerConfig, project), KtLibraryModule {
override val directRegularDependencies: List<KtModule> get() = emptyList()
internal val virtualFiles: Collection<VirtualFile> by lazy {
LibraryUtils.getAllVirtualFilesFromJar(jar)
}
override val libraryName: String
get() = moduleName
override val librarySources: KtLibrarySourceModule?
get() = null
override val contentScope: GlobalSearchScope =
GlobalSearchScope.filesScope(project, virtualFiles)
private val binaryRoots by lazy {
listOf(jar)
}
override fun getBinaryRoots(): Collection<Path> = binaryRoots
}
@@ -0,0 +1,52 @@
/*
* 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.project.structure.impl
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.cli.jvm.config.javaSourceRoots
import org.jetbrains.kotlin.psi.KtFile
import java.nio.file.Files
import java.nio.file.Paths
internal class ProjectStructureProviderByCompilerConfiguration(
private val compilerConfig: CompilerConfiguration,
project: Project,
ktFiles: List<KtFile>,
) : ProjectStructureProvider() {
private val sourceFiles: Set<String> by lazy {
buildSet {
compilerConfig.javaSourceRoots.forEach { srcRoot ->
val path = Paths.get(srcRoot)
if (Files.isDirectory(path)) {
// E.g., project/app/src
Files.walk(Paths.get(srcRoot))
.filter(Files::isRegularFile)
.forEach { add(it.toString()) }
} else {
// E.g., project/app/src/some/pkg/main.kt
add(srcRoot)
}
}
}
}
private val sourceModule = KtSourceModuleByCompilerConfiguration(compilerConfig, project, ktFiles)
override fun getKtModuleForKtElement(element: PsiElement): KtModule {
val containingFilePath = element.containingFile.virtualFile.path
return if (containingFilePath in sourceFiles) {
sourceModule
} else {
sourceModule.directRegularDependencies.find { libModule ->
(libModule as KtLibraryModuleByCompilerConfiguration).virtualFiles.any { it.path == containingFilePath }
} ?: error("Can't find module for $containingFilePath")
}
}
}
@@ -0,0 +1,86 @@
/*
* 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.standalone
import com.intellij.mock.MockProject
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.analysis.api.InvalidWayOfUsingAnalysisSession
import org.jetbrains.kotlin.analysis.api.KtAnalysisSessionProvider
import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions
import org.jetbrains.kotlin.analysis.api.components.RendererModifier
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.expressionMarkerProvider
import org.jetbrains.kotlin.analysis.api.impl.base.test.TestReferenceResolveResultRenderer.renderResolvedTo
import org.jetbrains.kotlin.analysis.api.impl.base.test.findReferencesAtCaret
import org.jetbrains.kotlin.analysis.api.impl.base.test.test.framework.AbstractHLApiSingleModuleTest
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.PackagePartProviderFactory
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProvider
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProviderFactory
import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProviderFactory
import org.jetbrains.kotlin.cli.jvm.config.addJavaSourceRoots
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
import java.io.File
abstract class AbstractStandaloneModeSingleModuleTest : AbstractHLApiSingleModuleTest() {
override fun doTestByFileStructure(ktFiles: List<KtFile>, module: TestModule, testServices: TestServices) {
val project = testServices.compilerConfigurationProvider.getProject(module) as MockProject
// (project.picoContainer as DefaultPicoContainer).release() // is way too strong :( even PsiManager is gone
unregisterServices(project)
// TODO: better to be part of `StandaloneModeUtilsConfiguratorService`
val compilerConfiguration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
compilerConfiguration.addJavaSourceRoots(ktFiles.map { File(it.virtualFilePath) })
configureProjectEnvironment(
project,
compilerConfiguration,
ktFiles,
testServices.compilerConfigurationProvider.getPackagePartProviderFactory(module)
)
val mainKtFile = ktFiles.singleOrNull() ?: ktFiles.first { it.name == "main.kt" }
val caretPosition = testServices.expressionMarkerProvider.getCaretPosition(mainKtFile)
val ktReferences = findReferencesAtCaret(mainKtFile, caretPosition)
if (ktReferences.isEmpty()) {
testServices.assertions.fail { "No references at caret found" }
}
val resolvedTo =
analyseForTest(
PsiTreeUtil.findElementOfClassAtOffset(mainKtFile, caretPosition, KtDeclaration::class.java, false) ?: mainKtFile
) {
val symbols = ktReferences.flatMap { it.resolveToSymbols() }
renderResolvedTo(symbols, renderingOptions)
}
val actual = "Resolved to:\n$resolvedTo"
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
}
private val renderingOptions = KtDeclarationRendererOptions.DEFAULT.copy(
modifiers = RendererModifier.DEFAULT - RendererModifier.ANNOTATIONS,
sortNestedDeclarations = true
)
@OptIn(InvalidWayOfUsingAnalysisSession::class)
private fun unregisterServices(project: MockProject) {
project.picoContainer.unregisterComponent(KtAnalysisSessionProvider::class.qualifiedName)
project.picoContainer.unregisterComponent(KotlinModificationTrackerFactory::class.qualifiedName)
RegisterComponentService.unregisterLLFirResolveStateService(project)
project.picoContainer.unregisterComponent(FirSealedClassInheritorsProcessorFactory::class.qualifiedName)
project.picoContainer.unregisterComponent(KtModuleScopeProvider::class.qualifiedName)
project.picoContainer.unregisterComponent(ProjectStructureProvider::class.qualifiedName)
project.picoContainer.unregisterComponent(KotlinDeclarationProviderFactory::class.qualifiedName)
project.picoContainer.unregisterComponent(KotlinPackageProviderFactory::class.qualifiedName)
project.picoContainer.unregisterComponent(PackagePartProviderFactory::class.qualifiedName)
}
}
@@ -0,0 +1,36 @@
/*
* 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.standalone
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.psi.KtFile
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
object StandaloneModeConfiguratorService : FrontendApiTestConfiguratorService {
override val allowDependedAnalysisSession: Boolean
get() = false
override fun TestConfigurationBuilder.configureTest(disposable: Disposable) {
with(FirFrontendApiTestConfiguratorService) { configureTest(disposable) }
}
// TODO: other variant to register project services by compiler configuration?
override fun registerProjectServices(project: MockProject) {
// Will be configured at the test
}
override fun registerApplicationServices(application: MockApplication) {
configureApplicationEnvironment(application)
}
override fun doOutOfBlockModification(file: KtFile) {
FirFrontendApiTestConfiguratorService.doOutOfBlockModification(file)
}
}
@@ -0,0 +1,47 @@
/*
* 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.standalone;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService;
import org.jetbrains.kotlin.analysis.api.standalone.StandaloneModeConfiguratorService;
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 GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("analysis/analysis-api/testData/standalone/singleModule")
@TestDataPath("$PROJECT_ROOT")
public class StandaloneModeSingleModuleTestGenerated extends AbstractStandaloneModeSingleModuleTest {
@NotNull
@Override
public FrontendApiTestConfiguratorService getConfigurator() {
return StandaloneModeConfiguratorService.INSTANCE;
}
@Test
public void testAllFilesPresentInSingleModule() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/standalone/singleModule"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("multipleFiles.kt")
public void testMultipleFiles() throws Exception {
runTest("analysis/analysis-api/testData/standalone/singleModule/multipleFiles.kt");
}
@Test
@TestMetadata("singleFile.kt")
public void testSingleFile() throws Exception {
runTest("analysis/analysis-api/testData/standalone/singleModule/singleFile.kt");
}
}
@@ -0,0 +1,25 @@
// FILE: main.kt
package test.pkg
import test.pkg.ColorSpace.Companion.MaxId
import test.pkg.ColorSpace.Companion.Min<caret>Id
annotation class IntRange(val from: Long, val to: Long)
private fun isSrgb(
@IntRange(from = MinId.toLong(), to = MaxId.toLong()) id: Int
): Boolean {
return if (id == 0) true else false
}
// FILE: ColorSpace.kt
package test.pkg
abstract class ColorSpace {
internal companion object {
internal const val MinId = -1
internal const val MaxId = 63
}
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in test.pkg.ColorSpace.Companion) internal const val MinId: kotlin.Int
@@ -0,0 +1,8 @@
package test
annotation class MyAnno
@<caret>MyAnno
class Foo {
fun bar(): Int = 42
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in test.MyAnno) constructor()
+1
View File
@@ -9,6 +9,7 @@ tasks.register("analysisAllTests") {
":analysis:analysis-api:test",
":analysis:analysis-api-fir:test",
":analysis:analysis-api-fe10:test",
":analysis:analysis-api-standalone:test",
":analysis:low-level-api-fir:test",
":analysis:symbol-light-classes:test"
)
@@ -110,7 +110,7 @@ public sealed interface KtBinaryModule : KtModule, KtModuleWithProject {
}
/**
* A module which represents a binary library. E.g, JAR o KLIB.
* A module which represents a binary library. E.g, JAR or KLIB.
*/
public interface KtLibraryModule : KtBinaryModule {
public val libraryName: String
+1
View File
@@ -303,6 +303,7 @@ extra["compilerArtifactsForIde"] = listOf(
":prepare:ide-plugin-dependencies:analysis-api-providers-for-ide",
":prepare:ide-plugin-dependencies:analysis-project-structure-for-ide",
":prepare:ide-plugin-dependencies:symbol-light-classes-for-ide",
":prepare:ide-plugin-dependencies:analysis-api-standalone-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-ir-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-common-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-fe10-for-ide",
@@ -14,9 +14,10 @@ dependencies {
testApi(projectTests(":generators:test-generator"))
testApi(projectTests(":compiler:tests-common"))
testApi(projectTests(":compiler:tests-spec"))
testApi(projectTests("::analysis:low-level-api-fir"))
testApi(projectTests(":analysis:low-level-api-fir"))
testApi(projectTests(":analysis:analysis-api-fir"))
testApi(projectTests(":analysis:analysis-api-fe10"))
testApi(projectTests(":analysis:analysis-api-standalone"))
testApi(projectTests(":analysis:decompiled:decompiler-to-file-stubs"))
testApi(projectTests(":analysis:symbol-light-classes"))
testApi(intellijCore())
@@ -25,4 +26,4 @@ dependencies {
val generateFrontendApiTests by generator("org.jetbrains.kotlin.generators.tests.analysis.api.GenerateAnalysisApiTestsKt")
testsJar()
testsJar()
@@ -21,4 +21,5 @@ private fun TestGroupSuite.generateTests() {
generateFirLowLevelApiTests()
generateDecompiledTests()
generateSymbolLightClassesTests()
generateStandaloneModeTests()
}
@@ -42,7 +42,6 @@ import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.component
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.group
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.test
import org.jetbrains.kotlin.generators.util.TestGeneratorUtil
import java.nio.file.Paths
fun TestGroupSuite.generateAnalysisApiTests() {
generateAnalysisApiComponentsTests()
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.analysis.api.fir.FirFrontendApiTestConfiguratorServi
import org.jetbrains.kotlin.analysis.api.fir.utils.libraries.binary.LibraryFrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.fir.utils.libraries.source.LibrarySourceFrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.standalone.StandaloneModeConfiguratorService
import org.jetbrains.kotlin.generators.TestGroup
import org.jetbrains.kotlin.generators.TestGroupSuite
import org.jetbrains.kotlin.generators.getDefaultSuiteTestClassName
@@ -27,6 +28,8 @@ internal sealed class TestModuleKind(val componentName: String) {
object LIBRARY : TestModuleKind("library")
object LIBRARY_SOURCE : TestModuleKind("librarySource")
object STANDALONE_MODE : TestModuleKind("StandaloneMode")
companion object {
val SOURCE_ONLY by lazy(LazyThreadSafetyMode.NONE) { listOf(SOURCE) }
val SOURCE_AND_LIBRARY_SOURCE by lazy(LazyThreadSafetyMode.NONE) { listOf(SOURCE, LIBRARY_SOURCE) }
@@ -59,7 +62,6 @@ internal fun FirAndFe10TestGroup.test(
}
}
internal fun TestGroupSuite.test(
baseClass: KClass<*>,
addFe10: Boolean = true,
@@ -69,20 +71,19 @@ internal fun TestGroupSuite.test(
FirAndFe10TestGroup(this, directory = null, testModuleKinds).test(baseClass, addFe10, init)
}
internal fun TestGroupSuite.group(
directory: String,
testModuleKinds: List<TestModuleKind> = TestModuleKind.SOURCE_ONLY,
init: FirAndFe10TestGroup.() -> Unit,
) {
FirAndFe10TestGroup(this, directory, testModuleKinds = listOf(TestModuleKind.SOURCE)).init()
FirAndFe10TestGroup(this, directory, testModuleKinds).init()
}
internal fun TestGroupSuite.component(
directory: String,
init: FirAndFe10TestGroup.() -> Unit,
) {
group("components/$directory", init)
group("components/$directory", init = init)
}
private fun FirAndFe10TestGroup.analysisApiTest(
@@ -95,7 +96,7 @@ private fun FirAndFe10TestGroup.analysisApiTest(
val fullTestPath = "analysis/analysis-api/testData" + directory?.let { "/$it" }.orEmpty()
testGroup(testRoot, fullTestPath) {
if (testModuleKinds.size == 1) {
analysisApiTestClass(frontend, moduleKind = TestModuleKind.SOURCE, testClass, prefixNeeded = false, init)
analysisApiTestClass(frontend, moduleKind = testModuleKinds.single(), testClass, prefixNeeded = false, init)
} else {
testModuleKinds.forEach { component ->
analysisApiTestClass(frontend, component, testClass, prefixNeeded = true, init)
@@ -138,7 +139,7 @@ private fun TestGroup.analysisApiTestClass(
}
}
private fun createConfigurator(
internal fun createConfigurator(
frontend: Frontend,
moduleKind: TestModuleKind
): KClass<out FrontendApiTestConfiguratorService> = when (frontend) {
@@ -146,11 +147,13 @@ private fun createConfigurator(
TestModuleKind.SOURCE -> FirFrontendApiTestConfiguratorService::class
TestModuleKind.LIBRARY -> LibraryFrontendApiTestConfiguratorService::class
TestModuleKind.LIBRARY_SOURCE -> LibrarySourceFrontendApiTestConfiguratorService::class
TestModuleKind.STANDALONE_MODE -> StandaloneModeConfiguratorService::class
}
Frontend.FE10 -> when (moduleKind) {
TestModuleKind.SOURCE -> KtFe10FrontendApiTestConfiguratorService::class
TestModuleKind.LIBRARY -> TODO("TestModuleKind.LIBRARY is unsupported for fe10")
TestModuleKind.LIBRARY_SOURCE -> TODO("TestModuleKind.LIBRARY_SOURCE is unsupported for fe10")
TestModuleKind.STANDALONE_MODE -> TODO("TestModuleKind.STANDALONE_MODE is unsupported for fe10")
}
}
@@ -0,0 +1,26 @@
/*
* 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.generators.tests.analysis.api
import org.jetbrains.kotlin.generators.TestGroupSuite
import org.jetbrains.kotlin.analysis.api.standalone.AbstractStandaloneModeSingleModuleTest
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.Frontend
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.FrontendConfiguratorTestModel
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.TestModuleKind
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.createConfigurator
internal fun TestGroupSuite.generateStandaloneModeTests() {
testGroup(
"analysis/analysis-api-standalone/tests",
"analysis/analysis-api/testData"
) {
val configurator = createConfigurator(Frontend.FIR, TestModuleKind.STANDALONE_MODE)
testClass<AbstractStandaloneModeSingleModuleTest> {
method(FrontendConfiguratorTestModel(configurator))
model("standalone/singleModule")
}
}
}
@@ -0,0 +1,5 @@
plugins {
kotlin("jvm")
}
publishJarsForIde(listOf(":analysis:analysis-api-standalone"))
+2
View File
@@ -374,6 +374,7 @@ if (!buildProperties.inJpsBuildIdeaSync) {
":prepare:ide-plugin-dependencies:analysis-api-providers-for-ide",
":prepare:ide-plugin-dependencies:analysis-project-structure-for-ide",
":prepare:ide-plugin-dependencies:symbol-light-classes-for-ide",
":prepare:ide-plugin-dependencies:analysis-api-standalone-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-ir-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-common-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-fe10-for-ide",
@@ -504,6 +505,7 @@ include ":generators:analysis-api-generator",
":analysis:kt-references",
":analysis:symbol-light-classes",
":analysis:project-structure",
":analysis:analysis-api-standalone",
":analysis:analysis-api-fe10",
":analysis:decompiled:decompiler-to-psi",
":analysis:decompiled:decompiler-to-stubs",