[FIR] add lazy resolution contract checks in resolve

This commit is contained in:
Ilya Kirillov
2022-11-01 17:10:01 +01:00
committed by Space Team
parent df5aa59185
commit 7bac119f20
40 changed files with 390 additions and 86 deletions
@@ -13,6 +13,9 @@ import org.jetbrains.kotlin.fir.symbols.FirLazyDeclarationResolver
@ThreadSafeMutableState
internal class LLFirLazyDeclarationResolver : FirLazyDeclarationResolver() {
override fun startResolvingPhase(phase: FirResolvePhase) {}
override fun finishResolvingPhase(phase: FirResolvePhase) {}
override fun lazyResolveToPhase(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase) {
val fir = symbol.fir
val session = fir.moduleData.session
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCloneableSymbolProvider
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
import org.jetbrains.kotlin.fir.resolve.transformers.FirCompilerLazyDeclarationResolver
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.session.registerCommonComponents
import org.jetbrains.kotlin.fir.session.registerCommonJavaComponents
@@ -27,6 +26,7 @@ import org.jetbrains.kotlin.fir.session.registerModuleData
import org.jetbrains.kotlin.fir.symbols.FirLazyDeclarationResolver
import java.util.concurrent.ConcurrentHashMap
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.fir.resolve.transformers.FirDummyCompilerLazyDeclarationResolver
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.isCommon
import org.jetbrains.kotlin.platform.isJs
@@ -52,7 +52,7 @@ class LLFirBuiltinsSessionFactory(
bindSession(this@session)
}
registerIdeComponents(project)
register(FirLazyDeclarationResolver::class, FirCompilerLazyDeclarationResolver)
register(FirLazyDeclarationResolver::class, FirDummyCompilerLazyDeclarationResolver)
registerCommonComponents(LanguageVersionSettingsImpl.DEFAULT/*TODO*/)
registerCommonJavaComponents(JavaModuleResolver.getInstance(project))
registerModuleData(moduleData)
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
import org.jetbrains.kotlin.fir.resolve.transformers.FirCompilerLazyDeclarationResolver
import org.jetbrains.kotlin.fir.resolve.transformers.FirDummyCompilerLazyDeclarationResolver
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.session.registerCommonComponents
import org.jetbrains.kotlin.fir.session.registerCommonJavaComponents
@@ -51,7 +51,7 @@ class LLFirLibrarySessionFactory(
val moduleData = LLFirModuleData(ktLibraryModule).apply { bindSession(this@session) }
registerModuleData(moduleData)
registerIdeComponents(project)
register(FirLazyDeclarationResolver::class, FirCompilerLazyDeclarationResolver)
register(FirLazyDeclarationResolver::class, FirDummyCompilerLazyDeclarationResolver)
registerCommonComponents(LanguageVersionSettingsImpl.DEFAULT/*TODO*/)
registerCommonJavaComponents(JavaModuleResolver.getInstance(project))
registerJavaSpecificResolveComponents()
@@ -80,5 +80,4 @@ class LLFirLibrarySessionFactory(
fun getInstance(project: Project): LLFirLibrarySessionFactory =
project.getService(LLFirLibrarySessionFactory::class.java)
}
}
@@ -522,7 +522,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
resolvedLibraries,
sessionProvider,
dependencyList.moduleDataProvider,
configuration.languageVersionSettings
configuration.languageVersionSettings,
registerExtraComponents = {},
)
val mainModuleData = FirModuleDataImpl(
@@ -540,7 +541,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
extensionRegistrars,
configuration.languageVersionSettings,
null,
sessionConfigurator,
registerExtraComponents = {},
init = sessionConfigurator,
)
val rawFirFiles = session.buildFirFromKtFiles(ktFiles)
@@ -5,16 +5,16 @@
package org.jetbrains.kotlin.fir.analysis.collectors
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.collectors.components.AbstractDiagnosticCollectorComponent
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.findArgumentByName
import org.jetbrains.kotlin.fir.declarations.unwrapVarargValue
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.SessionHolder
import org.jetbrains.kotlin.fir.symbols.lazyDeclarationResolver
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.name.Name
@@ -28,7 +28,9 @@ abstract class AbstractDiagnosticCollector(
fun collectDiagnostics(firDeclaration: FirDeclaration, reporter: DiagnosticReporter) {
val components = createComponents(reporter)
val visitor = createVisitor(components)
firDeclaration.accept(visitor, null)
session.lazyDeclarationResolver.disableLazyResolveContractChecksInside {
firDeclaration.accept(visitor, null)
}
}
protected abstract fun createVisitor(components: DiagnosticCollectorComponents): CheckerRunningDiagnosticCollectorVisitor
@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.jvm.JvmCallConflictResolverFactory
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirQualifierResolverImpl
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirTypeResolverImpl
import org.jetbrains.kotlin.fir.resolve.transformers.FirCompilerLazyDeclarationResolver
import org.jetbrains.kotlin.fir.resolve.transformers.FirDummyCompilerLazyDeclarationResolver
import org.jetbrains.kotlin.fir.resolve.transformers.PlatformSupertypeUpdater
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.GeneratedClassIndex
import org.jetbrains.kotlin.fir.scopes.FirOverrideService
@@ -76,7 +76,7 @@ fun FirSession.registerCommonComponents(languageVersionSettings: LanguageVersion
fun FirSession.registerCliCompilerOnlyComponents() {
register(FirCachesFactory::class, FirThreadUnsafeCachesFactory)
register(SealedClassInheritorsProvider::class, SealedClassInheritorsProviderImpl)
register(FirLazyDeclarationResolver::class, FirCompilerLazyDeclarationResolver)
register(FirLazyDeclarationResolver::class, FirDummyCompilerLazyDeclarationResolver)
register(FirRegisteredPluginAnnotations::class, FirRegisteredPluginAnnotationsImpl(this))
register(FirPredicateBasedProvider::class, FirPredicateBasedProviderImpl(this))
@@ -37,7 +37,7 @@ abstract class FirAbstractSessionFactory {
sessionProvider: FirProjectSessionProvider,
moduleDataProvider: ModuleDataProvider,
languageVersionSettings: LanguageVersionSettings,
registerExtraComponents: ((FirSession) -> Unit)?,
registerExtraComponents: ((FirSession) -> Unit),
createKotlinScopeProvider: () -> FirKotlinScopeProvider,
createProviders: (FirSession, FirModuleData, FirKotlinScopeProvider) -> List<FirSymbolProvider>
): FirSession {
@@ -49,7 +49,7 @@ abstract class FirAbstractSessionFactory {
registerCliCompilerOnlyComponents()
registerCommonComponents(languageVersionSettings)
registerExtraComponents?.invoke(this)
registerExtraComponents(this)
val kotlinScopeProvider = createKotlinScopeProvider.invoke()
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
@@ -77,7 +77,7 @@ abstract class FirAbstractSessionFactory {
lookupTracker: LookupTracker?,
enumWhenTracker: EnumWhenTracker?,
init: FirSessionConfigurator.() -> Unit,
registerExtraComponents: ((FirSession) -> Unit)?,
registerExtraComponents: ((FirSession) -> Unit),
registerExtraCheckers: ((FirSessionConfigurator) -> Unit)?,
createKotlinScopeProvider: () -> FirKotlinScopeProvider,
createProviders: (
@@ -93,7 +93,7 @@ abstract class FirAbstractSessionFactory {
registerCliCompilerOnlyComponents()
registerCommonComponents(languageVersionSettings)
registerResolveComponents(lookupTracker, enumWhenTracker)
registerExtraComponents?.invoke(this)
registerExtraComponents(this)
val kotlinScopeProvider = createKotlinScopeProvider.invoke()
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
@@ -21,13 +21,13 @@ import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
import org.jetbrains.kotlin.name.Name
object FirJsSessionFactory : FirAbstractSessionFactory() {
fun createJsModuleBasedSession(
moduleData: FirModuleData,
sessionProvider: FirProjectSessionProvider,
extensionRegistrars: List<FirExtensionRegistrar>,
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
lookupTracker: LookupTracker?,
registerExtraComponents: ((FirSession) -> Unit) = {},
init: FirSessionConfigurator.() -> Unit
): FirSession {
return createModuleBasedSession(
@@ -38,7 +38,10 @@ object FirJsSessionFactory : FirAbstractSessionFactory() {
lookupTracker,
null,
init,
registerExtraComponents = { it.registerJsSpecificResolveComponents() },
registerExtraComponents = { session ->
session.registerJsSpecificResolveComponents()
registerExtraComponents(session)
},
registerExtraCheckers = { it.registerJsCheckers() },
createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } },
createProviders = { _, _, symbolProvider, generatedSymbolsProvider, dependenciesSymbolProvider ->
@@ -57,12 +60,16 @@ object FirJsSessionFactory : FirAbstractSessionFactory() {
sessionProvider: FirProjectSessionProvider,
moduleDataProvider: ModuleDataProvider,
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
registerExtraComponents: ((FirSession) -> Unit),
) = createLibrarySession(
mainModuleName,
sessionProvider,
moduleDataProvider,
languageVersionSettings,
registerExtraComponents = { it.registerJsSpecificResolveComponents() },
registerExtraComponents = {
it.registerJsSpecificResolveComponents()
registerExtraComponents(it)
},
createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } },
createProviders = { session, builtinsModuleData, kotlinScopeProvider ->
listOf(
@@ -34,13 +34,17 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() {
scope: AbstractProjectFileSearchScope,
packagePartProvider: PackagePartProvider,
languageVersionSettings: LanguageVersionSettings,
registerExtraComponents: ((FirSession) -> Unit),
): FirSession {
return createLibrarySession(
mainModuleName,
sessionProvider,
dependencyList.moduleDataProvider,
languageVersionSettings,
registerExtraComponents = { it.registerCommonJavaComponents(projectEnvironment.getJavaModuleResolver()) },
registerExtraComponents = {
it.registerCommonJavaComponents(projectEnvironment.getJavaModuleResolver())
registerExtraComponents(it)
},
createKotlinScopeProvider = { FirKotlinScopeProvider(::wrapScopeWithJvmMapped) },
createProviders = { session, builtinsModuleData, kotlinScopeProvider ->
listOf(
@@ -72,6 +76,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() {
lookupTracker: LookupTracker? = null,
enumWhenTracker: EnumWhenTracker? = null,
needRegisterJavaElementFinder: Boolean,
registerExtraComponents: ((FirSession) -> Unit) = {},
init: FirSessionConfigurator.() -> Unit = {}
): FirSession {
return createModuleBasedSession(
@@ -85,6 +90,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() {
registerExtraComponents = {
it.registerCommonJavaComponents(projectEnvironment.getJavaModuleResolver())
it.registerJavaSpecificResolveComponents()
registerExtraComponents(it)
},
registerExtraCheckers = { it.registerJvmCheckers() },
createKotlinScopeProvider = { FirKotlinScopeProvider(::wrapScopeWithJvmMapped) },
@@ -48,7 +48,8 @@ object FirSessionFactoryHelper {
projectEnvironment,
librariesScope,
packagePartProvider,
languageVersionSettings
languageVersionSettings,
registerExtraComponents = {},
)
val mainModuleData = FirModuleDataImpl(
@@ -70,7 +71,8 @@ object FirSessionFactoryHelper {
lookupTracker,
enumWhenTracker,
needRegisterJavaElementFinder,
sessionConfigurator
registerExtraComponents = {},
sessionConfigurator,
)
}
@@ -324,7 +324,7 @@ class FirResolveModularizedTotalKotlinTest : AbstractModularizedTest() {
class FirCheckersResolveProcessor(
session: FirSession,
scopeSession: ScopeSession
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
) : FirTransformerBasedResolveProcessor(session, scopeSession, phase = null) {
val diagnosticCollector: AbstractDiagnosticCollector = FirDiagnosticsCollector.create(session, scopeSession)
override val transformer: FirTransformer<Nothing?> = FirCheckersRunnerTransformer(diagnosticCollector)
@@ -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.fir.resolve.transformers
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.FirLazyDeclarationResolver
class FirCompilerLazyDeclarationResolverWithPhaseChecking : FirLazyDeclarationResolver() {
private var currentTransformerPhase: FirResolvePhase? = null
private val exceptions = mutableListOf<FirLazyResolveContractViolationException>()
fun getContractViolationExceptions(): List<FirLazyResolveContractViolationException> =
exceptions
override fun lazyResolveToPhase(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase) {
checkIfCanLazyResolveToPhase(symbol, toPhase)
}
override fun startResolvingPhase(phase: FirResolvePhase) {
check(currentTransformerPhase == null)
currentTransformerPhase = phase
}
override fun finishResolvingPhase(phase: FirResolvePhase) {
check(currentTransformerPhase == phase)
currentTransformerPhase = null
}
private fun checkIfCanLazyResolveToPhase(symbol: FirBasedSymbol<*>, requestedPhase: FirResolvePhase) {
if (!lazyResolveContractChecksEnabled) return
val currentPhase = currentTransformerPhase
?: error("Current phase is not set, please call ${this::startResolvingPhase.name} before starting transforming the file")
if (requestedPhase >= currentPhase) {
exceptions += FirLazyResolveContractViolationException(
"""`lazyResolveToPhase($requestedPhase)` cannot be called from a transformer with a phase $currentPhase.
lazyResolveToPhase was called on a $symbol.
`lazyResolveToPhase` can be called only from a transformer with a phase which is strictly greater than a requested phase;
i.e., `lazyResolveToPhase(A)` may be only called from a lazy transformer with a phase B, where A < B. This is a contract of lazy resolve""".trimIndent()
)
}
}
}
class FirLazyResolveContractViolationException(message: String) : IllegalStateException(message)
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -9,10 +9,9 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.FirLazyDeclarationResolver
/**
* Compiler is non-lazy, so it does nothing.
*/
object FirCompilerLazyDeclarationResolver : FirLazyDeclarationResolver() {
override fun lazyResolveToPhase(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase) {
}
object FirDummyCompilerLazyDeclarationResolver : FirLazyDeclarationResolver() {
override fun startResolvingPhase(phase: FirResolvePhase) {}
override fun finishResolvingPhase(phase: FirResolvePhase) {}
override fun lazyResolveToPhase(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase) {}
}
@@ -24,7 +24,9 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
class FirImportResolveProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(session, scopeSession) {
class FirImportResolveProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(
session, scopeSession, FirResolvePhase.IMPORTS
) {
override val transformer = FirImportResolveTransformer(session)
}
@@ -7,26 +7,41 @@ package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.symbols.lazyDeclarationResolver
import org.jetbrains.kotlin.fir.visitors.FirTransformer
@RequiresOptIn(message = "Should be used just only in resolve processor")
annotation class AdapterForResolveProcessor
sealed class FirResolveProcessor(val session: FirSession, val scopeSession: ScopeSession) {
open fun beforePhase() {}
sealed class FirResolveProcessor(val session: FirSession, val scopeSession: ScopeSession, val phase: FirResolvePhase?) {
open fun beforePhase() {
if (phase != null) {
session.lazyDeclarationResolver.startResolvingPhase(phase)
}
}
open fun afterPhase() {}
open fun afterPhase() {
if (phase != null) {
session.lazyDeclarationResolver.finishResolvingPhase(phase)
}
}
}
abstract class FirGlobalResolveProcessor(session: FirSession, scopeSession: ScopeSession) : FirResolveProcessor(session, scopeSession) {
abstract class FirGlobalResolveProcessor(
session: FirSession,
scopeSession: ScopeSession,
phase: FirResolvePhase,
) : FirResolveProcessor(session, scopeSession, phase) {
abstract fun process(files: Collection<FirFile>)
}
abstract class FirTransformerBasedResolveProcessor(
session: FirSession,
scopeSession: ScopeSession
) : FirResolveProcessor(session, scopeSession) {
scopeSession: ScopeSession,
phase: FirResolvePhase?,
) : FirResolveProcessor(session, scopeSession, phase) {
abstract val transformer: FirTransformer<Nothing?>
open fun processFile(file: FirFile) {
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.name.ClassId
class FirSealedClassInheritorsProcessor(
session: FirSession,
scopeSession: ScopeSession
) : FirGlobalResolveProcessor(session, scopeSession) {
) : FirGlobalResolveProcessor(session, scopeSession, FirResolvePhase.SEALED_CLASS_INHERITORS) {
override fun process(files: Collection<FirFile>) {
val sealedClassInheritorsMap = mutableMapOf<FirRegularClass, MutableList<ClassId>>()
val inheritorsCollector = InheritorsCollector(session)
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.fir.whileAnalysing
class FirStatusResolveProcessor(
session: FirSession,
scopeSession: ScopeSession
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
) : FirTransformerBasedResolveProcessor(session, scopeSession, FirResolvePhase.STATUS) {
override val transformer = run {
val statusComputationSession = StatusComputationSession()
FirStatusResolveTransformer(
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.wrapNestedClassifierScopeWithSubstit
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
@@ -48,8 +49,9 @@ import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.types.model.TypeArgumentMarker
import org.jetbrains.kotlin.utils.addIfNotNull
class FirSupertypeResolverProcessor(session: FirSession, scopeSession: ScopeSession) :
FirTransformerBasedResolveProcessor(session, scopeSession) {
class FirSupertypeResolverProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(
session, scopeSession, FirResolvePhase.SUPER_TYPES
) {
override val transformer = FirSupertypeResolverTransformer(session, scopeSession)
}
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.mpp.FirExpectActualMatcherP
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.*
import org.jetbrains.kotlin.fir.withFileAnalysisExceptionWrapping
class FirTotalResolveProcessor(session: FirSession) {
class FirTotalResolveProcessor(private val session: FirSession) {
val scopeSession: ScopeSession = ScopeSession()
private val processors: List<FirResolveProcessor> = createAllCompilerResolveProcessors(
@@ -28,19 +28,22 @@ class FirTotalResolveProcessor(session: FirSession) {
fun process(files: List<FirFile>) {
for (processor in processors) {
processor.beforePhase()
when (processor) {
is FirTransformerBasedResolveProcessor -> {
for (file in files) {
withFileAnalysisExceptionWrapping(file) {
processor.processFile(file)
try {
when (processor) {
is FirTransformerBasedResolveProcessor -> {
for (file in files) {
withFileAnalysisExceptionWrapping(file) {
processor.processFile(file)
}
}
}
is FirGlobalResolveProcessor -> {
processor.process(files)
}
}
is FirGlobalResolveProcessor -> {
processor.process(files)
}
} finally {
processor.afterPhase()
}
processor.afterPhase()
}
}
}
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
class FirTypeResolveProcessor(
session: FirSession,
scopeSession: ScopeSession
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
) : FirTransformerBasedResolveProcessor(session, scopeSession, FirResolvePhase.TYPES) {
override val transformer = FirTypeResolveTransformer(session, scopeSession)
}
@@ -16,7 +16,9 @@ import org.jetbrains.kotlin.fir.resolve.transformers.FirTransformerBasedResolveP
import org.jetbrains.kotlin.fir.visitors.FirTransformer
@OptIn(AdapterForResolveProcessor::class)
class FirBodyResolveProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(session, scopeSession) {
class FirBodyResolveProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(
session, scopeSession, FirResolvePhase.BODY_RESOLVE
) {
override val transformer = FirBodyResolveTransformerAdapter(session, scopeSession)
}
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.fir.visitors.FirTransformer
class FirImplicitTypeBodyResolveProcessor(
session: FirSession,
scopeSession: ScopeSession
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
) : FirTransformerBasedResolveProcessor(session, scopeSession, FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) {
override val transformer = FirImplicitTypeBodyResolveTransformerAdapter(session, scopeSession)
}
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.AdapterForResolveProcessor
@@ -19,7 +20,9 @@ import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.transformSingle
@OptIn(AdapterForResolveProcessor::class)
class FirContractResolveProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(session, scopeSession) {
class FirContractResolveProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(
session, scopeSession, FirResolvePhase.CONTRACTS
) {
override val transformer = FirContractResolveTransformerAdapter(session, scopeSession)
}
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.resolve.multiplatform.compatible
class FirExpectActualMatcherProcessor(
session: FirSession,
scopeSession: ScopeSession
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
) : FirTransformerBasedResolveProcessor(session, scopeSession, FirResolvePhase.EXPECT_ACTUAL_MATCHING) {
private val enabled = session.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
override val transformer: FirTransformer<Nothing?> = FirExpectActualMatcherTransformer(session, scopeSession)
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.fir.visitors.FirTransformer
class FirAnnotationArgumentsMappingProcessor(
session: FirSession,
scopeSession: ScopeSession
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
) : FirTransformerBasedResolveProcessor(session, scopeSession, FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS) {
override val transformer: FirTransformer<Any?> = FirAnnotationArgumentsMappingTransformerAdapter(session, scopeSession)
}
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.fir.visitors.FirTransformer
class FirAnnotationArgumentsResolveProcessor(
session: FirSession,
scopeSession: ScopeSession
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
) : FirTransformerBasedResolveProcessor(session, scopeSession, FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS) {
override val transformer: FirTransformer<Any?> = FirAnnotationArgumentsResolveTransformerAdapter(session, scopeSession)
}
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.name.SpecialNames
class FirCompanionGenerationProcessor(
session: FirSession,
scopeSession: ScopeSession
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
) : FirTransformerBasedResolveProcessor(session, scopeSession, FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS) {
override val transformer: FirTransformer<Nothing?> = FirCompanionGenerationTransformer(session)
}
@@ -18,11 +18,16 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.fir.withFileAnalysisExceptionWrapping
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Deprecated
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.DeprecatedSinceKotlin
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.JvmRecord
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.WasExperimental
class FirCompilerRequiredAnnotationsResolveProcessor(
session: FirSession,
scopeSession: ScopeSession
) : FirGlobalResolveProcessor(session, scopeSession) {
) : FirGlobalResolveProcessor(session, scopeSession, FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS) {
override fun process(files: Collection<FirFile>) {
val computationSession = CompilerRequiredAnnotationsComputationSession()
@@ -36,11 +41,13 @@ class FirCompilerRequiredAnnotationsResolveProcessor(
@OptIn(FirSymbolProviderInternals::class)
override fun beforePhase() {
super.beforePhase()
session.generatedDeclarationsSymbolProvider?.disable()
}
@OptIn(FirSymbolProviderInternals::class)
override fun afterPhase() {
super.afterPhase()
session.generatedDeclarationsSymbolProvider?.enable()
}
}
@@ -18,6 +18,22 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
* @see org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
*/
abstract class FirLazyDeclarationResolver : FirSessionComponent {
var lazyResolveContractChecksEnabled: Boolean = true
abstract fun startResolvingPhase(phase: FirResolvePhase)
abstract fun finishResolvingPhase(phase: FirResolvePhase)
inline fun disableLazyResolveContractChecksInside(action: () -> Unit) {
val current = lazyResolveContractChecksEnabled
lazyResolveContractChecksEnabled = false
try {
action()
} finally {
lazyResolveContractChecksEnabled = current
}
}
abstract fun lazyResolveToPhase(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase)
}
@@ -40,6 +40,10 @@ object FirDiagnosticsDirectives : SimpleDirectivesContainer() {
description = "Enables light tree parser instead of PSI"
)
val FIR_DISABLE_LAZY_RESOLVE_CHECKS by directive(
description = "Temporary disables lazy resolve checks until the lazy resolve contract violation is fixed"
)
val COMPARE_WITH_LIGHT_TREE by directive(
description = """
Enable comparing diagnostics between PSI and light tree modes
@@ -0,0 +1,68 @@
/*
* 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.test.frontend.fir
import org.jetbrains.kotlin.test.WrappedException
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
import org.jetbrains.kotlin.test.model.AfterAnalysisChecker
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.moduleStructure
import org.jetbrains.kotlin.test.utils.firTestDataFile
import org.jetbrains.kotlin.test.utils.originalTestDataFile
import org.jetbrains.kotlin.test.utils.removeDirectiveFromFile
class DisableLazyResolveChecksAfterAnalysisChecker(
testServices: TestServices
) : AfterAnalysisChecker(testServices) {
companion object {
private val isTeamCityBuild: Boolean = System.getenv("TEAMCITY_VERSION") != null
}
override fun check(failedAssertions: List<WrappedException>) {
if (!isDisableLazyResolveDirectivePresent()) return
if (failedAssertions.isNotEmpty()) return
val testDataFile = testServices.moduleStructure.originalTestDataFiles.first()
if (!isTeamCityBuild) {
setOf(
testDataFile.originalTestDataFile,
testDataFile.firTestDataFile
).forEach { file ->
file.removeDirectiveFromFile(FirDiagnosticsDirectives.FIR_DISABLE_LAZY_RESOLVE_CHECKS)
}
}
val message = if (isTeamCityBuild) {
"Please remove // ${FirDiagnosticsDirectives.FIR_DISABLE_LAZY_RESOLVE_CHECKS} from the test source"
} else {
"Removed // ${FirDiagnosticsDirectives.FIR_DISABLE_LAZY_RESOLVE_CHECKS} from the test source"
}
throw TestWithDisableLazyResolveDirectivePassesException(
"""
Lazy resolve contracts are satisfied now for this test and the test pass
$message
Please re-run the test now
""".trimIndent()
)
}
override fun suppressIfNeeded(failedAssertions: List<WrappedException>): List<WrappedException> {
return if (isDisableLazyResolveDirectivePresent()) {
failedAssertions.filter { it.cause is TestWithDisableLazyResolveDirectivePassesException }
} else {
failedAssertions
}
}
private fun isDisableLazyResolveDirectivePresent(): Boolean {
val moduleStructure = testServices.moduleStructure
return FirDiagnosticsDirectives.FIR_DISABLE_LAZY_RESOLVE_CHECKS in moduleStructure.allDirectives
}
}
private class TestWithDisableLazyResolveDirectivePassesException(override val message: String) : IllegalStateException()
@@ -51,7 +51,7 @@ import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurato
import java.io.File
import java.nio.file.Paths
class FirFrontendFacade(
open class FirFrontendFacade(
testServices: TestServices,
private val additionalSessionConfiguration: SessionConfiguration?
) : FrontendFacade<FirOutputArtifact>(testServices, FrontendKinds.FIR) {
@@ -66,6 +66,8 @@ class FirFrontendFacade(
override val directiveContainers: List<DirectivesContainer>
get() = listOf(FirDiagnosticsDirectives)
open fun registerExtraComponents(session: FirSession) {}
override fun analyze(module: TestModule): FirOutputArtifact {
val moduleInfoProvider = testServices.firModuleInfoProvider
val compilerConfigurationProvider = testServices.compilerConfigurationProvider
@@ -126,6 +128,7 @@ class FirFrontendFacade(
projectFileSearchScope,
packagePartProvider,
languageVersionSettings,
registerExtraComponents = ::registerExtraComponents,
)
}
module.targetPlatform.isJs() -> {
@@ -138,6 +141,7 @@ class FirFrontendFacade(
testServices,
configuration,
languageVersionSettings,
registerExtraComponents = ::registerExtraComponents,
)
}
module.targetPlatform.isNative() -> {
@@ -147,6 +151,7 @@ class FirFrontendFacade(
moduleInfoProvider.firSessionProvider,
dependencyList,
languageVersionSettings,
registerExtraComponents = ::registerExtraComponents,
)
}
else -> error("Unsupported")
@@ -174,6 +179,7 @@ class FirFrontendFacade(
lookupTracker = null,
enumWhenTracker = null,
needRegisterJavaElementFinder = true,
registerExtraComponents = ::registerExtraComponents,
sessionConfigurator,
)
}
@@ -184,6 +190,7 @@ class FirFrontendFacade(
extensionRegistrars,
languageVersionSettings,
null,
registerExtraComponents = ::registerExtraComponents,
sessionConfigurator,
)
}
@@ -193,6 +200,7 @@ class FirFrontendFacade(
moduleInfoProvider.firSessionProvider,
extensionRegistrars,
languageVersionSettings,
registerExtraComponents = ::registerExtraComponents,
init = sessionConfigurator
)
}
@@ -25,7 +25,8 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
mainModuleName: Name,
sessionProvider: FirProjectSessionProvider,
dependencyListForCliModule: DependencyListForCliModule,
languageVersionSettings: LanguageVersionSettings
languageVersionSettings: LanguageVersionSettings,
registerExtraComponents: ((FirSession) -> Unit) = {},
): FirSession {
val moduleDataProvider = dependencyListForCliModule.moduleDataProvider
return createLibrarySession(
@@ -33,7 +34,7 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
sessionProvider,
moduleDataProvider,
languageVersionSettings,
null,
registerExtraComponents,
createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } },
createProviders = { session, builtinsModuleData, kotlinScopeProvider ->
listOf(
@@ -48,7 +49,8 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
sessionProvider: FirProjectSessionProvider,
extensionRegistrars: List<FirExtensionRegistrar>,
languageVersionSettings: LanguageVersionSettings,
init: FirSessionConfigurator.() -> Unit
init: FirSessionConfigurator.() -> Unit,
registerExtraComponents: ((FirSession) -> Unit) = {},
): FirSession {
return createModuleBasedSession(
moduleData,
@@ -58,7 +60,10 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
null,
null,
init,
registerExtraComponents = { it.registerExtraComponentsForModuleBased() },
registerExtraComponents = { session ->
session.registerExtraComponentsForModuleBased()
registerExtraComponents(session)
},
registerExtraCheckers = { it.registerNativeCheckers() },
createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } },
createProviders = { _, _, symbolProvider, generatedSymbolsProvider, dependenciesSymbolProvider ->
@@ -7,7 +7,9 @@ package org.jetbrains.kotlin.test.frontend.fir
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.DependencyListForCliModule
import org.jetbrains.kotlin.fir.FirModuleDataImpl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.session.FirJsSessionFactory
@@ -29,6 +31,7 @@ object TestFirJsSessionFactory {
testServices: TestServices,
configuration: CompilerConfiguration,
languageVersionSettings: LanguageVersionSettings,
registerExtraComponents: ((FirSession) -> Unit),
): FirSession {
val repositories = configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList()
val logger = configuration.resolverLogger
@@ -36,16 +39,28 @@ object TestFirJsSessionFactory {
val resolvedLibraries = jsResolveLibraries(libraries, repositories, logger).getFullResolvedList()
return FirJsSessionFactory.createJsLibrarySession(
mainModuleName, resolvedLibraries, sessionProvider, dependencyListForCliModule.moduleDataProvider, languageVersionSettings
mainModuleName,
resolvedLibraries,
sessionProvider,
dependencyListForCliModule.moduleDataProvider,
languageVersionSettings,
registerExtraComponents,
)
}
fun createModuleBasedSession(
mainModuleData: FirModuleDataImpl, sessionProvider: FirProjectSessionProvider, extensionRegistrars: List<FirExtensionRegistrar>,
languageVersionSettings: LanguageVersionSettings, lookupTracker: LookupTracker?,
sessionConfigurator: FirSessionConfigurator.() -> Unit
registerExtraComponents: ((FirSession) -> Unit),
sessionConfigurator: FirSessionConfigurator.() -> Unit,
): FirSession =
FirJsSessionFactory.createJsModuleBasedSession(
mainModuleData, sessionProvider, extensionRegistrars, languageVersionSettings, lookupTracker, sessionConfigurator
mainModuleData,
sessionProvider,
extensionRegistrars,
languageVersionSettings,
lookupTracker,
registerExtraComponents,
sessionConfigurator
)
}
@@ -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.test.frontend.fir.handlers
import org.jetbrains.kotlin.fir.resolve.transformers.FirCompilerLazyDeclarationResolverWithPhaseChecking
import org.jetbrains.kotlin.fir.symbols.lazyDeclarationResolver
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
class FirResolveContractViolationErrorHandler(testServices: TestServices) : FirAnalysisHandler(testServices) {
override fun processModule(module: TestModule, info: FirOutputArtifact) {
val session = info.session
val lazyResolver = session.lazyDeclarationResolver as? FirCompilerLazyDeclarationResolverWithPhaseChecking ?: return
val exceptions = lazyResolver.getContractViolationExceptions().ifEmpty { return }
testServices.assertions.failAll(exceptions)
}
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
}
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.renderer.FirCallNoArgumentsRenderer
import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
@@ -19,6 +18,7 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.symbols.lazyDeclarationResolver
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -80,12 +80,14 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS
val firClass = symbol.fir as? FirRegularClass ?: assertions.fail { "$fqName is not a class but ${symbol.fir.render()}" }
println("$fqName: ")
val scope = firClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = true)
val names = namesFromDirective.takeIf { it.isNotEmpty() }?.map { Name.identifier(it) } ?: scope.getCallableNames()
withIndent {
for (name in names) {
processFunctions(name, scope)
processProperties(name, scope)
session.lazyDeclarationResolver.disableLazyResolveContractChecksInside {
val scope = firClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = true)
val names = namesFromDirective.takeIf { it.isNotEmpty() }?.map { Name.identifier(it) } ?: scope.getCallableNames()
withIndent {
for (name in names) {
processFunctions(name, scope)
processProperties(name, scope)
}
}
}
println()
@@ -18,13 +18,13 @@ import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
import org.jetbrains.kotlin.test.frontend.classic.handlers.DeclarationsDumpHandler
import org.jetbrains.kotlin.test.frontend.classic.handlers.OldNewInferenceMetaInfoProcessor
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
import org.jetbrains.kotlin.test.frontend.fir.DisableLazyResolveChecksAfterAnalysisChecker
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
import org.jetbrains.kotlin.test.frontend.fir.handlers.*
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.frontend.fir.handlers.*
abstract class AbstractDiagnosticsNativeTestBase<R : ResultingArtifact.FrontendOutput<R>> : AbstractKotlinCompilerTest() {
abstract val targetFrontend: FrontendKind<R>
@@ -86,7 +86,7 @@ abstract class AbstractFirNativeDiagnosticsTest : AbstractDiagnosticsNativeTestB
get() = FrontendKinds.FIR
override val frontend: Constructor<FrontendFacade<FirOutputArtifact>>
get() = ::FirFrontendFacade
get() = ::FirFrontendFacadeForDiagnosticTests
override fun handlersSetup(builder: TestConfigurationBuilder) {
builder.firHandlersStep {
@@ -104,6 +104,17 @@ abstract class AbstractFirNativeDiagnosticsTest : AbstractDiagnosticsNativeTestB
override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder)
builder.useAfterAnalysisCheckers(
::DisableLazyResolveChecksAfterAnalysisChecker,
)
builder.firHandlersStep {
useHandlers(
::FirResolveContractViolationErrorHandler,
)
}
builder.forTestsMatching("compiler/testData/diagnostics/*") {
configurationForClassicAndFirTestsAlongside()
}
@@ -6,37 +6,48 @@
package org.jetbrains.kotlin.test.runners
import org.jetbrains.kotlin.config.ExplicitApiMode
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.resolve.transformers.FirCompilerLazyDeclarationResolverWithPhaseChecking
import org.jetbrains.kotlin.fir.symbols.FirLazyDeclarationResolver
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.test.bind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.firHandlersStep
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives.WITH_STDLIB
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.FIR_DUMP
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.USE_LIGHT_TREE
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.WITH_EXTENDED_CHECKERS
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JDK_KIND
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_REFLECT
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives.WITH_STDLIB
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.ALLOW_KOTLIN_PACKAGE
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.LANGUAGE
import org.jetbrains.kotlin.test.frontend.fir.FirFailingTestSuppressor
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
import org.jetbrains.kotlin.test.frontend.fir.*
import org.jetbrains.kotlin.test.frontend.fir.handlers.*
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendFacade
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.fir.FirOldFrontendMetaConfigurator
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
abstract class AbstractFirDiagnosticTest : AbstractKotlinCompilerTest() {
override fun TestConfigurationBuilder.configuration() {
baseFirDiagnosticTestConfiguration()
useAfterAnalysisCheckers(
::DisableLazyResolveChecksAfterAnalysisChecker,
)
firHandlersStep {
useHandlers(
::FirResolveContractViolationErrorHandler,
)
}
}
}
@@ -62,7 +73,7 @@ fun TestConfigurationBuilder.configurationForClassicAndFirTestsAlongside() {
// `baseDir` is used in Kotlin plugin from IJ infra
fun TestConfigurationBuilder.baseFirDiagnosticTestConfiguration(
baseDir: String = ".",
frontendFacade: Constructor<FrontendFacade<FirOutputArtifact>> = ::FirFrontendFacade
frontendFacade: Constructor<FrontendFacade<FirOutputArtifact>> = ::FirFrontendFacadeForDiagnosticTests
) {
globalDefaults {
frontend = FrontendKinds.FIR
@@ -161,3 +172,12 @@ fun TestConfigurationBuilder.baseFirDiagnosticTestConfiguration(
LANGUAGE + "+EnableDfaWarningsInK2"
}
}
class FirFrontendFacadeForDiagnosticTests(testServices: TestServices) : FirFrontendFacade(testServices) {
private val lazyResolver = FirCompilerLazyDeclarationResolverWithPhaseChecking()
@OptIn(org.jetbrains.kotlin.fir.SessionConfiguration::class)
override fun registerExtraComponents(session: FirSession) {
session.register(FirLazyDeclarationResolver::class, lazyResolver)
}
}
@@ -8,8 +8,11 @@ package org.jetbrains.kotlin.fir.plugin.runners
import org.jetbrains.kotlin.fir.plugin.services.ExtensionRegistrarConfigurator
import org.jetbrains.kotlin.fir.plugin.services.PluginAnnotationsProvider
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.firHandlersStep
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.ENABLE_PLUGIN_PHASES
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.FIR_DUMP
import org.jetbrains.kotlin.test.frontend.fir.DisableLazyResolveChecksAfterAnalysisChecker
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirResolveContractViolationErrorHandler
import org.jetbrains.kotlin.test.runners.AbstractFirDiagnosticTest
import org.jetbrains.kotlin.test.runners.codegen.AbstractFirBlackBoxCodegenTest
@@ -28,6 +31,16 @@ abstract class AbstractFirPluginDiagnosticTest : AbstractFirDiagnosticTest() {
}
fun TestConfigurationBuilder.commonFirWithPluginFrontendConfiguration() {
useAfterAnalysisCheckers(
::DisableLazyResolveChecksAfterAnalysisChecker,
)
firHandlersStep {
useHandlers(
::FirResolveContractViolationErrorHandler,
)
}
defaultDirectives {
+ENABLE_PLUGIN_PHASES
+FIR_DUMP
@@ -7,9 +7,12 @@ package org.jetbrains.kotlin.parcelize.test.runners
import org.jetbrains.kotlin.parcelize.test.services.ParcelizeEnvironmentConfigurator
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.firHandlersStep
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
import org.jetbrains.kotlin.test.frontend.fir.DisableLazyResolveChecksAfterAnalysisChecker
import org.jetbrains.kotlin.test.frontend.fir.FirFailingTestSuppressor
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirIdenticalChecker
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirResolveContractViolationErrorHandler
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest
import org.jetbrains.kotlin.test.runners.baseFirDiagnosticTestConfiguration
import org.jetbrains.kotlin.test.services.fir.FirOldFrontendMetaConfigurator
@@ -27,7 +30,16 @@ abstract class AbstractFirParcelizeDiagnosticTest : AbstractKotlinCompilerTest()
useAfterAnalysisCheckers(
::FirIdenticalChecker,
::FirFailingTestSuppressor,
::DisableLazyResolveChecksAfterAnalysisChecker,
)
firHandlersStep {
useHandlers(
::FirResolveContractViolationErrorHandler,
)
}
useMetaTestConfigurators(::FirOldFrontendMetaConfigurator)
}
}