AA: introduce static project structure provider by compiler configuration
Also add standalone mode utils to configure Application/Project environments
This commit is contained in:
committed by
Ilya Kirillov
parent
d219de0f88
commit
26e923e3ae
@@ -1,4 +1,3 @@
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
|
||||
+1
-4
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -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
|
||||
}
|
||||
|
||||
+4
-5
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-55
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+63
@@ -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>" }
|
||||
}
|
||||
}
|
||||
+14
-5
@@ -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()
|
||||
|
||||
+24
@@ -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());
|
||||
}
|
||||
}
|
||||
+154
@@ -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))
|
||||
}
|
||||
+90
@@ -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
|
||||
}
|
||||
+52
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
+86
@@ -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)
|
||||
}
|
||||
}
|
||||
+36
@@ -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)
|
||||
}
|
||||
}
|
||||
+47
@@ -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()
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
+1
@@ -21,4 +21,5 @@ private fun TestGroupSuite.generateTests() {
|
||||
generateFirLowLevelApiTests()
|
||||
generateDecompiledTests()
|
||||
generateSymbolLightClassesTests()
|
||||
generateStandaloneModeTests()
|
||||
}
|
||||
|
||||
-1
@@ -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
-7
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+26
@@ -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"))
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user