JVM: Add an extension point for file output

This commit is contained in:
Steven Schäfer
2020-11-30 14:01:28 +01:00
committed by Alexander Udalov
parent de9d2919a8
commit a54503cede
4 changed files with 32 additions and 2 deletions
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly; import org.jetbrains.annotations.TestOnly;
import org.jetbrains.kotlin.backend.common.output.OutputFile; import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection; import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
import org.jetbrains.kotlin.codegen.extensions.ClassFileFactoryFinalizerExtension;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.config.JvmAnalysisFlags; import org.jetbrains.kotlin.config.JvmAnalysisFlags;
import org.jetbrains.kotlin.load.kotlin.ModuleMappingUtilKt; import org.jetbrains.kotlin.load.kotlin.ModuleMappingUtilKt;
@@ -50,6 +51,7 @@ import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.getMappingFileName;
public class ClassFileFactory implements OutputFileCollection { public class ClassFileFactory implements OutputFileCollection {
private final GenerationState state; private final GenerationState state;
private final ClassBuilderFactory builderFactory; private final ClassBuilderFactory builderFactory;
private final List<ClassFileFactoryFinalizerExtension> finalizers;
private final Map<String, OutAndSourceFileList> generators = Collections.synchronizedMap(new LinkedHashMap<>()); private final Map<String, OutAndSourceFileList> generators = Collections.synchronizedMap(new LinkedHashMap<>());
private boolean isDone = false; private boolean isDone = false;
@@ -57,9 +59,10 @@ public class ClassFileFactory implements OutputFileCollection {
private final Set<File> sourceFiles = new HashSet<>(); private final Set<File> sourceFiles = new HashSet<>();
private final PackagePartRegistry packagePartRegistry = new PackagePartRegistry(); private final PackagePartRegistry packagePartRegistry = new PackagePartRegistry();
public ClassFileFactory(@NotNull GenerationState state, @NotNull ClassBuilderFactory builderFactory) { public ClassFileFactory(@NotNull GenerationState state, @NotNull ClassBuilderFactory builderFactory, @NotNull List<ClassFileFactoryFinalizerExtension> finalizers) {
this.state = state; this.state = state;
this.builderFactory = builderFactory; this.builderFactory = builderFactory;
this.finalizers = finalizers;
} }
public GenerationState getGenerationState() { public GenerationState getGenerationState() {
@@ -111,6 +114,9 @@ public class ClassFileFactory implements OutputFileCollection {
if (!isDone) { if (!isDone) {
isDone = true; isDone = true;
writeModuleMappings(); writeModuleMappings();
for (ClassFileFactoryFinalizerExtension extension : finalizers) {
extension.finalizeClassFactory(this);
}
} }
} }
@@ -0,0 +1,20 @@
/*
* 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.codegen.extensions
import org.jetbrains.kotlin.codegen.ClassFileFactory
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
/**
* Extension point which is called after the compiler outputs have been finalized,
* which allows inspecting all output files, except for jar manifests.
*/
interface ClassFileFactoryFinalizerExtension {
companion object : ProjectExtensionDescriptor<ClassFileFactoryFinalizerExtension>(
"org.jetbrains.kotlin.classFileFactoryFinalizerExtension", ClassFileFactoryFinalizerExtension::class.java)
fun finalizeClassFactory(factory: ClassFileFactory)
}
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.context.CodegenContext import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.context.RootContext import org.jetbrains.kotlin.codegen.context.RootContext
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
import org.jetbrains.kotlin.codegen.extensions.ClassFileFactoryFinalizerExtension
import org.jetbrains.kotlin.codegen.inline.GlobalInlineContext import org.jetbrains.kotlin.codegen.inline.GlobalInlineContext
import org.jetbrains.kotlin.codegen.inline.InlineCache import org.jetbrains.kotlin.codegen.inline.InlineCache
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
@@ -369,7 +370,8 @@ class GenerationState private constructor(
extension.interceptClassBuilderFactory(classBuilderFactory, originalFrontendBindingContext, diagnostics) extension.interceptClassBuilderFactory(classBuilderFactory, originalFrontendBindingContext, diagnostics)
} }
this.factory = ClassFileFactory(this, interceptedBuilderFactory) val finalizers = ClassFileFactoryFinalizerExtension.getInstances(project)
this.factory = ClassFileFactory(this, interceptedBuilderFactory, finalizers)
} }
fun beforeCompile() { fun beforeCompile() {
@@ -76,6 +76,7 @@ import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
import org.jetbrains.kotlin.codegen.extensions.ClassFileFactoryFinalizerExtension
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.*
@@ -641,6 +642,7 @@ class KotlinCoreEnvironment private constructor(
SyntheticResolveExtension.registerExtensionPoint(project) SyntheticResolveExtension.registerExtensionPoint(project)
SyntheticJavaResolveExtension.registerExtensionPoint(project) SyntheticJavaResolveExtension.registerExtensionPoint(project)
ClassBuilderInterceptorExtension.registerExtensionPoint(project) ClassBuilderInterceptorExtension.registerExtensionPoint(project)
ClassFileFactoryFinalizerExtension.registerExtensionPoint(project)
AnalysisHandlerExtension.registerExtensionPoint(project) AnalysisHandlerExtension.registerExtensionPoint(project)
PackageFragmentProviderExtension.registerExtensionPoint(project) PackageFragmentProviderExtension.registerExtensionPoint(project)
StorageComponentContainerContributor.registerExtensionPoint(project) StorageComponentContainerContributor.registerExtensionPoint(project)