FIR: implements multi-module resolve, add tests #KT-24093 Fixed
This commit introduces FIR session provider, dependency provider, library session + other infrastructure necessary for multi-module resolve
This commit is contained in:
@@ -7,6 +7,7 @@ plugins {
|
|||||||
jvmTarget = "1.6"
|
jvmTarget = "1.6"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
compile(project(":compiler:frontend.common"))
|
||||||
compile(project(":compiler:frontend.java"))
|
compile(project(":compiler:frontend.java"))
|
||||||
compile(project(":compiler:fir:resolve"))
|
compile(project(":compiler:fir:resolve"))
|
||||||
|
|
||||||
|
|||||||
@@ -6,21 +6,59 @@
|
|||||||
package org.jetbrains.kotlin.fir.java
|
package org.jetbrains.kotlin.fir.java
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.fir.FirModuleBasedSession
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.impl.FirDependenciesSymbolProviderImpl
|
||||||
import org.jetbrains.kotlin.fir.resolve.impl.FirLibrarySymbolProviderImpl
|
import org.jetbrains.kotlin.fir.resolve.impl.FirLibrarySymbolProviderImpl
|
||||||
import org.jetbrains.kotlin.fir.service
|
|
||||||
|
|
||||||
class FirJavaModuleBasedSession(moduleInfo: ModuleInfo, project: Project) : FirModuleBasedSession(moduleInfo) {
|
class FirJavaModuleBasedSession(
|
||||||
|
moduleInfo: ModuleInfo,
|
||||||
|
override val sessionProvider: FirProjectSessionProvider,
|
||||||
|
scope: GlobalSearchScope
|
||||||
|
) : FirModuleBasedSession(moduleInfo) {
|
||||||
init {
|
init {
|
||||||
|
sessionProvider.sessionCache[moduleInfo] = this
|
||||||
registerComponent(
|
registerComponent(
|
||||||
FirSymbolProvider::class,
|
FirSymbolProvider::class,
|
||||||
FirCompositeSymbolProvider(
|
FirCompositeSymbolProvider(
|
||||||
listOf(service<FirProvider>(), JavaSymbolProvider(project), FirLibrarySymbolProviderImpl(this))
|
listOf(
|
||||||
|
service<FirProvider>(),
|
||||||
|
JavaSymbolProvider(sessionProvider.project, scope),
|
||||||
|
FirDependenciesSymbolProviderImpl(this)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FirLibrarySession(
|
||||||
|
moduleInfo: ModuleInfo,
|
||||||
|
override val sessionProvider: FirProjectSessionProvider,
|
||||||
|
scope: GlobalSearchScope
|
||||||
|
) : FirSessionBase() {
|
||||||
|
init {
|
||||||
|
sessionProvider.sessionCache[moduleInfo] = this
|
||||||
|
registerComponent(
|
||||||
|
FirSymbolProvider::class,
|
||||||
|
FirCompositeSymbolProvider(
|
||||||
|
listOf(
|
||||||
|
FirLibrarySymbolProviderImpl(this),
|
||||||
|
JavaSymbolProvider(sessionProvider.project, scope),
|
||||||
|
FirDependenciesSymbolProviderImpl(this)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FirProjectSessionProvider(val project: Project) : FirSessionProvider {
|
||||||
|
override fun getSession(moduleInfo: ModuleInfo): FirSession? {
|
||||||
|
return sessionCache[moduleInfo]
|
||||||
|
}
|
||||||
|
|
||||||
|
val sessionCache = mutableMapOf<ModuleInfo, FirSession>()
|
||||||
|
}
|
||||||
@@ -8,38 +8,22 @@ package org.jetbrains.kotlin.fir.java
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.fir.java.symbols.JavaClassSymbol
|
import org.jetbrains.kotlin.fir.java.symbols.JavaClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.AbstractFirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||||
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||||
|
|
||||||
class JavaSymbolProvider(val project: Project) : FirSymbolProvider {
|
class JavaSymbolProvider(
|
||||||
|
val project: Project,
|
||||||
override val doesLookupInFir: Boolean
|
private val searchScope: GlobalSearchScope
|
||||||
get() = false
|
) : AbstractFirSymbolProvider() {
|
||||||
|
|
||||||
// TODO: Concrete scope here
|
|
||||||
private val allScope = GlobalSearchScope.allScope(project)
|
|
||||||
|
|
||||||
private val classCache = mutableMapOf<ClassId, ConeSymbol?>()
|
|
||||||
private val packageCache = mutableMapOf<FqName, FqName?>()
|
|
||||||
|
|
||||||
private inline fun <K, V : Any?> MutableMap<K, V>.lookupCacheOrCalculate(key: K, l: (K) -> V): V? {
|
|
||||||
return if (key in this.keys) {
|
|
||||||
this[key]
|
|
||||||
} else {
|
|
||||||
val calculated = l(key)
|
|
||||||
this[key] = calculated
|
|
||||||
calculated
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getSymbolByFqName(classId: ClassId): ConeSymbol? {
|
override fun getSymbolByFqName(classId: ClassId): ConeSymbol? {
|
||||||
return classCache.lookupCacheOrCalculate(classId) {
|
return classCache.lookupCacheOrCalculate(classId) {
|
||||||
val facade = KotlinJavaPsiFacade.getInstance(project)
|
val facade = KotlinJavaPsiFacade.getInstance(project)
|
||||||
val foundClass = facade.findClass(JavaClassFinder.Request(classId), allScope)
|
val foundClass = facade.findClass(JavaClassFinder.Request(classId), searchScope)
|
||||||
foundClass?.let { javaClass -> JavaClassSymbol(javaClass) }
|
foundClass?.let { javaClass -> JavaClassSymbol(javaClass) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,7 +31,7 @@ class JavaSymbolProvider(val project: Project) : FirSymbolProvider {
|
|||||||
override fun getPackage(fqName: FqName): FqName? {
|
override fun getPackage(fqName: FqName): FqName? {
|
||||||
return packageCache.lookupCacheOrCalculate(fqName) {
|
return packageCache.lookupCacheOrCalculate(fqName) {
|
||||||
val facade = KotlinJavaPsiFacade.getInstance(project)
|
val facade = KotlinJavaPsiFacade.getInstance(project)
|
||||||
val javaPackage = facade.findPackage(fqName.asString(), allScope) ?: return@lookupCacheOrCalculate null
|
val javaPackage = facade.findPackage(fqName.asString(), searchScope) ?: return@lookupCacheOrCalculate null
|
||||||
FqName(javaPackage.qualifiedName)
|
FqName(javaPackage.qualifiedName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. 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.fir.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
|
abstract class AbstractFirSymbolProvider : FirSymbolProvider {
|
||||||
|
protected val classCache = mutableMapOf<ClassId, ConeSymbol?>()
|
||||||
|
protected val packageCache = mutableMapOf<FqName, FqName?>()
|
||||||
|
|
||||||
|
protected inline fun <K, V : Any?> MutableMap<K, V>.lookupCacheOrCalculate(key: K, crossinline l: (K) -> V): V? {
|
||||||
|
return if (key in this.keys) {
|
||||||
|
this[key]
|
||||||
|
} else {
|
||||||
|
val calculated = l(key)
|
||||||
|
this[key] = calculated
|
||||||
|
calculated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,8 +13,6 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
|
|
||||||
interface FirSymbolProvider {
|
interface FirSymbolProvider {
|
||||||
|
|
||||||
val doesLookupInFir: Boolean
|
|
||||||
|
|
||||||
fun getSymbolByFqName(classId: ClassId): ConeSymbol?
|
fun getSymbolByFqName(classId: ClassId): ConeSymbol?
|
||||||
|
|
||||||
fun getPackage(fqName: FqName): FqName? // TODO: Replace to symbol sometime
|
fun getPackage(fqName: FqName): FqName? // TODO: Replace to symbol sometime
|
||||||
|
|||||||
-3
@@ -13,9 +13,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
|||||||
|
|
||||||
class FirCompositeSymbolProvider(val providers: List<FirSymbolProvider>) : FirSymbolProvider {
|
class FirCompositeSymbolProvider(val providers: List<FirSymbolProvider>) : FirSymbolProvider {
|
||||||
|
|
||||||
override val doesLookupInFir: Boolean
|
|
||||||
get() = providers.any(FirSymbolProvider::doesLookupInFir)
|
|
||||||
|
|
||||||
override fun getPackage(fqName: FqName): FqName? {
|
override fun getPackage(fqName: FqName): FqName? {
|
||||||
return providers.firstNotNullResult { it.getPackage(fqName) }
|
return providers.firstNotNullResult { it.getPackage(fqName) }
|
||||||
}
|
}
|
||||||
|
|||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. 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.fir.resolve.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.dependenciesWithoutSelf
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.AbstractFirSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.service
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
|
class FirDependenciesSymbolProviderImpl(val session: FirSession) : AbstractFirSymbolProvider() {
|
||||||
|
|
||||||
|
private val dependencyProviders by lazy {
|
||||||
|
val moduleInfo = session.moduleInfo ?: return@lazy emptyList()
|
||||||
|
moduleInfo.dependenciesWithoutSelf().mapNotNull {
|
||||||
|
session.sessionProvider?.getSession(it)?.service<FirSymbolProvider>()
|
||||||
|
}.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSymbolByFqName(classId: ClassId): ConeSymbol? {
|
||||||
|
return classCache.lookupCacheOrCalculate(classId) {
|
||||||
|
for (provider in dependencyProviders) {
|
||||||
|
provider.getSymbolByFqName(classId)?.let {
|
||||||
|
return@lookupCacheOrCalculate it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPackage(fqName: FqName): FqName? {
|
||||||
|
return packageCache.lookupCacheOrCalculate(fqName) {
|
||||||
|
for (provider in dependencyProviders) {
|
||||||
|
provider.getPackage(fqName)?.let {
|
||||||
|
return@lookupCacheOrCalculate it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-4
@@ -28,13 +28,10 @@ import java.io.InputStream
|
|||||||
|
|
||||||
class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider {
|
class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider {
|
||||||
|
|
||||||
override val doesLookupInFir: Boolean
|
|
||||||
get() = false
|
|
||||||
|
|
||||||
private class BuiltInsPackageFragment(stream: InputStream, val fqName: FqName) {
|
private class BuiltInsPackageFragment(stream: InputStream, val fqName: FqName) {
|
||||||
lateinit var version: BuiltInsBinaryVersion
|
lateinit var version: BuiltInsBinaryVersion
|
||||||
|
|
||||||
val packageProto = run {
|
val packageProto: ProtoBuf.PackageFragment = run {
|
||||||
|
|
||||||
version = BuiltInsBinaryVersion.readFrom(stream)
|
version = BuiltInsBinaryVersion.readFrom(stream)
|
||||||
|
|
||||||
|
|||||||
@@ -19,9 +19,6 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
|
|
||||||
class FirProviderImpl(val session: FirSession) : FirProvider {
|
class FirProviderImpl(val session: FirSession) : FirProvider {
|
||||||
|
|
||||||
override val doesLookupInFir: Boolean
|
|
||||||
get() = true
|
|
||||||
|
|
||||||
override fun getFirClassifierBySymbol(symbol: ConeSymbol): FirNamedDeclaration? {
|
override fun getFirClassifierBySymbol(symbol: ConeSymbol): FirNamedDeclaration? {
|
||||||
return when (symbol) {
|
return when (symbol) {
|
||||||
is FirBasedSymbol<*> -> symbol.fir as? FirNamedDeclaration
|
is FirBasedSymbol<*> -> symbol.fir as? FirNamedDeclaration
|
||||||
|
|||||||
+2
-1
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
|
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.impl.FirDependenciesSymbolProviderImpl
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirPosition
|
import org.jetbrains.kotlin.fir.scopes.FirPosition
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||||
@@ -21,7 +22,7 @@ abstract class FirAbstractStarImportingScope(val session: FirSession, lookupInFi
|
|||||||
|
|
||||||
val provider = FirSymbolProvider.getInstance(session).let {
|
val provider = FirSymbolProvider.getInstance(session).let {
|
||||||
when {
|
when {
|
||||||
it is FirCompositeSymbolProvider && !lookupInFir -> FirCompositeSymbolProvider(it.providers.filter { !it.doesLookupInFir })
|
it is FirCompositeSymbolProvider && !lookupInFir -> it.providers.find { it is FirDependenciesSymbolProviderImpl }!!
|
||||||
else -> it
|
else -> it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir
|
package org.jetbrains.kotlin.fir
|
||||||
|
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
@@ -21,13 +23,16 @@ abstract class AbstractFirResolveTestCase : AbstractFirResolveWithSessionTestCas
|
|||||||
return createEnvironmentWithMockJdk(ConfigurationKind.JDK_NO_RUNTIME)
|
return createEnvironmentWithMockJdk(ConfigurationKind.JDK_NO_RUNTIME)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doCreateAndProcessFir(ktFiles: List<KtFile>): List<FirFile> {
|
private fun doCreateAndProcessFir(ktFiles: List<KtFile>): List<FirFile> {
|
||||||
val session = createSession()
|
|
||||||
|
val scope = GlobalSearchScope.filesScope(project, ktFiles.mapNotNull { it.virtualFile })
|
||||||
|
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
|
||||||
|
val session = createSession(scope)
|
||||||
|
|
||||||
val builder = RawFirBuilder(session)
|
val builder = RawFirBuilder(session)
|
||||||
|
|
||||||
val transformer = FirTotalResolveTransformer()
|
val transformer = FirTotalResolveTransformer()
|
||||||
val firFiles = ktFiles.map {
|
return ktFiles.map {
|
||||||
val firFile = builder.buildFirFile(it)
|
val firFile = builder.buildFirFile(it)
|
||||||
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
|
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
|
||||||
firFile
|
firFile
|
||||||
@@ -39,8 +44,6 @@ abstract class AbstractFirResolveTestCase : AbstractFirResolveWithSessionTestCas
|
|||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return firFiles
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+18
-1
@@ -5,10 +5,27 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir
|
package org.jetbrains.kotlin.fir
|
||||||
|
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.fir.java.FirJavaModuleBasedSession
|
import org.jetbrains.kotlin.fir.java.FirJavaModuleBasedSession
|
||||||
|
import org.jetbrains.kotlin.fir.java.FirLibrarySession
|
||||||
|
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||||
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
|
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
|
||||||
|
|
||||||
abstract class AbstractFirResolveWithSessionTestCase : KotlinTestWithEnvironment() {
|
abstract class AbstractFirResolveWithSessionTestCase : KotlinTestWithEnvironment() {
|
||||||
|
|
||||||
open fun createSession(): FirSession = FirJavaModuleBasedSession(FirTestModuleInfo(), project)
|
open fun createSession(sourceScope: GlobalSearchScope): FirSession {
|
||||||
|
val moduleInfo = FirTestModuleInfo()
|
||||||
|
val provider = FirProjectSessionProvider(project)
|
||||||
|
return FirJavaModuleBasedSession(moduleInfo, provider, sourceScope).also {
|
||||||
|
createSessionForDependencies(provider, moduleInfo, sourceScope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createSessionForDependencies(
|
||||||
|
provider: FirProjectSessionProvider, moduleInfo: FirTestModuleInfo, sourceScope: GlobalSearchScope
|
||||||
|
) {
|
||||||
|
val dependenciesInfo = FirTestModuleInfo()
|
||||||
|
moduleInfo.dependencies.add(dependenciesInfo)
|
||||||
|
FirLibrarySession(dependenciesInfo, provider, GlobalSearchScope.notScope(sourceScope))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -11,11 +11,17 @@ import kotlin.reflect.KClass
|
|||||||
interface FirSession {
|
interface FirSession {
|
||||||
val moduleInfo: ModuleInfo?
|
val moduleInfo: ModuleInfo?
|
||||||
|
|
||||||
|
val sessionProvider: FirSessionProvider? get() = null
|
||||||
|
|
||||||
val components: Map<KClass<*>, Any>
|
val components: Map<KClass<*>, Any>
|
||||||
|
|
||||||
fun <T : Any> getService(kclass: KClass<T>): T =
|
fun <T : Any> getService(kclass: KClass<T>): T =
|
||||||
components[kclass] as T
|
components[kclass] as T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface FirSessionProvider {
|
||||||
|
fun getSession(moduleInfo: ModuleInfo): FirSession?
|
||||||
|
}
|
||||||
|
|
||||||
inline fun <reified T : Any> FirSession.service(): T =
|
inline fun <reified T : Any> FirSession.service(): T =
|
||||||
getService(T::class)
|
getService(T::class)
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir
|
package org.jetbrains.kotlin.fir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
|
|
||||||
fun <T : FirElement, D> MutableList<T>.transformInplace(transformer: FirTransformer<D>, data: D) {
|
fun <T : FirElement, D> MutableList<T>.transformInplace(transformer: FirTransformer<D>, data: D) {
|
||||||
@@ -32,3 +33,5 @@ fun <T : FirElement, D> MutableList<T>.transformInplace(transformer: FirTransfor
|
|||||||
fun <T : FirElement, D> T.transformSingle(transformer: FirTransformer<D>, data: D): T {
|
fun <T : FirElement, D> T.transformSingle(transformer: FirTransformer<D>, data: D): T {
|
||||||
return this.transform<T, D>(transformer, data).single
|
return this.transform<T, D>(transformer, data).single
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun ModuleInfo.dependenciesWithoutSelf(): Sequence<ModuleInfo> = dependencies().asSequence().filter { it != this }
|
||||||
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
|||||||
|
|
||||||
class FirTestModuleInfo(
|
class FirTestModuleInfo(
|
||||||
override val name: Name = Name.identifier("TestModule"),
|
override val name: Name = Name.identifier("TestModule"),
|
||||||
private val dependencies: List<ModuleInfo> = emptyList(),
|
val dependencies: MutableList<ModuleInfo> = mutableListOf(),
|
||||||
override val platform: TargetPlatform = JvmPlatform
|
override val platform: TargetPlatform = JvmPlatform
|
||||||
) : ModuleInfo {
|
) : ModuleInfo {
|
||||||
override fun dependencies(): List<ModuleInfo> = dependencies
|
override fun dependencies(): List<ModuleInfo> = dependencies
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ import org.jetbrains.kotlin.idea.editor.AbstractMultiLineStringIndentTest
|
|||||||
import org.jetbrains.kotlin.idea.editor.backspaceHandler.AbstractBackspaceHandlerTest
|
import org.jetbrains.kotlin.idea.editor.backspaceHandler.AbstractBackspaceHandlerTest
|
||||||
import org.jetbrains.kotlin.idea.editor.quickDoc.AbstractQuickDocProviderTest
|
import org.jetbrains.kotlin.idea.editor.quickDoc.AbstractQuickDocProviderTest
|
||||||
import org.jetbrains.kotlin.idea.filters.AbstractKotlinExceptionFilterTest
|
import org.jetbrains.kotlin.idea.filters.AbstractKotlinExceptionFilterTest
|
||||||
|
import org.jetbrains.kotlin.idea.fir.AbstractFirMultiModuleResolveTest
|
||||||
import org.jetbrains.kotlin.idea.folding.AbstractKotlinFoldingTest
|
import org.jetbrains.kotlin.idea.folding.AbstractKotlinFoldingTest
|
||||||
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyTest
|
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyTest
|
||||||
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyWithLibTest
|
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyWithLibTest
|
||||||
@@ -804,6 +805,10 @@ fun main(args: Array<String>) {
|
|||||||
model("scratch", extension = "kts", testMethod = "doReplTest", testClassName = "Repl", recursive = false)
|
model("scratch", extension = "kts", testMethod = "doReplTest", testClassName = "Repl", recursive = false)
|
||||||
model("scratch/multiFile", extension = null, testMethod = "doMultiFileTest", recursive = false)
|
model("scratch/multiFile", extension = null, testMethod = "doMultiFileTest", recursive = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractFirMultiModuleResolveTest> {
|
||||||
|
model("fir/multiModule", recursive = false, extension = null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
testGroup("idea/idea-maven/test", "idea/idea-maven/testData") {
|
testGroup("idea/idea-maven/test", "idea/idea-maven/testData") {
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ import org.jetbrains.kotlin.idea.editor.AbstractMultiLineStringIndentTest
|
|||||||
import org.jetbrains.kotlin.idea.editor.backspaceHandler.AbstractBackspaceHandlerTest
|
import org.jetbrains.kotlin.idea.editor.backspaceHandler.AbstractBackspaceHandlerTest
|
||||||
import org.jetbrains.kotlin.idea.editor.quickDoc.AbstractQuickDocProviderTest
|
import org.jetbrains.kotlin.idea.editor.quickDoc.AbstractQuickDocProviderTest
|
||||||
import org.jetbrains.kotlin.idea.filters.AbstractKotlinExceptionFilterTest
|
import org.jetbrains.kotlin.idea.filters.AbstractKotlinExceptionFilterTest
|
||||||
|
import org.jetbrains.kotlin.idea.fir.AbstractFirMultiModuleResolveTest
|
||||||
import org.jetbrains.kotlin.idea.folding.AbstractKotlinFoldingTest
|
import org.jetbrains.kotlin.idea.folding.AbstractKotlinFoldingTest
|
||||||
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyTest
|
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyTest
|
||||||
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyWithLibTest
|
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyWithLibTest
|
||||||
@@ -786,6 +787,10 @@ fun main(args: Array<String>) {
|
|||||||
model("scratch", extension = "kts", testMethod = "doReplTest", testClassName = "Repl", recursive = false)
|
model("scratch", extension = "kts", testMethod = "doReplTest", testClassName = "Repl", recursive = false)
|
||||||
model("scratch/multiFile", extension = null, testMethod = "doMultiFileTest", recursive = false)
|
model("scratch/multiFile", extension = null, testMethod = "doMultiFileTest", recursive = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractFirMultiModuleResolveTest> {
|
||||||
|
model("fir/multiModule", recursive = false, extension = null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ import org.jetbrains.kotlin.idea.editor.AbstractMultiLineStringIndentTest
|
|||||||
import org.jetbrains.kotlin.idea.editor.backspaceHandler.AbstractBackspaceHandlerTest
|
import org.jetbrains.kotlin.idea.editor.backspaceHandler.AbstractBackspaceHandlerTest
|
||||||
import org.jetbrains.kotlin.idea.editor.quickDoc.AbstractQuickDocProviderTest
|
import org.jetbrains.kotlin.idea.editor.quickDoc.AbstractQuickDocProviderTest
|
||||||
import org.jetbrains.kotlin.idea.filters.AbstractKotlinExceptionFilterTest
|
import org.jetbrains.kotlin.idea.filters.AbstractKotlinExceptionFilterTest
|
||||||
|
import org.jetbrains.kotlin.idea.fir.AbstractFirMultiModuleResolveTest
|
||||||
import org.jetbrains.kotlin.idea.folding.AbstractKotlinFoldingTest
|
import org.jetbrains.kotlin.idea.folding.AbstractKotlinFoldingTest
|
||||||
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyTest
|
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyTest
|
||||||
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyWithLibTest
|
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyWithLibTest
|
||||||
@@ -786,6 +787,10 @@ fun main(args: Array<String>) {
|
|||||||
model("scratch", extension = "kts", testMethod = "doReplTest", testClassName = "Repl", recursive = false)
|
model("scratch", extension = "kts", testMethod = "doReplTest", testClassName = "Repl", recursive = false)
|
||||||
model("scratch/multiFile", extension = null, testMethod = "doMultiFileTest", recursive = false)
|
model("scratch/multiFile", extension = null, testMethod = "doMultiFileTest", recursive = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractFirMultiModuleResolveTest> {
|
||||||
|
model("fir/multiModule", recursive = false, extension = null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ import org.jetbrains.kotlin.idea.editor.AbstractMultiLineStringIndentTest
|
|||||||
import org.jetbrains.kotlin.idea.editor.backspaceHandler.AbstractBackspaceHandlerTest
|
import org.jetbrains.kotlin.idea.editor.backspaceHandler.AbstractBackspaceHandlerTest
|
||||||
import org.jetbrains.kotlin.idea.editor.quickDoc.AbstractQuickDocProviderTest
|
import org.jetbrains.kotlin.idea.editor.quickDoc.AbstractQuickDocProviderTest
|
||||||
import org.jetbrains.kotlin.idea.filters.AbstractKotlinExceptionFilterTest
|
import org.jetbrains.kotlin.idea.filters.AbstractKotlinExceptionFilterTest
|
||||||
|
import org.jetbrains.kotlin.idea.fir.AbstractFirMultiModuleResolveTest
|
||||||
import org.jetbrains.kotlin.idea.folding.AbstractKotlinFoldingTest
|
import org.jetbrains.kotlin.idea.folding.AbstractKotlinFoldingTest
|
||||||
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyTest
|
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyTest
|
||||||
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyWithLibTest
|
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyWithLibTest
|
||||||
@@ -778,6 +779,10 @@ fun main(args: Array<String>) {
|
|||||||
model("scratch", extension = "kts", testMethod = "doReplTest", testClassName = "Repl", recursive = false)
|
model("scratch", extension = "kts", testMethod = "doReplTest", testClassName = "Repl", recursive = false)
|
||||||
model("scratch/multiFile", extension = null, testMethod = "doMultiFileTest", recursive = false)
|
model("scratch/multiFile", extension = null, testMethod = "doMultiFileTest", recursive = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractFirMultiModuleResolveTest> {
|
||||||
|
model("fir/multiModule", recursive = false, extension = null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ import org.jetbrains.kotlin.idea.editor.AbstractMultiLineStringIndentTest
|
|||||||
import org.jetbrains.kotlin.idea.editor.backspaceHandler.AbstractBackspaceHandlerTest
|
import org.jetbrains.kotlin.idea.editor.backspaceHandler.AbstractBackspaceHandlerTest
|
||||||
import org.jetbrains.kotlin.idea.editor.quickDoc.AbstractQuickDocProviderTest
|
import org.jetbrains.kotlin.idea.editor.quickDoc.AbstractQuickDocProviderTest
|
||||||
import org.jetbrains.kotlin.idea.filters.AbstractKotlinExceptionFilterTest
|
import org.jetbrains.kotlin.idea.filters.AbstractKotlinExceptionFilterTest
|
||||||
|
import org.jetbrains.kotlin.idea.fir.AbstractFirMultiModuleResolveTest
|
||||||
import org.jetbrains.kotlin.idea.folding.AbstractKotlinFoldingTest
|
import org.jetbrains.kotlin.idea.folding.AbstractKotlinFoldingTest
|
||||||
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyTest
|
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyTest
|
||||||
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyWithLibTest
|
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyWithLibTest
|
||||||
@@ -778,6 +779,10 @@ fun main(args: Array<String>) {
|
|||||||
model("scratch", extension = "kts", testMethod = "doReplTest", testClassName = "Repl", recursive = false)
|
model("scratch", extension = "kts", testMethod = "doReplTest", testClassName = "Repl", recursive = false)
|
||||||
model("scratch/multiFile", extension = null, testMethod = "doMultiFileTest", recursive = false)
|
model("scratch/multiFile", extension = null, testMethod = "doMultiFileTest", recursive = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractFirMultiModuleResolveTest> {
|
||||||
|
model("fir/multiModule", recursive = false, extension = null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -374,7 +374,7 @@ private class SdkScope(project: Project, val sdk: Sdk) :
|
|||||||
override fun toString() = "SdkScope($sdk)"
|
override fun toString() = "SdkScope($sdk)"
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun IdeaModuleInfo.isLibraryClasses() = this is SdkInfo || this is LibraryInfo
|
fun IdeaModuleInfo.isLibraryClasses() = this is SdkInfo || this is LibraryInfo
|
||||||
|
|
||||||
val OriginCapability = ModuleDescriptor.Capability<ModuleOrigin>("MODULE_ORIGIN")
|
val OriginCapability = ModuleDescriptor.Capability<ModuleOrigin>("MODULE_ORIGIN")
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package hello
|
||||||
|
|
||||||
|
class Hello(val msg: String)
|
||||||
|
|
||||||
|
class Test(val set: java.util.Set<*>)
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
FILE: base.kt
|
||||||
|
public final class Hello {
|
||||||
|
public constructor(msg: R|kotlin/String|): super<R|kotlin/Any|>()
|
||||||
|
|
||||||
|
public final property msg(val): R|kotlin/String|
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class Test {
|
||||||
|
public constructor(set: R|java/util/Set<*>|): super<R|kotlin/Any|>()
|
||||||
|
|
||||||
|
public final property set(val): R|java/util/Set<*>|
|
||||||
|
public get(): R|java/util/Set<*>|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import hello.Hello
|
||||||
|
|
||||||
|
fun foo(hello: Hello): String = hello.msg
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
FILE: user.kt
|
||||||
|
public final function foo(hello: R|hello/Hello|): R|kotlin/String| {
|
||||||
|
STUB
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. 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.idea.fir
|
||||||
|
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
import com.intellij.psi.PsiManager
|
||||||
|
import com.intellij.psi.search.FileTypeIndex
|
||||||
|
import org.jetbrains.kotlin.fir.FirRenderer
|
||||||
|
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
|
import org.jetbrains.kotlin.fir.dependenciesWithoutSelf
|
||||||
|
import org.jetbrains.kotlin.fir.java.FirJavaModuleBasedSession
|
||||||
|
import org.jetbrains.kotlin.fir.java.FirLibrarySession
|
||||||
|
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.service
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
|
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||||
|
import org.jetbrains.kotlin.idea.caches.project.isLibraryClasses
|
||||||
|
import org.jetbrains.kotlin.idea.caches.project.productionSourceInfo
|
||||||
|
import org.jetbrains.kotlin.idea.multiplatform.setupMppProjectFromDirStructure
|
||||||
|
import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest
|
||||||
|
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
||||||
|
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||||
|
import org.jetbrains.kotlin.idea.util.projectStructure.allModules
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
|
import org.jetbrains.kotlin.test.TestJdkKind
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
abstract class AbstractFirMultiModuleResolveTest : AbstractMultiModuleTest() {
|
||||||
|
override fun getTestDataPath(): String {
|
||||||
|
return File(PluginTestCaseBase.getTestDataPathBase(), "/fir/multiModule").path + File.separator
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doTest(dirPath: String) {
|
||||||
|
setupMppProjectFromDirStructure(File(dirPath))
|
||||||
|
for (module in project.allModules().drop(1)) {
|
||||||
|
ConfigLibraryUtil.configureSdk(
|
||||||
|
module,
|
||||||
|
PluginTestCaseBase.addJdk(testRootDisposable) { PluginTestCaseBase.jdk(TestJdkKind.MOCK_JDK) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
doFirResolveTest(dirPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createSession(module: Module, provider: FirProjectSessionProvider): FirJavaModuleBasedSession {
|
||||||
|
val moduleInfo = module.productionSourceInfo()!!
|
||||||
|
return FirJavaModuleBasedSession(moduleInfo, provider, moduleInfo.contentScope())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createLibrarySession(moduleInfo: IdeaModuleInfo, provider: FirProjectSessionProvider): FirLibrarySession {
|
||||||
|
val contentScope = moduleInfo.contentScope()
|
||||||
|
return FirLibrarySession(moduleInfo, provider, contentScope)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doFirResolveTest(dirPath: String) {
|
||||||
|
val firFiles = mutableListOf<FirFile>()
|
||||||
|
val provider = FirProjectSessionProvider(project)
|
||||||
|
for (module in project.allModules().drop(1)) {
|
||||||
|
val session = createSession(module, provider)
|
||||||
|
|
||||||
|
val builder = RawFirBuilder(session)
|
||||||
|
val psiManager = PsiManager.getInstance(project)
|
||||||
|
|
||||||
|
val ideaModuleInfo = session.moduleInfo.cast<IdeaModuleInfo>()
|
||||||
|
|
||||||
|
ideaModuleInfo.dependenciesWithoutSelf().forEach {
|
||||||
|
if (it is IdeaModuleInfo && it.isLibraryClasses()) {
|
||||||
|
createLibrarySession(it, provider)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val contentScope = ideaModuleInfo.contentScope()
|
||||||
|
|
||||||
|
val files = FileTypeIndex.getFiles(KotlinFileType.INSTANCE, contentScope)
|
||||||
|
|
||||||
|
println("Got vfiles: ${files.size}")
|
||||||
|
files.forEach {
|
||||||
|
val file = psiManager.findFile(it) as? KtFile ?: return@forEach
|
||||||
|
val firFile = builder.buildFirFile(file)
|
||||||
|
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
|
||||||
|
firFiles += firFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println("Raw fir up, files: ${firFiles.size}")
|
||||||
|
|
||||||
|
fun expectedTxtPath(virtualFile: VirtualFile): String {
|
||||||
|
val virtualPath = virtualFile.path
|
||||||
|
var result: String? = null
|
||||||
|
val root = File(dirPath)
|
||||||
|
for (file in root.walkTopDown()) {
|
||||||
|
if (!file.isDirectory && file.name in virtualPath) {
|
||||||
|
result = file.absolutePath.replace(".kt", ".txt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result!!
|
||||||
|
}
|
||||||
|
|
||||||
|
val transformer = FirTotalResolveTransformer()
|
||||||
|
for (file in firFiles) {
|
||||||
|
transformer.processFile(file)
|
||||||
|
val firFileDump = StringBuilder().also { file.accept(FirRenderer(it), null) }.toString()
|
||||||
|
val expectedPath = expectedTxtPath((file.psi as PsiFile).virtualFile)
|
||||||
|
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. 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.idea.fir;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||||
|
import org.jetbrains.kotlin.test.TargetBackend;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("idea/testData/fir/multiModule")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public class FirMultiModuleResolveTestGenerated extends AbstractFirMultiModuleResolveTest {
|
||||||
|
public void testAllFilesPresentInMultiModule() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/fir/multiModule"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("basic")
|
||||||
|
public void testBasic() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/fir/multiModule/basic/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user