Refactor GenerationState creation

This commit is contained in:
Dmitry Petrov
2017-11-28 16:49:19 +03:00
parent d6d6cef10d
commit d976eeabf7
10 changed files with 97 additions and 44 deletions
@@ -48,25 +48,69 @@ import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfigu
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import java.io.File
class GenerationState @JvmOverloads constructor(
class GenerationState private constructor(
val project: Project,
builderFactory: ClassBuilderFactory,
val module: ModuleDescriptor,
bindingContext: BindingContext,
val files: List<KtFile>,
val configuration: CompilerConfiguration,
val generateDeclaredClassFilter: GenerateClassFilter = GenerationState.GenerateClassFilter.GENERATE_ALL,
val codegenFactory: CodegenFactory = DefaultCodegenFactory,
// For incremental compilation
val targetId: TargetId? = null,
moduleName: String? = configuration.get(CommonConfigurationKeys.MODULE_NAME),
val generateDeclaredClassFilter: GenerateClassFilter,
val codegenFactory: CodegenFactory,
val targetId: TargetId?,
moduleName: String?,
val outDirectory: File?,
private val onIndependentPartCompilationEnd: GenerationStateEventCallback,
wantsDiagnostics: Boolean
) {
class Builder(
private val project: Project,
private val builderFactory: ClassBuilderFactory,
private val module: ModuleDescriptor,
private val bindingContext: BindingContext,
private val files: List<KtFile>,
private val configuration: CompilerConfiguration
) {
private var generateDeclaredClassFilter: GenerateClassFilter = GenerateClassFilter.GENERATE_ALL
fun generateDeclaredClassFilter(v: GenerateClassFilter) =
apply { generateDeclaredClassFilter = v }
private var codegenFactory: CodegenFactory = DefaultCodegenFactory
fun codegenFactory(v: CodegenFactory) =
apply { codegenFactory = v }
private var targetId: TargetId? = null
fun targetId(v: TargetId?) =
apply { targetId = v }
private var moduleName: String? = configuration[CommonConfigurationKeys.MODULE_NAME]
fun moduleName(v: String?) =
apply { moduleName = v }
// 'outDirectory' is a hack to correctly determine if a compiled class is from the same module as the callee during
// partial compilation. Module chunks are treated as a single module.
// TODO: get rid of it with the proper module infrastructure
val outDirectory: File? = null,
private val onIndependentPartCompilationEnd: GenerationStateEventCallback = GenerationStateEventCallback.DO_NOTHING,
wantsDiagnostics: Boolean = true
) {
private var outDirectory: File? = null
fun outDirectory(v: File?) =
apply { outDirectory = v }
private var onIndependentPartCompilationEnd: GenerationStateEventCallback = GenerationStateEventCallback.DO_NOTHING
fun onIndependentPartCompilationEnd(v: GenerationStateEventCallback) =
apply { onIndependentPartCompilationEnd = v }
private var wantsDiagnostics: Boolean = true
fun wantsDiagnostics(v: Boolean) =
apply { wantsDiagnostics = v }
fun build() =
GenerationState(
project, builderFactory, module, bindingContext, files, configuration,
generateDeclaredClassFilter, codegenFactory, targetId,
moduleName, outDirectory, onIndependentPartCompilationEnd, wantsDiagnostics
)
}
abstract class GenerateClassFilter {
abstract fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean
abstract fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean
@@ -421,6 +421,13 @@ object KotlinToJVMBytecodeCompiler {
override fun toString() = "All files under: $directories"
}
private fun GenerationState.Builder.withModule(module: Module?) =
apply {
targetId(module?.let { TargetId(it) })
moduleName(module?.getModuleName())
outDirectory(module?.let { File(it.getOutputDirectory()) })
}
private fun generate(
environment: KotlinCoreEnvironment,
configuration: CompilerConfiguration,
@@ -429,20 +436,19 @@ object KotlinToJVMBytecodeCompiler {
module: Module?
): GenerationState {
val isKapt2Enabled = environment.project.getUserData(IS_KAPT2_ENABLED_KEY) ?: false
val generationState = GenerationState(
val generationState = GenerationState.Builder(
environment.project,
ClassBuilderFactories.binaries(isKapt2Enabled),
result.moduleDescriptor,
result.bindingContext,
sourceFiles,
configuration,
GenerationState.GenerateClassFilter.GENERATE_ALL,
if (configuration.getBoolean(JVMConfigurationKeys.IR)) JvmIrCodegenFactory else DefaultCodegenFactory,
module?.let(::TargetId),
module?.let(Module::getModuleName),
module?.let { File(it.getOutputDirectory()) },
createOutputFilesFlushingCallbackIfPossible(configuration)
configuration
)
.codegenFactory(if (configuration.getBoolean(JVMConfigurationKeys.IR)) JvmIrCodegenFactory else DefaultCodegenFactory)
.withModule(module)
.onIndependentPartCompilationEnd(createOutputFilesFlushingCallbackIfPossible(configuration))
.build()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val generationStart = PerformanceCounter.currentTime()
@@ -83,14 +83,14 @@ open class GenericReplCompiler(disposable: Disposable,
else -> error("Unexpected result ${analysisResult::class.java}")
}
val generationState = GenerationState(
val generationState = GenerationState.Builder(
psiFile.project,
ClassBuilderFactories.binaries(false),
compilerState.analyzerEngine.module,
compilerState.analyzerEngine.trace.bindingContext,
listOf(psiFile),
compilerConfiguration
)
).build()
generationState.replSpecific.scriptResultFieldName = SCRIPT_RESULT_FIELD_NAME
generationState.replSpecific.earlierScriptsForReplInterpreter = compilerState.history.map { it.item }
generationState.beforeCompile()
@@ -47,16 +47,14 @@ fun buildLightClass(
try {
val classBuilderFactory = KotlinLightClassBuilderFactory(createJavaFileStub(project, packageFqName, files))
val state = GenerationState(
val state = GenerationState.Builder(
project,
classBuilderFactory,
context.module,
context.bindingContext,
files.toList(),
CompilerConfiguration.EMPTY,
generateClassFilter,
wantsDiagnostics = false
)
CompilerConfiguration.EMPTY
).generateDeclaredClassFilter(generateClassFilter).wantsDiagnostics(false).build()
state.beforeCompile()
generate(state, files)
@@ -59,11 +59,12 @@ object GenerationUtils {
val analysisResult = JvmResolveUtil.analyzeAndCheckForErrors(files.first().project, files, configuration, packagePartProvider)
analysisResult.throwIfError()
val state = GenerationState(
val state = GenerationState.Builder(
files.first().project, classBuilderFactory, analysisResult.moduleDescriptor, analysisResult.bindingContext,
files, configuration,
codegenFactory = if (configuration.getBoolean(JVMConfigurationKeys.IR)) JvmIrCodegenFactory else DefaultCodegenFactory
)
files, configuration
).codegenFactory(
if (configuration.getBoolean(JVMConfigurationKeys.IR)) JvmIrCodegenFactory else DefaultCodegenFactory
).build()
if (analysisResult.shouldGenerateCode) {
KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION)
}
@@ -187,14 +187,14 @@ class KotlinDebuggerCaches(project: Project) {
}
private fun createTypeMapper(file: KtFile, analysisResult: AnalysisResult): KotlinTypeMapper {
val state = GenerationState(
val state = GenerationState.Builder(
file.project,
ClassBuilderFactories.THROW_EXCEPTION,
analysisResult.moduleDescriptor,
analysisResult.bindingContext,
listOf(file),
CompilerConfiguration.EMPTY
)
).build()
state.beforeCompile()
return state.typeMapper
}
@@ -469,15 +469,14 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour
override fun shouldGenerateScript(script: KtScript) = false
}
val state = GenerationState(
val state = GenerationState.Builder(
fileForDebugger.project,
if (!DEBUG_MODE) ClassBuilderFactories.binaries(false) else ClassBuilderFactories.TEST,
moduleDescriptor,
bindingContext,
files,
CompilerConfiguration.EMPTY,
generateClassFilter
)
CompilerConfiguration.EMPTY
).generateDeclaredClassFilter(generateClassFilter).build()
val frameVisitor = FrameVisitor(context)
@@ -324,11 +324,15 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
}
};
GenerationState state = new GenerationState(
GenerationState state = new GenerationState.Builder(
ktFile.getProject(), ClassBuilderFactories.TEST, resolutionFacade.getModuleDescriptor(), bindingContext, toProcess,
configuration, generateClassFilter,
configuration.getBoolean(JVMConfigurationKeys.IR) ? JvmIrCodegenFactory.INSTANCE : DefaultCodegenFactory.INSTANCE
);
configuration
)
.generateDeclaredClassFilter(generateClassFilter)
.codegenFactory(configuration.getBoolean(JVMConfigurationKeys.IR)
? JvmIrCodegenFactory.INSTANCE
: DefaultCodegenFactory.INSTANCE)
.build();
KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION);
@@ -43,13 +43,14 @@ class StubProducerExtension(
bindingTrace: BindingTrace,
files: Collection<KtFile>
): AnalysisResult? {
val generationState = GenerationState(
val generationState = GenerationState.Builder(
project,
StubClassBuilderFactory(),
module,
bindingTrace.bindingContext,
files.toList(),
CompilerConfiguration.EMPTY)
CompilerConfiguration.EMPTY
).build()
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)
@@ -222,14 +222,14 @@ abstract class AbstractKapt3Extension(
name = compilerConfiguration[CommonConfigurationKeys.MODULE_NAME] ?: module.name.asString(),
type = "java-production")
val generationState = GenerationState(
val generationState = GenerationState.Builder(
project,
builderFactory,
module,
bindingContext,
files,
compilerConfiguration,
targetId = targetId)
compilerConfiguration
).targetId(targetId).build()
val (classFilesCompilationTime) = measureTimeMillis {
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)