From 49690fc6208823797af910ee861e7bdac8daf394 Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Wed, 27 May 2020 01:37:01 +0300 Subject: [PATCH] [JS IR] Properly detect whether nested class is external - Fix KT-38765 --- .../psi2ir/generators/FunctionGenerator.kt | 5 +- .../testData/ir/irJsText/external/kt38765.kt | 18 +++ .../testData/ir/irJsText/external/kt38765.txt | 129 ++++++++++++++++++ .../kotlin/ir/IrJsTextTestCaseGenerated.java | 18 +++ 4 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/ir/irJsText/external/kt38765.kt create mode 100644 compiler/testData/ir/irJsText/external/kt38765.txt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt index c34e032998d..a34a16618ac 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotationConstructor +import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -218,7 +219,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio if ( primaryConstructorDescriptor.isExpect || DescriptorUtils.isAnnotationClass(primaryConstructorDescriptor.constructedClass) || - primaryConstructorDescriptor.constructedClass.isExternal + primaryConstructorDescriptor.constructedClass.isEffectivelyExternal() ) null else @@ -229,7 +230,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio val constructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor) as ClassConstructorDescriptor return declareConstructor(ktConstructor, ktConstructor, constructorDescriptor) { when { - constructorDescriptor.constructedClass.isExternal -> + constructorDescriptor.constructedClass.isEffectivelyExternal() -> null ktConstructor.isConstructorDelegatingToSuper(context.bindingContext) -> diff --git a/compiler/testData/ir/irJsText/external/kt38765.kt b/compiler/testData/ir/irJsText/external/kt38765.kt new file mode 100644 index 00000000000..8b505ce8fa1 --- /dev/null +++ b/compiler/testData/ir/irJsText/external/kt38765.kt @@ -0,0 +1,18 @@ +package events + +external open class internal { + open class EventEmitterP : internal { + } + + open class EventEmitterS : internal { + constructor(a: Any) + } + + object NestedExternalObject : internal {} + + enum class NestedExternalEnum { + A, B + } + + interface NestedExternalInterface {} +} \ No newline at end of file diff --git a/compiler/testData/ir/irJsText/external/kt38765.txt b/compiler/testData/ir/irJsText/external/kt38765.txt new file mode 100644 index 00000000000..61df597cdf9 --- /dev/null +++ b/compiler/testData/ir/irJsText/external/kt38765.txt @@ -0,0 +1,129 @@ +FILE fqName:events fileName:/kt38765.kt + CLASS CLASS name:internal modality:OPEN visibility:public [external] superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:events.internal + CONSTRUCTOR visibility:public <> () returnType:events.internal [external,primary] + CLASS CLASS name:EventEmitterP modality:OPEN visibility:public [external] superTypes:[events.internal] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:events.internal.EventEmitterP + CONSTRUCTOR visibility:public <> () returnType:events.internal.EventEmitterP [external,primary] + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in events.internal + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in events.internal + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in events.internal + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:EventEmitterS modality:OPEN visibility:public [external] superTypes:[events.internal] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:events.internal.EventEmitterS + CONSTRUCTOR visibility:public <> (a:kotlin.Any) returnType:events.internal.EventEmitterS [external] + VALUE_PARAMETER name:a index:0 type:kotlin.Any + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in events.internal + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in events.internal + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in events.internal + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS OBJECT name:NestedExternalObject modality:FINAL visibility:public [external] superTypes:[events.internal] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:events.internal.NestedExternalObject + CONSTRUCTOR visibility:private <> () returnType:events.internal.NestedExternalObject [external,primary] + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in events.internal + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in events.internal + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in events.internal + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS ENUM_CLASS name:NestedExternalEnum modality:FINAL visibility:public [external] superTypes:[kotlin.Enum] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:events.internal.NestedExternalEnum + CONSTRUCTOR visibility:private <> () returnType:events.internal.NestedExternalEnum [external,primary] + ENUM_ENTRY name:A + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor () [external,primary] declared in events.internal.NestedExternalEnum' + ENUM_ENTRY name:B + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor () [external,primary] declared in events.internal.NestedExternalEnum' + FUN FAKE_OVERRIDE name:clone visibility:protected modality:FINAL <> ($this:kotlin.Enum) returnType:kotlin.Any [fake_override] + overridden: + protected final fun clone (): kotlin.Any declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + FUN FAKE_OVERRIDE name:compareTo visibility:public modality:FINAL <> ($this:kotlin.Enum, other:events.internal.NestedExternalEnum) returnType:kotlin.Int [fake_override,operator] + overridden: + public final fun compareTo (other: E of kotlin.Enum): kotlin.Int [operator] declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + VALUE_PARAMETER name:other index:0 type:events.internal.NestedExternalEnum + FUN FAKE_OVERRIDE name:equals visibility:public modality:FINAL <> ($this:kotlin.Enum, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public final fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:FINAL <> ($this:kotlin.Enum) returnType:kotlin.Int [fake_override] + overridden: + public final fun hashCode (): kotlin.Int declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + PROPERTY FAKE_OVERRIDE name:name visibility:public modality:FINAL [external,fake_override,val] + FUN FAKE_OVERRIDE name: visibility:public modality:FINAL <> ($this:kotlin.Enum) returnType:kotlin.String [fake_override] + correspondingProperty: PROPERTY FAKE_OVERRIDE name:name visibility:public modality:FINAL [external,fake_override,val] + overridden: + public final fun (): kotlin.String declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + PROPERTY FAKE_OVERRIDE name:ordinal visibility:public modality:FINAL [external,fake_override,val] + FUN FAKE_OVERRIDE name: visibility:public modality:FINAL <> ($this:kotlin.Enum) returnType:kotlin.Int [fake_override] + correspondingProperty: PROPERTY FAKE_OVERRIDE name:ordinal visibility:public modality:FINAL [external,fake_override,val] + overridden: + public final fun (): kotlin.Int declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Enum) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + FUN ENUM_CLASS_SPECIAL_MEMBER name:values visibility:public modality:FINAL <> () returnType:kotlin.Array + SYNTHETIC_BODY kind=ENUM_VALUES + FUN ENUM_CLASS_SPECIAL_MEMBER name:valueOf visibility:public modality:FINAL <> (value:kotlin.String) returnType:events.internal.NestedExternalEnum + VALUE_PARAMETER name:value index:0 type:kotlin.String + SYNTHETIC_BODY kind=ENUM_VALUEOF + CLASS INTERFACE name:NestedExternalInterface modality:ABSTRACT visibility:public [external] superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:events.internal.NestedExternalInterface + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrJsTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrJsTextTestCaseGenerated.java index 5ee510a385f..8d640c5a783 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrJsTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrJsTextTestCaseGenerated.java @@ -151,6 +151,24 @@ public class IrJsTextTestCaseGenerated extends AbstractIrJsTextTestCase { } } + @TestMetadata("compiler/testData/ir/irJsText/external") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class External extends AbstractIrJsTextTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInExternal() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irJsText/external"), Pattern.compile("^(.+)\\.kt(s)?$"), null, true); + } + + @TestMetadata("kt38765.kt") + public void testKt38765() throws Exception { + runTest("compiler/testData/ir/irJsText/external/kt38765.kt"); + } + } + @TestMetadata("compiler/testData/ir/irJsText/native") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)