Pass CompilerConfiguration to GenerationState instead of ton of parameters

This commit is contained in:
Alexander Udalov
2016-05-20 12:07:35 +03:00
parent 1492c71e88
commit f8816b5d67
13 changed files with 96 additions and 129 deletions
@@ -29,6 +29,8 @@ import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
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
import org.jetbrains.kotlin.codegen.optimization.OptimizationClassBuilderFactory import org.jetbrains.kotlin.codegen.optimization.OptimizationClassBuilderFactory
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.ScriptDescriptor import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
@@ -51,13 +53,8 @@ class GenerationState @JvmOverloads constructor(
val module: ModuleDescriptor, val module: ModuleDescriptor,
bindingContext: BindingContext, bindingContext: BindingContext,
val files: List<KtFile>, val files: List<KtFile>,
disableCallAssertions: Boolean = true, val configuration: CompilerConfiguration,
disableParamAssertions: Boolean = true,
val generateDeclaredClassFilter: GenerateClassFilter = GenerationState.GenerateClassFilter.GENERATE_ALL, val generateDeclaredClassFilter: GenerateClassFilter = GenerationState.GenerateClassFilter.GENERATE_ALL,
disableInline: Boolean = false,
disableOptimization: Boolean = false,
val useTypeTableInSerializer: Boolean = false,
val inheritMultifileParts: Boolean = false,
val packagesWithObsoleteParts: Collection<FqName> = emptySet(), val packagesWithObsoleteParts: Collection<FqName> = emptySet(),
val obsoleteMultifileClasses: Collection<FqName> = emptySet(), val obsoleteMultifileClasses: Collection<FqName> = emptySet(),
// for PackageCodegen in incremental compilation mode // for PackageCodegen in incremental compilation mode
@@ -136,22 +133,18 @@ class GenerationState @JvmOverloads constructor(
var hasResult: Boolean = false var hasResult: Boolean = false
} }
val isCallAssertionsEnabled: Boolean = !disableCallAssertions val isCallAssertionsEnabled: Boolean = !configuration.get(JVMConfigurationKeys.DISABLE_CALL_ASSERTIONS, false)
@JvmName("isCallAssertionsEnabled") get val isParamAssertionsEnabled: Boolean = !configuration.get(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS, false)
val isInlineEnabled: Boolean = !configuration.get(JVMConfigurationKeys.DISABLE_INLINE, false)
val isParamAssertionsEnabled: Boolean = !disableParamAssertions val useTypeTableInSerializer: Boolean = configuration.get(JVMConfigurationKeys.USE_TYPE_TABLE, false)
@JvmName("isParamAssertionsEnabled") get val inheritMultifileParts: Boolean = configuration.get(JVMConfigurationKeys.INHERIT_MULTIFILE_PARTS, false)
val isInlineEnabled: Boolean = !disableInline
@JvmName("isInlineEnabled") get
val rootContext: CodegenContext<*> = RootContext(this) val rootContext: CodegenContext<*> = RootContext(this)
init { init {
this.interceptedBuilderFactory = builderFactory this.interceptedBuilderFactory = builderFactory
.wrapWith( .wrapWith(
{ OptimizationClassBuilderFactory(it, disableOptimization) }, { OptimizationClassBuilderFactory(it, configuration.get(JVMConfigurationKeys.DISABLE_OPTIMIZATION, false)) },
{ BuilderFactoryForDuplicateSignatureDiagnostics( { BuilderFactoryForDuplicateSignatureDiagnostics(
it, this.bindingContext, diagnostics, fileClassesProvider, it, this.bindingContext, diagnostics, fileClassesProvider,
getIncrementalCacheForThisTarget(), getIncrementalCacheForThisTarget(),
@@ -397,13 +397,8 @@ object KotlinToJVMBytecodeCompiler {
result.moduleDescriptor, result.moduleDescriptor,
result.bindingContext, result.bindingContext,
sourceFiles, sourceFiles,
configuration.get(JVMConfigurationKeys.DISABLE_CALL_ASSERTIONS, false), configuration,
configuration.get(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS, false),
GenerationState.GenerateClassFilter.GENERATE_ALL, GenerationState.GenerateClassFilter.GENERATE_ALL,
configuration.get(JVMConfigurationKeys.DISABLE_INLINE, false),
configuration.get(JVMConfigurationKeys.DISABLE_OPTIMIZATION, false),
/* useTypeTableInSerializer = */ false,
configuration.get(JVMConfigurationKeys.INHERIT_MULTIFILE_PARTS, false),
packagesWithObsoleteParts, packagesWithObsoleteParts,
obsoleteMultifileClasses, obsoleteMultifileClasses,
targetId, targetId,
@@ -411,7 +406,8 @@ object KotlinToJVMBytecodeCompiler {
outputDirectory, outputDirectory,
incrementalCompilationComponents, incrementalCompilationComponents,
onIndependentPartCompilationEnd = onIndependentPartCompilationEnd, onIndependentPartCompilationEnd = onIndependentPartCompilationEnd,
dumpBinarySignatureMappingTo = configuration.get(JVMConfigurationKeys.DECLARATIONS_JSON_PATH)?.let { File(it) }) dumpBinarySignatureMappingTo = configuration.get(JVMConfigurationKeys.DECLARATIONS_JSON_PATH)?.let { File(it) }
)
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val generationStart = PerformanceCounter.currentTime() val generationStart = PerformanceCounter.currentTime()
@@ -70,7 +70,7 @@ import java.net.URLClassLoader
class ReplInterpreter( class ReplInterpreter(
disposable: Disposable, disposable: Disposable,
configuration: CompilerConfiguration, private val configuration: CompilerConfiguration,
private val ideMode: Boolean, private val ideMode: Boolean,
private val replReader: ReplSystemInWrapper? private val replReader: ReplSystemInWrapper?
) { ) {
@@ -239,7 +239,9 @@ class ReplInterpreter(
val scriptDescriptor = doAnalyze(psiFile, errorHolder) val scriptDescriptor = doAnalyze(psiFile, errorHolder)
?: return LineResult.compileError(errorHolder.renderedDiagnostics) ?: return LineResult.compileError(errorHolder.renderedDiagnostics)
val state = GenerationState(psiFile.project, ClassBuilderFactories.BINARIES, module, trace.bindingContext, listOf(psiFile)) val state = GenerationState(
psiFile.project, ClassBuilderFactories.BINARIES, module, trace.bindingContext, listOf(psiFile), configuration
)
compileScript(psiFile.script!!, earlierLines.map(EarlierLine::getScriptDescriptor), state, CompilationErrorHandler.THROW_EXCEPTION) compileScript(psiFile.script!!, earlierLines.map(EarlierLine::getScriptDescriptor), state, CompilationErrorHandler.THROW_EXCEPTION)
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.asJava package org.jetbrains.kotlin.asJava
import com.google.common.collect.Lists
import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProcessCanceledException
@@ -40,6 +39,7 @@ import com.intellij.util.containers.Stack
import org.jetbrains.kotlin.codegen.CompilationErrorHandler import org.jetbrains.kotlin.codegen.CompilationErrorHandler
import org.jetbrains.kotlin.codegen.binding.CodegenBinding import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
import org.jetbrains.kotlin.fileClasses.getFileClassType import org.jetbrains.kotlin.fileClasses.getFileClassType
@@ -97,13 +97,10 @@ abstract class LightClassDataProvider<T : WithFileStubAndExtraDiagnostics>(
KotlinLightClassBuilderFactory(stubStack), KotlinLightClassBuilderFactory(stubStack),
context.module, context.module,
context.bindingContext, context.bindingContext,
Lists.newArrayList(files), files.toMutableList(),
disableCallAssertions = false, CompilerConfiguration.EMPTY,
disableParamAssertions = false, generateClassFilter
generateDeclaredClassFilter = generateClassFilter, )
disableInline = false,
disableOptimization = false,
useTypeTableInSerializer = false)
state.beforeCompile() state.beforeCompile()
bindingContext = state.bindingContext bindingContext = state.bindingContext
@@ -16,9 +16,11 @@
package org.jetbrains.kotlin.codegen package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.ConfigurationKind
@@ -33,7 +35,6 @@ abstract class AbstractDumpDeclarationsTest : CodegenTestCase() {
compileAndCompareDump(files, expectedResult) compileAndCompareDump(files, expectedResult)
} }
private fun compileAndCompareDump(files: List<TestFile>, expectedResult: File) { private fun compileAndCompareDump(files: List<TestFile>, expectedResult: File) {
configurationKind = ConfigurationKind.NO_KOTLIN_REFLECT configurationKind = ConfigurationKind.NO_KOTLIN_REFLECT
@@ -50,19 +51,15 @@ abstract class AbstractDumpDeclarationsTest : CodegenTestCase() {
} }
private fun compileManyFilesGetDeclarationsDump(files: List<KtFile>): File { private fun compileManyFilesGetDeclarationsDump(files: List<KtFile>): File {
val analysisResult = JvmResolveUtil.analyzeAndCheckForErrors(files, myEnvironment) val (bindingContext, moduleDescriptor) =
JvmResolveUtil.analyzeAndCheckForErrors(files, myEnvironment).apply(AnalysisResult::throwIfError)
analysisResult.throwIfError()
val dumpToFile = KotlinTestUtils.tmpDirForTest(this).resolve(this.name + ".json") val dumpToFile = KotlinTestUtils.tmpDirForTest(this).resolve(this.name + ".json")
val state = GenerationState( val state = GenerationState(
myEnvironment.project, ClassBuilderFactories.TEST, myEnvironment.project, ClassBuilderFactories.TEST, moduleDescriptor, bindingContext, files, CompilerConfiguration.EMPTY,
analysisResult.moduleDescriptor, analysisResult.bindingContext, dumpBinarySignatureMappingTo = dumpToFile
files, )
disableCallAssertions = false,
disableParamAssertions = false,
dumpBinarySignatureMappingTo = dumpToFile)
KotlinCodegenFacade.compileCorrectFiles(state, org.jetbrains.kotlin.codegen.CompilationErrorHandler.THROW_EXCEPTION) KotlinCodegenFacade.compileCorrectFiles(state, org.jetbrains.kotlin.codegen.CompilationErrorHandler.THROW_EXCEPTION)
state.destroy() state.destroy()
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime; import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.config.CompilerConfiguration; import org.jetbrains.kotlin.config.CompilerConfiguration;
import org.jetbrains.kotlin.config.JVMConfigurationKeys;
import org.jetbrains.kotlin.resolve.AnalyzingUtils; import org.jetbrains.kotlin.resolve.AnalyzingUtils;
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil; import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil;
import org.jetbrains.kotlin.test.KotlinTestUtils; import org.jetbrains.kotlin.test.KotlinTestUtils;
@@ -57,13 +56,7 @@ public class CodegenTestUtil {
analysisResult.getModuleDescriptor(), analysisResult.getModuleDescriptor(),
analysisResult.getBindingContext(), analysisResult.getBindingContext(),
files.getPsiFiles(), files.getPsiFiles(),
configuration.get(JVMConfigurationKeys.DISABLE_CALL_ASSERTIONS, false), configuration
configuration.get(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS, false),
GenerationState.GenerateClassFilter.GENERATE_ALL,
configuration.get(JVMConfigurationKeys.DISABLE_INLINE, false),
configuration.get(JVMConfigurationKeys.DISABLE_OPTIMIZATION, false),
/* useTypeTableInSerializer = */ false,
configuration.get(JVMConfigurationKeys.INHERIT_MULTIFILE_PARTS, false)
); );
if (analysisResult.getShouldGenerateCode()) { if (analysisResult.getShouldGenerateCode()) {
@@ -66,13 +66,8 @@ public class GenerationUtils {
CollectionsKt.first(files).getProject(), ClassBuilderFactories.TEST, CollectionsKt.first(files).getProject(), ClassBuilderFactories.TEST,
analysisResult.getModuleDescriptor(), analysisResult.getBindingContext(), analysisResult.getModuleDescriptor(), analysisResult.getBindingContext(),
files, files,
configuration.get(JVMConfigurationKeys.DISABLE_CALL_ASSERTIONS, false), configuration,
configuration.get(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS, false),
GenerationState.GenerateClassFilter.GENERATE_ALL, GenerationState.GenerateClassFilter.GENERATE_ALL,
configuration.get(JVMConfigurationKeys.DISABLE_INLINE, false),
configuration.get(JVMConfigurationKeys.DISABLE_OPTIMIZATION, false),
configuration.get(JVMConfigurationKeys.USE_TYPE_TABLE, false),
configuration.get(JVMConfigurationKeys.INHERIT_MULTIFILE_PARTS, false),
Collections.<FqName>emptySet(), Collections.<FqName>emptySet(),
Collections.<FqName>emptySet(), Collections.<FqName>emptySet(),
null, null,
@@ -30,9 +30,11 @@ import com.intellij.util.containers.MultiMap
import org.apache.log4j.Logger import org.apache.log4j.Logger
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.eval4j.Value import org.jetbrains.eval4j.Value
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.codegen.ClassBuilderFactories import org.jetbrains.kotlin.codegen.ClassBuilderFactories
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
@@ -152,38 +154,30 @@ class KotlinDebuggerCaches(project: Project) {
} }
} }
private fun createTypeMapperForLibraryFile(element: KtElement, file: KtFile): KotlinTypeMapper {
return runReadAction {
val analysisResult = element.analyzeAndGetResult()
val state = GenerationState(
file.project,
ClassBuilderFactories.THROW_EXCEPTION,
analysisResult.moduleDescriptor,
analysisResult.bindingContext,
listOf(file))
state.beforeCompile()
state.typeMapper
}
}
private fun getElementToCreateTypeMapperForLibraryFile(element: PsiElement?) = private fun getElementToCreateTypeMapperForLibraryFile(element: PsiElement?) =
runReadAction { if (element is KtElement) element else PsiTreeUtil.getParentOfType(element, KtElement::class.java)!! } runReadAction { if (element is KtElement) element else PsiTreeUtil.getParentOfType(element, KtElement::class.java)!! }
private fun createTypeMapperForSourceFile(file: KtFile): KotlinTypeMapper { private fun createTypeMapperForLibraryFile(element: KtElement, file: KtFile): KotlinTypeMapper =
return runReadAction { runReadAction {
val analysisResult = file.analyzeFullyAndGetResult() createTypeMapper(file, element.analyzeAndGetResult())
analysisResult.throwIfError() }
val state = GenerationState( private fun createTypeMapperForSourceFile(file: KtFile): KotlinTypeMapper =
file.project, runReadAction {
ClassBuilderFactories.THROW_EXCEPTION, createTypeMapper(file, file.analyzeFullyAndGetResult().apply(AnalysisResult::throwIfError))
analysisResult.moduleDescriptor, }
analysisResult.bindingContext,
listOf(file)) private fun createTypeMapper(file: KtFile, analysisResult: AnalysisResult): KotlinTypeMapper {
state.beforeCompile() val state = GenerationState(
state.typeMapper file.project,
} ClassBuilderFactories.THROW_EXCEPTION,
analysisResult.moduleDescriptor,
analysisResult.bindingContext,
listOf(file),
CompilerConfiguration.EMPTY
)
state.beforeCompile()
return state.typeMapper
} }
@TestOnly fun addTypeMapper(file: KtFile, typeMapper: KotlinTypeMapper) { @TestOnly fun addTypeMapper(file: KtFile, typeMapper: KotlinTypeMapper) {
@@ -48,6 +48,7 @@ import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.binding.CodegenBinding import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.diagnostics.Severity import org.jetbrains.kotlin.diagnostics.Severity
@@ -394,7 +395,9 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour
moduleDescriptor, moduleDescriptor,
bindingContext, bindingContext,
files, files,
generateDeclaredClassFilter = generateClassFilter) CompilerConfiguration.EMPTY,
generateClassFilter
)
val frameVisitor = FrameVisitor(context) val frameVisitor = FrameVisitor(context)
@@ -41,6 +41,8 @@ import org.jetbrains.kotlin.codegen.ClassBuilderFactories;
import org.jetbrains.kotlin.codegen.CompilationErrorHandler; import org.jetbrains.kotlin.codegen.CompilationErrorHandler;
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade; import org.jetbrains.kotlin.codegen.KotlinCodegenFacade;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.config.CompilerConfiguration;
import org.jetbrains.kotlin.config.JVMConfigurationKeys;
import org.jetbrains.kotlin.diagnostics.Diagnostic; import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages; import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages;
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils; import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils;
@@ -73,7 +75,7 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
"No Kotlin source file is opened.\n" + "No Kotlin source file is opened.\n" +
"*/"; "*/";
public class UpdateBytecodeToolWindowTask extends LongRunningReadTask<Location, String> { private class UpdateBytecodeToolWindowTask extends LongRunningReadTask<Location, String> {
@Override @Override
protected Location prepareRequestInfo() { protected Location prepareRequestInfo() {
if (!toolWindow.isVisible()) { if (!toolWindow.isVisible()) {
@@ -109,10 +111,22 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
@NotNull @NotNull
@Override @Override
protected String processRequest(@NotNull Location location) { protected String processRequest(@NotNull Location location) {
KtFile jetFile = location.getKFile(); KtFile ktFile = location.getKFile();
assert jetFile != null; assert ktFile != null;
return getBytecodeForFile(jetFile, enableInline.isSelected(), enableAssertions.isSelected(), enableOptimization.isSelected()); CompilerConfiguration configuration = new CompilerConfiguration();
if (!enableInline.isSelected()) {
configuration.put(JVMConfigurationKeys.DISABLE_INLINE, true);
}
if (!enableAssertions.isSelected()) {
configuration.put(JVMConfigurationKeys.DISABLE_CALL_ASSERTIONS, true);
configuration.put(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS, true);
}
if (!enableOptimization.isSelected()) {
configuration.put(JVMConfigurationKeys.DISABLE_OPTIMIZATION, true);
}
return getBytecodeForFile(ktFile, configuration);
} }
@Override @Override
@@ -161,7 +175,7 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
private final JCheckBox enableAssertions; private final JCheckBox enableAssertions;
private final JButton decompile; private final JButton decompile;
public KotlinBytecodeToolWindow(final Project project, ToolWindow toolWindow) { public KotlinBytecodeToolWindow(Project project, ToolWindow toolWindow) {
super(new BorderLayout()); super(new BorderLayout());
myProject = project; myProject = project;
this.toolWindow = toolWindow; this.toolWindow = toolWindow;
@@ -214,15 +228,10 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
// public for tests // public for tests
@NotNull @NotNull
public static String getBytecodeForFile( public static String getBytecodeForFile(@NotNull KtFile ktFile, @NotNull CompilerConfiguration configuration) {
final KtFile jetFile,
boolean enableInline,
boolean enableAssertions,
boolean enableOptimization
) {
GenerationState state; GenerationState state;
try { try {
state = compileSingleFile(jetFile, enableInline, enableAssertions, enableOptimization); state = compileSingleFile(ktFile, configuration);
} }
catch (ProcessCanceledException e) { catch (ProcessCanceledException e) {
throw e; throw e;
@@ -260,25 +269,19 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
} }
@NotNull @NotNull
public static GenerationState compileSingleFile( public static GenerationState compileSingleFile(@NotNull final KtFile ktFile, @NotNull CompilerConfiguration configuration) {
final KtFile ktFile,
boolean enableInline,
boolean enableAssertions,
boolean enableOptimization
) {
ResolutionFacade resolutionFacade = ResolutionUtils.getResolutionFacade(ktFile); ResolutionFacade resolutionFacade = ResolutionUtils.getResolutionFacade(ktFile);
BindingContext bindingContextForFile = resolutionFacade.analyzeFullyAndGetResult(Collections.singletonList(ktFile)).getBindingContext(); BindingContext bindingContextForFile = resolutionFacade.analyzeFullyAndGetResult(Collections.singletonList(ktFile)).getBindingContext();
kotlin.Pair<BindingContext, List<KtFile>> result = DebuggerUtils.INSTANCE.analyzeInlinedFunctions( kotlin.Pair<BindingContext, List<KtFile>> result = DebuggerUtils.INSTANCE.analyzeInlinedFunctions(
resolutionFacade, bindingContextForFile, ktFile, !enableInline resolutionFacade, bindingContextForFile, ktFile, configuration.get(JVMConfigurationKeys.DISABLE_INLINE, false)
); );
BindingContext bindingContext = result.getFirst(); BindingContext bindingContext = result.getFirst();
List<KtFile> toProcess = result.getSecond(); List<KtFile> toProcess = result.getSecond();
GenerationState.GenerateClassFilter generateClassFilter = new GenerationState.GenerateClassFilter() { GenerationState.GenerateClassFilter generateClassFilter = new GenerationState.GenerateClassFilter() {
@Override @Override
public boolean shouldGeneratePackagePart(@NotNull KtFile file) { public boolean shouldGeneratePackagePart(@NotNull KtFile file) {
return file == ktFile; return file == ktFile;
@@ -300,15 +303,10 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
} }
}; };
GenerationState state = new GenerationState(ktFile.getProject(), ClassBuilderFactories.TEST, GenerationState state = new GenerationState(
resolutionFacade.getModuleDescriptor(), bindingContext, ktFile.getProject(), ClassBuilderFactories.TEST, resolutionFacade.getModuleDescriptor(), bindingContext, toProcess,
toProcess, configuration, generateClassFilter
!enableAssertions, );
!enableAssertions,
generateClassFilter,
!enableInline,
!enableOptimization,
/*useTypeTableInSerializer=*/false);
KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION); KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION);
return state; return state;
} }
@@ -25,6 +25,7 @@ import org.jetbrains.java.decompiler.main.decompiler.BaseDecompiler
import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences
import org.jetbrains.java.decompiler.main.extern.IResultSaver import org.jetbrains.java.decompiler.main.extern.IResultSaver
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.idea.actions.canBeDecompiledToJava import org.jetbrains.kotlin.idea.actions.canBeDecompiledToJava
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import java.io.File import java.io.File
@@ -71,7 +72,7 @@ class KotlinDecompilerServiceImpl : KotlinDecompilerService {
} }
fun bytecodeMapForSourceFile(file: KtFile): Map<File, () -> ByteArray> { fun bytecodeMapForSourceFile(file: KtFile): Map<File, () -> ByteArray> {
val generationState = KotlinBytecodeToolWindow.compileSingleFile(file, true, true, true) val generationState = KotlinBytecodeToolWindow.compileSingleFile(file, CompilerConfiguration.EMPTY)
val bytecodeMap = hashMapOf<File, () -> ByteArray>() val bytecodeMap = hashMapOf<File, () -> ByteArray>()
generationState.factory.asList().filter { FileUtilRt.extensionEquals(it.relativePath, "class") }.forEach { generationState.factory.asList().filter { FileUtilRt.extensionEquals(it.relativePath, "class") }.forEach {
@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.idea.internal package org.jetbrains.kotlin.idea.internal
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
@@ -38,11 +40,13 @@ abstract class AbstractBytecodeToolWindowTest: KotlinLightCodeInsightFixtureTest
val file = myFixture.file as KtFile val file = myFixture.file as KtFile
val enableInline = InTextDirectivesUtils.getPrefixedBoolean(mainFileText, "// INLINE:") ?: true val configuration = CompilerConfiguration()
val bytecodes = KotlinBytecodeToolWindow.getBytecodeForFile(file, enableInline, true, true) if (InTextDirectivesUtils.getPrefixedBoolean(mainFileText, "// INLINE:") == false) {
configuration.put(JVMConfigurationKeys.DISABLE_INLINE, true)
}
val bytecodes = KotlinBytecodeToolWindow.getBytecodeForFile(file, configuration)
assert(bytecodes.contains("// ================")) { assert(bytecodes.contains("// ================")) {
"The header \"// ================\" is missing.\n This means that there is an exception failed during compilation:\n$bytecodes" "The header \"// ================\" is missing.\n This means that there is an exception failed during compilation:\n$bytecodes"
} }
} }
} }
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAll import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAll
import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
@@ -31,21 +32,14 @@ import org.jetbrains.org.objectweb.asm.ClassWriter
import java.io.File import java.io.File
class StubProducerExtension(val stubsOutputDir: File, val messageCollector: MessageCollector) : AnalysisCompletedHandlerExtension { class StubProducerExtension(val stubsOutputDir: File, val messageCollector: MessageCollector) : AnalysisCompletedHandlerExtension {
override fun analysisCompleted( override fun analysisCompleted(
project: Project, project: Project,
module: ModuleDescriptor, module: ModuleDescriptor,
bindingContext: BindingContext, bindingContext: BindingContext,
files: Collection<KtFile> files: Collection<KtFile>
): AnalysisResult? { ): AnalysisResult? {
val generationState = GenerationState( val generationState =
project, GenerationState(project, StubClassBuilderFactory(), module, bindingContext, files.toList(), CompilerConfiguration.EMPTY)
StubClassBuilderFactory(),
module,
bindingContext,
files.toList(),
disableCallAssertions = false,
disableParamAssertions = false)
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION) KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)
@@ -74,4 +68,4 @@ private class StubClassBuilderFactory : ClassBuilderFactory {
override fun close() { override fun close() {
} }
} }