From ac703dfda62dd5b4bfe1703e6c8c137922bed5c5 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 28 Jun 2016 17:49:17 +0300 Subject: [PATCH] KT-12877: serialize information about file annotations. For each top-level declaration store containing file. Use this information to properly handle file-targeted JsModule. --- .../serialization/js/DebugJsProtoBuf.java | 929 +++++++++++++++++- .../js/KotlinJavascriptSerializerTest.kt | 2 +- .../js/translate/utils/AnnotationsUtils.java | 66 +- js/js.serializer/src/js.proto | 8 + .../kotlin/serialization/js/JsProtoBuf.java | 633 ++++++++++++ .../serialization/js/KotlinFileRegistry.kt | 28 + .../js/KotlinJavascriptPackageFragment.kt | 43 + .../js/KotlinJavascriptSerializationUtil.kt | 47 +- ...KotlinJavascriptSerializedResourcePaths.kt | 3 + .../js/KotlinJavascriptSerializerExtension.kt | 41 +- .../jetbrains/kotlin/js/test/BasicBoxTest.kt | 22 +- .../js/test/MultipleFilesTranslationTest.java | 21 +- .../js/test/semantics/BoxJsTestGenerated.java | 51 + .../test/semantics/JsModuleTestGenerated.java | 61 -- .../kotlin/js/facade/K2JSTranslator.java | 5 +- .../kotlin/js/facade/TranslationResult.kt | 8 +- .../js/translate/context/StaticContext.java | 22 +- .../js/translate/general/Translation.java | 7 +- .../native => box/jsModule}/externalClass.js | 0 .../cases => box/jsModule}/externalClass.kt | 5 +- .../jsModule}/externalFunction.js | 0 .../jsModule}/externalFunction.kt | 4 +- .../native => box/jsModule}/externalObject.js | 0 .../cases => box/jsModule}/externalObject.kt | 4 +- .../testData/box/jsModule/externalPackage.js | 28 + .../testData/box/jsModule/externalPackage.kt | 31 + .../externalPackageInDifferentFile.js | 34 + .../externalPackageInDifferentFile.kt | 44 + .../jsModule}/externalProperty.js | 0 .../jsModule}/externalProperty.kt | 4 +- .../amd/jsModuleOnPackage.js | 28 + .../amd/jsModuleOnPackage.kt | 39 + .../cases/jsModuleOnPackage/dependencies.txt | 2 + .../cases/jsModuleOnPackage/lib/lib.kt | 16 + .../cases/jsModuleOnPackage/main/main.kt | 16 + 35 files changed, 2087 insertions(+), 165 deletions(-) create mode 100644 js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinFileRegistry.kt delete mode 100644 js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsModuleTestGenerated.java rename js/js.translator/testData/{jsModule/native => box/jsModule}/externalClass.js (100%) rename js/js.translator/testData/{jsModule/cases => box/jsModule}/externalClass.kt (66%) rename js/js.translator/testData/{jsModule/native => box/jsModule}/externalFunction.js (100%) rename js/js.translator/testData/{jsModule/cases => box/jsModule}/externalFunction.kt (51%) rename js/js.translator/testData/{jsModule/native => box/jsModule}/externalObject.js (100%) rename js/js.translator/testData/{jsModule/cases => box/jsModule}/externalObject.kt (76%) create mode 100644 js/js.translator/testData/box/jsModule/externalPackage.js create mode 100644 js/js.translator/testData/box/jsModule/externalPackage.kt create mode 100644 js/js.translator/testData/box/jsModule/externalPackageInDifferentFile.js create mode 100644 js/js.translator/testData/box/jsModule/externalPackageInDifferentFile.kt rename js/js.translator/testData/{jsModule/native => box/jsModule}/externalProperty.js (100%) rename js/js.translator/testData/{jsModule/cases => box/jsModule}/externalProperty.kt (53%) create mode 100644 js/js.translator/testData/box/multiModuleWrappers/amd/jsModuleOnPackage.js create mode 100644 js/js.translator/testData/box/multiModuleWrappers/amd/jsModuleOnPackage.kt create mode 100644 js/js.translator/testData/multiModuleWrappers/cases/jsModuleOnPackage/dependencies.txt create mode 100644 js/js.translator/testData/multiModuleWrappers/cases/jsModuleOnPackage/lib/lib.kt create mode 100644 js/js.translator/testData/multiModuleWrappers/cases/jsModuleOnPackage/main/main.kt 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 51b3ee21286..86adbd11b68 100644 --- a/build-common/test/org/jetbrains/kotlin/serialization/js/DebugJsProtoBuf.java +++ b/build-common/test/org/jetbrains/kotlin/serialization/js/DebugJsProtoBuf.java @@ -8,15 +8,795 @@ public final class DebugJsProtoBuf { public static void registerAllExtensions( org.jetbrains.kotlin.protobuf.ExtensionRegistry registry) { registry.add(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.classAnnotation); + registry.add(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.classContainingFileId); registry.add(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.constructorAnnotation); registry.add(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.functionAnnotation); + registry.add(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.functionContainingFileId); registry.add(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.propertyAnnotation); registry.add(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.compileTimeValue); + registry.add(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.propertyContainingFileId); registry.add(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.enumEntryAnnotation); registry.add(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.parameterAnnotation); registry.add(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.typeAnnotation); registry.add(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.typeParameterAnnotation); } + public interface FileOrBuilder extends + // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.File) + org.jetbrains.kotlin.protobuf.MessageOrBuilder { + + /** + * required int32 id = 1; + */ + boolean hasId(); + /** + * required int32 id = 1; + */ + int getId(); + + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + java.util.List + getAnnotationList(); + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation getAnnotation(int index); + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + int getAnnotationCount(); + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + java.util.List + getAnnotationOrBuilderList(); + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + org.jetbrains.kotlin.serialization.DebugProtoBuf.AnnotationOrBuilder getAnnotationOrBuilder( + int index); + } + /** + * Protobuf type {@code org.jetbrains.kotlin.serialization.js.File} + */ + public static final class File extends + org.jetbrains.kotlin.protobuf.GeneratedMessage implements + // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.File) + FileOrBuilder { + // Use File.newBuilder() to construct. + private File(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private File(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final File defaultInstance; + public static File getDefaultInstance() { + return defaultInstance; + } + + public File getDefaultInstanceForType() { + return defaultInstance; + } + + private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final org.jetbrains.kotlin.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private File( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields = + org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + bitField0_ |= 0x00000001; + id_ = input.readInt32(); + break; + } + case 18: { + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + annotation_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + annotation_.add(input.readMessage(org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.PARSER, extensionRegistry)); + break; + } + } + } + } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + annotation_ = java.util.Collections.unmodifiableList(annotation_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_File_descriptor; + } + + protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_File_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File.class, org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File.Builder.class); + } + + public static org.jetbrains.kotlin.protobuf.Parser PARSER = + new org.jetbrains.kotlin.protobuf.AbstractParser() { + public File parsePartialFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return new File(input, extensionRegistry); + } + }; + + @java.lang.Override + public org.jetbrains.kotlin.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + public static final int ID_FIELD_NUMBER = 1; + private int id_; + /** + * required int32 id = 1; + */ + public boolean hasId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required int32 id = 1; + */ + public int getId() { + return id_; + } + + public static final int ANNOTATION_FIELD_NUMBER = 2; + private java.util.List annotation_; + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public java.util.List getAnnotationList() { + return annotation_; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public java.util.List + getAnnotationOrBuilderList() { + return annotation_; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public int getAnnotationCount() { + return annotation_.size(); + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation getAnnotation(int index) { + return annotation_.get(index); + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public org.jetbrains.kotlin.serialization.DebugProtoBuf.AnnotationOrBuilder getAnnotationOrBuilder( + int index) { + return annotation_.get(index); + } + + private void initFields() { + id_ = 0; + annotation_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasId()) { + memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getAnnotationCount(); i++) { + if (!getAnnotation(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeInt32(1, id_); + } + for (int i = 0; i < annotation_.size(); i++) { + output.writeMessage(2, annotation_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += org.jetbrains.kotlin.protobuf.CodedOutputStream + .computeInt32Size(1, id_); + } + for (int i = 0; i < annotation_.size(); i++) { + size += org.jetbrains.kotlin.protobuf.CodedOutputStream + .computeMessageSize(2, annotation_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File parseFrom( + org.jetbrains.kotlin.protobuf.ByteString data) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File parseFrom( + org.jetbrains.kotlin.protobuf.ByteString data, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File parseFrom(byte[] data) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File parseFrom( + byte[] data, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File parseFrom( + java.io.InputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File parseDelimitedFrom( + java.io.InputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File parseFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File parseFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code org.jetbrains.kotlin.serialization.js.File} + */ + public static final class Builder extends + org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder implements + // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.File) + org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.FileOrBuilder { + public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_File_descriptor; + } + + protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_File_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File.class, org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File.Builder.class); + } + + // Construct using org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getAnnotationFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + id_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + if (annotationBuilder_ == null) { + annotation_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + } else { + annotationBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_File_descriptor; + } + + public org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File getDefaultInstanceForType() { + return org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File.getDefaultInstance(); + } + + public org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File build() { + org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File buildPartial() { + org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File result = new org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.id_ = id_; + if (annotationBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002)) { + annotation_ = java.util.Collections.unmodifiableList(annotation_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.annotation_ = annotation_; + } else { + result.annotation_ = annotationBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) { + if (other instanceof org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File) { + return mergeFrom((org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File other) { + if (other == org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File.getDefaultInstance()) return this; + if (other.hasId()) { + setId(other.getId()); + } + if (annotationBuilder_ == null) { + if (!other.annotation_.isEmpty()) { + if (annotation_.isEmpty()) { + annotation_ = other.annotation_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureAnnotationIsMutable(); + annotation_.addAll(other.annotation_); + } + onChanged(); + } + } else { + if (!other.annotation_.isEmpty()) { + if (annotationBuilder_.isEmpty()) { + annotationBuilder_.dispose(); + annotationBuilder_ = null; + annotation_ = other.annotation_; + bitField0_ = (bitField0_ & ~0x00000002); + annotationBuilder_ = + org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getAnnotationFieldBuilder() : null; + } else { + annotationBuilder_.addAllMessages(other.annotation_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasId()) { + + return false; + } + for (int i = 0; i < getAnnotationCount(); i++) { + if (!getAnnotation(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.jetbrains.kotlin.serialization.js.DebugJsProtoBuf.File) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private int id_ ; + /** + * required int32 id = 1; + */ + public boolean hasId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required int32 id = 1; + */ + public int getId() { + return id_; + } + /** + * required int32 id = 1; + */ + public Builder setId(int value) { + bitField0_ |= 0x00000001; + id_ = value; + onChanged(); + return this; + } + /** + * required int32 id = 1; + */ + public Builder clearId() { + bitField0_ = (bitField0_ & ~0x00000001); + id_ = 0; + onChanged(); + return this; + } + + private java.util.List annotation_ = + java.util.Collections.emptyList(); + private void ensureAnnotationIsMutable() { + if (!((bitField0_ & 0x00000002) == 0x00000002)) { + annotation_ = new java.util.ArrayList(annotation_); + bitField0_ |= 0x00000002; + } + } + + private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder< + org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation, org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.AnnotationOrBuilder> annotationBuilder_; + + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public java.util.List getAnnotationList() { + if (annotationBuilder_ == null) { + return java.util.Collections.unmodifiableList(annotation_); + } else { + return annotationBuilder_.getMessageList(); + } + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public int getAnnotationCount() { + if (annotationBuilder_ == null) { + return annotation_.size(); + } else { + return annotationBuilder_.getCount(); + } + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation getAnnotation(int index) { + if (annotationBuilder_ == null) { + return annotation_.get(index); + } else { + return annotationBuilder_.getMessage(index); + } + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder setAnnotation( + int index, org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation value) { + if (annotationBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureAnnotationIsMutable(); + annotation_.set(index, value); + onChanged(); + } else { + annotationBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder setAnnotation( + int index, org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Builder builderForValue) { + if (annotationBuilder_ == null) { + ensureAnnotationIsMutable(); + annotation_.set(index, builderForValue.build()); + onChanged(); + } else { + annotationBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder addAnnotation(org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation value) { + if (annotationBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureAnnotationIsMutable(); + annotation_.add(value); + onChanged(); + } else { + annotationBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder addAnnotation( + int index, org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation value) { + if (annotationBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureAnnotationIsMutable(); + annotation_.add(index, value); + onChanged(); + } else { + annotationBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder addAnnotation( + org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Builder builderForValue) { + if (annotationBuilder_ == null) { + ensureAnnotationIsMutable(); + annotation_.add(builderForValue.build()); + onChanged(); + } else { + annotationBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder addAnnotation( + int index, org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Builder builderForValue) { + if (annotationBuilder_ == null) { + ensureAnnotationIsMutable(); + annotation_.add(index, builderForValue.build()); + onChanged(); + } else { + annotationBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder addAllAnnotation( + java.lang.Iterable values) { + if (annotationBuilder_ == null) { + ensureAnnotationIsMutable(); + org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll( + values, annotation_); + onChanged(); + } else { + annotationBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder clearAnnotation() { + if (annotationBuilder_ == null) { + annotation_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + } else { + annotationBuilder_.clear(); + } + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder removeAnnotation(int index) { + if (annotationBuilder_ == null) { + ensureAnnotationIsMutable(); + annotation_.remove(index); + onChanged(); + } else { + annotationBuilder_.remove(index); + } + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Builder getAnnotationBuilder( + int index) { + return getAnnotationFieldBuilder().getBuilder(index); + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public org.jetbrains.kotlin.serialization.DebugProtoBuf.AnnotationOrBuilder getAnnotationOrBuilder( + int index) { + if (annotationBuilder_ == null) { + return annotation_.get(index); } else { + return annotationBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public java.util.List + getAnnotationOrBuilderList() { + if (annotationBuilder_ != null) { + return annotationBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(annotation_); + } + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Builder addAnnotationBuilder() { + return getAnnotationFieldBuilder().addBuilder( + org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance()); + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Builder addAnnotationBuilder( + int index) { + return getAnnotationFieldBuilder().addBuilder( + index, org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance()); + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public java.util.List + getAnnotationBuilderList() { + return getAnnotationFieldBuilder().getBuilderList(); + } + private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder< + org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation, org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.AnnotationOrBuilder> + getAnnotationFieldBuilder() { + if (annotationBuilder_ == null) { + annotationBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder< + org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation, org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.AnnotationOrBuilder>( + annotation_, + ((bitField0_ & 0x00000002) == 0x00000002), + getParentForChildren(), + isClean()); + annotation_ = null; + } + return annotationBuilder_; + } + + // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.File) + } + + static { + defaultInstance = new File(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.File) + } + public interface ClassesOrBuilder extends // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.Classes) org.jetbrains.kotlin.protobuf.MessageOrBuilder { @@ -2195,6 +2975,17 @@ public final class DebugJsProtoBuf { .newFileScopedGeneratedExtension( org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class, org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance()); + public static final int CLASS_CONTAINING_FILE_ID_FIELD_NUMBER = 135; + /** + * extend .org.jetbrains.kotlin.serialization.Class { ... } + */ + public static final + org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension< + org.jetbrains.kotlin.serialization.DebugProtoBuf.Class, + java.lang.Integer> classContainingFileId = org.jetbrains.kotlin.protobuf.GeneratedMessage + .newFileScopedGeneratedExtension( + java.lang.Integer.class, + null); public static final int CONSTRUCTOR_ANNOTATION_FIELD_NUMBER = 130; /** * extend .org.jetbrains.kotlin.serialization.Constructor { ... } @@ -2217,6 +3008,17 @@ public final class DebugJsProtoBuf { .newFileScopedGeneratedExtension( org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class, org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance()); + public static final int FUNCTION_CONTAINING_FILE_ID_FIELD_NUMBER = 135; + /** + * extend .org.jetbrains.kotlin.serialization.Function { ... } + */ + public static final + org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension< + org.jetbrains.kotlin.serialization.DebugProtoBuf.Function, + java.lang.Integer> functionContainingFileId = org.jetbrains.kotlin.protobuf.GeneratedMessage + .newFileScopedGeneratedExtension( + java.lang.Integer.class, + null); public static final int PROPERTY_ANNOTATION_FIELD_NUMBER = 130; /** * extend .org.jetbrains.kotlin.serialization.Property { ... } @@ -2239,6 +3041,17 @@ public final class DebugJsProtoBuf { .newFileScopedGeneratedExtension( org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Argument.Value.class, org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Argument.Value.getDefaultInstance()); + public static final int PROPERTY_CONTAINING_FILE_ID_FIELD_NUMBER = 135; + /** + * extend .org.jetbrains.kotlin.serialization.Property { ... } + */ + public static final + org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension< + org.jetbrains.kotlin.serialization.DebugProtoBuf.Property, + java.lang.Integer> propertyContainingFileId = org.jetbrains.kotlin.protobuf.GeneratedMessage + .newFileScopedGeneratedExtension( + java.lang.Integer.class, + null); public static final int ENUM_ENTRY_ANNOTATION_FIELD_NUMBER = 130; /** * extend .org.jetbrains.kotlin.serialization.EnumEntry { ... } @@ -2283,6 +3096,11 @@ public final class DebugJsProtoBuf { .newFileScopedGeneratedExtension( org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class, org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance()); + private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor + internal_static_org_jetbrains_kotlin_serialization_js_File_descriptor; + private static + org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_org_jetbrains_kotlin_serialization_js_File_fieldAccessorTable; private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor internal_static_org_jetbrains_kotlin_serialization_js_Classes_descriptor; private static @@ -2310,44 +3128,52 @@ public final class DebugJsProtoBuf { "\n#js/js.serializer/src/js.debug.proto\022%o" + "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\"\225\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\017imported_module\030\003 \003(\t\032*\n\tFileEntry\022\014" + - "\n\004path\030\001 \002(\t\022\017\n\007content\030\002 \002(\014\"2\n\004Kind\022\t\n", - "\005PLAIN\020\001\022\007\n\003AMD\020\002\022\r\n\tCOMMON_JS\020\003\022\007\n\003UMD\020" + - "\004:t\n\020class_annotation\022).org.jetbrains.ko" + - "tlin.serialization.Class\030\202\001 \003(\0132..org.je" + - "tbrains.kotlin.serialization.Annotation:" + - "\200\001\n\026constructor_annotation\022/.org.jetbrai" + - "ns.kotlin.serialization.Constructor\030\202\001 \003" + - "(\0132..org.jetbrains.kotlin.serialization." + - "Annotation:z\n\023function_annotation\022,.org." + - "jetbrains.kotlin.serialization.Function\030" + - "\202\001 \003(\0132..org.jetbrains.kotlin.serializat", - "ion.Annotation:z\n\023property_annotation\022,." + - "org.jetbrains.kotlin.serialization.Prope" + - "rty\030\202\001 \003(\0132..org.jetbrains.kotlin.serial" + - "ization.Annotation:\210\001\n\022compile_time_valu" + - "e\022,.org.jetbrains.kotlin.serialization.P" + - "roperty\030\203\001 \001(\0132=.org.jetbrains.kotlin.se" + - "rialization.Annotation.Argument.Value:}\n" + - "\025enum_entry_annotation\022-.org.jetbrains.k" + - "otlin.serialization.EnumEntry\030\202\001 \003(\0132..o" + - "rg.jetbrains.kotlin.serialization.Annota", - "tion:\201\001\n\024parameter_annotation\0222.org.jetb" + - "rains.kotlin.serialization.ValueParamete" + + ".proto\"V\n\004File\022\n\n\002id\030\001 \002(\005\022B\n\nannotation" + + "\030\002 \003(\0132..org.jetbrains.kotlin.serializat" + + "ion.Annotation\"!\n\007Classes\022\026\n\nclass_name\030" + + "\001 \003(\005B\002\020\001\"\225\002\n\007Library\022G\n\005entry\030\001 \003(\01328.o" + + "rg.jetbrains.kotlin.serialization.js.Lib" + + "rary.FileEntry\022H\n\004kind\030\002 \001(\01623.org.jetbr" + + "ains.kotlin.serialization.js.Library.Kin", + "d:\005PLAIN\022\027\n\017imported_module\030\003 \003(\t\032*\n\tFil" + + "eEntry\022\014\n\004path\030\001 \002(\t\022\017\n\007content\030\002 \002(\014\"2\n" + + "\004Kind\022\t\n\005PLAIN\020\001\022\007\n\003AMD\020\002\022\r\n\tCOMMON_JS\020\003" + + "\022\007\n\003UMD\020\004:t\n\020class_annotation\022).org.jetb" + + "rains.kotlin.serialization.Class\030\202\001 \003(\0132" + + "..org.jetbrains.kotlin.serialization.Ann" + + "otation:L\n\030class_containing_file_id\022).or" + + "g.jetbrains.kotlin.serialization.Class\030\207" + + "\001 \001(\005:\200\001\n\026constructor_annotation\022/.org.j" + + "etbrains.kotlin.serialization.Constructo", "r\030\202\001 \003(\0132..org.jetbrains.kotlin.serializ" + - "ation.Annotation:r\n\017type_annotation\022(.or" + - "g.jetbrains.kotlin.serialization.Type\030\202\001" + - " \003(\0132..org.jetbrains.kotlin.serializatio" + - "n.Annotation:\205\001\n\031type_parameter_annotati" + - "on\0221.org.jetbrains.kotlin.serialization." + - "TypeParameter\030\202\001 \003(\0132..org.jetbrains.kot" + - "lin.serialization.AnnotationB\021B\017DebugJsP", - "rotoBuf" + "ation.Annotation:z\n\023function_annotation\022" + + ",.org.jetbrains.kotlin.serialization.Fun" + + "ction\030\202\001 \003(\0132..org.jetbrains.kotlin.seri" + + "alization.Annotation:R\n\033function_contain" + + "ing_file_id\022,.org.jetbrains.kotlin.seria" + + "lization.Function\030\207\001 \001(\005:z\n\023property_ann" + + "otation\022,.org.jetbrains.kotlin.serializa" + + "tion.Property\030\202\001 \003(\0132..org.jetbrains.kot" + + "lin.serialization.Annotation:\210\001\n\022compile", + "_time_value\022,.org.jetbrains.kotlin.seria" + + "lization.Property\030\203\001 \001(\0132=.org.jetbrains" + + ".kotlin.serialization.Annotation.Argumen" + + "t.Value:R\n\033property_containing_file_id\022," + + ".org.jetbrains.kotlin.serialization.Prop" + + "erty\030\207\001 \001(\005:}\n\025enum_entry_annotation\022-.o" + + "rg.jetbrains.kotlin.serialization.EnumEn" + + "try\030\202\001 \003(\0132..org.jetbrains.kotlin.serial" + + "ization.Annotation:\201\001\n\024parameter_annotat" + + "ion\0222.org.jetbrains.kotlin.serialization", + ".ValueParameter\030\202\001 \003(\0132..org.jetbrains.k" + + "otlin.serialization.Annotation:r\n\017type_a" + + "nnotation\022(.org.jetbrains.kotlin.seriali" + + "zation.Type\030\202\001 \003(\0132..org.jetbrains.kotli" + + "n.serialization.Annotation:\205\001\n\031type_para" + + "meter_annotation\0221.org.jetbrains.kotlin." + + "serialization.TypeParameter\030\202\001 \003(\0132..org" + + ".jetbrains.kotlin.serialization.Annotati" + + "onB\021B\017DebugJsProtoBuf" }; org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { @@ -2362,14 +3188,20 @@ public final class DebugJsProtoBuf { new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor[] { org.jetbrains.kotlin.serialization.DebugProtoBuf.getDescriptor(), }, assigner); - internal_static_org_jetbrains_kotlin_serialization_js_Classes_descriptor = + internal_static_org_jetbrains_kotlin_serialization_js_File_descriptor = getDescriptor().getMessageTypes().get(0); + internal_static_org_jetbrains_kotlin_serialization_js_File_fieldAccessorTable = new + org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_org_jetbrains_kotlin_serialization_js_File_descriptor, + new java.lang.String[] { "Id", "Annotation", }); + internal_static_org_jetbrains_kotlin_serialization_js_Classes_descriptor = + getDescriptor().getMessageTypes().get(1); internal_static_org_jetbrains_kotlin_serialization_js_Classes_fieldAccessorTable = new org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_org_jetbrains_kotlin_serialization_js_Classes_descriptor, new java.lang.String[] { "ClassName", }); internal_static_org_jetbrains_kotlin_serialization_js_Library_descriptor = - getDescriptor().getMessageTypes().get(1); + getDescriptor().getMessageTypes().get(2); 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, @@ -2381,14 +3213,17 @@ public final class DebugJsProtoBuf { internal_static_org_jetbrains_kotlin_serialization_js_Library_FileEntry_descriptor, new java.lang.String[] { "Path", "Content", }); classAnnotation.internalInit(descriptor.getExtensions().get(0)); - constructorAnnotation.internalInit(descriptor.getExtensions().get(1)); - functionAnnotation.internalInit(descriptor.getExtensions().get(2)); - propertyAnnotation.internalInit(descriptor.getExtensions().get(3)); - compileTimeValue.internalInit(descriptor.getExtensions().get(4)); - enumEntryAnnotation.internalInit(descriptor.getExtensions().get(5)); - parameterAnnotation.internalInit(descriptor.getExtensions().get(6)); - typeAnnotation.internalInit(descriptor.getExtensions().get(7)); - typeParameterAnnotation.internalInit(descriptor.getExtensions().get(8)); + classContainingFileId.internalInit(descriptor.getExtensions().get(1)); + constructorAnnotation.internalInit(descriptor.getExtensions().get(2)); + functionAnnotation.internalInit(descriptor.getExtensions().get(3)); + functionContainingFileId.internalInit(descriptor.getExtensions().get(4)); + propertyAnnotation.internalInit(descriptor.getExtensions().get(5)); + compileTimeValue.internalInit(descriptor.getExtensions().get(6)); + propertyContainingFileId.internalInit(descriptor.getExtensions().get(7)); + enumEntryAnnotation.internalInit(descriptor.getExtensions().get(8)); + parameterAnnotation.internalInit(descriptor.getExtensions().get(9)); + typeAnnotation.internalInit(descriptor.getExtensions().get(10)); + typeParameterAnnotation.internalInit(descriptor.getExtensions().get(11)); org.jetbrains.kotlin.serialization.DebugProtoBuf.getDescriptor(); } diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt index 0c21008c6b9..78af6f0fc6b 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt @@ -77,7 +77,7 @@ class KotlinJavascriptSerializerTest : TestCaseWithTmpdir() { imported = listOf(), data = analysisResult.moduleDescriptor ) - FileUtil.writeToFile(metaFile, KotlinJavascriptSerializationUtil.metadataAsString(description)) + FileUtil.writeToFile(metaFile, KotlinJavascriptSerializationUtil.metadataAsString(analysisResult.bindingContext, description)) } finally { Disposer.dispose(rootDisposable) diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/translate/utils/AnnotationsUtils.java b/js/js.frontend/src/org/jetbrains/kotlin/js/translate/utils/AnnotationsUtils.java index 68e941337ff..1b16e8700db 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/translate/utils/AnnotationsUtils.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/translate/utils/AnnotationsUtils.java @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.js.translate.utils; +import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.*; @@ -24,8 +25,18 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget; import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.js.PredefinedAnnotation; import org.jetbrains.kotlin.name.FqName; +import org.jetbrains.kotlin.name.FqNameUnsafe; +import org.jetbrains.kotlin.psi.KtAnnotationEntry; +import org.jetbrains.kotlin.psi.KtFile; +import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.constants.ConstantValue; +import org.jetbrains.kotlin.resolve.source.PsiSourceFile; +import org.jetbrains.kotlin.serialization.js.KotlinJavascriptPackageFragment; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; public final class AnnotationsUtils { private static final String JS_NAME = "kotlin.js.JsName"; @@ -174,10 +185,63 @@ public final class AnnotationsUtils { @Nullable public static String getModuleName(@NotNull DeclarationDescriptor declaration) { AnnotationDescriptor annotation = declaration.getAnnotations().findAnnotation(JS_MODULE_ANNOTATION); - if (annotation == null) return null; + return annotation != null ? extractJsModuleName(annotation) : null; + } + @Nullable + public static String getFileModuleName(@NotNull BindingContext bindingContext, @NotNull DeclarationDescriptor declaration) { + for (AnnotationDescriptor annotation : getContainingFileAnnotations(bindingContext, declaration)) { + DeclarationDescriptor annotationType = annotation.getType().getConstructor().getDeclarationDescriptor(); + if (annotationType == null) continue; + + FqNameUnsafe fqName = DescriptorUtils.getFqName(annotation.getType().getConstructor().getDeclarationDescriptor()); + if (fqName.equals(JS_MODULE_ANNOTATION.toUnsafe())) { + return extractJsModuleName(annotation); + } + } + + return null; + } + + @NotNull + private static String extractJsModuleName(@NotNull AnnotationDescriptor annotation) { ConstantValue importValue = annotation.getAllValueArguments().values().iterator().next(); assert importValue != null : "JsModule annotation should have at least one argument"; return (String) importValue.getValue(); } + + @NotNull + public static List getContainingFileAnnotations( + @NotNull BindingContext bindingContext, + @NotNull DeclarationDescriptor descriptor + ) { + PackageFragmentDescriptor containingPackage = DescriptorUtils.getParentOfType(descriptor, PackageFragmentDescriptor.class, false); + if (containingPackage instanceof KotlinJavascriptPackageFragment) { + return ((KotlinJavascriptPackageFragment) containingPackage).getContainingFileAnnotations(descriptor); + } + + KtFile kotlinFile = getFile(descriptor); + if (kotlinFile != null) { + List annotations = new ArrayList(); + for (KtAnnotationEntry psiAnnotation : kotlinFile.getAnnotationEntries()) { + AnnotationDescriptor annotation = bindingContext.get(BindingContext.ANNOTATION, psiAnnotation); + annotations.add(annotation); + } + return annotations; + } + + return Collections.emptyList(); + } + + @Nullable + private static KtFile getFile(DeclarationDescriptor descriptor) { + if (!(descriptor instanceof DeclarationDescriptorWithSource)) return null; + SourceFile file = ((DeclarationDescriptorWithSource) descriptor).getSource().getContainingFile(); + if (!(file instanceof PsiSourceFile)) return null; + + PsiFile psiFile = ((PsiSourceFile) file).getPsiFile(); + if (!(psiFile instanceof KtFile)) return null; + + return (KtFile) psiFile; + } } diff --git a/js/js.serializer/src/js.proto b/js/js.serializer/src/js.proto index cde55f81ffa..f593e3ff49e 100644 --- a/js/js.serializer/src/js.proto +++ b/js/js.serializer/src/js.proto @@ -21,8 +21,14 @@ import "core/deserialization/src/descriptors.proto"; option java_outer_classname = "JsProtoBuf"; option optimize_for = LITE_RUNTIME; +message File { + required int32 id = 1; + repeated Annotation annotation = 2; +} + extend Class { repeated Annotation class_annotation = 130; + optional int32 class_containing_file_id = 135; } extend Constructor { @@ -31,11 +37,13 @@ extend Constructor { extend Function { repeated Annotation function_annotation = 130; + optional int32 function_containing_file_id = 135; } extend Property { repeated Annotation property_annotation = 130; optional Annotation.Argument.Value compile_time_value = 131; + optional int32 property_containing_file_id = 135; } extend EnumEntry { 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 f161788c22e..b6b0c89339d 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 @@ -8,15 +8,600 @@ public final class JsProtoBuf { public static void registerAllExtensions( org.jetbrains.kotlin.protobuf.ExtensionRegistryLite registry) { registry.add(org.jetbrains.kotlin.serialization.js.JsProtoBuf.classAnnotation); + registry.add(org.jetbrains.kotlin.serialization.js.JsProtoBuf.classContainingFileId); registry.add(org.jetbrains.kotlin.serialization.js.JsProtoBuf.constructorAnnotation); registry.add(org.jetbrains.kotlin.serialization.js.JsProtoBuf.functionAnnotation); + registry.add(org.jetbrains.kotlin.serialization.js.JsProtoBuf.functionContainingFileId); registry.add(org.jetbrains.kotlin.serialization.js.JsProtoBuf.propertyAnnotation); registry.add(org.jetbrains.kotlin.serialization.js.JsProtoBuf.compileTimeValue); + registry.add(org.jetbrains.kotlin.serialization.js.JsProtoBuf.propertyContainingFileId); registry.add(org.jetbrains.kotlin.serialization.js.JsProtoBuf.enumEntryAnnotation); registry.add(org.jetbrains.kotlin.serialization.js.JsProtoBuf.parameterAnnotation); registry.add(org.jetbrains.kotlin.serialization.js.JsProtoBuf.typeAnnotation); registry.add(org.jetbrains.kotlin.serialization.js.JsProtoBuf.typeParameterAnnotation); } + public interface FileOrBuilder extends + // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.File) + org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder { + + /** + * required int32 id = 1; + */ + boolean hasId(); + /** + * required int32 id = 1; + */ + int getId(); + + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + java.util.List + getAnnotationList(); + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + org.jetbrains.kotlin.serialization.ProtoBuf.Annotation getAnnotation(int index); + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + int getAnnotationCount(); + } + /** + * Protobuf type {@code org.jetbrains.kotlin.serialization.js.File} + */ + public static final class File extends + org.jetbrains.kotlin.protobuf.GeneratedMessageLite implements + // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.File) + FileOrBuilder { + // Use File.newBuilder() to construct. + private File(org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private File(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.ByteString.EMPTY;} + + private static final File defaultInstance; + public static File getDefaultInstance() { + return defaultInstance; + } + + public File getDefaultInstanceForType() { + return defaultInstance; + } + + private final org.jetbrains.kotlin.protobuf.ByteString unknownFields; + private File( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + org.jetbrains.kotlin.protobuf.ByteString.Output unknownFieldsOutput = + org.jetbrains.kotlin.protobuf.ByteString.newOutput(); + org.jetbrains.kotlin.protobuf.CodedOutputStream unknownFieldsCodedOutput = + org.jetbrains.kotlin.protobuf.CodedOutputStream.newInstance( + unknownFieldsOutput); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFieldsCodedOutput, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + bitField0_ |= 0x00000001; + id_ = input.readInt32(); + break; + } + case 18: { + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + annotation_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + annotation_.add(input.readMessage(org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.PARSER, extensionRegistry)); + break; + } + } + } + } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + annotation_ = java.util.Collections.unmodifiableList(annotation_); + } + try { + unknownFieldsCodedOutput.flush(); + } catch (java.io.IOException e) { + // Should not happen + } finally { + unknownFields = unknownFieldsOutput.toByteString(); + } + makeExtensionsImmutable(); + } + } + public static org.jetbrains.kotlin.protobuf.Parser PARSER = + new org.jetbrains.kotlin.protobuf.AbstractParser() { + public File parsePartialFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return new File(input, extensionRegistry); + } + }; + + @java.lang.Override + public org.jetbrains.kotlin.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + public static final int ID_FIELD_NUMBER = 1; + private int id_; + /** + * required int32 id = 1; + */ + public boolean hasId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required int32 id = 1; + */ + public int getId() { + return id_; + } + + public static final int ANNOTATION_FIELD_NUMBER = 2; + private java.util.List annotation_; + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public java.util.List getAnnotationList() { + return annotation_; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public java.util.List + getAnnotationOrBuilderList() { + return annotation_; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public int getAnnotationCount() { + return annotation_.size(); + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public org.jetbrains.kotlin.serialization.ProtoBuf.Annotation getAnnotation(int index) { + return annotation_.get(index); + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public org.jetbrains.kotlin.serialization.ProtoBuf.AnnotationOrBuilder getAnnotationOrBuilder( + int index) { + return annotation_.get(index); + } + + private void initFields() { + id_ = 0; + annotation_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasId()) { + memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getAnnotationCount(); i++) { + if (!getAnnotation(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeInt32(1, id_); + } + for (int i = 0; i < annotation_.size(); i++) { + output.writeMessage(2, annotation_.get(i)); + } + output.writeRawBytes(unknownFields); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += org.jetbrains.kotlin.protobuf.CodedOutputStream + .computeInt32Size(1, id_); + } + for (int i = 0; i < annotation_.size(); i++) { + size += org.jetbrains.kotlin.protobuf.CodedOutputStream + .computeMessageSize(2, annotation_.get(i)); + } + size += unknownFields.size(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.jetbrains.kotlin.serialization.js.JsProtoBuf.File parseFrom( + org.jetbrains.kotlin.protobuf.ByteString data) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.jetbrains.kotlin.serialization.js.JsProtoBuf.File parseFrom( + org.jetbrains.kotlin.protobuf.ByteString data, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.jetbrains.kotlin.serialization.js.JsProtoBuf.File parseFrom(byte[] data) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.jetbrains.kotlin.serialization.js.JsProtoBuf.File parseFrom( + byte[] data, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.jetbrains.kotlin.serialization.js.JsProtoBuf.File parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.jetbrains.kotlin.serialization.js.JsProtoBuf.File parseFrom( + java.io.InputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.jetbrains.kotlin.serialization.js.JsProtoBuf.File parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.jetbrains.kotlin.serialization.js.JsProtoBuf.File parseDelimitedFrom( + java.io.InputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.jetbrains.kotlin.serialization.js.JsProtoBuf.File parseFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.jetbrains.kotlin.serialization.js.JsProtoBuf.File parseFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.JsProtoBuf.File prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + /** + * Protobuf type {@code org.jetbrains.kotlin.serialization.js.File} + */ + public static final class Builder extends + org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder< + org.jetbrains.kotlin.serialization.js.JsProtoBuf.File, Builder> + implements + // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.File) + org.jetbrains.kotlin.serialization.js.JsProtoBuf.FileOrBuilder { + // Construct using org.jetbrains.kotlin.serialization.js.JsProtoBuf.File.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + id_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + annotation_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public org.jetbrains.kotlin.serialization.js.JsProtoBuf.File getDefaultInstanceForType() { + return org.jetbrains.kotlin.serialization.js.JsProtoBuf.File.getDefaultInstance(); + } + + public org.jetbrains.kotlin.serialization.js.JsProtoBuf.File build() { + org.jetbrains.kotlin.serialization.js.JsProtoBuf.File result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.jetbrains.kotlin.serialization.js.JsProtoBuf.File buildPartial() { + org.jetbrains.kotlin.serialization.js.JsProtoBuf.File result = new org.jetbrains.kotlin.serialization.js.JsProtoBuf.File(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.id_ = id_; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + annotation_ = java.util.Collections.unmodifiableList(annotation_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.annotation_ = annotation_; + result.bitField0_ = to_bitField0_; + return result; + } + + public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.JsProtoBuf.File other) { + if (other == org.jetbrains.kotlin.serialization.js.JsProtoBuf.File.getDefaultInstance()) return this; + if (other.hasId()) { + setId(other.getId()); + } + if (!other.annotation_.isEmpty()) { + if (annotation_.isEmpty()) { + annotation_ = other.annotation_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureAnnotationIsMutable(); + annotation_.addAll(other.annotation_); + } + + } + setUnknownFields( + getUnknownFields().concat(other.unknownFields)); + return this; + } + + public final boolean isInitialized() { + if (!hasId()) { + + return false; + } + for (int i = 0; i < getAnnotationCount(); i++) { + if (!getAnnotation(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.jetbrains.kotlin.serialization.js.JsProtoBuf.File parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.jetbrains.kotlin.serialization.js.JsProtoBuf.File) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private int id_ ; + /** + * required int32 id = 1; + */ + public boolean hasId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required int32 id = 1; + */ + public int getId() { + return id_; + } + /** + * required int32 id = 1; + */ + public Builder setId(int value) { + bitField0_ |= 0x00000001; + id_ = value; + + return this; + } + /** + * required int32 id = 1; + */ + public Builder clearId() { + bitField0_ = (bitField0_ & ~0x00000001); + id_ = 0; + + return this; + } + + private java.util.List annotation_ = + java.util.Collections.emptyList(); + private void ensureAnnotationIsMutable() { + if (!((bitField0_ & 0x00000002) == 0x00000002)) { + annotation_ = new java.util.ArrayList(annotation_); + bitField0_ |= 0x00000002; + } + } + + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public java.util.List getAnnotationList() { + return java.util.Collections.unmodifiableList(annotation_); + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public int getAnnotationCount() { + return annotation_.size(); + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public org.jetbrains.kotlin.serialization.ProtoBuf.Annotation getAnnotation(int index) { + return annotation_.get(index); + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder setAnnotation( + int index, org.jetbrains.kotlin.serialization.ProtoBuf.Annotation value) { + if (value == null) { + throw new NullPointerException(); + } + ensureAnnotationIsMutable(); + annotation_.set(index, value); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder setAnnotation( + int index, org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Builder builderForValue) { + ensureAnnotationIsMutable(); + annotation_.set(index, builderForValue.build()); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder addAnnotation(org.jetbrains.kotlin.serialization.ProtoBuf.Annotation value) { + if (value == null) { + throw new NullPointerException(); + } + ensureAnnotationIsMutable(); + annotation_.add(value); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder addAnnotation( + int index, org.jetbrains.kotlin.serialization.ProtoBuf.Annotation value) { + if (value == null) { + throw new NullPointerException(); + } + ensureAnnotationIsMutable(); + annotation_.add(index, value); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder addAnnotation( + org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Builder builderForValue) { + ensureAnnotationIsMutable(); + annotation_.add(builderForValue.build()); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder addAnnotation( + int index, org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Builder builderForValue) { + ensureAnnotationIsMutable(); + annotation_.add(index, builderForValue.build()); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder addAllAnnotation( + java.lang.Iterable values) { + ensureAnnotationIsMutable(); + org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll( + values, annotation_); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder clearAnnotation() { + annotation_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.serialization.Annotation annotation = 2; + */ + public Builder removeAnnotation(int index) { + ensureAnnotationIsMutable(); + annotation_.remove(index); + + return this; + } + + // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.File) + } + + static { + defaultInstance = new File(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.File) + } + public interface ClassesOrBuilder extends // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.Classes) org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder { @@ -1890,6 +2475,22 @@ public final class JsProtoBuf { org.jetbrains.kotlin.protobuf.WireFormat.FieldType.MESSAGE, false, org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.class); + public static final int CLASS_CONTAINING_FILE_ID_FIELD_NUMBER = 135; + /** + * extend .org.jetbrains.kotlin.serialization.Class { ... } + */ + public static final + org.jetbrains.kotlin.protobuf.GeneratedMessageLite.GeneratedExtension< + org.jetbrains.kotlin.serialization.ProtoBuf.Class, + java.lang.Integer> classContainingFileId = org.jetbrains.kotlin.protobuf.GeneratedMessageLite + .newSingularGeneratedExtension( + org.jetbrains.kotlin.serialization.ProtoBuf.Class.getDefaultInstance(), + 0, + null, + null, + 135, + org.jetbrains.kotlin.protobuf.WireFormat.FieldType.INT32, + java.lang.Integer.class); public static final int CONSTRUCTOR_ANNOTATION_FIELD_NUMBER = 130; /** * extend .org.jetbrains.kotlin.serialization.Constructor { ... } @@ -1922,6 +2523,22 @@ public final class JsProtoBuf { org.jetbrains.kotlin.protobuf.WireFormat.FieldType.MESSAGE, false, org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.class); + public static final int FUNCTION_CONTAINING_FILE_ID_FIELD_NUMBER = 135; + /** + * extend .org.jetbrains.kotlin.serialization.Function { ... } + */ + public static final + org.jetbrains.kotlin.protobuf.GeneratedMessageLite.GeneratedExtension< + org.jetbrains.kotlin.serialization.ProtoBuf.Function, + java.lang.Integer> functionContainingFileId = org.jetbrains.kotlin.protobuf.GeneratedMessageLite + .newSingularGeneratedExtension( + org.jetbrains.kotlin.serialization.ProtoBuf.Function.getDefaultInstance(), + 0, + null, + null, + 135, + org.jetbrains.kotlin.protobuf.WireFormat.FieldType.INT32, + java.lang.Integer.class); public static final int PROPERTY_ANNOTATION_FIELD_NUMBER = 130; /** * extend .org.jetbrains.kotlin.serialization.Property { ... } @@ -1954,6 +2571,22 @@ public final class JsProtoBuf { 131, org.jetbrains.kotlin.protobuf.WireFormat.FieldType.MESSAGE, org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value.class); + public static final int PROPERTY_CONTAINING_FILE_ID_FIELD_NUMBER = 135; + /** + * extend .org.jetbrains.kotlin.serialization.Property { ... } + */ + public static final + org.jetbrains.kotlin.protobuf.GeneratedMessageLite.GeneratedExtension< + org.jetbrains.kotlin.serialization.ProtoBuf.Property, + java.lang.Integer> propertyContainingFileId = org.jetbrains.kotlin.protobuf.GeneratedMessageLite + .newSingularGeneratedExtension( + org.jetbrains.kotlin.serialization.ProtoBuf.Property.getDefaultInstance(), + 0, + null, + null, + 135, + org.jetbrains.kotlin.protobuf.WireFormat.FieldType.INT32, + java.lang.Integer.class); public static final int ENUM_ENTRY_ANNOTATION_FIELD_NUMBER = 130; /** * extend .org.jetbrains.kotlin.serialization.EnumEntry { ... } diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinFileRegistry.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinFileRegistry.kt new file mode 100644 index 00000000000..d80cc8a4994 --- /dev/null +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinFileRegistry.kt @@ -0,0 +1,28 @@ +/* + * 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 + +import org.jetbrains.kotlin.psi.KtFile + +class KotlinFileRegistry { + private val fileIdsImpl = mutableMapOf() + + fun lookup(file: KtFile) = fileIdsImpl.getOrPut(file) { fileIdsImpl.size } + + val fileIds: Map + get() = fileIdsImpl +} 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 6b91f33eef8..277cc859238 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,13 +16,22 @@ package org.jetbrains.kotlin.serialization.js +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.protobuf.CodedInputStream +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.DeserializedPackageFragment import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor import org.jetbrains.kotlin.storage.StorageManager import java.io.InputStream @@ -37,6 +46,20 @@ class KotlinJavascriptPackageFragment( NameResolverImpl.read(stream) } + private val fileMap: Map by lazy { + loadResource(KotlinJavascriptSerializedResourcePaths.getFileListFilePath(fqName))?.use { rawInput -> + val input = CodedInputStream.newInstance(rawInput) + val count = input.readInt32() + val result = mutableListOf() + (1..count).forEach { result += JsProtoBuf.File.parseFrom(input) } + result.map { it.id to FileHolder(it.annotationList) }.toMap() + }.orEmpty() + } + + private val annotationDeserializer: AnnotationDeserializer by lazy { + AnnotationDeserializer(module, components.notFoundClasses) + } + override val classDataFinder = KotlinJavascriptClassDataFinder(nameResolver, loadResource) override fun computeMemberScope(): DeserializedPackageMemberScope = @@ -56,4 +79,24 @@ class KotlinJavascriptPackageFragment( private fun loadResourceSure(path: String): InputStream = loadResource(path) ?: throw IllegalStateException("Resource not found in classpath: $path") + + fun getContainingFileAnnotations(descriptor: DeclarationDescriptor): List { + if (DescriptorUtils.getParentOfType(descriptor, PackageFragmentDescriptor::class.java) != this) { + throw IllegalArgumentException("Provided descriptor $descriptor does not belong to this package $this") + } + val fileId = when (descriptor) { + is DeserializedClassDescriptor -> descriptor.classProto.getExtension(JsProtoBuf.classContainingFileId) + is DeserializedSimpleFunctionDescriptor -> descriptor.proto.getExtension(JsProtoBuf.functionContainingFileId) + is DeserializedPropertyDescriptor -> descriptor.proto.getExtension(JsProtoBuf.propertyContainingFileId) + else -> null + } + + return fileId?.let { fileMap[it] }?.annotations.orEmpty() + } + + private inner class FileHolder(val annotationsProto: List) { + val annotations: List by lazy { + annotationsProto.map { annotationDeserializer.deserializeAnnotation(it, nameResolver) } + } + } } 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 9699ba8e7bc..f39b6b7618e 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 @@ -19,10 +19,13 @@ package org.jetbrains.kotlin.serialization.js import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.protobuf.ByteString +import org.jetbrains.kotlin.protobuf.CodedOutputStream +import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.serialization.AnnotationSerializer import org.jetbrains.kotlin.serialization.DescriptorSerializer import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.StringTableImpl @@ -51,7 +54,7 @@ object KotlinJavascriptSerializationUtil { } private val STRING_TABLE_DEFAULT_BYTES = run { - val serializer = DescriptorSerializer.createTopLevel(KotlinJavascriptSerializerExtension()) + val serializer = DescriptorSerializer.createTopLevel(KotlinJavascriptSerializerExtension(KotlinFileRegistry())) val stream = ByteArrayOutputStream() serializer.stringTable.serializeTo(stream) stream.toByteArray() @@ -75,8 +78,7 @@ object KotlinJavascriptSerializationUtil { val packageFqNames = getPackages(contentMap).map(::FqName).toSet() if (packageFqNames.isEmpty()) return null - return createKotlinJavascriptPackageFragmentProvider(storageManager, moduleDescriptor, packageFqNames, configuration) { - path -> + return createKotlinJavascriptPackageFragmentProvider(storageManager, moduleDescriptor, packageFqNames, configuration) { path -> if (!contentMap.containsKey(path)) { when { isPackageMetadataFile(path) -> @@ -118,16 +120,18 @@ object KotlinJavascriptSerializationUtil { return byteStream.toByteArray() } - fun metadataAsString(jsDescriptor: JsModuleDescriptor): String = - KotlinJavascriptMetadataUtils.formatMetadataAsString(jsDescriptor.name, jsDescriptor.toBinaryMetadata()) + fun metadataAsString(bindingContext: BindingContext, jsDescriptor: JsModuleDescriptor): String = + KotlinJavascriptMetadataUtils.formatMetadataAsString(jsDescriptor.name, jsDescriptor.toBinaryMetadata(bindingContext)) - fun serializePackage(module: ModuleDescriptor, fqName: FqName, writeFun: (String, ByteArray) -> Unit) { + fun serializePackage(bindingContext: BindingContext, module: ModuleDescriptor, fqName: FqName, + writeFun: (String, ByteArray) -> Unit) { val packageView = module.getPackage(fqName) // TODO: ModuleDescriptor should be able to return the package only with the contents of that module, without dependencies val skip: (DeclarationDescriptor) -> Boolean = { DescriptorUtils.getContainingModule(it) != module } - val serializerExtension = KotlinJavascriptSerializerExtension() + val fileRegistry = KotlinFileRegistry() + val serializerExtension = KotlinJavascriptSerializerExtension(fileRegistry) val serializer = DescriptorSerializer.createTopLevel(serializerExtension) val classifierDescriptors = DescriptorSerializer.sort(packageView.memberScope.getContributedDescriptors( @@ -141,6 +145,9 @@ object KotlinJavascriptSerializationUtil { } }, skip) + writeFun(KotlinJavascriptSerializedResourcePaths.getFileListFilePath(fqName), + serializeFiles(fileRegistry, bindingContext, AnnotationSerializer(serializer.stringTable))) + val packageStream = ByteArrayOutputStream() val fragments = packageView.fragments val members = fragments @@ -190,15 +197,34 @@ object KotlinJavascriptSerializationUtil { } } + private fun serializeFiles(fileRegistry: KotlinFileRegistry, bindingContext: BindingContext, + serializer: AnnotationSerializer): ByteArray { + val filesProto = JsProtoBuf.Files.newBuilder() + for ((file, id) in fileRegistry.fileIds) { + val fileProto = JsProtoBuf.File.newBuilder() + fileProto.id = id + for (annotationPsi in file.annotationEntries) { + val annotation = bindingContext[BindingContext.ANNOTATION, annotationPsi]!! + fileProto.addAnnotation(serializer.serializeAnnotation(annotation)) + } + filesProto.addFile(fileProto) + } + + return ByteArrayOutputStream().use { out -> + filesProto.build().writeTo(out) + out + }.toByteArray() + } + private fun getFileName(classDescriptor: ClassDescriptor): String { return KotlinJavascriptSerializedResourcePaths.getClassMetadataPath(classDescriptor.classId!!) } - fun toContentMap(module: ModuleDescriptor): Map { + fun toContentMap(bindingContext: BindingContext, module: ModuleDescriptor): Map { val contentMap = hashMapOf() getPackagesFqNames(module).forEach { - serializePackage(module, it) { + serializePackage(bindingContext, module, it) { fileName, bytes -> contentMap[fileName] = bytes } } @@ -243,7 +269,8 @@ object KotlinJavascriptSerializationUtil { return result.map { it.substringAfter('/').replace('/', '.') }.toSet() } - private fun JsModuleDescriptor.toBinaryMetadata() = contentMapToByteArray(toContentMap(data), kind, imported) + private fun JsModuleDescriptor.toBinaryMetadata(bindingContext: BindingContext) = + contentMapToByteArray(toContentMap(bindingContext, data), kind, imported) } private fun ByteArray.readAsContentMap(name: String): JsModuleDescriptor> { diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializedResourcePaths.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializedResourcePaths.kt index 57441aa9868..07121d4a6d2 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializedResourcePaths.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializedResourcePaths.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.name.Name object KotlinJavascriptSerializedResourcePaths { private val CLASSES_FILE_EXTENSION = "kotlin_classes" private val STRING_TABLE_FILE_EXTENSION = "kotlin_string_table" + private val FILE_LIST_FILE_EXTENSION = "kotlin_file_table" fun getClassesInPackageFilePath(fqName: FqName): String = fqName.toPath().withSepIfNotEmpty() + shortName(fqName) + "." + CLASSES_FILE_EXTENSION @@ -39,6 +40,8 @@ object KotlinJavascriptSerializedResourcePaths { fun getStringTableFilePath(fqName: FqName): String = fqName.toPath().withSepIfNotEmpty() + shortName(fqName) + "." + STRING_TABLE_FILE_EXTENSION + fun getFileListFilePath(fqName: FqName) = fqName.toPath().withSepIfNotEmpty() + shortName(fqName) + "." + FILE_LIST_FILE_EXTENSION + private fun FqName.toPath() = this.asString().replace('.', '/') private fun String.withSepIfNotEmpty() = if (this.isEmpty()) this else this + "/" diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerExtension.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerExtension.kt index 705af6dfc1a..c669e175b21 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerExtension.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerExtension.kt @@ -16,16 +16,55 @@ package org.jetbrains.kotlin.serialization.js +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.source.PsiSourceFile import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol import org.jetbrains.kotlin.types.FlexibleType -class KotlinJavascriptSerializerExtension : KotlinSerializerExtensionBase(JsSerializerProtocol) { +class KotlinJavascriptSerializerExtension(private val fileRegistry: KotlinFileRegistry) : + KotlinSerializerExtensionBase(JsSerializerProtocol) { override fun serializeFlexibleType(flexibleType: FlexibleType, lowerProto: ProtoBuf.Type.Builder, upperProto: ProtoBuf.Type.Builder) { lowerProto.flexibleTypeCapabilitiesId = stringTable.getStringIndex(DynamicTypeDeserializer.id) } + + override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) { + val id = getFileId(descriptor) + if (id != null) { + proto.setExtension(JsProtoBuf.classContainingFileId, id) + } + super.serializeClass(descriptor, proto) + } + + override fun serializeProperty(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder) { + val id = getFileId(descriptor) + if (id != null) { + proto.setExtension(JsProtoBuf.propertyContainingFileId, id) + } + super.serializeProperty(descriptor, proto) + } + + override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder) { + val id = getFileId(descriptor) + if (id != null) { + proto.setExtension(JsProtoBuf.functionContainingFileId, id) + } + super.serializeFunction(descriptor, proto) + } + + private fun getFileId(descriptor: DeclarationDescriptor): Int? { + if (!DescriptorUtils.isTopLevelDeclaration(descriptor) || descriptor !is DeclarationDescriptorWithSource) return null + + val file = descriptor.source.containingFile + if (file !is PsiSourceFile) return null + + val psiFile = file.psiFile + return (psiFile as? KtFile)?.let { fileRegistry.lookup(it) } + } } object JsSerializerProtocol : SerializerExtensionProtocol( diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt index 37604010559..dcb2aad73d4 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt @@ -79,6 +79,8 @@ abstract class BasicBoxTest( val expectedText = KotlinTestUtils.doLoadFile(file) TestFileFactoryImpl().use { testFactory -> + testFactory.defaultModule.moduleKind + val inputFiles = KotlinTestUtils.createTestFiles(file.name, expectedText, testFactory) val modules = inputFiles .map { it.module }.distinct() @@ -116,7 +118,7 @@ abstract class BasicBoxTest( } val additionalFiles = mutableListOf() - if (modules.size > 1) { + if (modules.size > 1 || MODULE_KIND_PATTERN.matcher(expectedText).find()) { additionalFiles += MODULE_EMULATION_FILE } val additionalJsFile = filePath.removeSuffix("." + KotlinFileType.EXTENSION) + JavaScript.DOT_EXTENSION @@ -259,12 +261,14 @@ abstract class BasicBoxTest( return LibrarySourcesConfig(project, configuration) } - private inner class TestFileFactoryImpl() : TestFileFactory, Closeable { + private inner class TestFileFactoryImpl : TestFileFactory, Closeable { var testPackage: String? = null val tmpDir = KotlinTestUtils.tmpDir("js-tests") val defaultModule = TestModule(TEST_MODULE, emptyList()) override fun createFile(module: TestModule?, fileName: String, text: String, directives: Map): TestFile? { + val currentModule = module ?: defaultModule + val ktFile = KtPsiFactory(project).createFile(text) val boxFunction = ktFile.declarations.find { it is KtNamedFunction && it.name == TEST_FUNCTION } if (boxFunction != null) { @@ -274,22 +278,20 @@ abstract class BasicBoxTest( } } - if (module != null) { - val moduleKindMatcher = MODULE_KIND_PATTERN.matcher(text) - if (moduleKindMatcher.find()) { - module.moduleKind = ModuleKind.valueOf(moduleKindMatcher.group(1)) - } + val moduleKindMatcher = MODULE_KIND_PATTERN.matcher(text) + if (moduleKindMatcher.find()) { + currentModule.moduleKind = ModuleKind.valueOf(moduleKindMatcher.group(1)) } if (NO_INLINE_PATTERN.matcher(text).find()) { - (module ?: defaultModule).inliningDisabled = true + currentModule.inliningDisabled = true } - val temporaryFile = File(tmpDir, "${(module ?: defaultModule).name}/$fileName") + val temporaryFile = File(tmpDir, "${currentModule.name}/$fileName") KotlinTestUtils.mkdirs(temporaryFile.parentFile) temporaryFile.writeText(text, Charsets.UTF_8) - return TestFile(temporaryFile.absolutePath, module ?: defaultModule) + return TestFile(temporaryFile.absolutePath, currentModule) } override fun createModule(name: String, dependencies: List): TestModule? { diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/MultipleFilesTranslationTest.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/MultipleFilesTranslationTest.java index 6768ea095ae..eca192f183f 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/MultipleFilesTranslationTest.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/MultipleFilesTranslationTest.java @@ -33,20 +33,22 @@ public abstract class MultipleFilesTranslationTest extends BasicTest { @Override protected void checkFooBoxIsOkByPath(String filePath) throws Exception { - throw new UnsupportedOperationException("checkFooBoxIsOkByPath not supported yet in MultipleFilesTranslationTest"); + runMultiFileTest(getTestName(true), TEST_PACKAGE, TEST_FUNCTION, "OK"); } - protected void generateJsFromDir(@NotNull String dirName, @NotNull Iterable ecmaVersions) throws Exception { + private void generateJsFromDir(@NotNull String dirName, @NotNull Iterable ecmaVersions) throws Exception { List fullFilePaths = getAllFilesInDir(getInputFilePath(dirName)); generateJavaScriptFiles(fullFilePaths, dirName, MainCallParameters.noCall(), ecmaVersions); } - protected void runMultiFileTest(@NotNull String dirName, @NotNull String packageName, - @NotNull String functionName, @NotNull Object expectedResult) throws Exception { + private void runMultiFileTest( + @NotNull String dirName, @NotNull String packageName, + @NotNull String functionName, @NotNull Object expectedResult + ) throws Exception { runMultiFileTests(DEFAULT_ECMA_VERSIONS, dirName, packageName, functionName, expectedResult); } - protected void runMultiFileTests( + private void runMultiFileTests( @NotNull Iterable ecmaVersions, @NotNull String dirName, @NotNull String packageName, @@ -56,14 +58,5 @@ public abstract class MultipleFilesTranslationTest extends BasicTest { generateJsFromDir(dirName, ecmaVersions); runRhinoTests(dirName + ".kt", ecmaVersions, new RhinoFunctionResultChecker(TEST_MODULE, packageName, functionName, expectedResult)); } - - public void checkFooBoxIsTrue(@NotNull String dirName) throws Exception { - runMultiFileTest(dirName, TEST_PACKAGE, TEST_FUNCTION, true); - } - - public void checkFooBoxIsOk() throws Exception { - String dir = getTestName(true); - runMultiFileTest(dir, TEST_PACKAGE, TEST_FUNCTION, "OK"); - } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index cfb2bc39f23..0ecdc88116d 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -4974,6 +4974,51 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { } } + @TestMetadata("js/js.translator/testData/box/jsModule") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class JsModule extends AbstractBoxJsTest { + public void testAllFilesPresentInJsModule() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/box/jsModule"), Pattern.compile("^([^_](.+))\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("externalClass.kt") + public void testExternalClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/jsModule/externalClass.kt"); + doTest(fileName); + } + + @TestMetadata("externalFunction.kt") + public void testExternalFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/jsModule/externalFunction.kt"); + doTest(fileName); + } + + @TestMetadata("externalObject.kt") + public void testExternalObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/jsModule/externalObject.kt"); + doTest(fileName); + } + + @TestMetadata("externalPackage.kt") + public void testExternalPackage() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/jsModule/externalPackage.kt"); + doTest(fileName); + } + + @TestMetadata("externalPackageInDifferentFile.kt") + public void testExternalPackageInDifferentFile() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/jsModule/externalPackageInDifferentFile.kt"); + doTest(fileName); + } + + @TestMetadata("externalProperty.kt") + public void testExternalProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/jsModule/externalProperty.kt"); + doTest(fileName); + } + } + @TestMetadata("js/js.translator/testData/box/jsName") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -5218,6 +5263,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/box/multiModuleWrappers/amd"), Pattern.compile("^([^_](.+))\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("jsModuleOnPackage.kt") + public void testJsModuleOnPackage() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/multiModuleWrappers/amd/jsModuleOnPackage.kt"); + doTest(fileName); + } + @TestMetadata("moduleWithNonIdentifierName.kt") public void testModuleWithNonIdentifierName() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/multiModuleWrappers/amd/moduleWithNonIdentifierName.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsModuleTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsModuleTestGenerated.java deleted file mode 100644 index 380a3dcff80..00000000000 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsModuleTestGenerated.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.js.test.semantics; - -import com.intellij.testFramework.TestDataPath; -import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; -import org.jetbrains.kotlin.test.KotlinTestUtils; -import org.jetbrains.kotlin.test.TestMetadata; -import org.junit.runner.RunWith; - -import java.io.File; -import java.util.regex.Pattern; - -/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ -@SuppressWarnings("all") -@TestMetadata("js/js.translator/testData/jsModule/cases") -@TestDataPath("$PROJECT_ROOT") -@RunWith(JUnit3RunnerWithInners.class) -public class JsModuleTestGenerated extends AbstractJsModuleTest { - public void testAllFilesPresentInCases() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/jsModule/cases"), Pattern.compile("^(.+)\\.kt$"), true); - } - - @TestMetadata("externalClass.kt") - public void testExternalClass() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/jsModule/cases/externalClass.kt"); - doTest(fileName); - } - - @TestMetadata("externalFunction.kt") - public void testExternalFunction() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/jsModule/cases/externalFunction.kt"); - doTest(fileName); - } - - @TestMetadata("externalObject.kt") - public void testExternalObject() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/jsModule/cases/externalObject.kt"); - doTest(fileName); - } - - @TestMetadata("externalProperty.kt") - public void testExternalProperty() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/jsModule/cases/externalProperty.kt"); - doTest(fileName); - } -} 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 be8763dd08c..74b0eccb1bf 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 @@ -79,7 +79,7 @@ public final class K2JSTranslator { ModuleDescriptor moduleDescriptor = analysisResult.getModuleDescriptor(); Diagnostics diagnostics = bindingTrace.getBindingContext().getDiagnostics(); - TranslationContext context = Translation.generateAst(bindingTrace, files, mainCallParameters, config); + TranslationContext context = Translation.generateAst(bindingTrace, files, mainCallParameters, moduleDescriptor, config); ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); if (hasError(diagnostics)) return new TranslationResult.Fail(diagnostics); @@ -97,6 +97,7 @@ public final class K2JSTranslator { ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); List importedModules = new ArrayList(context.getImportedModules().keySet()); - return new TranslationResult.Success(config, files, program, diagnostics, importedModules, moduleDescriptor); + return new TranslationResult.Success(config, files, program, diagnostics, importedModules, moduleDescriptor, + bindingTrace.getBindingContext()); } } 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 0da4fd783be..cfe4b338bfe 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 @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.js.sourceMap.JsSourceGenerationVisitor 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.BindingContext import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics import org.jetbrains.kotlin.serialization.js.JsModuleDescriptor import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil @@ -45,7 +46,8 @@ abstract class TranslationResult protected constructor(val diagnostics: Diagnost val program: JsProgram, diagnostics: Diagnostics, private val importedModules: List, - private val moduleDescriptor: ModuleDescriptor + private val moduleDescriptor: ModuleDescriptor, + private val bindingContext: BindingContext ) : TranslationResult(diagnostics) { @Suppress("unused") // Used in kotlin-web-demo in WebDemoTranslatorFacade fun getCode(): String = getCode(TextOutputImpl(), sourceMapBuilder = null) @@ -80,14 +82,14 @@ abstract class TranslationResult protected constructor(val diagnostics: Diagnost kind = config.moduleKind, imported = importedModules ) - val metaFileContent = KotlinJavascriptSerializationUtil.metadataAsString(moduleDescription) + val metaFileContent = KotlinJavascriptSerializationUtil.metadataAsString(bindingContext, moduleDescription) val sourceFilesForMetaFile = ArrayList(sourceFiles) val jsMetaFile = SimpleOutputFile(sourceFilesForMetaFile, metaFileName, metaFileContent) outputFiles.add(jsMetaFile) } if (config.configuration.getBoolean(JSConfigurationKeys.KJSM)) { - KotlinJavascriptSerializationUtil.toContentMap(moduleDescriptor).forEach { + KotlinJavascriptSerializationUtil.toContentMap(bindingContext, moduleDescriptor).forEach { // TODO Add correct source files outputFiles.add(SimpleOutputBinaryFile(emptyList(), config.moduleId + VfsUtilCore.VFS_SEPARATOR_CHAR + it.key, it.value)) } 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 d1f0ce0a54c..7f0459bc56d 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 @@ -235,6 +235,18 @@ public final class StaticContext { @NotNull private JsExpression buildQualifiedExpression(@NotNull DeclarationDescriptor descriptor) { + String moduleName = AnnotationsUtils.getModuleName(descriptor); + if (moduleName != null) { + return JsAstUtils.pureFqn(getModuleInternalName(moduleName), null); + } + + if (isNativeObject(descriptor)) { + String fileModuleName = AnnotationsUtils.getFileModuleName(getBindingContext(), descriptor); + if (fileModuleName != null) { + return pureFqn(getNameForDescriptor(descriptor), pureFqn(getModuleInternalName(fileModuleName), null)); + } + } + if (descriptor instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) descriptor; if (KotlinBuiltIns.isAny(classDescriptor)) { @@ -396,9 +408,6 @@ public final class StaticContext { return config; } - // TODO: add this to NameSuggestion: - // String moduleName = AnnotationsUtils.getModuleName(descriptor); - @NotNull public JsName importDeclaration(@NotNull String suggestedName, @NotNull JsExpression declaration) { // Adding prefix is a workaround for a problem with scopes. @@ -599,12 +608,7 @@ public final class StaticContext { if (UNKNOWN_EXTERNAL_MODULE_NAME.equals(moduleName)) return null; - return getModuleReference(moduleName); - } - - @NotNull - private JsNameRef getModuleReference(@NotNull String baseName) { - return JsAstUtils.pureFqn(getModuleInternalName(baseName), null); + return getModuleInternalName(moduleName); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java index b51be3ba030..cef9f941463 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.descriptors.FunctionDescriptor; +import org.jetbrains.kotlin.descriptors.ModuleDescriptor; import org.jetbrains.kotlin.idea.MainFunctionDetector; import org.jetbrains.kotlin.js.config.JSConfigurationKeys; import org.jetbrains.kotlin.js.config.JsConfig; @@ -228,10 +229,11 @@ public final class Translation { @NotNull BindingTrace bindingTrace, @NotNull Collection files, @NotNull MainCallParameters mainCallParameters, + @NotNull ModuleDescriptor moduleDescriptor, @NotNull JsConfig config ) throws TranslationException { try { - return doGenerateAst(bindingTrace, files, mainCallParameters, config); + return doGenerateAst(bindingTrace, files, mainCallParameters, moduleDescriptor, config); } catch (UnsupportedOperationException e) { throw new UnsupportedFeatureException("Unsupported feature used.", e); @@ -246,9 +248,10 @@ public final class Translation { @NotNull BindingTrace bindingTrace, @NotNull Collection files, @NotNull MainCallParameters mainCallParameters, + @NotNull ModuleDescriptor moduleDescriptor, @NotNull JsConfig config ) { - StaticContext staticContext = StaticContext.generateStaticContext(bindingTrace, config); + StaticContext staticContext = StaticContext.generateStaticContext(bindingTrace, config, moduleDescriptor); JsProgram program = staticContext.getProgram(); JsName rootPackageName = program.getRootScope().declareName(Namer.getRootPackageName()); diff --git a/js/js.translator/testData/jsModule/native/externalClass.js b/js/js.translator/testData/box/jsModule/externalClass.js similarity index 100% rename from js/js.translator/testData/jsModule/native/externalClass.js rename to js/js.translator/testData/box/jsModule/externalClass.js diff --git a/js/js.translator/testData/jsModule/cases/externalClass.kt b/js/js.translator/testData/box/jsModule/externalClass.kt similarity index 66% rename from js/js.translator/testData/jsModule/cases/externalClass.kt rename to js/js.translator/testData/box/jsModule/externalClass.kt index bc519353308..3b733182ff3 100644 --- a/js/js.translator/testData/jsModule/cases/externalClass.kt +++ b/js/js.translator/testData/box/jsModule/externalClass.kt @@ -1,6 +1,8 @@ +// MODULE_KIND: AMD package foo -@JsModule("lib") @native class A(@native val x: Int = noImpl) { +@JsModule("lib") +@native class A(@native val x: Int = noImpl) { @native fun foo(y: Int): Int = noImpl } @@ -8,5 +10,6 @@ fun box(): String { val a = A(23) assertEquals(23, a.x) assertEquals(65, a.foo(42)) + return "OK" } \ No newline at end of file diff --git a/js/js.translator/testData/jsModule/native/externalFunction.js b/js/js.translator/testData/box/jsModule/externalFunction.js similarity index 100% rename from js/js.translator/testData/jsModule/native/externalFunction.js rename to js/js.translator/testData/box/jsModule/externalFunction.js diff --git a/js/js.translator/testData/jsModule/cases/externalFunction.kt b/js/js.translator/testData/box/jsModule/externalFunction.kt similarity index 51% rename from js/js.translator/testData/jsModule/cases/externalFunction.kt rename to js/js.translator/testData/box/jsModule/externalFunction.kt index 962af3c212d..a2cb32fabf4 100644 --- a/js/js.translator/testData/jsModule/cases/externalFunction.kt +++ b/js/js.translator/testData/box/jsModule/externalFunction.kt @@ -1,6 +1,8 @@ +// MODULE_KIND: AMD package foo -@JsModule("lib") @native fun foo(y: Int): Int = noImpl +@JsModule("lib") +@native fun foo(y: Int): Int = noImpl fun box(): String { assertEquals(65, foo(42)) diff --git a/js/js.translator/testData/jsModule/native/externalObject.js b/js/js.translator/testData/box/jsModule/externalObject.js similarity index 100% rename from js/js.translator/testData/jsModule/native/externalObject.js rename to js/js.translator/testData/box/jsModule/externalObject.js diff --git a/js/js.translator/testData/jsModule/cases/externalObject.kt b/js/js.translator/testData/box/jsModule/externalObject.kt similarity index 76% rename from js/js.translator/testData/jsModule/cases/externalObject.kt rename to js/js.translator/testData/box/jsModule/externalObject.kt index 849047d3a61..2a799bda81b 100644 --- a/js/js.translator/testData/jsModule/cases/externalObject.kt +++ b/js/js.translator/testData/box/jsModule/externalObject.kt @@ -1,6 +1,8 @@ +// MODULE_KIND: AMD package foo -@JsModule("lib") @native object A { +@JsModule("lib") +@native object A { @native val x: Int = noImpl @native fun foo(y: Int): Int = noImpl diff --git a/js/js.translator/testData/box/jsModule/externalPackage.js b/js/js.translator/testData/box/jsModule/externalPackage.js new file mode 100644 index 00000000000..6cf28680393 --- /dev/null +++ b/js/js.translator/testData/box/jsModule/externalPackage.js @@ -0,0 +1,28 @@ +define("lib", [], function() { + function A(x) { + this.x = x; + } + A.prototype.foo = function (y) { + return this.x + y; + }; + + B = { + x: 123, + foo: function(y) { + return this.x + y; + } + }; + + function foo(y) { + return 323 + y; + } + + var bar = 423; + + return { + A: A, + B: B, + foo: foo, + bar: bar + }; +}); \ No newline at end of file diff --git a/js/js.translator/testData/box/jsModule/externalPackage.kt b/js/js.translator/testData/box/jsModule/externalPackage.kt new file mode 100644 index 00000000000..81fc11480b7 --- /dev/null +++ b/js/js.translator/testData/box/jsModule/externalPackage.kt @@ -0,0 +1,31 @@ +// MODULE_KIND: AMD +@file:JsModule("lib") +package foo + +@native class A(@native val x: Int = noImpl) { + @native fun foo(y: Int): Int = noImpl +} + +@native object B { + @native val x: Int = noImpl + + @native fun foo(y: Int): Int = noImpl +} + +@native fun foo(y: Int): Int = noImpl + +@native val bar: Int = noImpl + +fun box(): String { + val a = A(23) + assertEquals(23, a.x) + assertEquals(65, a.foo(42)) + + assertEquals(123, B.x) + assertEquals(265, B.foo(142)) + + assertEquals(365, foo(23)) + assertEquals(423, bar) + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/box/jsModule/externalPackageInDifferentFile.js b/js/js.translator/testData/box/jsModule/externalPackageInDifferentFile.js new file mode 100644 index 00000000000..e945b85304b --- /dev/null +++ b/js/js.translator/testData/box/jsModule/externalPackageInDifferentFile.js @@ -0,0 +1,34 @@ +define("lib", [], function() { + function A(x) { + this.x = x; + } + A.prototype.foo = function (y) { + return this.x + y; + }; + + B = { + x: 123, + foo: function(y) { + return this.x + y; + } + }; + + function foo(y) { + return 323 + y; + } + + var bar = 423; + + return { + A: A, + B: B, + foo: foo, + bar: bar + }; +}); + +C = { + f: function() { + return 12345; + } +}; \ No newline at end of file diff --git a/js/js.translator/testData/box/jsModule/externalPackageInDifferentFile.kt b/js/js.translator/testData/box/jsModule/externalPackageInDifferentFile.kt new file mode 100644 index 00000000000..fecb2a5568f --- /dev/null +++ b/js/js.translator/testData/box/jsModule/externalPackageInDifferentFile.kt @@ -0,0 +1,44 @@ +// MODULE_KIND: AMD +// FILE: lib.kt +@file:JsModule("lib") +package foo + +@native class A(@native val x: Int = noImpl) { + @native fun foo(y: Int): Int = noImpl +} + +@native object B { + @native val x: Int = noImpl + + @native fun foo(y: Int): Int = noImpl +} + +@native fun foo(y: Int): Int = noImpl + +@native val bar: Int = noImpl + +// FILE: lib2.kt +package foo + +@native object C { + fun f(): Int = noImpl +} + +// FILE: main.kt +package foo + +fun box(): String { + val a = A(23) + assertEquals(23, a.x) + assertEquals(65, a.foo(42)) + + assertEquals(123, B.x) + assertEquals(265, B.foo(142)) + + assertEquals(365, foo(23)) + assertEquals(423, bar) + + assertEquals(12345, C.f()) + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/jsModule/native/externalProperty.js b/js/js.translator/testData/box/jsModule/externalProperty.js similarity index 100% rename from js/js.translator/testData/jsModule/native/externalProperty.js rename to js/js.translator/testData/box/jsModule/externalProperty.js diff --git a/js/js.translator/testData/jsModule/cases/externalProperty.kt b/js/js.translator/testData/box/jsModule/externalProperty.kt similarity index 53% rename from js/js.translator/testData/jsModule/cases/externalProperty.kt rename to js/js.translator/testData/box/jsModule/externalProperty.kt index d2889d863d4..7118eb09074 100644 --- a/js/js.translator/testData/jsModule/cases/externalProperty.kt +++ b/js/js.translator/testData/box/jsModule/externalProperty.kt @@ -1,6 +1,8 @@ +// MODULE_KIND: AMD package foo -@JsModule("lib") @native val foo: Int = noImpl +@JsModule("lib") +@native val foo: Int = noImpl fun box(): String { assertEquals(23, foo) diff --git a/js/js.translator/testData/box/multiModuleWrappers/amd/jsModuleOnPackage.js b/js/js.translator/testData/box/multiModuleWrappers/amd/jsModuleOnPackage.js new file mode 100644 index 00000000000..296a54aa94f --- /dev/null +++ b/js/js.translator/testData/box/multiModuleWrappers/amd/jsModuleOnPackage.js @@ -0,0 +1,28 @@ +define("native-lib", [], function() { + function A(x) { + this.x = x; + } + A.prototype.foo = function (y) { + return this.x + y; + }; + + B = { + x: 123, + foo: function(y) { + return this.x + y; + } + }; + + function foo(y) { + return 323 + y; + } + + var bar = 423; + + return { + A: A, + B: B, + foo: foo, + bar: bar + }; +}); \ No newline at end of file diff --git a/js/js.translator/testData/box/multiModuleWrappers/amd/jsModuleOnPackage.kt b/js/js.translator/testData/box/multiModuleWrappers/amd/jsModuleOnPackage.kt new file mode 100644 index 00000000000..3e3718624a2 --- /dev/null +++ b/js/js.translator/testData/box/multiModuleWrappers/amd/jsModuleOnPackage.kt @@ -0,0 +1,39 @@ +// MODULE: lib +// FILE: lib.kt +// MODULE_KIND: AMD +@file:JsModule("native-lib") +package foo + +@native class A(@native val x: Int = noImpl) { + @native fun foo(y: Int): Int = noImpl +} + +@native object B { + @native val x: Int = noImpl + + @native fun foo(y: Int): Int = noImpl +} + +@native fun foo(y: Int): Int = noImpl + +@native val bar: Int = noImpl + + +// MODULE: main(lib) +// FILE: main.kt +// MODULE_KIND: AMD +package foo + +fun box(): String { + val a = A(23) + assertEquals(23, a.x) + assertEquals(65, a.foo(42)) + + assertEquals(123, B.x) + assertEquals(265, B.foo(142)) + + assertEquals(365, foo(23)) + assertEquals(423, bar) + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/multiModuleWrappers/cases/jsModuleOnPackage/dependencies.txt b/js/js.translator/testData/multiModuleWrappers/cases/jsModuleOnPackage/dependencies.txt new file mode 100644 index 00000000000..e74a34660da --- /dev/null +++ b/js/js.translator/testData/multiModuleWrappers/cases/jsModuleOnPackage/dependencies.txt @@ -0,0 +1,2 @@ +lib-> +main->lib \ No newline at end of file diff --git a/js/js.translator/testData/multiModuleWrappers/cases/jsModuleOnPackage/lib/lib.kt b/js/js.translator/testData/multiModuleWrappers/cases/jsModuleOnPackage/lib/lib.kt new file mode 100644 index 00000000000..81629dba835 --- /dev/null +++ b/js/js.translator/testData/multiModuleWrappers/cases/jsModuleOnPackage/lib/lib.kt @@ -0,0 +1,16 @@ +@file:JsModule("native-lib") +package foo + +@native class A(@native val x: Int = noImpl) { + @native fun foo(y: Int): Int = noImpl +} + +@native object B { + @native val x: Int = noImpl + + @native fun foo(y: Int): Int = noImpl +} + +@native fun foo(y: Int): Int = noImpl + +@native val bar: Int = noImpl \ No newline at end of file diff --git a/js/js.translator/testData/multiModuleWrappers/cases/jsModuleOnPackage/main/main.kt b/js/js.translator/testData/multiModuleWrappers/cases/jsModuleOnPackage/main/main.kt new file mode 100644 index 00000000000..3dba15db599 --- /dev/null +++ b/js/js.translator/testData/multiModuleWrappers/cases/jsModuleOnPackage/main/main.kt @@ -0,0 +1,16 @@ +package foo + +fun box(): String { + val a = A(23) + assertEquals(23, a.x) + assertEquals(65, a.foo(42)) + + assertEquals(123, B.x) + assertEquals(265, B.foo(142)) + + /* TODO: get rid of usages of getQualifier, then uncomment it (it's already fixed by js-name branch) + assertEquals(365, foo(23)) + assertEquals(423, bar)*/ + + return "OK" +} \ No newline at end of file