FIR: don't create delegated constructor call in expect
#KT-51756 Fixed
This commit is contained in:
+6
@@ -3225,6 +3225,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/doubleGenericDiamond.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("expectConstructor.kt")
|
||||
public void testExpectConstructor() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/expectConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("fakeTypeMismatchOnExtensionReference.kt")
|
||||
public void testFakeTypeMismatchOnExtensionReference() throws Exception {
|
||||
|
||||
+5
@@ -2844,6 +2844,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/doubleGenericDiamond.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("expectConstructor.kt")
|
||||
public void testExpectConstructor() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/expectConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("fakeTypeMismatchOnExtensionReference.kt")
|
||||
public void testFakeTypeMismatchOnExtensionReference() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/fakeTypeMismatchOnExtensionReference.kt");
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
FILE: expectConstructor.kt
|
||||
public open class Base : R|kotlin/Any| {
|
||||
public constructor(v: R|kotlin/String|): R|Base| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final expect class Derived : R|Base| {
|
||||
public expect constructor(v: R|kotlin/String|): R|Derived|
|
||||
|
||||
}
|
||||
public open expect class ExpectBase : R|kotlin/Any| {
|
||||
public expect constructor(v: R|kotlin/String|): R|ExpectBase|
|
||||
|
||||
}
|
||||
public final expect class ExpectDerived : R|ExpectBase| {
|
||||
public expect constructor(v: R|kotlin/String|): R|ExpectDerived|
|
||||
|
||||
}
|
||||
public open expect class IOException : R|kotlin/Any| {
|
||||
public expect constructor(message: R|kotlin/String|, cause: R|kotlin/Throwable?|): R|IOException|
|
||||
|
||||
public expect constructor(message: R|kotlin/String|): R|IOException| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final expect class EOFException : R|IOException| {
|
||||
public expect constructor(message: R|kotlin/String|): R|EOFException|
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
open class Base(v: String)
|
||||
|
||||
expect class Derived(v: String) : Base
|
||||
|
||||
expect open class ExpectBase(v: String)
|
||||
|
||||
expect class ExpectDerived(v: String) : ExpectBase
|
||||
|
||||
expect open class IOException(message: String, cause: Throwable?) {
|
||||
<!PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED!>constructor(message: String)<!>
|
||||
}
|
||||
|
||||
expect class EOFException(message: String) : IOException
|
||||
+1
-3
@@ -1,9 +1,7 @@
|
||||
Module: m1-common
|
||||
FILE: common.kt
|
||||
public open expect class A<T> : R|kotlin/Any| {
|
||||
public expect constructor<T>(): R|A<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
public expect constructor<T>(): R|A<T>|
|
||||
|
||||
public open expect fun foo(arg: R|T|): R|kotlin/Unit|
|
||||
|
||||
|
||||
+1
-3
@@ -1,9 +1,7 @@
|
||||
Module: m1-common
|
||||
FILE: common.kt
|
||||
public open expect class A : R|kotlin/Any| {
|
||||
public expect constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
public expect constructor(): R|A|
|
||||
|
||||
public final expect fun foo(): R|kotlin/Unit|
|
||||
|
||||
|
||||
+1
-3
@@ -1,9 +1,7 @@
|
||||
Module: m1-common
|
||||
FILE: common.kt
|
||||
public open expect class A : R|kotlin/Any| {
|
||||
public expect constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
public expect constructor(): R|A|
|
||||
|
||||
public final expect fun foo(): R|kotlin/Unit|
|
||||
|
||||
|
||||
+6
@@ -3225,6 +3225,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/doubleGenericDiamond.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("expectConstructor.kt")
|
||||
public void testExpectConstructor() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/expectConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("fakeTypeMismatchOnExtensionReference.kt")
|
||||
public void testFakeTypeMismatchOnExtensionReference() throws Exception {
|
||||
|
||||
+6
@@ -3225,6 +3225,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/doubleGenericDiamond.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("expectConstructor.kt")
|
||||
public void testExpectConstructor() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/expectConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("fakeTypeMismatchOnExtensionReference.kt")
|
||||
public void testFakeTypeMismatchOnExtensionReference() throws Exception {
|
||||
|
||||
+27
-21
@@ -56,6 +56,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
import org.jetbrains.kotlin.name.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runUnless
|
||||
|
||||
class DeclarationsConverter(
|
||||
session: FirSession,
|
||||
@@ -711,6 +712,7 @@ class DeclarationsConverter(
|
||||
}
|
||||
|
||||
val enumEntryName = identifier.nameAsSafeName()
|
||||
val containingClassIsExpectClass = classWrapper.hasExpect() || context.containerIsExpect
|
||||
return buildEnumEntry {
|
||||
source = enumEntry.toFirSourceElement()
|
||||
moduleData = baseModuleData
|
||||
@@ -720,7 +722,7 @@ class DeclarationsConverter(
|
||||
symbol = FirEnumEntrySymbol(CallableId(context.currentClassId, enumEntryName))
|
||||
status = FirDeclarationStatusImpl(Visibilities.Public, Modality.FINAL).apply {
|
||||
isStatic = true
|
||||
isExpect = classWrapper.hasExpect() || context.containerIsExpect
|
||||
isExpect = containingClassIsExpectClass
|
||||
}
|
||||
if (classWrapper.hasDefaultConstructor && enumEntry.getChildNodeByType(INITIALIZER_LIST) == null &&
|
||||
modifiers.annotations.isEmpty() && classBodyNode == null
|
||||
@@ -762,7 +764,7 @@ class DeclarationsConverter(
|
||||
enumClassWrapper,
|
||||
superTypeCallEntry?.toFirSourceElement(),
|
||||
isEnumEntry = true,
|
||||
containingClassIsExpectClass = false
|
||||
containingClassIsExpectClass = containingClassIsExpectClass
|
||||
)?.let { declarations += it.firConstructor }
|
||||
classBodyNode?.also {
|
||||
// Use ANONYMOUS_OBJECT_NAME for the owner class id of enum entry declarations
|
||||
@@ -828,7 +830,9 @@ class DeclarationsConverter(
|
||||
): PrimaryConstructor? {
|
||||
if (primaryConstructor == null && !classWrapper.isEnumEntry() && classWrapper.hasSecondaryConstructor) return null
|
||||
val classKind = classWrapper.classBuilder.classKind
|
||||
if (primaryConstructor == null && (containingClassIsExpectClass && classKind != ClassKind.ENUM_CLASS)) return null
|
||||
if (primaryConstructor == null &&
|
||||
(containingClassIsExpectClass && classKind != ClassKind.ENUM_CLASS && classKind != ClassKind.ENUM_ENTRY)
|
||||
) return null
|
||||
if (classWrapper.isInterface()) return null
|
||||
|
||||
var modifiers = Modifier()
|
||||
@@ -841,26 +845,28 @@ class DeclarationsConverter(
|
||||
}
|
||||
|
||||
val defaultVisibility = classWrapper.defaultConstructorVisibility()
|
||||
val firDelegatedCall = buildDelegatedConstructorCall {
|
||||
source = delegatedConstructorSource ?: selfTypeSource?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
|
||||
constructedTypeRef = classWrapper.delegatedSuperTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef)
|
||||
isThis = false
|
||||
calleeReference = buildExplicitSuperReference {
|
||||
//[dirty] in case of enum classWrapper.delegatedSuperTypeRef.source is whole enum source
|
||||
source = if (!isEnumEntry) {
|
||||
classWrapper.delegatedSuperTypeRef.source?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
|
||||
?: this@buildDelegatedConstructorCall.source?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
|
||||
} else {
|
||||
delegatedConstructorSource
|
||||
?.lighterASTNode
|
||||
?.getChildNodeByType(CONSTRUCTOR_CALLEE)
|
||||
?.toFirSourceElement(KtFakeSourceElementKind.DelegatingConstructorCall)
|
||||
?: this@buildDelegatedConstructorCall.source
|
||||
}
|
||||
val firDelegatedCall = runUnless(containingClassIsExpectClass) {
|
||||
buildDelegatedConstructorCall {
|
||||
source = delegatedConstructorSource ?: selfTypeSource?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
|
||||
constructedTypeRef = classWrapper.delegatedSuperTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef)
|
||||
isThis = false
|
||||
calleeReference = buildExplicitSuperReference {
|
||||
//[dirty] in case of enum classWrapper.delegatedSuperTypeRef.source is whole enum source
|
||||
source = if (!isEnumEntry) {
|
||||
classWrapper.delegatedSuperTypeRef.source?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
|
||||
?: this@buildDelegatedConstructorCall.source?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
|
||||
} else {
|
||||
delegatedConstructorSource
|
||||
?.lighterASTNode
|
||||
?.getChildNodeByType(CONSTRUCTOR_CALLEE)
|
||||
?.toFirSourceElement(KtFakeSourceElementKind.DelegatingConstructorCall)
|
||||
?: this@buildDelegatedConstructorCall.source
|
||||
}
|
||||
|
||||
superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef
|
||||
superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef
|
||||
}
|
||||
extractArgumentsFrom(classWrapper.superTypeCallEntry)
|
||||
}
|
||||
extractArgumentsFrom(classWrapper.superTypeCallEntry)
|
||||
}
|
||||
|
||||
val explicitVisibility = runIf(primaryConstructor != null) {
|
||||
|
||||
@@ -837,6 +837,7 @@ open class RawFirBuilder(
|
||||
delegatedSelfTypeRef ?: delegatedSuperTypeRef!!,
|
||||
owner = this,
|
||||
containerTypeParameters,
|
||||
containingClassIsExpectClass,
|
||||
body = null
|
||||
)
|
||||
container.declarations += firPrimaryConstructor
|
||||
@@ -851,12 +852,13 @@ open class RawFirBuilder(
|
||||
delegatedSelfTypeRef: FirTypeRef,
|
||||
owner: KtClassOrObject,
|
||||
ownerTypeParameters: List<FirTypeParameterRef>,
|
||||
containingClassIsExpectClass: Boolean,
|
||||
body: FirBlock? = null
|
||||
): FirConstructor {
|
||||
val constructorCall = superTypeCallEntry?.toFirSourceElement()
|
||||
val constructorSource = this?.toFirSourceElement()
|
||||
?: owner.toKtPsiSourceElement(KtFakeSourceElementKind.ImplicitConstructor)
|
||||
val firDelegatedCall = buildDelegatedConstructorCall {
|
||||
val firDelegatedCall = if (containingClassIsExpectClass) null else buildDelegatedConstructorCall {
|
||||
source = constructorCall ?: constructorSource.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall)
|
||||
constructedTypeRef = delegatedSuperTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef)
|
||||
isThis = false
|
||||
@@ -945,6 +947,7 @@ open class RawFirBuilder(
|
||||
ownerClassHasDefaultConstructor: Boolean
|
||||
): FirDeclaration {
|
||||
val ktEnumEntry = this@toFirEnumEntry
|
||||
val containingClassIsExpectClass = hasExpectModifier() || this@RawFirBuilder.context.containerIsExpect
|
||||
return buildEnumEntry {
|
||||
source = toFirSourceElement()
|
||||
moduleData = baseModuleData
|
||||
@@ -953,7 +956,7 @@ open class RawFirBuilder(
|
||||
name = nameAsSafeName
|
||||
status = FirDeclarationStatusImpl(Visibilities.Public, Modality.FINAL).apply {
|
||||
isStatic = true
|
||||
isExpect = hasExpectModifier() || this@RawFirBuilder.context.containerIsExpect
|
||||
isExpect = containingClassIsExpectClass
|
||||
}
|
||||
symbol = FirEnumEntrySymbol(callableIdForName(nameAsSafeName))
|
||||
if (ownerClassHasDefaultConstructor && ktEnumEntry.initializerList == null &&
|
||||
@@ -992,7 +995,8 @@ open class RawFirBuilder(
|
||||
correctedEnumSelfTypeRef,
|
||||
delegatedEntrySelfType,
|
||||
owner = ktEnumEntry,
|
||||
typeParameters
|
||||
typeParameters,
|
||||
containingClassIsExpectClass
|
||||
)
|
||||
// Use ANONYMOUS_OBJECT_NAME for the owner class id for enum entry declarations (see KT-42351)
|
||||
withChildClassName(SpecialNames.ANONYMOUS, forceLocalContext = true, isExpect = false) {
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
// FILE: common.kt
|
||||
|
||||
expect enum class En(x: Int) {
|
||||
<!NONE_APPLICABLE!>E1,<!>
|
||||
E1,
|
||||
E2(42),
|
||||
;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user