From b781661279901b38e1b07030475c30ac7514d05f Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 12 Oct 2017 13:46:48 +0300 Subject: [PATCH] JS: fix copying functions with default arguments across interfaces Copy function to super interface first, then copy from interface to class. Add interface set to JsClassModel for this purpose. See KT-20625 --- .../js/ast/DebugJsAstProtoBuf.java | 230 +++++++++++++++--- .../kotlin/js/backend/ast/JsClassModel.kt | 1 + js/js.serializer/src/js-ast.proto | 1 + .../serialization/js/ast/JsAstDeserializer.kt | 1 + .../serialization/js/ast/JsAstProtoBuf.java | 171 ++++++++++++- .../serialization/js/ast/JsAstSerializer.kt | 1 + .../js/test/semantics/BoxJsTestGenerated.java | 6 + .../declaration/ClassModelGenerator.kt | 2 + .../kotlin/js/translate/general/Merger.kt | 7 +- .../inheritViaAnotherInterface.kt | 82 +++++++ 10 files changed, 453 insertions(+), 49 deletions(-) create mode 100644 js/js.translator/testData/box/defaultArguments/inheritViaAnotherInterface.kt diff --git a/build-common/test/org/jetbrains/kotlin/serialization/js/ast/DebugJsAstProtoBuf.java b/build-common/test/org/jetbrains/kotlin/serialization/js/ast/DebugJsAstProtoBuf.java index 8f32bf61ac4..d89f07ec27f 100644 --- a/build-common/test/org/jetbrains/kotlin/serialization/js/ast/DebugJsAstProtoBuf.java +++ b/build-common/test/org/jetbrains/kotlin/serialization/js/ast/DebugJsAstProtoBuf.java @@ -44837,6 +44837,19 @@ public final class DebugJsAstProtoBuf { */ int getSuperNameId(); + /** + * repeated int32 interface_name_id = 4; + */ + java.util.List getInterfaceNameIdList(); + /** + * repeated int32 interface_name_id = 4; + */ + int getInterfaceNameIdCount(); + /** + * repeated int32 interface_name_id = 4; + */ + int getInterfaceNameId(int index); + /** * optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3; */ @@ -44925,6 +44938,27 @@ public final class DebugJsAstProtoBuf { bitField0_ |= 0x00000004; break; } + case 32: { + if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + interfaceNameId_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000004; + } + interfaceNameId_.add(input.readInt32()); + break; + } + case 34: { + int length = input.readRawVarint32(); + int limit = input.pushLimit(length); + if (!((mutable_bitField0_ & 0x00000004) == 0x00000004) && input.getBytesUntilLimit() > 0) { + interfaceNameId_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000004; + } + while (input.getBytesUntilLimit() > 0) { + interfaceNameId_.add(input.readInt32()); + } + input.popLimit(limit); + break; + } } } } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { @@ -44933,6 +44967,9 @@ public final class DebugJsAstProtoBuf { throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { + if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + interfaceNameId_ = java.util.Collections.unmodifiableList(interfaceNameId_); + } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } @@ -44995,6 +45032,28 @@ public final class DebugJsAstProtoBuf { return superNameId_; } + public static final int INTERFACE_NAME_ID_FIELD_NUMBER = 4; + private java.util.List interfaceNameId_; + /** + * repeated int32 interface_name_id = 4; + */ + public java.util.List + getInterfaceNameIdList() { + return interfaceNameId_; + } + /** + * repeated int32 interface_name_id = 4; + */ + public int getInterfaceNameIdCount() { + return interfaceNameId_.size(); + } + /** + * repeated int32 interface_name_id = 4; + */ + public int getInterfaceNameId(int index) { + return interfaceNameId_.get(index); + } + public static final int POST_DECLARATION_BLOCK_FIELD_NUMBER = 3; private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock postDeclarationBlock_; /** @@ -45019,6 +45078,7 @@ public final class DebugJsAstProtoBuf { private void initFields() { nameId_ = 0; superNameId_ = 0; + interfaceNameId_ = java.util.Collections.emptyList(); postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance(); } private byte memoizedIsInitialized = -1; @@ -45053,6 +45113,9 @@ public final class DebugJsAstProtoBuf { if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeMessage(3, postDeclarationBlock_); } + for (int i = 0; i < interfaceNameId_.size(); i++) { + output.writeInt32(4, interfaceNameId_.get(i)); + } getUnknownFields().writeTo(output); } @@ -45074,6 +45137,15 @@ public final class DebugJsAstProtoBuf { size += org.jetbrains.kotlin.protobuf.CodedOutputStream .computeMessageSize(3, postDeclarationBlock_); } + { + int dataSize = 0; + for (int i = 0; i < interfaceNameId_.size(); i++) { + dataSize += org.jetbrains.kotlin.protobuf.CodedOutputStream + .computeInt32SizeNoTag(interfaceNameId_.get(i)); + } + size += dataSize; + size += 1 * getInterfaceNameIdList().size(); + } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -45196,12 +45268,14 @@ public final class DebugJsAstProtoBuf { bitField0_ = (bitField0_ & ~0x00000001); superNameId_ = 0; bitField0_ = (bitField0_ & ~0x00000002); + interfaceNameId_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); if (postDeclarationBlockBuilder_ == null) { postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance(); } else { postDeclarationBlockBuilder_.clear(); } - bitField0_ = (bitField0_ & ~0x00000004); + bitField0_ = (bitField0_ & ~0x00000008); return this; } @@ -45238,7 +45312,12 @@ public final class DebugJsAstProtoBuf { to_bitField0_ |= 0x00000002; } result.superNameId_ = superNameId_; - if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + if (((bitField0_ & 0x00000004) == 0x00000004)) { + interfaceNameId_ = java.util.Collections.unmodifiableList(interfaceNameId_); + bitField0_ = (bitField0_ & ~0x00000004); + } + result.interfaceNameId_ = interfaceNameId_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { to_bitField0_ |= 0x00000004; } if (postDeclarationBlockBuilder_ == null) { @@ -45268,6 +45347,16 @@ public final class DebugJsAstProtoBuf { if (other.hasSuperNameId()) { setSuperNameId(other.getSuperNameId()); } + if (!other.interfaceNameId_.isEmpty()) { + if (interfaceNameId_.isEmpty()) { + interfaceNameId_ = other.interfaceNameId_; + bitField0_ = (bitField0_ & ~0x00000004); + } else { + ensureInterfaceNameIdIsMutable(); + interfaceNameId_.addAll(other.interfaceNameId_); + } + onChanged(); + } if (other.hasPostDeclarationBlock()) { mergePostDeclarationBlock(other.getPostDeclarationBlock()); } @@ -45372,6 +45461,72 @@ public final class DebugJsAstProtoBuf { return this; } + private java.util.List interfaceNameId_ = java.util.Collections.emptyList(); + private void ensureInterfaceNameIdIsMutable() { + if (!((bitField0_ & 0x00000004) == 0x00000004)) { + interfaceNameId_ = new java.util.ArrayList(interfaceNameId_); + bitField0_ |= 0x00000004; + } + } + /** + * repeated int32 interface_name_id = 4; + */ + public java.util.List + getInterfaceNameIdList() { + return java.util.Collections.unmodifiableList(interfaceNameId_); + } + /** + * repeated int32 interface_name_id = 4; + */ + public int getInterfaceNameIdCount() { + return interfaceNameId_.size(); + } + /** + * repeated int32 interface_name_id = 4; + */ + public int getInterfaceNameId(int index) { + return interfaceNameId_.get(index); + } + /** + * repeated int32 interface_name_id = 4; + */ + public Builder setInterfaceNameId( + int index, int value) { + ensureInterfaceNameIdIsMutable(); + interfaceNameId_.set(index, value); + onChanged(); + return this; + } + /** + * repeated int32 interface_name_id = 4; + */ + public Builder addInterfaceNameId(int value) { + ensureInterfaceNameIdIsMutable(); + interfaceNameId_.add(value); + onChanged(); + return this; + } + /** + * repeated int32 interface_name_id = 4; + */ + public Builder addAllInterfaceNameId( + java.lang.Iterable values) { + ensureInterfaceNameIdIsMutable(); + org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll( + values, interfaceNameId_); + onChanged(); + return this; + } + /** + * repeated int32 interface_name_id = 4; + */ + public Builder clearInterfaceNameId() { + interfaceNameId_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + return this; + } + private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance(); private org.jetbrains.kotlin.protobuf.SingleFieldBuilder< org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder> postDeclarationBlockBuilder_; @@ -45379,7 +45534,7 @@ public final class DebugJsAstProtoBuf { * optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3; */ public boolean hasPostDeclarationBlock() { - return ((bitField0_ & 0x00000004) == 0x00000004); + return ((bitField0_ & 0x00000008) == 0x00000008); } /** * optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3; @@ -45404,7 +45559,7 @@ public final class DebugJsAstProtoBuf { } else { postDeclarationBlockBuilder_.setMessage(value); } - bitField0_ |= 0x00000004; + bitField0_ |= 0x00000008; return this; } /** @@ -45418,7 +45573,7 @@ public final class DebugJsAstProtoBuf { } else { postDeclarationBlockBuilder_.setMessage(builderForValue.build()); } - bitField0_ |= 0x00000004; + bitField0_ |= 0x00000008; return this; } /** @@ -45426,7 +45581,7 @@ public final class DebugJsAstProtoBuf { */ public Builder mergePostDeclarationBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock value) { if (postDeclarationBlockBuilder_ == null) { - if (((bitField0_ & 0x00000004) == 0x00000004) && + if (((bitField0_ & 0x00000008) == 0x00000008) && postDeclarationBlock_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance()) { postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.newBuilder(postDeclarationBlock_).mergeFrom(value).buildPartial(); @@ -45437,7 +45592,7 @@ public final class DebugJsAstProtoBuf { } else { postDeclarationBlockBuilder_.mergeFrom(value); } - bitField0_ |= 0x00000004; + bitField0_ |= 0x00000008; return this; } /** @@ -45450,14 +45605,14 @@ public final class DebugJsAstProtoBuf { } else { postDeclarationBlockBuilder_.clear(); } - bitField0_ = (bitField0_ & ~0x00000004); + bitField0_ = (bitField0_ & ~0x00000008); return this; } /** * optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3; */ public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder getPostDeclarationBlockBuilder() { - bitField0_ |= 0x00000004; + bitField0_ |= 0x00000008; onChanged(); return getPostDeclarationBlockFieldBuilder().getBuilder(); } @@ -49376,33 +49531,34 @@ public final class DebugJsAstProtoBuf { "expression\030\002 \002(\01325.org.jetbrains.kotlin." + "serialization.js.ast.Expression\"3\n\013NameB" + "inding\022\024\n\014signature_id\030\001 \002(\005\022\016\n\006nameId\030\002" + - " \002(\005\"\214\001\n\nClassModel\022\017\n\007name_id\030\001 \002(\005\022\025\n\r" + - "super_name_id\030\002 \001(\005\022V\n\026post_declaration_" + - "block\030\003 \001(\01326.org.jetbrains.kotlin.seria" + - "lization.js.ast.GlobalBlock\";\n\014InlineMod" + - "ule\022\024\n\014signature_id\030\001 \002(\005\022\025\n\rexpression_" + - "id\030\002 \002(\005\"\034\n\013StringTable\022\r\n\005entry\030\001 \003(\t\"K" + - "\n\tNameTable\022>\n\005entry\030\001 \003(\0132/.org.jetbrai", - "ns.kotlin.serialization.js.ast.Name\"\263\001\n\004" + - "Name\022\021\n\ttemporary\030\001 \002(\010\022\022\n\nidentifier\030\002 " + - "\001(\005\022\025\n\rlocal_name_id\030\003 \001(\005\022\027\n\010imported\030\004" + - " \001(\010:\005false\022T\n\020special_function\030\005 \001(\0162:." + - "org.jetbrains.kotlin.serialization.js.as" + - "t.SpecialFunction\"\346\001\n\005Chunk\022L\n\014string_ta" + - "ble\030\001 \002(\01326.org.jetbrains.kotlin.seriali" + - "zation.js.ast.StringTable\022H\n\nname_table\030" + - "\002 \002(\01324.org.jetbrains.kotlin.serializati" + - "on.js.ast.NameTable\022E\n\010fragment\030\003 \002(\01323.", - "org.jetbrains.kotlin.serialization.js.as" + - "t.Fragment*@\n\013SideEffects\022\021\n\rAFFECTS_STA" + - "TE\020\001\022\024\n\020DEPENDS_ON_STATE\020\002\022\010\n\004PURE\020\003*?\n\016" + - "InlineStrategy\022\017\n\013AS_FUNCTION\020\000\022\014\n\010IN_PL" + - "ACE\020\001\022\016\n\nNOT_INLINE\020\002*\275\001\n\017SpecialFunctio" + - "n\022\032\n\026DEFINE_INLINE_FUNCTION\020\001\022\021\n\rWRAP_FU" + - "NCTION\020\002\022\021\n\rTO_BOXED_CHAR\020\003\022\016\n\nUNBOX_CHA" + - "R\020\004\022\020\n\014SUSPEND_CALL\020\005\022\024\n\020COROUTINE_RESUL" + - "T\020\006\022\030\n\024COROUTINE_CONTROLLER\020\007\022\026\n\022COROUTI" + - "NE_RECEIVER\020\010B\024B\022DebugJsAstProtoBuf" + " \002(\005\"\247\001\n\nClassModel\022\017\n\007name_id\030\001 \002(\005\022\025\n\r" + + "super_name_id\030\002 \001(\005\022\031\n\021interface_name_id" + + "\030\004 \003(\005\022V\n\026post_declaration_block\030\003 \001(\01326" + + ".org.jetbrains.kotlin.serialization.js.a" + + "st.GlobalBlock\";\n\014InlineModule\022\024\n\014signat" + + "ure_id\030\001 \002(\005\022\025\n\rexpression_id\030\002 \002(\005\"\034\n\013S" + + "tringTable\022\r\n\005entry\030\001 \003(\t\"K\n\tNameTable\022>", + "\n\005entry\030\001 \003(\0132/.org.jetbrains.kotlin.ser" + + "ialization.js.ast.Name\"\263\001\n\004Name\022\021\n\ttempo" + + "rary\030\001 \002(\010\022\022\n\nidentifier\030\002 \001(\005\022\025\n\rlocal_" + + "name_id\030\003 \001(\005\022\027\n\010imported\030\004 \001(\010:\005false\022T" + + "\n\020special_function\030\005 \001(\0162:.org.jetbrains" + + ".kotlin.serialization.js.ast.SpecialFunc" + + "tion\"\346\001\n\005Chunk\022L\n\014string_table\030\001 \002(\01326.o" + + "rg.jetbrains.kotlin.serialization.js.ast" + + ".StringTable\022H\n\nname_table\030\002 \002(\01324.org.j" + + "etbrains.kotlin.serialization.js.ast.Nam", + "eTable\022E\n\010fragment\030\003 \002(\01323.org.jetbrains" + + ".kotlin.serialization.js.ast.Fragment*@\n" + + "\013SideEffects\022\021\n\rAFFECTS_STATE\020\001\022\024\n\020DEPEN" + + "DS_ON_STATE\020\002\022\010\n\004PURE\020\003*?\n\016InlineStrateg" + + "y\022\017\n\013AS_FUNCTION\020\000\022\014\n\010IN_PLACE\020\001\022\016\n\nNOT_" + + "INLINE\020\002*\275\001\n\017SpecialFunction\022\032\n\026DEFINE_I" + + "NLINE_FUNCTION\020\001\022\021\n\rWRAP_FUNCTION\020\002\022\021\n\rT" + + "O_BOXED_CHAR\020\003\022\016\n\nUNBOX_CHAR\020\004\022\020\n\014SUSPEN" + + "D_CALL\020\005\022\024\n\020COROUTINE_RESULT\020\006\022\030\n\024COROUT" + + "INE_CONTROLLER\020\007\022\026\n\022COROUTINE_RECEIVER\020\010", + "B\024B\022DebugJsAstProtoBuf" }; org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { @@ -49715,7 +49871,7 @@ public final class DebugJsAstProtoBuf { internal_static_org_jetbrains_kotlin_serialization_js_ast_ClassModel_fieldAccessorTable = new org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_org_jetbrains_kotlin_serialization_js_ast_ClassModel_descriptor, - new java.lang.String[] { "NameId", "SuperNameId", "PostDeclarationBlock", }); + new java.lang.String[] { "NameId", "SuperNameId", "InterfaceNameId", "PostDeclarationBlock", }); internal_static_org_jetbrains_kotlin_serialization_js_ast_InlineModule_descriptor = getDescriptor().getMessageTypes().get(50); internal_static_org_jetbrains_kotlin_serialization_js_ast_InlineModule_fieldAccessorTable = new diff --git a/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/JsClassModel.kt b/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/JsClassModel.kt index 13eed8b27cb..0a4df27a1cd 100644 --- a/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/JsClassModel.kt +++ b/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/JsClassModel.kt @@ -17,5 +17,6 @@ package org.jetbrains.kotlin.js.backend.ast class JsClassModel(val name: JsName, val superName: JsName?) { + val interfaces: MutableSet = mutableSetOf() val postDeclarationBlock = JsGlobalBlock() } diff --git a/js/js.serializer/src/js-ast.proto b/js/js.serializer/src/js-ast.proto index 9635474d45d..eca42fe7395 100644 --- a/js/js.serializer/src/js-ast.proto +++ b/js/js.serializer/src/js-ast.proto @@ -403,6 +403,7 @@ message NameBinding { message ClassModel { required int32 name_id = 1; optional int32 super_name_id = 2; + repeated int32 interface_name_id = 4; optional GlobalBlock post_declaration_block = 3; } diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstDeserializer.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstDeserializer.kt index 06ccb635204..af29c241d0a 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstDeserializer.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstDeserializer.kt @@ -103,6 +103,7 @@ class JsAstDeserializer(program: JsProgram, private val sourceRoots: Iterablerepeated int32 interface_name_id = 4; + */ + java.util.List getInterfaceNameIdList(); + /** + * repeated int32 interface_name_id = 4; + */ + int getInterfaceNameIdCount(); + /** + * repeated int32 interface_name_id = 4; + */ + int getInterfaceNameId(int index); + /** * optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3; */ @@ -32990,6 +33003,27 @@ public final class JsAstProtoBuf { bitField0_ |= 0x00000004; break; } + case 32: { + if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + interfaceNameId_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000004; + } + interfaceNameId_.add(input.readInt32()); + break; + } + case 34: { + int length = input.readRawVarint32(); + int limit = input.pushLimit(length); + if (!((mutable_bitField0_ & 0x00000004) == 0x00000004) && input.getBytesUntilLimit() > 0) { + interfaceNameId_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000004; + } + while (input.getBytesUntilLimit() > 0) { + interfaceNameId_.add(input.readInt32()); + } + input.popLimit(limit); + break; + } } } } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { @@ -32998,6 +33032,9 @@ public final class JsAstProtoBuf { throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException( e.getMessage()).setUnfinishedMessage(this); } finally { + if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + interfaceNameId_ = java.util.Collections.unmodifiableList(interfaceNameId_); + } try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { @@ -33054,6 +33091,28 @@ public final class JsAstProtoBuf { return superNameId_; } + public static final int INTERFACE_NAME_ID_FIELD_NUMBER = 4; + private java.util.List interfaceNameId_; + /** + * repeated int32 interface_name_id = 4; + */ + public java.util.List + getInterfaceNameIdList() { + return interfaceNameId_; + } + /** + * repeated int32 interface_name_id = 4; + */ + public int getInterfaceNameIdCount() { + return interfaceNameId_.size(); + } + /** + * repeated int32 interface_name_id = 4; + */ + public int getInterfaceNameId(int index) { + return interfaceNameId_.get(index); + } + public static final int POST_DECLARATION_BLOCK_FIELD_NUMBER = 3; private org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.GlobalBlock postDeclarationBlock_; /** @@ -33072,6 +33131,7 @@ public final class JsAstProtoBuf { private void initFields() { nameId_ = 0; superNameId_ = 0; + interfaceNameId_ = java.util.Collections.emptyList(); postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.GlobalBlock.getDefaultInstance(); } private byte memoizedIsInitialized = -1; @@ -33106,6 +33166,9 @@ public final class JsAstProtoBuf { if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeMessage(3, postDeclarationBlock_); } + for (int i = 0; i < interfaceNameId_.size(); i++) { + output.writeInt32(4, interfaceNameId_.get(i)); + } output.writeRawBytes(unknownFields); } @@ -33127,6 +33190,15 @@ public final class JsAstProtoBuf { size += org.jetbrains.kotlin.protobuf.CodedOutputStream .computeMessageSize(3, postDeclarationBlock_); } + { + int dataSize = 0; + for (int i = 0; i < interfaceNameId_.size(); i++) { + dataSize += org.jetbrains.kotlin.protobuf.CodedOutputStream + .computeInt32SizeNoTag(interfaceNameId_.get(i)); + } + size += dataSize; + size += 1 * getInterfaceNameIdList().size(); + } size += unknownFields.size(); memoizedSerializedSize = size; return size; @@ -33225,8 +33297,10 @@ public final class JsAstProtoBuf { bitField0_ = (bitField0_ & ~0x00000001); superNameId_ = 0; bitField0_ = (bitField0_ & ~0x00000002); - postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.GlobalBlock.getDefaultInstance(); + interfaceNameId_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000004); + postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.GlobalBlock.getDefaultInstance(); + bitField0_ = (bitField0_ & ~0x00000008); return this; } @@ -33258,7 +33332,12 @@ public final class JsAstProtoBuf { to_bitField0_ |= 0x00000002; } result.superNameId_ = superNameId_; - if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + if (((bitField0_ & 0x00000004) == 0x00000004)) { + interfaceNameId_ = java.util.Collections.unmodifiableList(interfaceNameId_); + bitField0_ = (bitField0_ & ~0x00000004); + } + result.interfaceNameId_ = interfaceNameId_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { to_bitField0_ |= 0x00000004; } result.postDeclarationBlock_ = postDeclarationBlock_; @@ -33274,6 +33353,16 @@ public final class JsAstProtoBuf { if (other.hasSuperNameId()) { setSuperNameId(other.getSuperNameId()); } + if (!other.interfaceNameId_.isEmpty()) { + if (interfaceNameId_.isEmpty()) { + interfaceNameId_ = other.interfaceNameId_; + bitField0_ = (bitField0_ & ~0x00000004); + } else { + ensureInterfaceNameIdIsMutable(); + interfaceNameId_.addAll(other.interfaceNameId_); + } + + } if (other.hasPostDeclarationBlock()) { mergePostDeclarationBlock(other.getPostDeclarationBlock()); } @@ -33379,12 +33468,78 @@ public final class JsAstProtoBuf { return this; } + private java.util.List interfaceNameId_ = java.util.Collections.emptyList(); + private void ensureInterfaceNameIdIsMutable() { + if (!((bitField0_ & 0x00000004) == 0x00000004)) { + interfaceNameId_ = new java.util.ArrayList(interfaceNameId_); + bitField0_ |= 0x00000004; + } + } + /** + * repeated int32 interface_name_id = 4; + */ + public java.util.List + getInterfaceNameIdList() { + return java.util.Collections.unmodifiableList(interfaceNameId_); + } + /** + * repeated int32 interface_name_id = 4; + */ + public int getInterfaceNameIdCount() { + return interfaceNameId_.size(); + } + /** + * repeated int32 interface_name_id = 4; + */ + public int getInterfaceNameId(int index) { + return interfaceNameId_.get(index); + } + /** + * repeated int32 interface_name_id = 4; + */ + public Builder setInterfaceNameId( + int index, int value) { + ensureInterfaceNameIdIsMutable(); + interfaceNameId_.set(index, value); + + return this; + } + /** + * repeated int32 interface_name_id = 4; + */ + public Builder addInterfaceNameId(int value) { + ensureInterfaceNameIdIsMutable(); + interfaceNameId_.add(value); + + return this; + } + /** + * repeated int32 interface_name_id = 4; + */ + public Builder addAllInterfaceNameId( + java.lang.Iterable values) { + ensureInterfaceNameIdIsMutable(); + org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll( + values, interfaceNameId_); + + return this; + } + /** + * repeated int32 interface_name_id = 4; + */ + public Builder clearInterfaceNameId() { + interfaceNameId_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + + return this; + } + private org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.GlobalBlock postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.GlobalBlock.getDefaultInstance(); /** * optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3; */ public boolean hasPostDeclarationBlock() { - return ((bitField0_ & 0x00000004) == 0x00000004); + return ((bitField0_ & 0x00000008) == 0x00000008); } /** * optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3; @@ -33401,7 +33556,7 @@ public final class JsAstProtoBuf { } postDeclarationBlock_ = value; - bitField0_ |= 0x00000004; + bitField0_ |= 0x00000008; return this; } /** @@ -33411,14 +33566,14 @@ public final class JsAstProtoBuf { org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.GlobalBlock.Builder builderForValue) { postDeclarationBlock_ = builderForValue.build(); - bitField0_ |= 0x00000004; + bitField0_ |= 0x00000008; return this; } /** * optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3; */ public Builder mergePostDeclarationBlock(org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.GlobalBlock value) { - if (((bitField0_ & 0x00000004) == 0x00000004) && + if (((bitField0_ & 0x00000008) == 0x00000008) && postDeclarationBlock_ != org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.GlobalBlock.getDefaultInstance()) { postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.GlobalBlock.newBuilder(postDeclarationBlock_).mergeFrom(value).buildPartial(); @@ -33426,7 +33581,7 @@ public final class JsAstProtoBuf { postDeclarationBlock_ = value; } - bitField0_ |= 0x00000004; + bitField0_ |= 0x00000008; return this; } /** @@ -33435,7 +33590,7 @@ public final class JsAstProtoBuf { public Builder clearPostDeclarationBlock() { postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.GlobalBlock.getDefaultInstance(); - bitField0_ = (bitField0_ & ~0x00000004); + bitField0_ = (bitField0_ & ~0x00000008); return this; } diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstSerializer.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstSerializer.kt index a6275fc2f62..08e3a0775cb 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstSerializer.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstSerializer.kt @@ -109,6 +109,7 @@ class JsAstSerializer(private val pathResolver: (File) -> String) { val builder = ClassModel.newBuilder() builder.nameId = serialize(classModel.name) classModel.superName?.let { builder.superNameId = serialize(it) } + classModel.interfaces.forEach { builder.addInterfaceNameId(serialize(it)) } if (classModel.postDeclarationBlock.statements.isNotEmpty()) { builder.postDeclarationBlock = serializeBlock(classModel.postDeclarationBlock) } 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 f5a3f143cf7..4feed688ab0 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 @@ -1205,6 +1205,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("inheritViaAnotherInterface.kt") + public void testInheritViaAnotherInterface() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/defaultArguments/inheritViaAnotherInterface.kt"); + doTest(fileName); + } + @TestMetadata("overloadFunWithDefArg.kt") public void testOverloadFunWithDefArg() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/defaultArguments/overloadFunWithDefArg.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassModelGenerator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassModelGenerator.kt index 241ed123c7b..26bdfa93e27 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassModelGenerator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassModelGenerator.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn import org.jetbrains.kotlin.js.translate.utils.generateDelegateCall import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny +import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces import org.jetbrains.kotlin.resolve.descriptorUtil.hasOrInheritsParametersWithDefaultValue import org.jetbrains.kotlin.resolve.descriptorUtil.hasOwnParametersWithDefaultValue import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter @@ -40,6 +41,7 @@ class ClassModelGenerator(val context: TranslationContext) { fun generateClassModel(descriptor: ClassDescriptor): JsClassModel { val superName = descriptor.getSuperClassNotAny()?.let { context.getInlineableInnerNameForDescriptor(it) } val model = JsClassModel(context.getInlineableInnerNameForDescriptor(descriptor), superName) + descriptor.getSuperInterfaces().mapTo(model.interfaces) { context.getInlineableInnerNameForDescriptor(it) } if (descriptor.kind != ClassKind.ANNOTATION_CLASS && !AnnotationsUtils.isNativeObject(descriptor)) { copyDefaultMembers(descriptor, model) generateBridgeMethods(descriptor, model) diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt index 5082161250a..23775f79011 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt @@ -129,6 +129,7 @@ class Merger(private val rootFunction: JsFunction, val internalModuleName: JsNam val classes = fragment.classes.values.map { cls -> JsClassModel(rename(cls.name), cls.superName?.let { rename(it) }).apply { postDeclarationBlock.statements += rename(cls.postDeclarationBlock).statements + cls.interfaces.mapTo(interfaces) { rename(it) } } } fragment.classes.clear() @@ -214,10 +215,8 @@ class Merger(private val rootFunction: JsFunction, val internalModuleName: JsNam ) { if (!visited.add(name)) return val cls = classes[name] ?: return - val superName = cls.superName - if (superName != null) { - addClassPostDeclarations(superName, visited, statements) - } + cls.superName?.let { addClassPostDeclarations(it, visited, statements) } + cls.interfaces.forEach { addClassPostDeclarations(it, visited, statements) } statements += cls.postDeclarationBlock.statements } } \ No newline at end of file diff --git a/js/js.translator/testData/box/defaultArguments/inheritViaAnotherInterface.kt b/js/js.translator/testData/box/defaultArguments/inheritViaAnotherInterface.kt new file mode 100644 index 00000000000..e8e61349c71 --- /dev/null +++ b/js/js.translator/testData/box/defaultArguments/inheritViaAnotherInterface.kt @@ -0,0 +1,82 @@ +// EXPECTED_REACHABLE_NODES: 1147 +// FILE: classes.kt +class C : J + +class D : J { + override fun foo(x: String): String = "D.foo($x)" +} + +class E : J { + override fun bar(x: String): String = "E.bar($x)" +} + +class F : L { + override fun bar(x: String): String = "F.bar($x)" +} + +interface I { + fun foo(x: String = "Q"): String = "I.foo($x)" + + fun bar(x: String = "Q"): String = "I.bar($x)" +} + +interface J : I { + override fun foo(x: String): String = "J.foo($x)" +} + +interface K { + fun foo(x: String = "Q"): String + + fun bar(x: String = "Q"): String +} + +interface L : K { + override fun foo(x: String): String = "L.foo($x)" +} + +// FILE: main.kt +// RECOMPILE +fun box(): String { + var o: I = C() + + var r = o.foo() + if (r != "J.foo(Q)") return "fail C.foo(): $r" + r = o.foo("W") + if (r != "J.foo(W)") return "fail C.foo(W): $r" + r = o.bar() + if (r != "I.bar(Q)") return "fail C.bar(): $r" + r = o.bar("W") + if (r != "I.bar(W)") return "fail C.bar(W): $r" + + o = D() + r = o.foo() + if (r != "D.foo(Q)") return "fail D.foo(): $r" + r = o.foo("W") + if (r != "D.foo(W)") return "fail D.foo(W): $r" + r = o.bar() + if (r != "I.bar(Q)") return "fail D.bar(): $r" + r = o.bar("W") + if (r != "I.bar(W)") return "fail D.bar(W): $r" + + o = E() + r = o.foo() + if (r != "J.foo(Q)") return "fail E.foo(): $r" + r = o.foo("W") + if (r != "J.foo(W)") return "fail E.foo(W): $r" + r = o.bar() + if (r != "E.bar(Q)") return "fail E.bar(): $r" + r = o.bar("W") + if (r != "E.bar(W)") return "fail E.bar(W): $r" + + val p: K = F() + r = p.foo() + if (r != "L.foo(Q)") return "fail F.foo(): $r" + r = p.foo("W") + if (r != "L.foo(W)") return "fail F.foo(W): $r" + r = p.bar() + if (r != "F.bar(Q)") return "fail F.bar(): $r" + r = p.bar("W") + if (r != "F.bar(W)") return "fail F.bar(W): $r" + + return "OK" +} \ No newline at end of file