From 62df2b3195dc25176957364ed7c6793d5930b64d Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Fri, 7 Aug 2020 22:28:01 +0300 Subject: [PATCH] FIR IDE: run SUPER_TYPES & BODY_RESOLVE phases under global lock --- .../level/api/FirIdeJavaModuleBasedSession.kt | 3 +- .../level/api/FirIdeResolveStateService.kt | 2 ++ .../idea/fir/low/level/api/FirPhaseRunner.kt | 35 +++++++++++++++++++ .../level/api/file/builder/FirFileBuilder.kt | 7 ++-- 4 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirPhaseRunner.kt diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeJavaModuleBasedSession.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeJavaModuleBasedSession.kt index 3cc6c9b1d86..955584e7694 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeJavaModuleBasedSession.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeJavaModuleBasedSession.kt @@ -46,10 +46,11 @@ internal class FirIdeJavaModuleBasedSession private constructor( fun create( project: Project, moduleInfo: ModuleSourceInfo, + firPhaseRunner: FirPhaseRunner, sessionProvider: FirSessionProvider, ): FirIdeJavaModuleBasedSession { val scopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped) - val firBuilder = FirFileBuilder(sessionProvider as FirIdeSessionProvider, scopeProvider) + val firBuilder = FirFileBuilder(sessionProvider as FirIdeSessionProvider, scopeProvider, firPhaseRunner) return FirIdeJavaModuleBasedSession(moduleInfo, sessionProvider, firBuilder).apply { val cache = ModuleFileCacheImpl(this) val phasedFirFileResolver = IdePhasedFirFileResolver(firBuilder, cache) diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeResolveStateService.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeResolveStateService.kt index ab2ab3582c6..5432e936dbb 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeResolveStateService.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeResolveStateService.kt @@ -18,9 +18,11 @@ internal class FirIdeResolveStateService(private val project: Project) { private fun createResolveStateFor(moduleInfo: IdeaModuleInfo): FirModuleResolveStateImpl { val sessionProvider = FirIdeSessionProvider(project) + val firPhaseRunner = FirPhaseRunner() val session = FirIdeJavaModuleBasedSession.create( project, moduleInfo as ModuleSourceInfo, + firPhaseRunner, sessionProvider, ).apply { sessionProvider.registerSession(moduleInfo, this) } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirPhaseRunner.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirPhaseRunner.kt new file mode 100644 index 00000000000..d454234a8db --- /dev/null +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirPhaseRunner.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2020 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.idea.fir.low.level.api + +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.resolve.transformers.createTransformerBasedProcessorByPhase +import java.util.concurrent.locks.ReentrantLock +import kotlin.concurrent.withLock + +internal class FirPhaseRunner { + private val superTypesBodyResolveLock = ReentrantLock() + private val implicitTypesResolveLock = ReentrantLock() + + fun runPhase(firFile: FirFile, phase: FirResolvePhase, scopeSession: ScopeSession) = when (phase) { + FirResolvePhase.SUPER_TYPES -> superTypesBodyResolveLock.withLock { + runPhaseWithoutLock(firFile, phase, scopeSession) + } + FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE -> implicitTypesResolveLock.withLock { + runPhaseWithoutLock(firFile, phase, scopeSession) + } + else -> { + runPhaseWithoutLock(firFile, phase, scopeSession) + } + } + + private fun runPhaseWithoutLock(firFile: FirFile, phase: FirResolvePhase, scopeSession: ScopeSession) { + val phaseProcessor = phase.createTransformerBasedProcessorByPhase(firFile.session, scopeSession) + phaseProcessor.processFile(firFile) + } +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/FirFileBuilder.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/FirFileBuilder.kt index 1148453201f..d743dde276f 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/FirFileBuilder.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/FirFileBuilder.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.transformers.createTransformerBasedProcessorByPhase import org.jetbrains.kotlin.fir.scopes.FirScopeProvider import org.jetbrains.kotlin.idea.fir.low.level.api.FirIdeSessionProvider +import org.jetbrains.kotlin.idea.fir.low.level.api.FirPhaseRunner import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.ThreadSafe @@ -22,7 +23,8 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.ThreadSafe @ThreadSafe internal class FirFileBuilder( private val sessionProvider: FirIdeSessionProvider, - private val scopeProvider: FirScopeProvider + private val scopeProvider: FirScopeProvider, + private val firPhaseRunner: FirPhaseRunner ) { /** * Builds a [FirFile] by given [ktFile] and records it's parenting info if it not present in [cache] @@ -70,8 +72,7 @@ internal class FirFileBuilder( var currentPhase = fromPhase while (currentPhase < toPhase) { currentPhase = currentPhase.next - val phaseProcessor = currentPhase.createTransformerBasedProcessorByPhase(firFile.session, scopeSession) - phaseProcessor.processFile(firFile) + firPhaseRunner.runPhase(firFile, currentPhase, scopeSession) } } }