diff --git a/.idea/modules.xml b/.idea/modules.xml
index 94fd8b45917..dc0a656a7a2 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -38,6 +38,7 @@
+
diff --git a/build.xml b/build.xml
index 41ff53d1416..48d249c9403 100644
--- a/build.xml
+++ b/build.xml
@@ -117,6 +117,7 @@
+
@@ -142,6 +143,7 @@
+
@@ -210,6 +212,7 @@
+
diff --git a/js/js.serializer/js.serializer.iml b/js/js.serializer/js.serializer.iml
new file mode 100644
index 00000000000..59e4679c930
--- /dev/null
+++ b/js/js.serializer/js.serializer.iml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/js/js.serializer/src/org/jetbrains/kotlin/utils/serializer/ClassSerializationUtil.kt b/js/js.serializer/src/org/jetbrains/kotlin/utils/serializer/ClassSerializationUtil.kt
new file mode 100644
index 00000000000..4f3c814f72b
--- /dev/null
+++ b/js/js.serializer/src/org/jetbrains/kotlin/utils/serializer/ClassSerializationUtil.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.utils.serializer
+
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.serialization.ProtoBuf
+import org.jetbrains.kotlin.serialization.DescriptorSerializer
+import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+
+public object ClassSerializationUtil {
+ public trait Sink {
+ fun writeClass(classDescriptor: ClassDescriptor, classProto: ProtoBuf.Class)
+ }
+
+ private fun serializeClass(classDescriptor: ClassDescriptor, serializer: DescriptorSerializer, sink: Sink, skip: (DeclarationDescriptor) -> Boolean) {
+ if (skip(classDescriptor)) return
+
+ val classProto = serializer.classProto(classDescriptor).build() ?: error("Class not serialized: $classDescriptor")
+ sink.writeClass(classDescriptor, classProto)
+
+ serializeClasses(classDescriptor.getUnsubstitutedInnerClassesScope().getDescriptors(), serializer, sink, skip)
+ }
+
+ public fun serializeClasses(descriptors: Collection, serializer: DescriptorSerializer, sink: Sink, skip: (DeclarationDescriptor) -> Boolean) {
+ for (descriptor in descriptors) {
+ if (descriptor is ClassDescriptor) {
+ serializeClass(descriptor, serializer, sink, skip)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/js/js.serializer/src/org/jetbrains/kotlin/utils/serializer/KotlinJavaScriptSerializer.kt b/js/js.serializer/src/org/jetbrains/kotlin/utils/serializer/KotlinJavaScriptSerializer.kt
new file mode 100644
index 00000000000..a696487876b
--- /dev/null
+++ b/js/js.serializer/src/org/jetbrains/kotlin/utils/serializer/KotlinJavaScriptSerializer.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2010-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.utils.serializer
+
+import org.jetbrains.kotlin.builtins.BuiltInsSerializationUtil
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+import org.jetbrains.kotlin.descriptors.ModuleDescriptor
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.resolve.DescriptorUtils
+import org.jetbrains.kotlin.resolve.descriptorUtil.classId
+import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
+import org.jetbrains.kotlin.serialization.DescriptorSerializer
+import org.jetbrains.kotlin.serialization.NameSerializationUtil
+import org.jetbrains.kotlin.serialization.ProtoBuf
+import org.jetbrains.kotlin.serialization.builtins.BuiltInsSerializerExtension
+import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil
+import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
+import java.io.ByteArrayOutputStream
+import java.io.File
+
+public class KotlinJavaScriptSerializer() {
+
+ public fun serialize(moduleName: String, moduleDescriptor: ModuleDescriptor, metaFile: File) {
+ val contentMap = hashMapOf()
+
+ DescriptorUtils.getPackagesFqNames(moduleDescriptor).forEach {
+ fqName -> serializePackage(moduleDescriptor, fqName) {
+ (fileName, stream) -> contentMap[fileName] = stream.toByteArray()
+ }
+ }
+
+ val content = KotlinJavascriptSerializationUtil.contentMapToByteArray(contentMap)
+ KotlinJavascriptMetadataUtils.writeMetadata(moduleName, content, metaFile)
+ }
+
+ fun serializePackage(module: ModuleDescriptor, fqName: FqName, writeFun: (String, ByteArrayOutputStream) -> Unit) {
+ val packageView = module.getPackage(fqName) ?: error("No package resolved in $module")
+
+ // TODO: perform some kind of validation? At the moment not possible because DescriptorValidator is in compiler-tests
+ // DescriptorValidator.validate(packageView)
+
+ val skip: (DeclarationDescriptor) -> Boolean = { DescriptorUtils.getContainingModule(it) != module}
+
+ val serializer = DescriptorSerializer.createTopLevel(BuiltInsSerializerExtension)
+
+ val classifierDescriptors = DescriptorSerializer.sort(packageView.getMemberScope().getDescriptors(DescriptorKindFilter.CLASSIFIERS))
+
+ ClassSerializationUtil.serializeClasses(classifierDescriptors, serializer, object : ClassSerializationUtil.Sink {
+ override fun writeClass(classDescriptor: ClassDescriptor, classProto: ProtoBuf.Class) {
+ val stream = ByteArrayOutputStream()
+ classProto.writeTo(stream)
+ writeFun(getFileName(classDescriptor), stream)
+ }
+ }, skip)
+
+ val packageStream = ByteArrayOutputStream()
+ val fragments = module.getPackageFragmentProvider().getPackageFragments(fqName)
+ val packageProto = serializer.packageProto(fragments, skip).build() ?: error("Package fragments not serialized: $fragments")
+ packageProto.writeTo(packageStream)
+ writeFun(BuiltInsSerializationUtil.getPackageFilePath(fqName), packageStream)
+
+ val nameStream = ByteArrayOutputStream()
+ NameSerializationUtil.serializeStringTable(nameStream, serializer.getStringTable())
+ writeFun(BuiltInsSerializationUtil.getStringTableFilePath(fqName), nameStream)
+ }
+
+ fun getFileName(classDescriptor: ClassDescriptor): String {
+ return BuiltInsSerializationUtil.getClassMetadataPath(classDescriptor.classId)
+ }
+}
\ No newline at end of file