From 29095335220c1e043b0c3df840c33a8ca706acf2 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 8 Apr 2016 19:05:03 +0300 Subject: [PATCH] KT-3008 Add module kind. Include module kind and module dependencies in metadata --- .../serialization/js/DebugJsProtoBuf.java | 440 ++++++++++++++++-- .../AbstractDiagnosticsTestWithJsStdLib.java | 5 +- .../js/KotlinJavascriptSerializerTest.kt | 11 +- .../idea/caches/resolve/JsAnalyzerFacade.kt | 4 +- ...JavaScriptDecompiledTextConsistencyTest.kt | 2 +- .../analyze/TopDownAnalyzerFacadeForJS.java | 5 +- .../jetbrains/kotlin/js/config/JsConfig.java | 53 ++- .../js/config/LibrarySourcesConfig.java | 1 + js/js.serializer/src/js.proto | 8 + .../serialization/js/JsModuleDescriptor.kt | 21 + .../kotlin/serialization/js/JsProtoBuf.java | 341 ++++++++++++++ .../js/KotlinJavascriptSerializationUtil.kt | 60 ++- .../kotlin/serialization/js/ModuleKind.java | 25 + .../kotlin/js/facade/K2JSTranslator.java | 5 +- .../kotlin/js/facade/TranslationResult.kt | 10 +- .../js/translate/context/StaticContext.java | 57 ++- .../translate/context/TranslationContext.java | 5 + 17 files changed, 979 insertions(+), 74 deletions(-) create mode 100644 js/js.serializer/src/org/jetbrains/kotlin/serialization/js/JsModuleDescriptor.kt create mode 100644 js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ModuleKind.java diff --git a/build-common/test/org/jetbrains/kotlin/serialization/js/DebugJsProtoBuf.java b/build-common/test/org/jetbrains/kotlin/serialization/js/DebugJsProtoBuf.java index 6feaa0a19fe..8a468eee221 100644 --- a/build-common/test/org/jetbrains/kotlin/serialization/js/DebugJsProtoBuf.java +++ b/build-common/test/org/jetbrains/kotlin/serialization/js/DebugJsProtoBuf.java @@ -575,6 +575,36 @@ public final class DebugJsProtoBuf { */ org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.FileEntryOrBuilder getEntryOrBuilder( int index); + + // optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + boolean hasKind(); + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.Kind getKind(); + + // repeated string importedModules = 3; + /** + * repeated string importedModules = 3; + */ + java.util.List + getImportedModulesList(); + /** + * repeated string importedModules = 3; + */ + int getImportedModulesCount(); + /** + * repeated string importedModules = 3; + */ + java.lang.String getImportedModules(int index); + /** + * repeated string importedModules = 3; + */ + com.google.protobuf.ByteString + getImportedModulesBytes(int index); } /** * Protobuf type {@code org.jetbrains.kotlin.serialization.js.Library} @@ -635,6 +665,25 @@ public final class DebugJsProtoBuf { entry_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.FileEntry.PARSER, extensionRegistry)); break; } + case 16: { + int rawValue = input.readEnum(); + org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.Kind value = org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.Kind.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(2, rawValue); + } else { + bitField0_ |= 0x00000001; + kind_ = value; + } + break; + } + case 26: { + if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + importedModules_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000004; + } + importedModules_.add(input.readBytes()); + break; + } } } } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { @@ -646,6 +695,9 @@ public final class DebugJsProtoBuf { if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { entry_ = java.util.Collections.unmodifiableList(entry_); } + if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + importedModules_ = new com.google.protobuf.UnmodifiableLazyStringList(importedModules_); + } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } @@ -677,6 +729,97 @@ public final class DebugJsProtoBuf { return PARSER; } + /** + * Protobuf enum {@code org.jetbrains.kotlin.serialization.js.Library.Kind} + */ + public enum Kind + implements com.google.protobuf.ProtocolMessageEnum { + /** + * PLAIN = 1; + */ + PLAIN(0, 1), + /** + * AMD = 2; + */ + AMD(1, 2), + /** + * COMMON_JS = 3; + */ + COMMON_JS(2, 3), + ; + + /** + * PLAIN = 1; + */ + public static final int PLAIN_VALUE = 1; + /** + * AMD = 2; + */ + public static final int AMD_VALUE = 2; + /** + * COMMON_JS = 3; + */ + public static final int COMMON_JS_VALUE = 3; + + + public final int getNumber() { return value; } + + public static Kind valueOf(int value) { + switch (value) { + case 1: return PLAIN; + case 2: return AMD; + case 3: return COMMON_JS; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public Kind findValueByNumber(int number) { + return Kind.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.getDescriptor().getEnumTypes().get(0); + } + + private static final Kind[] VALUES = values(); + + public static Kind valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private Kind(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:org.jetbrains.kotlin.serialization.js.Library.Kind) + } + public interface FileEntryOrBuilder extends org.jetbrains.kotlin.protobuf.MessageOrBuilder { @@ -1248,6 +1391,7 @@ public final class DebugJsProtoBuf { // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.Library.FileEntry) } + private int bitField0_; // repeated .org.jetbrains.kotlin.serialization.js.Library.FileEntry entry = 1; public static final int ENTRY_FIELD_NUMBER = 1; private java.util.List entry_; @@ -1284,8 +1428,56 @@ public final class DebugJsProtoBuf { return entry_.get(index); } + // optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + public static final int KIND_FIELD_NUMBER = 2; + private org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.Kind kind_; + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + public boolean hasKind() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + public org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.Kind getKind() { + return kind_; + } + + // repeated string importedModules = 3; + public static final int IMPORTEDMODULES_FIELD_NUMBER = 3; + private com.google.protobuf.LazyStringList importedModules_; + /** + * repeated string importedModules = 3; + */ + public java.util.List + getImportedModulesList() { + return importedModules_; + } + /** + * repeated string importedModules = 3; + */ + public int getImportedModulesCount() { + return importedModules_.size(); + } + /** + * repeated string importedModules = 3; + */ + public java.lang.String getImportedModules(int index) { + return importedModules_.get(index); + } + /** + * repeated string importedModules = 3; + */ + public com.google.protobuf.ByteString + getImportedModulesBytes(int index) { + return importedModules_.getByteString(index); + } + private void initFields() { entry_ = java.util.Collections.emptyList(); + kind_ = org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.Kind.PLAIN; + importedModules_ = com.google.protobuf.LazyStringArrayList.EMPTY; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -1308,6 +1500,12 @@ public final class DebugJsProtoBuf { for (int i = 0; i < entry_.size(); i++) { output.writeMessage(1, entry_.get(i)); } + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeEnum(2, kind_.getNumber()); + } + for (int i = 0; i < importedModules_.size(); i++) { + output.writeBytes(3, importedModules_.getByteString(i)); + } getUnknownFields().writeTo(output); } @@ -1321,6 +1519,19 @@ public final class DebugJsProtoBuf { size += org.jetbrains.kotlin.protobuf.CodedOutputStream .computeMessageSize(1, entry_.get(i)); } + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(2, kind_.getNumber()); + } + { + int dataSize = 0; + for (int i = 0; i < importedModules_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(importedModules_.getByteString(i)); + } + size += dataSize; + size += 1 * getImportedModulesList().size(); + } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -1444,6 +1655,10 @@ public final class DebugJsProtoBuf { } else { entryBuilder_.clear(); } + kind_ = org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.Kind.PLAIN; + bitField0_ = (bitField0_ & ~0x00000002); + importedModules_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); return this; } @@ -1471,6 +1686,7 @@ public final class DebugJsProtoBuf { public org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library buildPartial() { org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library result = new org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library(this); int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; if (entryBuilder_ == null) { if (((bitField0_ & 0x00000001) == 0x00000001)) { entry_ = java.util.Collections.unmodifiableList(entry_); @@ -1480,6 +1696,17 @@ public final class DebugJsProtoBuf { } else { result.entry_ = entryBuilder_.build(); } + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000001; + } + result.kind_ = kind_; + if (((bitField0_ & 0x00000004) == 0x00000004)) { + importedModules_ = new com.google.protobuf.UnmodifiableLazyStringList( + importedModules_); + bitField0_ = (bitField0_ & ~0x00000004); + } + result.importedModules_ = importedModules_; + result.bitField0_ = to_bitField0_; onBuilt(); return result; } @@ -1521,6 +1748,19 @@ public final class DebugJsProtoBuf { } } } + if (other.hasKind()) { + setKind(other.getKind()); + } + if (!other.importedModules_.isEmpty()) { + if (importedModules_.isEmpty()) { + importedModules_ = other.importedModules_; + bitField0_ = (bitField0_ & ~0x00000004); + } else { + ensureImportedModulesIsMutable(); + importedModules_.addAll(other.importedModules_); + } + onChanged(); + } this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -1794,6 +2034,135 @@ public final class DebugJsProtoBuf { return entryBuilder_; } + // optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + private org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.Kind kind_ = org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.Kind.PLAIN; + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + public boolean hasKind() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + public org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.Kind getKind() { + return kind_; + } + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + public Builder setKind(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.Kind value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + kind_ = value; + onChanged(); + return this; + } + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + public Builder clearKind() { + bitField0_ = (bitField0_ & ~0x00000002); + kind_ = org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.Library.Kind.PLAIN; + onChanged(); + return this; + } + + // repeated string importedModules = 3; + private com.google.protobuf.LazyStringList importedModules_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureImportedModulesIsMutable() { + if (!((bitField0_ & 0x00000004) == 0x00000004)) { + importedModules_ = new com.google.protobuf.LazyStringArrayList(importedModules_); + bitField0_ |= 0x00000004; + } + } + /** + * repeated string importedModules = 3; + */ + public java.util.List + getImportedModulesList() { + return java.util.Collections.unmodifiableList(importedModules_); + } + /** + * repeated string importedModules = 3; + */ + public int getImportedModulesCount() { + return importedModules_.size(); + } + /** + * repeated string importedModules = 3; + */ + public java.lang.String getImportedModules(int index) { + return importedModules_.get(index); + } + /** + * repeated string importedModules = 3; + */ + public com.google.protobuf.ByteString + getImportedModulesBytes(int index) { + return importedModules_.getByteString(index); + } + /** + * repeated string importedModules = 3; + */ + public Builder setImportedModules( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureImportedModulesIsMutable(); + importedModules_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string importedModules = 3; + */ + public Builder addImportedModules( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureImportedModulesIsMutable(); + importedModules_.add(value); + onChanged(); + return this; + } + /** + * repeated string importedModules = 3; + */ + public Builder addAllImportedModules( + java.lang.Iterable values) { + ensureImportedModulesIsMutable(); + super.addAll(values, importedModules_); + onChanged(); + return this; + } + /** + * repeated string importedModules = 3; + */ + public Builder clearImportedModules() { + importedModules_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + return this; + } + /** + * repeated string importedModules = 3; + */ + public Builder addImportedModulesBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureImportedModulesIsMutable(); + importedModules_.add(value); + onChanged(); + return this; + } + // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.Library) } @@ -1932,39 +2301,42 @@ public final class DebugJsProtoBuf { "rg.jetbrains.kotlin.serialization.js\0320co" + "re/deserialization/src/descriptors.debug" + ".proto\"!\n\007Classes\022\026\n\nclass_name\030\001 \003(\005B\002\020" + - "\001\"~\n\007Library\022G\n\005entry\030\001 \003(\01328.org.jetbra" + - "ins.kotlin.serialization.js.Library.File" + - "Entry\032*\n\tFileEntry\022\014\n\004path\030\001 \002(\t\022\017\n\007cont" + - "ent\030\002 \002(\014:t\n\020class_annotation\022).org.jetb" + - "rains.kotlin.serialization.Class\030\202\001 \003(\0132" + - "..org.jetbrains.kotlin.serialization.Ann", - "otation:\200\001\n\026constructor_annotation\022/.org" + - ".jetbrains.kotlin.serialization.Construc" + - "tor\030\202\001 \003(\0132..org.jetbrains.kotlin.serial" + - "ization.Annotation:z\n\023function_annotatio" + - "n\022,.org.jetbrains.kotlin.serialization.F" + - "unction\030\202\001 \003(\0132..org.jetbrains.kotlin.se" + - "rialization.Annotation:z\n\023property_annot" + - "ation\022,.org.jetbrains.kotlin.serializati" + - "on.Property\030\202\001 \003(\0132..org.jetbrains.kotli" + - "n.serialization.Annotation:\210\001\n\022compile_t", - "ime_value\022,.org.jetbrains.kotlin.seriali" + - "zation.Property\030\203\001 \001(\0132=.org.jetbrains.k" + - "otlin.serialization.Annotation.Argument." + - "Value:}\n\025enum_entry_annotation\022-.org.jet" + - "brains.kotlin.serialization.EnumEntry\030\202\001" + - " \003(\0132..org.jetbrains.kotlin.serializatio" + - "n.Annotation:\201\001\n\024parameter_annotation\0222." + - "org.jetbrains.kotlin.serialization.Value" + - "Parameter\030\202\001 \003(\0132..org.jetbrains.kotlin." + - "serialization.Annotation:r\n\017type_annotat", - "ion\022(.org.jetbrains.kotlin.serialization" + - ".Type\030\202\001 \003(\0132..org.jetbrains.kotlin.seri" + - "alization.Annotation:\205\001\n\031type_parameter_" + - "annotation\0221.org.jetbrains.kotlin.serial" + - "ization.TypeParameter\030\202\001 \003(\0132..org.jetbr" + - "ains.kotlin.serialization.AnnotationB\021B\017" + - "DebugJsProtoBuf" + "\001\"\214\002\n\007Library\022G\n\005entry\030\001 \003(\01328.org.jetbr" + + "ains.kotlin.serialization.js.Library.Fil" + + "eEntry\022H\n\004kind\030\002 \001(\01623.org.jetbrains.kot" + + "lin.serialization.js.Library.Kind:\005PLAIN" + + "\022\027\n\017importedModules\030\003 \003(\t\032*\n\tFileEntry\022\014" + + "\n\004path\030\001 \002(\t\022\017\n\007content\030\002 \002(\014\")\n\004Kind\022\t\n", + "\005PLAIN\020\001\022\007\n\003AMD\020\002\022\r\n\tCOMMON_JS\020\003:t\n\020clas" + + "s_annotation\022).org.jetbrains.kotlin.seri" + + "alization.Class\030\202\001 \003(\0132..org.jetbrains.k" + + "otlin.serialization.Annotation:\200\001\n\026const" + + "ructor_annotation\022/.org.jetbrains.kotlin" + + ".serialization.Constructor\030\202\001 \003(\0132..org." + + "jetbrains.kotlin.serialization.Annotatio" + + "n:z\n\023function_annotation\022,.org.jetbrains" + + ".kotlin.serialization.Function\030\202\001 \003(\0132.." + + "org.jetbrains.kotlin.serialization.Annot", + "ation:z\n\023property_annotation\022,.org.jetbr" + + "ains.kotlin.serialization.Property\030\202\001 \003(" + + "\0132..org.jetbrains.kotlin.serialization.A" + + "nnotation:\210\001\n\022compile_time_value\022,.org.j" + + "etbrains.kotlin.serialization.Property\030\203" + + "\001 \001(\0132=.org.jetbrains.kotlin.serializati" + + "on.Annotation.Argument.Value:}\n\025enum_ent" + + "ry_annotation\022-.org.jetbrains.kotlin.ser" + + "ialization.EnumEntry\030\202\001 \003(\0132..org.jetbra" + + "ins.kotlin.serialization.Annotation:\201\001\n\024", + "parameter_annotation\0222.org.jetbrains.kot" + + "lin.serialization.ValueParameter\030\202\001 \003(\0132" + + "..org.jetbrains.kotlin.serialization.Ann" + + "otation:r\n\017type_annotation\022(.org.jetbrai" + + "ns.kotlin.serialization.Type\030\202\001 \003(\0132..or" + + "g.jetbrains.kotlin.serialization.Annotat" + + "ion:\205\001\n\031type_parameter_annotation\0221.org." + + "jetbrains.kotlin.serialization.TypeParam" + + "eter\030\202\001 \003(\0132..org.jetbrains.kotlin.seria" + + "lization.AnnotationB\021B\017DebugJsProtoBuf" }; org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -1982,7 +2354,7 @@ public final class DebugJsProtoBuf { internal_static_org_jetbrains_kotlin_serialization_js_Library_fieldAccessorTable = new org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_org_jetbrains_kotlin_serialization_js_Library_descriptor, - new java.lang.String[] { "Entry", }); + new java.lang.String[] { "Entry", "Kind", "ImportedModules", }); internal_static_org_jetbrains_kotlin_serialization_js_Library_FileEntry_descriptor = internal_static_org_jetbrains_kotlin_serialization_js_Library_descriptor.getNestedTypes().get(0); internal_static_org_jetbrains_kotlin_serialization_js_Library_FileEntry_fieldAccessorTable = new diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTestWithJsStdLib.java b/compiler/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTestWithJsStdLib.java index 3997262fecf..005d37f9a33 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTestWithJsStdLib.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTestWithJsStdLib.java @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.resolve.BindingTrace; import org.jetbrains.kotlin.resolve.TargetPlatformKt; +import org.jetbrains.kotlin.serialization.js.JsModuleDescriptor; import org.jetbrains.kotlin.storage.StorageManager; import org.jetbrains.kotlin.test.KotlinTestUtils; @@ -99,8 +100,8 @@ public abstract class AbstractDiagnosticsTestWithJsStdLib extends AbstractDiagno List dependencies = new ArrayList(); dependencies.add(module); - for (ModuleDescriptorImpl moduleDescriptor : config.getModuleDescriptors()) { - dependencies.add(moduleDescriptor); + for (JsModuleDescriptor moduleDescriptor : config.getModuleDescriptors()) { + dependencies.add(moduleDescriptor.getData()); } dependencies.add(module.getBuiltIns().getBuiltInsModule()); diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt index 56cd3a05384..1d43ad3760d 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.serialization.builtins +package org.jetbrains.kotlin.serialization.js import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.io.FileUtil @@ -30,7 +30,6 @@ import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.LibrarySourcesConfig import org.jetbrains.kotlin.js.resolve.JsPlatform import org.jetbrains.kotlin.jvm.compiler.LoadDescriptorUtil.TEST_PACKAGE_FQNAME -import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.TestCaseWithTmpdir @@ -71,6 +70,12 @@ class KotlinJavascriptSerializerTest : TestCaseWithTmpdir() { val files = environment.getSourceFiles() val config = LibrarySourcesConfig(environment.project, environment.configuration) val analysisResult = TopDownAnalyzerFacadeForJS.analyzeFiles(files, config) + val description = JsModuleDescriptor( + name = MODULE_NAME, + kind = ModuleKind.PLAIN, + imported = listOf(), + data = analysisResult.moduleDescriptor + ); FileUtil.writeToFile(metaFile, KotlinJavascriptSerializationUtil.metadataAsString( KotlinTestUtils.TEST_MODULE_NAME, analysisResult.moduleDescriptor )) @@ -85,7 +90,7 @@ class KotlinJavascriptSerializerTest : TestCaseWithTmpdir() { val metadata = KotlinJavascriptMetadataUtils.loadMetadata(metaFile) assert(metadata.size == 1) - val provider = KotlinJavascriptSerializationUtil.createPackageFragmentProvider(module, metadata[0].body, LockBasedStorageManager()) + val provider = KotlinJavascriptSerializationUtil.readModule(metadata[0].body, LockBasedStorageManager(), module).data .sure { "No package fragment provider was created" } module.initialize(provider) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/JsAnalyzerFacade.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/JsAnalyzerFacade.kt index 1dcf53d9c38..b9e8d51a09c 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/JsAnalyzerFacade.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/JsAnalyzerFacade.kt @@ -65,7 +65,9 @@ object JsAnalyzerFacade : AnalyzerFacade() { val providers = moduleInfo.library.getFiles(OrderRootType.CLASSES) .flatMap { KotlinJavascriptMetadataUtils.loadMetadata(PathUtil.getLocalPath(it)!!) } .filter { it.isAbiVersionCompatible } - .mapNotNull { KotlinJavascriptSerializationUtil.createPackageFragmentProvider(moduleDescriptor, it.body, moduleContext.storageManager) } + .mapNotNull { + KotlinJavascriptSerializationUtil.readModule(it.body, moduleContext.storageManager, moduleDescriptor).data + } if (providers.isNotEmpty()) { packageFragmentProvider = CompositePackageFragmentProvider(listOf(packageFragmentProvider) + providers) diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/KotlinJavaScriptDecompiledTextConsistencyTest.kt b/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/KotlinJavaScriptDecompiledTextConsistencyTest.kt index 3ccf8a01bbf..2ec2413cb75 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/KotlinJavaScriptDecompiledTextConsistencyTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/KotlinJavaScriptDecompiledTextConsistencyTest.kt @@ -52,7 +52,7 @@ class KotlinJavaScriptDecompiledTextConsistencyTest : TextConsistencyBaseTest() val metadata = KotlinJavascriptMetadataUtils.loadMetadata(stdlibJar) assert(metadata.size == 1) - val provider = KotlinJavascriptSerializationUtil.createPackageFragmentProvider(module, metadata[0].body, LockBasedStorageManager()) + val provider = KotlinJavascriptSerializationUtil.readModule(metadata[0].body, LockBasedStorageManager(), module).data .sure { "No package fragment provider was created" } module.initialize(provider) diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.java b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.java index 468a27ee137..c6f398363ba 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.java @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.resolve.*; import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory; +import org.jetbrains.kotlin.serialization.js.JsModuleDescriptor; import java.util.ArrayList; import java.util.Collection; @@ -58,7 +59,9 @@ public final class TopDownAnalyzerFacadeForJS { private static List computeDependencies(ModuleDescriptorImpl module, @NotNull JsConfig config) { List allDependencies = new ArrayList(); allDependencies.add(module); - allDependencies.addAll(config.getModuleDescriptors()); + for (JsModuleDescriptor descriptor : config.getModuleDescriptors()) { + allDependencies.add(descriptor.getData()); + } allDependencies.add(JsPlatform.INSTANCE.getBuiltIns().getBuiltInsModule()); return allDependencies; } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JsConfig.java b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JsConfig.java index 323d5c5d966..726b37d9638 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JsConfig.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JsConfig.java @@ -31,12 +31,16 @@ import org.jetbrains.kotlin.js.resolve.JsPlatform; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.resolve.TargetPlatformKt; +import org.jetbrains.kotlin.serialization.js.JsModuleDescriptor; import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil; +import org.jetbrains.kotlin.serialization.js.ModuleKind; import org.jetbrains.kotlin.storage.LockBasedStorageManager; import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata; import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; /** @@ -47,8 +51,24 @@ public abstract class JsConfig { private final CompilerConfiguration configuration; private final LockBasedStorageManager storageManager = new LockBasedStorageManager(); private final List sourceFilesFromLibraries = new SmartList(); + @NotNull + private final EcmaVersion target; + + @NotNull + private final String moduleId; + + private final boolean sourcemap; + private final boolean metaInfo; + private final boolean kjsm; + + @NotNull protected final List metadata = new SmartList(); - private List moduleDescriptors = null; + + @Nullable + private List> moduleDescriptors = null; + + @NotNull + private final ModuleKind moduleKind; private boolean initialized = false; @@ -72,23 +92,35 @@ public abstract class JsConfig { return configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME); } + @NotNull + public ModuleKind getModuleKind() { + return moduleKind; + } + public abstract boolean checkLibFilesAndReportErrors(@NotNull Function1 report); protected abstract void init(@NotNull List sourceFilesInLibraries, @NotNull List metadata); @NotNull - public List getModuleDescriptors() { + public List> getModuleDescriptors() { init(); if (moduleDescriptors != null) return moduleDescriptors; - moduleDescriptors = new SmartList(); + moduleDescriptors = new SmartList>(); + List kotlinModuleDescriptors = new ArrayList(); for (KotlinJavascriptMetadata metadataEntry : metadata) { - moduleDescriptors.add(createModuleDescriptor(metadataEntry)); + JsModuleDescriptor descriptor = createModuleDescriptor(metadataEntry); + moduleDescriptors.add(descriptor); + kotlinModuleDescriptors.add(descriptor.getData()); } - for (ModuleDescriptorImpl module : moduleDescriptors) { - setDependencies(module, moduleDescriptors); + + for (JsModuleDescriptor module : moduleDescriptors) { + // TODO: remove downcast + setDependencies(module.getData(), kotlinModuleDescriptors); } + moduleDescriptors = Collections.unmodifiableList(moduleDescriptors); + return moduleDescriptors; } @@ -105,7 +137,7 @@ public abstract class JsConfig { initialized = true; } - private ModuleDescriptorImpl createModuleDescriptor(KotlinJavascriptMetadata metadata) { + private JsModuleDescriptor createModuleDescriptor(KotlinJavascriptMetadata metadata) { assert metadata.isAbiVersionCompatible() : "expected abi version " + KotlinJavascriptMetadataUtils.ABI_VERSION + ", but metadata.abiVersion = " + metadata.getAbiVersion(); @@ -114,12 +146,13 @@ public abstract class JsConfig { JsPlatform.INSTANCE, Name.special("<" + metadata.getModuleName() + ">"), storageManager, JsPlatform.INSTANCE.getBuiltIns()); - PackageFragmentProvider provider = - KotlinJavascriptSerializationUtil.createPackageFragmentProvider(moduleDescriptor, metadata.getBody(), storageManager); + JsModuleDescriptor rawDescriptor = KotlinJavascriptSerializationUtil.readModule( + metadata.getBody(), storageManager, moduleDescriptor); + PackageFragmentProvider provider = rawDescriptor.getData(); moduleDescriptor.initialize(provider != null ? provider : PackageFragmentProvider.Empty.INSTANCE); - return moduleDescriptor; + return rawDescriptor.copy(moduleDescriptor); } private static void setDependencies(ModuleDescriptorImpl module, List modules) { diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/config/LibrarySourcesConfig.java b/js/js.frontend/src/org/jetbrains/kotlin/js/config/LibrarySourcesConfig.java index c34ed9eadbb..e80aa2d7c9c 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/config/LibrarySourcesConfig.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/config/LibrarySourcesConfig.java @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration; import org.jetbrains.kotlin.idea.KotlinFileType; import org.jetbrains.kotlin.js.JavaScript; import org.jetbrains.kotlin.psi.KtFile; +import org.jetbrains.kotlin.serialization.js.ModuleKind; import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata; import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils; import org.jetbrains.kotlin.utils.LibraryUtils; diff --git a/js/js.serializer/src/js.proto b/js/js.serializer/src/js.proto index 8d42dc3093e..d4bbc76b028 100644 --- a/js/js.serializer/src/js.proto +++ b/js/js.serializer/src/js.proto @@ -65,5 +65,13 @@ message Library { required bytes content = 2; } + enum Kind { + PLAIN = 1; + AMD = 2; + COMMON_JS = 3; + } + repeated FileEntry entry = 1; + optional Kind kind = 2 [default = PLAIN]; + repeated string importedModules = 3; } diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/JsModuleDescriptor.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/JsModuleDescriptor.kt new file mode 100644 index 00000000000..c0e05a2d74b --- /dev/null +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/JsModuleDescriptor.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2016 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.serialization.js + +class JsModuleDescriptor(val name: String, val kind: ModuleKind, val imported: List, val data: T) { + fun copy(newData: S) = JsModuleDescriptor(name, kind, imported, newData) +} \ No newline at end of file diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/JsProtoBuf.java b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/JsProtoBuf.java index e3c8c4f1f0e..79ae35558c3 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/JsProtoBuf.java +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/JsProtoBuf.java @@ -502,6 +502,36 @@ public final class JsProtoBuf { * repeated .org.jetbrains.kotlin.serialization.js.Library.FileEntry entry = 1; */ int getEntryCount(); + + // optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + boolean hasKind(); + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library.Kind getKind(); + + // repeated string importedModules = 3; + /** + * repeated string importedModules = 3; + */ + java.util.List + getImportedModulesList(); + /** + * repeated string importedModules = 3; + */ + int getImportedModulesCount(); + /** + * repeated string importedModules = 3; + */ + java.lang.String getImportedModules(int index); + /** + * repeated string importedModules = 3; + */ + com.google.protobuf.ByteString + getImportedModulesBytes(int index); } /** * Protobuf type {@code org.jetbrains.kotlin.serialization.js.Library} @@ -554,6 +584,23 @@ public final class JsProtoBuf { entry_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library.FileEntry.PARSER, extensionRegistry)); break; } + case 16: { + int rawValue = input.readEnum(); + org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library.Kind value = org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library.Kind.valueOf(rawValue); + if (value != null) { + bitField0_ |= 0x00000001; + kind_ = value; + } + break; + } + case 26: { + if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + importedModules_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000004; + } + importedModules_.add(input.readBytes()); + break; + } } } } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { @@ -565,6 +612,9 @@ public final class JsProtoBuf { if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { entry_ = java.util.Collections.unmodifiableList(entry_); } + if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + importedModules_ = new com.google.protobuf.UnmodifiableLazyStringList(importedModules_); + } makeExtensionsImmutable(); } } @@ -583,6 +633,71 @@ public final class JsProtoBuf { return PARSER; } + /** + * Protobuf enum {@code org.jetbrains.kotlin.serialization.js.Library.Kind} + */ + public enum Kind + implements com.google.protobuf.Internal.EnumLite { + /** + * PLAIN = 1; + */ + PLAIN(0, 1), + /** + * AMD = 2; + */ + AMD(1, 2), + /** + * COMMON_JS = 3; + */ + COMMON_JS(2, 3), + ; + + /** + * PLAIN = 1; + */ + public static final int PLAIN_VALUE = 1; + /** + * AMD = 2; + */ + public static final int AMD_VALUE = 2; + /** + * COMMON_JS = 3; + */ + public static final int COMMON_JS_VALUE = 3; + + + public final int getNumber() { return value; } + + public static Kind valueOf(int value) { + switch (value) { + case 1: return PLAIN; + case 2: return AMD; + case 3: return COMMON_JS; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public Kind findValueByNumber(int number) { + return Kind.valueOf(number); + } + }; + + private final int value; + + private Kind(int index, int value) { + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:org.jetbrains.kotlin.serialization.js.Library.Kind) + } + public interface FileEntryOrBuilder extends org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder { @@ -1091,6 +1206,7 @@ public final class JsProtoBuf { // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.Library.FileEntry) } + private int bitField0_; // repeated .org.jetbrains.kotlin.serialization.js.Library.FileEntry entry = 1; public static final int ENTRY_FIELD_NUMBER = 1; private java.util.List entry_; @@ -1127,8 +1243,56 @@ public final class JsProtoBuf { return entry_.get(index); } + // optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + public static final int KIND_FIELD_NUMBER = 2; + private org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library.Kind kind_; + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + public boolean hasKind() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + public org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library.Kind getKind() { + return kind_; + } + + // repeated string importedModules = 3; + public static final int IMPORTEDMODULES_FIELD_NUMBER = 3; + private com.google.protobuf.LazyStringList importedModules_; + /** + * repeated string importedModules = 3; + */ + public java.util.List + getImportedModulesList() { + return importedModules_; + } + /** + * repeated string importedModules = 3; + */ + public int getImportedModulesCount() { + return importedModules_.size(); + } + /** + * repeated string importedModules = 3; + */ + public java.lang.String getImportedModules(int index) { + return importedModules_.get(index); + } + /** + * repeated string importedModules = 3; + */ + public com.google.protobuf.ByteString + getImportedModulesBytes(int index) { + return importedModules_.getByteString(index); + } + private void initFields() { entry_ = java.util.Collections.emptyList(); + kind_ = org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library.Kind.PLAIN; + importedModules_ = com.google.protobuf.LazyStringArrayList.EMPTY; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -1151,6 +1315,12 @@ public final class JsProtoBuf { for (int i = 0; i < entry_.size(); i++) { output.writeMessage(1, entry_.get(i)); } + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeEnum(2, kind_.getNumber()); + } + for (int i = 0; i < importedModules_.size(); i++) { + output.writeBytes(3, importedModules_.getByteString(i)); + } } private int memoizedSerializedSize = -1; @@ -1163,6 +1333,19 @@ public final class JsProtoBuf { size += org.jetbrains.kotlin.protobuf.CodedOutputStream .computeMessageSize(1, entry_.get(i)); } + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(2, kind_.getNumber()); + } + { + int dataSize = 0; + for (int i = 0; i < importedModules_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(importedModules_.getByteString(i)); + } + size += dataSize; + size += 1 * getImportedModulesList().size(); + } memoizedSerializedSize = size; return size; } @@ -1256,6 +1439,10 @@ public final class JsProtoBuf { super.clear(); entry_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000001); + kind_ = org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library.Kind.PLAIN; + bitField0_ = (bitField0_ & ~0x00000002); + importedModules_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); return this; } @@ -1278,11 +1465,23 @@ public final class JsProtoBuf { public org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library buildPartial() { org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library result = new org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library(this); int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { entry_ = java.util.Collections.unmodifiableList(entry_); bitField0_ = (bitField0_ & ~0x00000001); } result.entry_ = entry_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000001; + } + result.kind_ = kind_; + if (((bitField0_ & 0x00000004) == 0x00000004)) { + importedModules_ = new com.google.protobuf.UnmodifiableLazyStringList( + importedModules_); + bitField0_ = (bitField0_ & ~0x00000004); + } + result.importedModules_ = importedModules_; + result.bitField0_ = to_bitField0_; return result; } @@ -1297,6 +1496,19 @@ public final class JsProtoBuf { entry_.addAll(other.entry_); } + } + if (other.hasKind()) { + setKind(other.getKind()); + } + if (!other.importedModules_.isEmpty()) { + if (importedModules_.isEmpty()) { + importedModules_ = other.importedModules_; + bitField0_ = (bitField0_ & ~0x00000004); + } else { + ensureImportedModulesIsMutable(); + importedModules_.addAll(other.importedModules_); + } + } return this; } @@ -1455,6 +1667,135 @@ public final class JsProtoBuf { return this; } + // optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + private org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library.Kind kind_ = org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library.Kind.PLAIN; + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + public boolean hasKind() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + public org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library.Kind getKind() { + return kind_; + } + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + public Builder setKind(org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library.Kind value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + kind_ = value; + + return this; + } + /** + * optional .org.jetbrains.kotlin.serialization.js.Library.Kind kind = 2 [default = PLAIN]; + */ + public Builder clearKind() { + bitField0_ = (bitField0_ & ~0x00000002); + kind_ = org.jetbrains.kotlin.serialization.js.JsProtoBuf.Library.Kind.PLAIN; + + return this; + } + + // repeated string importedModules = 3; + private com.google.protobuf.LazyStringList importedModules_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureImportedModulesIsMutable() { + if (!((bitField0_ & 0x00000004) == 0x00000004)) { + importedModules_ = new com.google.protobuf.LazyStringArrayList(importedModules_); + bitField0_ |= 0x00000004; + } + } + /** + * repeated string importedModules = 3; + */ + public java.util.List + getImportedModulesList() { + return java.util.Collections.unmodifiableList(importedModules_); + } + /** + * repeated string importedModules = 3; + */ + public int getImportedModulesCount() { + return importedModules_.size(); + } + /** + * repeated string importedModules = 3; + */ + public java.lang.String getImportedModules(int index) { + return importedModules_.get(index); + } + /** + * repeated string importedModules = 3; + */ + public com.google.protobuf.ByteString + getImportedModulesBytes(int index) { + return importedModules_.getByteString(index); + } + /** + * repeated string importedModules = 3; + */ + public Builder setImportedModules( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureImportedModulesIsMutable(); + importedModules_.set(index, value); + + return this; + } + /** + * repeated string importedModules = 3; + */ + public Builder addImportedModules( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureImportedModulesIsMutable(); + importedModules_.add(value); + + return this; + } + /** + * repeated string importedModules = 3; + */ + public Builder addAllImportedModules( + java.lang.Iterable values) { + ensureImportedModulesIsMutable(); + super.addAll(values, importedModules_); + + return this; + } + /** + * repeated string importedModules = 3; + */ + public Builder clearImportedModules() { + importedModules_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + + return this; + } + /** + * repeated string importedModules = 3; + */ + public Builder addImportedModulesBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureImportedModulesIsMutable(); + importedModules_.add(value); + + return this; + } + // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.Library) } 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 bb9edd8e151..a34d86ecfe0 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 @@ -27,7 +27,6 @@ import org.jetbrains.kotlin.serialization.DescriptorSerializer import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.StringTableImpl import org.jetbrains.kotlin.storage.StorageManager -import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream @@ -57,9 +56,16 @@ object KotlinJavascriptSerializationUtil { stream.toByteArray() } - @JvmStatic fun createPackageFragmentProvider(moduleDescriptor: ModuleDescriptor, metadata: ByteArray, storageManager: StorageManager): PackageFragmentProvider? { - val contentMap = metadata.toContentMap() + @JvmStatic fun readModule(metadata: ByteArray, storageManager: StorageManager, + kotlinModule: ModuleDescriptor): JsModuleDescriptor { + val prototype = metadata.toContentMap() + val packageFragmentProvider = createPackageFragmentProvider(kotlinModule, prototype.contentMap, storageManager); + return JsModuleDescriptor(kotlinModule.name.asString(), prototype.kind, prototype.imported, packageFragmentProvider) + } + + @JvmStatic private fun createPackageFragmentProvider(moduleDescriptor: ModuleDescriptor, contentMap: Map, + storageManager: StorageManager): PackageFragmentProvider? { val packageFqNames = getPackages(contentMap).map { FqName(it) }.toSet() if (packageFqNames.isEmpty()) return null @@ -77,27 +83,36 @@ object KotlinJavascriptSerializationUtil { null } } - else ByteArrayInputStream(contentMap.get(path)) + else ByteArrayInputStream(contentMap[path]) } } - fun contentMapToByteArray(contentMap: Map): ByteArray { + fun contentMapToByteArray(contentMap: Map, moduleKind: ModuleKind, importedModules: List): ByteArray { val contentBuilder = JsProtoBuf.Library.newBuilder() + + contentBuilder.kind = when (moduleKind) { + ModuleKind.PLAIN -> JsProtoBuf.Library.Kind.PLAIN + ModuleKind.AMD -> JsProtoBuf.Library.Kind.AMD + ModuleKind.COMMON_JS -> JsProtoBuf.Library.Kind.COMMON_JS + }; + + importedModules.forEach { contentBuilder.addImportedModules(it) } + contentMap.forEach { val entry = JsProtoBuf.Library.FileEntry.newBuilder().setPath(it.key).setContent(ByteString.copyFrom(it.value)).build() contentBuilder.addEntry(entry) } val byteStream = ByteArrayOutputStream() - val gzipOutputStream = GZIPOutputStream(byteStream) - contentBuilder.build().writeTo(gzipOutputStream) - gzipOutputStream.close() + GZIPOutputStream(byteStream).use { + contentBuilder.build().writeTo(it) + } return byteStream.toByteArray() } - fun metadataAsString(moduleName: String, moduleDescriptor: ModuleDescriptor): String = - KotlinJavascriptMetadataUtils.formatMetadataAsString(moduleName, moduleDescriptor.toBinaryMetadata()) + fun metadataAsString(jsDescriptor: JsModuleDescriptor): String = + KotlinJavascriptMetadataUtils.formatMetadataAsString(jsDescriptor.name, jsDescriptor.toBinaryMetadata()) fun serializePackage(module: ModuleDescriptor, fqName: FqName, writeFun: (String, ByteArray) -> Unit) { val packageView = module.getPackage(fqName) @@ -107,7 +122,8 @@ object KotlinJavascriptSerializationUtil { val serializerExtension = KotlinJavascriptSerializerExtension() val serializer = DescriptorSerializer.createTopLevel(serializerExtension) - val classifierDescriptors = DescriptorSerializer.sort(packageView.memberScope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS)) + val classifierDescriptors = DescriptorSerializer.sort(packageView.memberScope.getContributedDescriptors( + DescriptorKindFilter.CLASSIFIERS)) ClassSerializationUtil.serializeClasses(classifierDescriptors, serializer, object : ClassSerializationUtil.Sink { override fun writeClass(classDescriptor: ClassDescriptor, classProto: ProtoBuf.Class) { @@ -216,14 +232,10 @@ object KotlinJavascriptSerializationUtil { return result.map { it.substringAfter('/').replace('/', '.') }.toSet() } - private fun ModuleDescriptor.toBinaryMetadata(): ByteArray = - KotlinJavascriptSerializationUtil.contentMapToByteArray(toContentMap(this)) + private fun JsModuleDescriptor.toBinaryMetadata() = contentMapToByteArray(toContentMap(data), kind, imported) } -fun KotlinJavascriptMetadata.forEachFile(operation: (filePath: String, fileContent: ByteArray) -> Unit): Unit = - this.body.toContentMap().forEach { operation(it.key, it.value) } - -private fun ByteArray.toContentMap(): Map { +private fun ByteArray.toContentMap(): JsModuleProto { val gzipInputStream = GZIPInputStream(ByteArrayInputStream(this)) val content = JsProtoBuf.Library.parseFrom(gzipInputStream) gzipInputStream.close() @@ -231,5 +243,15 @@ private fun ByteArray.toContentMap(): Map { val contentMap: MutableMap = hashMapOf() content.entryList.forEach { entry -> contentMap[entry.path] = entry.content.toByteArray() } - return contentMap -} \ No newline at end of file + return JsModuleProto( + contentMap = contentMap, + kind = when (content.kind) { + null, JsProtoBuf.Library.Kind.PLAIN -> ModuleKind.PLAIN + JsProtoBuf.Library.Kind.AMD -> ModuleKind.AMD + JsProtoBuf.Library.Kind.COMMON_JS -> ModuleKind.COMMON_JS + }, + imported = content.importedModulesList + ) +} + +private class JsModuleProto(val contentMap: Map, val kind: ModuleKind, val imported: List) \ No newline at end of file diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ModuleKind.java b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ModuleKind.java new file mode 100644 index 00000000000..e6b222c2ab0 --- /dev/null +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ModuleKind.java @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2016 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.serialization.js; + +// TODO revisit module dependencies and general design of translator pipeline. This shouldn't be in js.serializer, +// but it's impossible to put this enum anywhere else. +public enum ModuleKind { + PLAIN, + AMD, + COMMON_JS +} diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java index b4699b452a2..2e267134f0c 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.resolve.BindingTrace; import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics; +import java.util.ArrayList; import java.util.List; import static org.jetbrains.kotlin.diagnostics.DiagnosticUtils.hasError; @@ -86,6 +87,8 @@ public final class K2JSTranslator { expandIsCalls(program, context); ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); - return new TranslationResult.Success(config, files, program, diagnostics, moduleDescriptor); + + List importedModules = new ArrayList(context.getImportedModules().keySet()); + return new TranslationResult.Success(config, files, program, diagnostics, importedModules, moduleDescriptor); } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/facade/TranslationResult.kt b/js/js.translator/src/org/jetbrains/kotlin/js/facade/TranslationResult.kt index a7e711af77d..d04bf2ed340 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/facade/TranslationResult.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/facade/TranslationResult.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder import org.jetbrains.kotlin.js.sourceMap.SourceMapBuilder import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics +import org.jetbrains.kotlin.serialization.js.JsModuleDescriptor import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils import java.io.File @@ -44,6 +45,7 @@ abstract class TranslationResult protected constructor(val diagnostics: Diagnost private val files: List, val program: JsProgram, diagnostics: Diagnostics, + private val importedModules: List, private val moduleDescriptor: ModuleDescriptor ) : TranslationResult(diagnostics) { @Suppress("unused") // Used in kotlin-web-demo in WebDemoTranslatorFacade @@ -73,7 +75,13 @@ abstract class TranslationResult protected constructor(val diagnostics: Diagnost if (config.configuration.getBoolean(JSConfigurationKeys.META_INFO)) { val metaFileName = KotlinJavascriptMetadataUtils.replaceSuffix(outputFile.name) - val metaFileContent = KotlinJavascriptSerializationUtil.metadataAsString(config.moduleId, moduleDescriptor) + val moduleDescription = JsModuleDescriptor( + name = config.moduleId, + data = moduleDescriptor, + kind = config.moduleKind, + imported = importedModules + ); + val metaFileContent = KotlinJavascriptSerializationUtil.metadataAsString(moduleDescription) val sourceFilesForMetaFile = ArrayList(sourceFiles) val jsMetaFile = SimpleOutputFile(sourceFilesForMetaFile, metaFileName, metaFileContent) outputFiles.add(jsMetaFile) diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java index 7e8b364d776..a83d85de7dd 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java @@ -24,7 +24,7 @@ import com.google.dart.compiler.backend.js.ast.metadata.MetadataProperties; import com.google.dart.compiler.backend.js.ast.metadata.SideEffectKind; import com.intellij.openapi.util.Factory; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.hash.LinkedHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.ReflectionTypes; @@ -42,6 +42,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject; import java.util.List; +import java.util.Collections; import java.util.Map; import java.util.Set; @@ -109,6 +110,11 @@ public final class StaticContext { @NotNull private final JsConfig config; + @NotNull + private final Map importedModules = new LinkedHashMap(); + + private Map importedModulesSafe; + //TODO: too many parameters in constructor private StaticContext( @NotNull JsProgram program, @@ -165,6 +171,14 @@ public final class StaticContext { return rootScope; } + @NotNull + public Map getImportedModules() { + if (importedModulesSafe == null) { + importedModulesSafe = Collections.unmodifiableMap(importedModules); + } + return importedModulesSafe; + } + @NotNull public JsScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) { JsScope scope = scopes.get(descriptor.getOriginal()); @@ -540,6 +554,13 @@ public final class StaticContext { return null; } + JsName moduleId = importedModules.get(moduleName); + if (moduleId == null) { + moduleId = rootScope.declareFreshName(suggestedModuleName(moduleName)); + importedModules.put(moduleName, moduleId); + } + // TODO: use just generated moduleId to refer to module. This requires to rewrite how JS module is written + return JsAstUtils.replaceRootReference( result, namer.getModuleReference(program.getStringLiteral(moduleName))); } @@ -635,6 +656,40 @@ public final class StaticContext { } } + private static String suggestedModuleName(String id) { + if (id.isEmpty()) { + return "_"; + } + + StringBuilder sb = new StringBuilder(id.length()); + char c = id.charAt(0); + if (Character.isJavaIdentifierStart(c)) { + sb.append(c); + } + else { + sb.append('_'); + if (Character.isJavaIdentifierPart(c)) { + sb.append(c); + } + } + + sb.append(Character.isJavaIdentifierStart(c) ? c : '_'); + for (int i = 1; i < id.length(); ++i) { + c = id.charAt(i); + sb.append(Character.isJavaIdentifierPart(c) ? c : '_'); + } + + return sb.toString(); + } + + @Nullable + private static ClassDescriptor getEnclosing(@Nullable DeclarationDescriptor descriptor) { + while (descriptor != null && !(descriptor instanceof ClassDescriptor)) { + descriptor = descriptor.getContainingDeclaration(); + } + return (ClassDescriptor) descriptor; + } + private static JsExpression applySideEffects(JsExpression expression, DeclarationDescriptor descriptor) { if (expression instanceof HasMetadata) { if (descriptor instanceof FunctionDescriptor || diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java index a487e9e32eb..efc46a1db80 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java @@ -91,6 +91,11 @@ public class TranslationContext { } } + @NotNull + public Map getImportedModules() { + return staticContext.getImportedModules(); + } + @Nullable public UsageTracker usageTracker() { return usageTracker;