[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
This commit is contained in:
Nikolay Lunyak
2023-04-05 19:39:57 +03:00
committed by Space Team
parent 96a25b7b7d
commit 247f5529d2
8 changed files with 34 additions and 7 deletions
@@ -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)) {
@@ -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'
+2 -2
View File
@@ -9,7 +9,7 @@ FILE fqName:events fileName:/kt38765.kt
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:events.internal.EventEmitterP
CONSTRUCTOR visibility:public <> () returnType:events.internal.EventEmitterP [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in events.internal'
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [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:<this> type:events.internal.NestedExternalObject
CONSTRUCTOR visibility:private <> () returnType:events.internal.NestedExternalObject [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in events.internal'
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [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:
+2 -2
View File
@@ -9,7 +9,7 @@ open external class internal {
open class EventEmitterP : internal {
constructor() /* primary */ {
super/*internal*/()
super/*Any*/()
/* <init>() */
}
@@ -27,7 +27,7 @@ open external class internal {
object NestedExternalObject : internal {
private constructor() /* primary */ {
super/*internal*/()
super/*Any*/()
/* <init>() */
}
@@ -24,7 +24,7 @@ FILE fqName:foo fileName:/nativeNativeKotlin.kt
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:foo.B
CONSTRUCTOR visibility:public <> () returnType:foo.B [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in foo.A'
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [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:<this> type:foo.B
@@ -13,7 +13,7 @@ open external class A {
open external class B : A {
constructor() /* primary */ {
super/*A*/()
super/*Any*/()
/* <init>() */
}
@@ -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 {
@@ -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 {