Generation test utils: extract compileFilesUsing standard mode / FIR

This commit is contained in:
Mikhail Glukhikh
2019-11-19 09:58:14 +03:00
parent 9df2f69f09
commit 2ab3769998
@@ -17,11 +17,11 @@
package org.jetbrains.kotlin.codegen
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.ProjectScope
import org.jetbrains.kotlin.TestsCompiletimeError
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
@@ -36,25 +36,16 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.fir.createSession
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
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.createSession
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.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.AnalyzingUtils
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
import java.io.File
@@ -90,67 +81,9 @@ object GenerationUtils {
): GenerationState {
val project = files.first().project
val state = if (configuration.getBoolean(CommonConfigurationKeys.USE_FIR)) {
Extensions.getArea(project)
.getExtensionPoint(PsiElementFinder.EP_NAME)
.unregisterExtension(JavaElementFinder::class.java)
val scope = GlobalSearchScope.filesScope(project, files.map { it.virtualFile })
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
val librariesScope = ProjectScope.getLibrariesScope(project)
val session = createSession(project, scope, librariesScope, packagePartProvider)
val builder = RawFirBuilder(session, stubMode = false)
val resolveTransformer = FirTotalResolveTransformer()
val firFiles = files.map {
val firFile = builder.buildFirFile(it)
(session.firProvider as FirProviderImpl).recordFile(firFile)
firFile
}.also {
try {
resolveTransformer.processFiles(it)
} catch (e: Exception) {
throw e
}
}
val (moduleFragment, symbolTable, sourceManager) =
Fir2IrConverter.createModuleFragment(session, firFiles, configuration.languageVersionSettings)
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
val codegenFactory = JvmIrCodegenFactory(configuration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases))
val generationState = GenerationState.Builder(
project, classBuilderFactory, moduleFragment.descriptor, dummyBindingContext, files, configuration
).codegenFactory(
codegenFactory
).isIrBackend(
true
).build()
generationState.beforeCompile()
codegenFactory.generateModuleInFrontendIRMode(
generationState, moduleFragment, CompilationErrorHandler.THROW_EXCEPTION, symbolTable, sourceManager
)
generationState.factory.done()
generationState
compileFilesUsingFrontendIR(project, files, configuration, classBuilderFactory, packagePartProvider)
} else {
val analysisResult =
JvmResolveUtil.analyzeAndCheckForErrors(project, files, configuration, packagePartProvider, trace)
analysisResult.throwIfError()
/* Currently Kapt3 only works with the old JVM backend, so disable IR for everything except actual bytecode generation. */
val isIrBackend =
classBuilderFactory.classBuilderMode == ClassBuilderMode.FULL && configuration.getBoolean(JVMConfigurationKeys.IR)
val state = GenerationState.Builder(
project, classBuilderFactory, analysisResult.moduleDescriptor, analysisResult.bindingContext,
files, configuration
).codegenFactory(
if (isIrBackend)
JvmIrCodegenFactory(configuration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases))
else DefaultCodegenFactory
).isIrBackend(isIrBackend).build()
if (analysisResult.shouldGenerateCode) {
KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION)
}
state
compileFilesUsingStandardMode(project, files, configuration, classBuilderFactory, packagePartProvider, trace)
}
// For JVM-specific errors
@@ -162,4 +95,83 @@ object GenerationUtils {
return state
}
}
private fun compileFilesUsingFrontendIR(
project: Project,
files: List<KtFile>,
configuration: CompilerConfiguration,
classBuilderFactory: ClassBuilderFactory,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider
): GenerationState {
Extensions.getArea(project)
.getExtensionPoint(PsiElementFinder.EP_NAME)
.unregisterExtension(JavaElementFinder::class.java)
val scope = GlobalSearchScope.filesScope(project, files.map { it.virtualFile })
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
val librariesScope = ProjectScope.getLibrariesScope(project)
val session = createSession(project, scope, librariesScope, packagePartProvider)
val builder = RawFirBuilder(session, stubMode = false)
val resolveTransformer = FirTotalResolveTransformer()
val firFiles = files.map {
val firFile = builder.buildFirFile(it)
(session.firProvider as FirProviderImpl).recordFile(firFile)
firFile
}.also {
try {
resolveTransformer.processFiles(it)
} catch (e: Exception) {
throw e
}
}
val (moduleFragment, symbolTable, sourceManager) =
Fir2IrConverter.createModuleFragment(session, firFiles, configuration.languageVersionSettings)
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
val codegenFactory = JvmIrCodegenFactory(configuration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases))
val generationState = GenerationState.Builder(
project, classBuilderFactory, moduleFragment.descriptor, dummyBindingContext, files, configuration
).codegenFactory(
codegenFactory
).isIrBackend(
true
).build()
generationState.beforeCompile()
codegenFactory.generateModuleInFrontendIRMode(
generationState, moduleFragment, CompilationErrorHandler.THROW_EXCEPTION, symbolTable, sourceManager
)
generationState.factory.done()
return generationState
}
private fun compileFilesUsingStandardMode(
project: Project,
files: List<KtFile>,
configuration: CompilerConfiguration,
classBuilderFactory: ClassBuilderFactory,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
trace: BindingTrace
): GenerationState {
val analysisResult =
JvmResolveUtil.analyzeAndCheckForErrors(project, files, configuration, packagePartProvider, trace)
analysisResult.throwIfError()
/* Currently Kapt3 only works with the old JVM backend, so disable IR for everything except actual bytecode generation. */
val isIrBackend =
classBuilderFactory.classBuilderMode == ClassBuilderMode.FULL && configuration.getBoolean(JVMConfigurationKeys.IR)
val generationState = GenerationState.Builder(
project, classBuilderFactory, analysisResult.moduleDescriptor, analysisResult.bindingContext,
files, configuration
).codegenFactory(
if (isIrBackend)
JvmIrCodegenFactory(configuration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases))
else DefaultCodegenFactory
).isIrBackend(isIrBackend).build()
if (analysisResult.shouldGenerateCode) {
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)
}
return generationState
}
}