Extract shouldWritePreReleaseFlag(), use in JS as well as JVM

Fix the difference in behavior between JS and JVM
This commit is contained in:
Alexander Udalov
2017-10-12 18:29:12 +02:00
parent 0510c553c3
commit 8b0b334601
6 changed files with 47 additions and 23 deletions
@@ -17,8 +17,7 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.KotlinCompilerVersion
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.shouldWritePreReleaseFlag
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
@@ -37,9 +36,7 @@ fun writeKotlinMetadata(
av.visit(JvmAnnotationNames.BYTECODE_VERSION_FIELD_NAME, JvmBytecodeBinaryVersion.INSTANCE.toArray())
av.visit(JvmAnnotationNames.KIND_FIELD_NAME, kind.id)
var flags = extraFlags
val languageVersion = state.languageVersionSettings.languageVersion
if (KotlinCompilerVersion.isPreRelease() && languageVersion == LanguageVersion.LATEST_STABLE ||
!languageVersion.isStable) {
if (state.languageVersionSettings.shouldWritePreReleaseFlag()) {
flags = flags or JvmAnnotationNames.METADATA_PRE_RELEASE_FLAG
}
if (flags != 0) {
@@ -53,4 +50,4 @@ fun writeSyntheticClassMetadata(cb: ClassBuilder, state: GenerationState) {
writeKotlinMetadata(cb, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, 0) { _ ->
// Do nothing
}
}
}
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.addKotlinSourceRoots
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
@@ -78,7 +79,9 @@ class KotlinJavascriptSerializerTest : TestCaseWithTmpdir() {
imported = listOf(),
data = analysisResult.moduleDescriptor
)
FileUtil.writeToFile(metaFile, KotlinJavascriptSerializationUtil.metadataAsString(analysisResult.bindingContext, description))
FileUtil.writeToFile(metaFile, KotlinJavascriptSerializationUtil.metadataAsString(
analysisResult.bindingContext, description, configuration.languageVersionSettings
))
}
finally {
Disposer.dispose(rootDisposable)
@@ -184,3 +184,9 @@ class LanguageVersionSettingsImpl @JvmOverloads constructor(
val DEFAULT = LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE)
}
}
fun LanguageVersionSettings.shouldWritePreReleaseFlag(): Boolean {
if (!languageVersion.isStable) return true
return KotlinCompilerVersion.isPreRelease() && languageVersion == LanguageVersion.LATEST_STABLE
}
@@ -16,7 +16,8 @@
package org.jetbrains.kotlin.serialization.js
import org.jetbrains.kotlin.config.KotlinCompilerVersion
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.shouldWritePreReleaseFlag
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.name.FqName
@@ -116,10 +117,16 @@ object KotlinJavascriptSerializationUtil {
return builder.build()
}
fun metadataAsString(bindingContext: BindingContext, jsDescriptor: JsModuleDescriptor<ModuleDescriptor>): String =
KotlinJavascriptMetadataUtils.formatMetadataAsString(jsDescriptor.name, jsDescriptor.serializeToBinaryMetadata(bindingContext))
fun metadataAsString(
bindingContext: BindingContext,
jsDescriptor: JsModuleDescriptor<ModuleDescriptor>,
languageVersionSettings: LanguageVersionSettings
): String = KotlinJavascriptMetadataUtils.formatMetadataAsString(
jsDescriptor.name,
jsDescriptor.serializeToBinaryMetadata(bindingContext, languageVersionSettings)
)
fun serializePackageFragment(bindingContext: BindingContext, module: ModuleDescriptor, fqName: FqName): ProtoBuf.PackageFragment {
private fun serializePackageFragment(bindingContext: BindingContext, module: ModuleDescriptor, fqName: FqName): ProtoBuf.PackageFragment {
val packageView = module.getPackage(fqName)
return serializeDescriptors(bindingContext, module, packageView.memberScope.getContributedDescriptors(), fqName)
}
@@ -200,7 +207,11 @@ object KotlinJavascriptSerializationUtil {
return filesProto.build()
}
fun toContentMap(bindingContext: BindingContext, module: ModuleDescriptor): Map<String, ByteArray> {
fun toContentMap(
bindingContext: BindingContext,
module: ModuleDescriptor,
languageVersionSettings: LanguageVersionSettings
): Map<String, ByteArray> {
val contentMap = hashMapOf<String, ByteArray>()
for (fqName in getPackagesFqNames(module)) {
@@ -216,7 +227,7 @@ object KotlinJavascriptSerializationUtil {
version.forEach(this::writeInt)
}
serializeHeader(fqName).writeDelimitedTo(stream)
serializeHeader(fqName, languageVersionSettings).writeDelimitedTo(stream)
part.writeTo(stream)
contentMap[JsSerializerProtocol.getKjsmFilePath(fqName)] = stream.toByteArray()
@@ -225,14 +236,14 @@ object KotlinJavascriptSerializationUtil {
return contentMap
}
fun serializeHeader(packageFqName: FqName?): JsProtoBuf.Header {
fun serializeHeader(packageFqName: FqName?, languageVersionSettings: LanguageVersionSettings): JsProtoBuf.Header {
val header = JsProtoBuf.Header.newBuilder()
if (packageFqName != null) {
header.packageFqName = packageFqName.asString()
}
if (KotlinCompilerVersion.isPreRelease()) {
if (languageVersionSettings.shouldWritePreReleaseFlag()) {
header.flags = 1
}
@@ -261,10 +272,13 @@ object KotlinJavascriptSerializationUtil {
}
}
private fun JsModuleDescriptor<ModuleDescriptor>.serializeToBinaryMetadata(bindingContext: BindingContext): ByteArray {
private fun JsModuleDescriptor<ModuleDescriptor>.serializeToBinaryMetadata(
bindingContext: BindingContext,
languageVersionSettings: LanguageVersionSettings
): ByteArray {
return ByteArrayOutputStream().apply {
GZIPOutputStream(this).use { stream ->
serializeHeader(null).writeDelimitedTo(stream)
serializeHeader(null, languageVersionSettings).writeDelimitedTo(stream)
serializeMetadata(bindingContext, data, kind, imported).writeTo(stream)
}
}.toByteArray()
@@ -19,8 +19,11 @@ package org.jetbrains.kotlin.js.facade;
import com.intellij.openapi.vfs.VfsUtilCore;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.config.CommonConfigurationKeysKt;
import org.jetbrains.kotlin.config.LanguageVersionSettings;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer;
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS;
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult;
import org.jetbrains.kotlin.js.backend.ast.JsImportedModule;
@@ -29,7 +32,6 @@ import org.jetbrains.kotlin.js.config.JSConfigurationKeys;
import org.jetbrains.kotlin.js.config.JsConfig;
import org.jetbrains.kotlin.js.coroutine.CoroutineTransformer;
import org.jetbrains.kotlin.js.facade.exceptions.TranslationException;
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer;
import org.jetbrains.kotlin.js.inline.JsInliner;
import org.jetbrains.kotlin.js.inline.clean.LabeledBlockToDoWhileTransformation;
import org.jetbrains.kotlin.js.inline.clean.RemoveDuplicateImportsKt;
@@ -52,7 +54,6 @@ import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static org.jetbrains.kotlin.diagnostics.DiagnosticUtils.hasError;
@@ -182,7 +183,8 @@ public final class K2JSTranslator {
incrementalResults.processPackagePart(ioFile, packagePart.toByteArray(), binaryAst);
}
incrementalResults.processHeader(serializationUtil.serializeHeader(null).toByteArray());
LanguageVersionSettings settings = CommonConfigurationKeysKt.getLanguageVersionSettings(config.getConfiguration());
incrementalResults.processHeader(serializationUtil.serializeHeader(null, settings).toByteArray());
}
RemoveDuplicateImportsKt.removeDuplicateImports(translationResult.getProgram());
@@ -19,16 +19,17 @@ package org.jetbrains.kotlin.js.facade
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VfsUtilCore
import org.jetbrains.kotlin.backend.common.output.*
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.js.backend.JsToStringGenerationVisitor
import org.jetbrains.kotlin.js.backend.NoOpSourceLocationConsumer
import org.jetbrains.kotlin.js.backend.SourceLocationConsumer
import org.jetbrains.kotlin.js.backend.ast.JsProgram
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.config.JsConfig
import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding
import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver
import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder
import org.jetbrains.kotlin.js.backend.SourceLocationConsumer
import org.jetbrains.kotlin.js.util.TextOutput
import org.jetbrains.kotlin.js.util.TextOutputImpl
import org.jetbrains.kotlin.psi.KtFile
@@ -105,12 +106,13 @@ abstract class TranslationResult protected constructor(val diagnostics: Diagnost
kind = config.moduleKind,
imported = importedModules
)
val metaFileContent = KotlinJavascriptSerializationUtil.metadataAsString(bindingContext, moduleDescription)
val settings = config.configuration.languageVersionSettings
val metaFileContent = KotlinJavascriptSerializationUtil.metadataAsString(bindingContext, moduleDescription, settings)
val sourceFilesForMetaFile = ArrayList(sourceFiles)
val jsMetaFile = SimpleOutputFile(sourceFilesForMetaFile, metaFileName, metaFileContent)
outputFiles.add(jsMetaFile)
KotlinJavascriptSerializationUtil.toContentMap(bindingContext, moduleDescriptor).forEach {
KotlinJavascriptSerializationUtil.toContentMap(bindingContext, moduleDescriptor, settings).forEach {
// TODO Add correct source files
outputFiles.add(SimpleOutputBinaryFile(emptyList(), config.moduleId + VfsUtilCore.VFS_SEPARATOR_CHAR + it.key, it.value))
}