From 25c1828288560ca1a15dfc917e345b8f7fab4d98 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 7 Feb 2017 12:04:52 +0300 Subject: [PATCH] JS: write and load pre-release flag on binaries --- .../jvm/platform/JvmPlatformConfigurator.kt | 2 - .../kotlin/resolve/TargetPlatform.kt | 6 +- .../library/a.kt | 9 +++ .../output.txt | 41 ++++++++++ .../source.kt | 15 ++++ ...ompileKotlinAgainstCustomBinariesTest.java | 81 +++++++++++++++---- .../builtins/BuiltInsPackageFragment.kt | 2 +- .../DeserializedPackageFragmentImpl.kt | 17 ++-- .../ProtoBasedClassDataFinder.kt | 5 +- .../DeserializedMemberDescriptor.kt | 1 + .../js/KotlinJavascriptPackageFragment.kt | 26 +++++- .../js/KotlinJavascriptSerializationUtil.kt | 19 +++-- ...kotlinJavascriptPackageFragmentProvider.kt | 3 +- 13 files changed, 189 insertions(+), 38 deletions(-) create mode 100644 compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/library/a.kt create mode 100644 compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/output.txt create mode 100644 compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt index 49391cf8b9b..29592421464 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt @@ -54,7 +54,6 @@ object JvmPlatformConfigurator : PlatformConfigurator( ProtectedInSuperClassCompanionCallChecker(), UnsupportedSyntheticCallableReferenceChecker(), SuperCallWithDefaultArgumentsChecker(), - MissingDependencyClassChecker, ProtectedSyntheticExtensionCallChecker, ReifiedTypeParameterSubstitutionChecker() ), @@ -67,7 +66,6 @@ object JvmPlatformConfigurator : PlatformConfigurator( ), additionalClassifierUsageCheckers = listOf( - MissingDependencyClassChecker.ClassifierUsage ), additionalAnnotationCheckers = listOf( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt index 9d6e54b7236..4f6b72eae00 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt @@ -92,11 +92,13 @@ private val DEFAULT_CALL_CHECKERS = listOf( CapturingInClosureChecker(), InlineCheckerWrapper(), SafeCallChecker(), DeprecatedCallChecker, CallReturnsArrayOfNothingChecker(), InfixCallChecker(), OperatorCallChecker(), ConstructorHeaderCallChecker, ProtectedConstructorCallChecker, ApiVersionCallChecker, - CoroutineSuspendCallChecker, BuilderFunctionsCallChecker, DslScopeViolationCallChecker, + CoroutineSuspendCallChecker, BuilderFunctionsCallChecker, DslScopeViolationCallChecker, MissingDependencyClassChecker, CallableReferenceCompatibilityChecker() ) private val DEFAULT_TYPE_CHECKERS = emptyList() -private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf(DeprecatedClassifierUsageChecker(), ApiVersionClassifierUsageChecker) +private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf( + DeprecatedClassifierUsageChecker(), ApiVersionClassifierUsageChecker, MissingDependencyClassChecker.ClassifierUsage +) abstract class PlatformConfigurator( diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/library/a.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/library/a.kt new file mode 100644 index 00000000000..79d858eaf54 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/library/a.kt @@ -0,0 +1,9 @@ +package a + +open class A { + class Nested +} + +fun foo() = "" +var bar = 42 +typealias TA = String diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/output.txt new file mode 100644 index 00000000000..da733c44417 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/output.txt @@ -0,0 +1,41 @@ +error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors +compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:5:16: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler +fun baz(param: A, nested: A.Nested) { + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:5:27: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler +fun baz(param: A, nested: A.Nested) { + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:5:29: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler +fun baz(param: A, nested: A.Nested) { + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:6:23: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler + val constructor = A() + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:7:18: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler + val nested = A.Nested() + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:7:20: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler + val nested = A.Nested() + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:8:22: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler + val methodCall = param.method() + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:8:28: error: unresolved reference: method + val methodCall = param.method() + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:9:30: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler + val supertype = object : A() {} + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:11:13: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler + val x = foo() + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:12:13: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler + val y = bar + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:13:5: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler + bar = 239 + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:14:12: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler + val z: TA = "" + ^ +COMPILATION_ERROR \ No newline at end of file diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt new file mode 100644 index 00000000000..f15b2e0bd70 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt @@ -0,0 +1,15 @@ +package usage + +import a.* + +fun baz(param: A, nested: A.Nested) { + val constructor = A() + val nested = A.Nested() + val methodCall = param.method() + val supertype = object : A() {} + + val x = foo() + val y = bar + bar = 239 + val z: TA = "" +} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.java index 8dca69f7d72..beb6fc80001 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.java @@ -30,10 +30,12 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.analyzer.AnalysisResult; import org.jetbrains.kotlin.cli.AbstractCliTest; import org.jetbrains.kotlin.cli.WrongBytecodeVersionTest; +import org.jetbrains.kotlin.cli.common.CLICompiler; import org.jetbrains.kotlin.cli.common.ExitCode; import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport; import org.jetbrains.kotlin.cli.common.messages.MessageRenderer; import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector; +import org.jetbrains.kotlin.cli.js.K2JSCompiler; import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler; import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles; import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment; @@ -87,10 +89,16 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir { @NotNull private File compileLibrary(@NotNull String sourcePath, @NotNull File... extraClassPath) { - File result = new File(tmpdir, sourcePath + ".jar"); - Pair output = compileKotlin(sourcePath, result, extraClassPath); + File destination = new File(tmpdir, sourcePath + ".jar"); + compileLibrary(new K2JVMCompiler(), sourcePath, destination, extraClassPath); + return destination; + } + + private void compileLibrary( + @NotNull CLICompiler compiler, @NotNull String sourcePath, @NotNull File destination, @NotNull File... extraClassPath + ) { + Pair output = compileKotlin(compiler, sourcePath, destination, Collections.emptyList(), extraClassPath); Assert.assertEquals(normalizeOutput(new Pair("", ExitCode.OK)), normalizeOutput(output)); - return result; } @NotNull @@ -218,22 +226,49 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir { private Pair compileKotlin( @NotNull String fileName, @NotNull File output, - List additionalOptions, + @NotNull List additionalOptions, + @NotNull File... classpath + ) { + return compileKotlin(new K2JVMCompiler(), fileName, output, additionalOptions, classpath); + } + + @NotNull + private Pair compileKotlin( + @NotNull CLICompiler compiler, + @NotNull String fileName, + @NotNull File output, + @NotNull List additionalOptions, @NotNull File... classpath ) { List args = new ArrayList(); File sourceFile = new File(getTestDataDirectory(), fileName); assert sourceFile.exists() : "Source file does not exist: " + sourceFile.getAbsolutePath(); args.add(sourceFile.getPath()); - if (classpath.length > 0) { - args.add("-classpath"); - args.add(StringsKt.join(Arrays.asList(classpath), File.pathSeparator)); + + if (compiler instanceof K2JSCompiler) { + if (classpath.length > 0) { + args.add("-libraries"); + args.add(StringsKt.join(Arrays.asList(classpath), File.pathSeparator)); + } + args.add("-output"); + args.add(output.getPath()); + args.add("-meta-info"); } - args.add("-d"); - args.add(output.getPath()); + else if (compiler instanceof K2JVMCompiler) { + if (classpath.length > 0) { + args.add("-classpath"); + args.add(StringsKt.join(Arrays.asList(classpath), File.pathSeparator)); + } + args.add("-d"); + args.add(output.getPath()); + } + else { + throw new UnsupportedOperationException(compiler.toString()); + } + args.addAll(additionalOptions); - return AbstractCliTest.executeCompilerGrabOutput(new K2JVMCompiler(), args); + return AbstractCliTest.executeCompilerGrabOutput(compiler, args); } private void doTestBrokenJavaLibrary(@NotNull String libraryName, @NotNull String... pathsToDelete) throws Exception { @@ -278,13 +313,18 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir { } @SuppressWarnings("deprecation") - private void doTestPreReleaseKotlinLibrary(@NotNull String libraryName, @NotNull String... additionalOptions) throws Exception { + private void doTestPreReleaseKotlinLibrary( + @NotNull CLICompiler compiler, + @NotNull String libraryName, + @NotNull File destination, + @NotNull File result, + @NotNull String... additionalOptions + ) throws Exception { // Compiles the library with the "pre-release" flag, then compiles a usage of this library in the release mode - File library; try { System.setProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY, "true"); - library = compileLibrary(libraryName); + compileLibrary(compiler, libraryName, destination); } finally { System.clearProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY); @@ -293,7 +333,7 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir { Pair output; try { System.setProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY, "false"); - output = compileKotlin("source.kt", tmpdir, Arrays.asList(additionalOptions), library); + output = compileKotlin(compiler, "source.kt", tmpdir, Arrays.asList(additionalOptions), result); } finally { System.clearProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY); @@ -414,11 +454,20 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir { } public void testReleaseCompilerAgainstPreReleaseLibrary() throws Exception { - doTestPreReleaseKotlinLibrary("library"); + File destination = new File(tmpdir, "library.jar"); + doTestPreReleaseKotlinLibrary(new K2JVMCompiler(), "library", destination, destination); + } + + public void testReleaseCompilerAgainstPreReleaseLibraryJs() throws Exception { + doTestPreReleaseKotlinLibrary(new K2JSCompiler(), "library", + new File(tmpdir, "library.js"), + new File(tmpdir, "library.meta.js")); } public void testReleaseCompilerAgainstPreReleaseLibrarySkipVersionCheck() throws Exception { - doTestPreReleaseKotlinLibrary("library", "-Xskip-metadata-version-check"); + File destination = new File(tmpdir, "library.jar"); + doTestPreReleaseKotlinLibrary(new K2JVMCompiler(), "library", destination, destination, + "-Xskip-metadata-version-check"); } public void testWrongMetadataVersion() throws Exception { diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltInsPackageFragment.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltInsPackageFragment.kt index ba12612978b..a47fe6a13cc 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltInsPackageFragment.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltInsPackageFragment.kt @@ -41,4 +41,4 @@ class BuiltInsPackageFragment( } ProtoBuf.PackageFragment.parseFrom(stream, BuiltInSerializerProtocol.extensionRegistry) -}) +}, containerSource = null) diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragmentImpl.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragmentImpl.kt index 4c7ab49c9ec..ba39366b5d7 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragmentImpl.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragmentImpl.kt @@ -17,8 +17,10 @@ package org.jetbrains.kotlin.serialization.deserialization import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.serialization.ProtoBuf +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope import org.jetbrains.kotlin.storage.StorageManager @@ -26,17 +28,20 @@ abstract class DeserializedPackageFragmentImpl( fqName: FqName, storageManager: StorageManager, module: ModuleDescriptor, - protected val proto: ProtoBuf.PackageFragment + protected val proto: ProtoBuf.PackageFragment, + private val containerSource: DeserializedContainerSource? ) : DeserializedPackageFragment(fqName, storageManager, module) { protected val nameResolver = NameResolverImpl(proto.strings, proto.qualifiedNames) - override val classDataFinder = ProtoBasedClassDataFinder(proto, nameResolver) + override val classDataFinder = ProtoBasedClassDataFinder(proto, nameResolver) { containerSource ?: SourceElement.NO_SOURCE } override fun computeMemberScope() = DeserializedPackageMemberScope( - this, proto.`package`, nameResolver, containerSource = null, components = components, - classNames = { classDataFinder.allClassIds.filter { classId -> - !classId.isNestedClass && classId !in ClassDeserializer.BLACK_LIST - }.map { it.shortClassName } } + this, proto.`package`, nameResolver, containerSource, components, + classNames = { + classDataFinder.allClassIds.filter { classId -> + !classId.isNestedClass && classId !in ClassDeserializer.BLACK_LIST + }.map { it.shortClassName } + } ) } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoBasedClassDataFinder.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoBasedClassDataFinder.kt index 51712eba6a7..60601961477 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoBasedClassDataFinder.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoBasedClassDataFinder.kt @@ -24,7 +24,8 @@ import org.jetbrains.kotlin.serialization.ProtoBuf class ProtoBasedClassDataFinder( proto: ProtoBuf.PackageFragment, - private val nameResolver: NameResolver + private val nameResolver: NameResolver, + private val classSource: (ClassId) -> SourceElement = { SourceElement.NO_SOURCE } ) : ClassDataFinder { private val classIdToProto = proto.class_List.associateBy { klass -> @@ -35,6 +36,6 @@ class ProtoBasedClassDataFinder( override fun findClassData(classId: ClassId): ClassDataWithSource? { val classProto = classIdToProto[classId] ?: return null - return ClassDataWithSource(ClassData(nameResolver, classProto), SourceElement.NO_SOURCE) + return ClassDataWithSource(ClassData(nameResolver, classProto), classSource(classId)) } } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberDescriptor.kt index ab5b16d8d8a..1ae7b93e790 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberDescriptor.kt @@ -45,6 +45,7 @@ interface DeserializedMemberDescriptor : MemberDescriptor { get() = SinceKotlinInfo.create(proto, nameResolver, sinceKotlinInfoTable) // Information about the origin of this callable's container (class or package part on JVM) or null if there's no such information. + // TODO: merge with sourceElement of containingDeclaration val containerSource: DeserializedContainerSource? } diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptPackageFragment.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptPackageFragment.kt index 720e140a92a..81c416fc7f9 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptPackageFragment.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptPackageFragment.kt @@ -16,16 +16,20 @@ package org.jetbrains.kotlin.serialization.js +import org.jetbrains.kotlin.config.KotlinCompilerVersion import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor +import org.jetbrains.kotlin.descriptors.SourceFile import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.AnnotationDeserializer import org.jetbrains.kotlin.serialization.deserialization.DeserializedPackageFragmentImpl +import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor import org.jetbrains.kotlin.storage.StorageManager @@ -35,8 +39,9 @@ class KotlinJavascriptPackageFragment( fqName: FqName, storageManager: StorageManager, module: ModuleDescriptor, - proto: ProtoBuf.PackageFragment -) : DeserializedPackageFragmentImpl(fqName, storageManager, module, proto) { + proto: ProtoBuf.PackageFragment, + header: JsProtoBuf.Header +) : DeserializedPackageFragmentImpl(fqName, storageManager, module, proto, JsContainerSource(fqName, header)) { private val fileMap: Map by storageManager.createLazyValue { this.proto.getExtension(JsProtoBuf.packageFragmentFiles).fileList.withIndex().associate { (index, file) -> (if (file.hasId()) file.id else index) to FileHolder(file.annotationList) @@ -66,4 +71,21 @@ class KotlinJavascriptPackageFragment( annotationsProto.map { annotationDeserializer.deserializeAnnotation(it, nameResolver) } } } + + private class JsContainerSource(private val fqName: FqName, private val header: JsProtoBuf.Header) : DeserializedContainerSource { + // TODO + override fun getContainingFile(): SourceFile = SourceFile.NO_SOURCE_FILE + + // This is null because we look for incompatible libraries in dependencies in the beginning of the compilation anyway, + // and refuse to compile against them completely + override val incompatibility: IncompatibleVersionErrorData<*>? + get() = null + + override val isPreReleaseInvisible: Boolean + get() = (header.flags and 1) != 0 && !KotlinCompilerVersion.isPreRelease() + + // TODO: this is not a class + override val presentableString: String + get() = "Package '$fqName'" + } } diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt index fefdbb7ecb2..8aa23ba4c16 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.serialization.js +import org.jetbrains.kotlin.config.KotlinCompilerVersion import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.BindingContext @@ -44,7 +45,10 @@ object KotlinJavascriptSerializationUtil { metadata: ByteArray, storageManager: StorageManager, module: ModuleDescriptor, configuration: DeserializationConfiguration ): JsModuleDescriptor { val jsModule = metadata.deserializeToLibraryParts(module.name.asString()) - return jsModule.copy(createKotlinJavascriptPackageFragmentProvider(storageManager, module, jsModule.data, configuration)) + val (header, packageFragmentProtos) = jsModule.data + return jsModule.copy(createKotlinJavascriptPackageFragmentProvider( + storageManager, module, header, packageFragmentProtos, configuration + )) } private fun serializeMetadata( @@ -185,7 +189,10 @@ object KotlinJavascriptSerializationUtil { header.packageFqName = packageFqName.asString() } - // TODO: write pre-release flag if needed + if (KotlinCompilerVersion.isPreRelease()) { + header.flags = 1 + } + // TODO: write JS code binary version return header.build() @@ -220,15 +227,15 @@ object KotlinJavascriptSerializationUtil { }.toByteArray() } - private fun ByteArray.deserializeToLibraryParts(name: String): JsModuleDescriptor> { - val content = GZIPInputStream(ByteArrayInputStream(this)).use { stream -> - JsProtoBuf.Header.parseDelimitedFrom(stream, JsSerializerProtocol.extensionRegistry) + private fun ByteArray.deserializeToLibraryParts(name: String): JsModuleDescriptor>> { + val (header, content) = GZIPInputStream(ByteArrayInputStream(this)).use { stream -> + JsProtoBuf.Header.parseDelimitedFrom(stream, JsSerializerProtocol.extensionRegistry) to JsProtoBuf.Library.parseFrom(stream, JsSerializerProtocol.extensionRegistry) } return JsModuleDescriptor( name = name, - data = content.packageFragmentList, + data = header to content.packageFragmentList, kind = when (content.kind) { null, JsProtoBuf.Library.Kind.PLAIN -> ModuleKind.PLAIN JsProtoBuf.Library.Kind.AMD -> ModuleKind.AMD diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt index fa85768692b..1822ff95f95 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt @@ -28,12 +28,13 @@ import org.jetbrains.kotlin.storage.StorageManager fun createKotlinJavascriptPackageFragmentProvider( storageManager: StorageManager, module: ModuleDescriptor, + header: JsProtoBuf.Header, packageFragmentProtos: List, configuration: DeserializationConfiguration ): PackageFragmentProvider { val packageFragments = packageFragmentProtos.mapNotNull { proto -> proto.fqName?.let { fqName -> - KotlinJavascriptPackageFragment(fqName, storageManager, module, proto) + KotlinJavascriptPackageFragment(fqName, storageManager, module, proto, header) } }