From 247f5529d232036543068133e24d2c9edce0032c Mon Sep 17 00:00:00 2001 From: Nikolay Lunyak Date: Wed, 5 Apr 2023 19:39:57 +0300 Subject: [PATCH] [FIR] KT-57809: Allow external constructors without arguments The constructor with the required parameters may not have been defined, and since JS/IR box tests pass, it seems, we don't have to resolve into anything meaningful. We could generate the appropriate constructor like dynamic type members are generated, but, again, K1 IR doesn't even contain a delegating constructor call. ^KT-57809 Fixed --- .../body/resolve/FirExpressionsResolveTransformer.kt | 9 ++++++++- .../jsExternalSuperclassWithoutArguments.kt | 8 ++++++++ .../testData/ir/irText/js/external/kt38765.fir.ir.txt | 4 ++-- .../testData/ir/irText/js/external/kt38765.fir.kt.txt | 4 ++-- .../ir/irText/js/native/nativeNativeKotlin.fir.ir.txt | 2 +- .../ir/irText/js/native/nativeNativeKotlin.fir.kt.txt | 2 +- .../runners/DiagnosticsTestWithJsStdLibGenerated.java | 6 ++++++ .../fir/FirPsiJsOldFrontendDiagnosticsTestGenerated.java | 6 ++++++ 8 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/diagnostics/testsWithJsStdLib/jsExternalSuperclassWithoutArguments.kt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 94abf66b9bb..df2a15f6fa6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fakeElement import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.utils.isExternal import org.jetbrains.kotlin.fir.declarations.utils.isLocal import org.jetbrains.kotlin.fir.diagnostics.* import org.jetbrains.kotlin.fir.expressions.* @@ -1265,7 +1266,10 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT val superClass = containingClass.superTypeRefs.firstOrNull { if (it !is FirResolvedTypeRef) return@firstOrNull false val declaration = extractSuperTypeDeclaration(it) ?: return@firstOrNull false - declaration.classKind == ClassKind.CLASS + val isExternalConstructorWithoutArguments = declaration.isExternal + && delegatedConstructorCall.isCallToDelegatedConstructorWithoutArguments + declaration.classKind == ClassKind.CLASS && !isExternalConstructorWithoutArguments + } as FirResolvedTypeRef? ?: session.builtinTypes.anyType delegatedConstructorCall.replaceConstructedTypeRef(superClass) delegatedConstructorCall.replaceCalleeReference(buildExplicitSuperReference { @@ -1307,6 +1311,9 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT return result } + private val FirDelegatedConstructorCall.isCallToDelegatedConstructorWithoutArguments + get() = source?.kind == KtFakeSourceElementKind.DelegatingConstructorCall + private fun extractSuperTypeDeclaration(typeRef: FirTypeRef): FirRegularClass? { if (typeRef !is FirResolvedTypeRef) return null return when (val declaration = typeRef.firClassLike(session)) { diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/jsExternalSuperclassWithoutArguments.kt b/compiler/testData/diagnostics/testsWithJsStdLib/jsExternalSuperclassWithoutArguments.kt new file mode 100644 index 00000000000..76ff2a20572 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLib/jsExternalSuperclassWithoutArguments.kt @@ -0,0 +1,8 @@ +// FIR_IDENTICAL +// ISSUE: KT-57809 + +package bar.baz + +open external class LIcon(options: String) + +external class DivIcon(options: String) : LIcon // No value passed for parameter 'options' diff --git a/compiler/testData/ir/irText/js/external/kt38765.fir.ir.txt b/compiler/testData/ir/irText/js/external/kt38765.fir.ir.txt index cf4276dd3b2..5ea48f0a227 100644 --- a/compiler/testData/ir/irText/js/external/kt38765.fir.ir.txt +++ b/compiler/testData/ir/irText/js/external/kt38765.fir.ir.txt @@ -9,7 +9,7 @@ FILE fqName:events fileName:/kt38765.kt $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:events.internal.EventEmitterP CONSTRUCTOR visibility:public <> () returnType:events.internal.EventEmitterP [primary] BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in events.internal' + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:EventEmitterP modality:OPEN visibility:public superTypes:[events.internal]' FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: @@ -48,7 +48,7 @@ FILE fqName:events fileName:/kt38765.kt $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:events.internal.NestedExternalObject CONSTRUCTOR visibility:private <> () returnType:events.internal.NestedExternalObject [primary] BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in events.internal' + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name:NestedExternalObject modality:FINAL visibility:public superTypes:[events.internal]' FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: diff --git a/compiler/testData/ir/irText/js/external/kt38765.fir.kt.txt b/compiler/testData/ir/irText/js/external/kt38765.fir.kt.txt index 7f31e0f1344..fff00105ce0 100644 --- a/compiler/testData/ir/irText/js/external/kt38765.fir.kt.txt +++ b/compiler/testData/ir/irText/js/external/kt38765.fir.kt.txt @@ -9,7 +9,7 @@ open external class internal { open class EventEmitterP : internal { constructor() /* primary */ { - super/*internal*/() + super/*Any*/() /* () */ } @@ -27,7 +27,7 @@ open external class internal { object NestedExternalObject : internal { private constructor() /* primary */ { - super/*internal*/() + super/*Any*/() /* () */ } diff --git a/compiler/testData/ir/irText/js/native/nativeNativeKotlin.fir.ir.txt b/compiler/testData/ir/irText/js/native/nativeNativeKotlin.fir.ir.txt index d8656a63fe0..684b075d89c 100644 --- a/compiler/testData/ir/irText/js/native/nativeNativeKotlin.fir.ir.txt +++ b/compiler/testData/ir/irText/js/native/nativeNativeKotlin.fir.ir.txt @@ -24,7 +24,7 @@ FILE fqName:foo fileName:/nativeNativeKotlin.kt $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:foo.B CONSTRUCTOR visibility:public <> () returnType:foo.B [primary] BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in foo.A' + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:B modality:OPEN visibility:public [external] superTypes:[foo.A]' FUN name:bar visibility:public modality:FINAL <> ($this:foo.B) returnType:kotlin.String $this: VALUE_PARAMETER name: type:foo.B diff --git a/compiler/testData/ir/irText/js/native/nativeNativeKotlin.fir.kt.txt b/compiler/testData/ir/irText/js/native/nativeNativeKotlin.fir.kt.txt index dd9dfda4280..2314cf35101 100644 --- a/compiler/testData/ir/irText/js/native/nativeNativeKotlin.fir.kt.txt +++ b/compiler/testData/ir/irText/js/native/nativeNativeKotlin.fir.kt.txt @@ -13,7 +13,7 @@ open external class A { open external class B : A { constructor() /* primary */ { - super/*A*/() + super/*Any*/() /* () */ } diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsTestWithJsStdLibGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsTestWithJsStdLibGenerated.java index d02edd14462..0c681fc4177 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsTestWithJsStdLibGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsTestWithJsStdLibGenerated.java @@ -48,6 +48,12 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes runTest("compiler/testData/diagnostics/testsWithJsStdLib/jsExternalInheritorsOnly.kt"); } + @Test + @TestMetadata("jsExternalSuperclassWithoutArguments.kt") + public void testJsExternalSuperclassWithoutArguments() throws Exception { + runTest("compiler/testData/diagnostics/testsWithJsStdLib/jsExternalSuperclassWithoutArguments.kt"); + } + @Test @TestMetadata("localClassMetadata.kt") public void testLocalClassMetadata() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirPsiJsOldFrontendDiagnosticsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirPsiJsOldFrontendDiagnosticsTestGenerated.java index 19739dba38d..debf89221ed 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirPsiJsOldFrontendDiagnosticsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirPsiJsOldFrontendDiagnosticsTestGenerated.java @@ -49,6 +49,12 @@ public class FirPsiJsOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiJ runTest("compiler/testData/diagnostics/testsWithJsStdLib/jsExternalInheritorsOnly.kt"); } + @Test + @TestMetadata("jsExternalSuperclassWithoutArguments.kt") + public void testJsExternalSuperclassWithoutArguments() throws Exception { + runTest("compiler/testData/diagnostics/testsWithJsStdLib/jsExternalSuperclassWithoutArguments.kt"); + } + @Test @TestMetadata("localClassMetadata.kt") public void testLocalClassMetadata() throws Exception {