[FE] Stop ignoring ABSTRACT_MEMBER_NOT_IMPLEMENTED for expect classes

^KT-59739 Fixed
Review: https://jetbrains.team/p/kt/reviews/11038/timeline
This commit is contained in:
Nikita Bobko
2023-07-10 11:23:25 +02:00
committed by Space Team
parent bfcb90c716
commit 4f3ecedbca
25 changed files with 161 additions and 42 deletions
@@ -386,7 +386,6 @@ fun FirCallableSymbol<*>.getImplementationStatus(
isFinal -> ImplementationStatus.CANNOT_BE_IMPLEMENTED isFinal -> ImplementationStatus.CANNOT_BE_IMPLEMENTED
containingClassSymbol === parentClassSymbol && (origin == FirDeclarationOrigin.Source || origin == FirDeclarationOrigin.Precompiled) -> containingClassSymbol === parentClassSymbol && (origin == FirDeclarationOrigin.Source || origin == FirDeclarationOrigin.Precompiled) ->
ImplementationStatus.ALREADY_IMPLEMENTED ImplementationStatus.ALREADY_IMPLEMENTED
containingClassSymbol is FirRegularClassSymbol && containingClassSymbol.isExpect -> ImplementationStatus.CANNOT_BE_IMPLEMENTED
isAbstract -> ImplementationStatus.NOT_IMPLEMENTED isAbstract -> ImplementationStatus.NOT_IMPLEMENTED
else -> ImplementationStatus.INHERITED_OR_SYNTHESIZED else -> ImplementationStatus.INHERITED_OR_SYNTHESIZED
} }
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_IMPLEMENTED_B
import org.jetbrains.kotlin.fir.containingClassLookupTag import org.jetbrains.kotlin.fir.containingClassLookupTag
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.delegatedWrapperData import org.jetbrains.kotlin.fir.delegatedWrapperData
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
@@ -42,7 +41,6 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
if (sourceKind is KtFakeSourceElementKind && sourceKind != KtFakeSourceElementKind.EnumInitializer) return if (sourceKind is KtFakeSourceElementKind && sourceKind != KtFakeSourceElementKind.EnumInitializer) return
val modality = declaration.modality() val modality = declaration.modality()
val canHaveAbstractDeclarations = modality == Modality.ABSTRACT || modality == Modality.SEALED val canHaveAbstractDeclarations = modality == Modality.ABSTRACT || modality == Modality.SEALED
if (declaration is FirRegularClass && declaration.isExpect) return
val classKind = declaration.classKind val classKind = declaration.classKind
if (classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.ENUM_CLASS) return if (classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.ENUM_CLASS) return
val classSymbol = declaration.symbol val classSymbol = declaration.symbol
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.platform.PlatformSpecificDiagnosticComponents import org.jetbrains.kotlin.platform.PlatformSpecificDiagnosticComponents
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractFakeOverride import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractDeclaration
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
import org.jetbrains.kotlin.resolve.calls.util.isOrOverridesSynthesized import org.jetbrains.kotlin.resolve.calls.util.isOrOverridesSynthesized
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
@@ -132,7 +132,7 @@ class OverrideResolver(
this(delegateStrategy.klass, delegateStrategy.classDescriptor) this(delegateStrategy.klass, delegateStrategy.classDescriptor)
override fun doReportErrors() { override fun doReportErrors() {
val canHaveAbstractMembers = classCanHaveAbstractFakeOverride(classDescriptor) val canHaveAbstractMembers = classCanHaveAbstractDeclaration(classDescriptor)
if (abstractInBaseClassNoImpl.isNotEmpty() && !canHaveAbstractMembers) { if (abstractInBaseClassNoImpl.isNotEmpty() && !canHaveAbstractMembers) {
if (languageVersionSettings.supportsFeature(AbstractClassMemberNotImplementedWithIntermediateAbstractClass)) { if (languageVersionSettings.supportsFeature(AbstractClassMemberNotImplementedWithIntermediateAbstractClass)) {
trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.first())) trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.first()))
@@ -260,7 +260,7 @@ class OverrideResolver(
} }
open fun doReportErrors() { open fun doReportErrors() {
val canHaveAbstractMembers = classCanHaveAbstractFakeOverride(classDescriptor) val canHaveAbstractMembers = classCanHaveAbstractDeclaration(classDescriptor)
if (abstractInBaseClassNoImpl.isNotEmpty() && !canHaveAbstractMembers) { if (abstractInBaseClassNoImpl.isNotEmpty() && !canHaveAbstractMembers) {
trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.first())) trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.first()))
} else if (abstractNoImpl.isNotEmpty() && !canHaveAbstractMembers) { } else if (abstractNoImpl.isNotEmpty() && !canHaveAbstractMembers) {
@@ -708,11 +708,9 @@ class OverrideResolver(
for (overridden in relevantDirectlyOverridden) { for (overridden in relevantDirectlyOverridden) {
val containingDeclaration = overridden.containingDeclaration as? ClassDescriptor ?: continue val containingDeclaration = overridden.containingDeclaration as? ClassDescriptor ?: continue
if (containingDeclaration.kind == ClassKind.CLASS) { if (containingDeclaration.kind == ClassKind.CLASS) {
if (overridden.kind == FAKE_OVERRIDE && !containingDeclaration.isExpect) { if (overridden.kind == FAKE_OVERRIDE) {
// Fake override in a class in fact can mean an interface member // Fake override in a class in fact can mean an interface member
// We will process it at the end // We will process it at the end
// Note: with expect containing class, the situation is unclear, so we miss this case
// See extendExpectedClassWithAbstractMember.kt (BaseA, BaseAImpl, DerivedA1)
fakeOverrideInBaseClass = overridden fakeOverrideInBaseClass = overridden
} }
overridesClassMember = true overridesClassMember = true
@@ -13,7 +13,9 @@ interface I2 {
fun f(): String fun f(): String
} }
expect class C() : I1, I2 expect class C() : I1, I2 {
override fun f(): String
}
fun test() = C().f() fun test() = C().f()
@@ -21,7 +23,7 @@ fun test() = C().f()
// FILE: platform.kt // FILE: platform.kt
actual class C : I1, I2 { actual class C : I1, I2 {
override fun f() = "OK" actual override fun f() = "OK"
} }
fun box() = test() fun box() = test()
@@ -19,9 +19,9 @@ expect interface My {
val f: Int val f: Int
} }
class MyImpl1: My <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class MyImpl1<!>: My
class MyImpl2: My { <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class MyImpl2<!>: My {
override fun foo() {} override fun foo() {}
override val f = 0 override val f = 0
override val e = 1 override val e = 1
@@ -0,0 +1,22 @@
// WITH_STDLIB
// MODULE: m1-common
// FILE: common.kt
interface B {
override fun toString(): String
}
expect value <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class C<!>(val s: String) : B
expect value <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class D<!>(val s: String) : B
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
@JvmInline
actual value class C(actual val s: String) : B {
override fun toString(): String = s
}
@JvmInline
actual value class D(actual val s: String) : B
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// WITH_STDLIB // WITH_STDLIB
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
@@ -0,0 +1,17 @@
// MODULE: m1-common
// FILE: common.kt
interface Base {
fun foo()
}
expect <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>object Implementation<!> : Base
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
abstract class RealImplementation : Base {
override fun foo() {}
}
actual object Implementation : RealImplementation(), Base
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
@@ -6,7 +5,7 @@ interface Base {
fun foo() fun foo()
} }
expect object Implementation : Base expect <!ABSTRACT_MEMBER_NOT_IMPLEMENTED, ABSTRACT_MEMBER_NOT_IMPLEMENTED{JVM}!>object Implementation<!> : Base
// MODULE: m1-jvm()()(m1-common) // MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt // FILE: jvm.kt
@@ -0,0 +1,27 @@
// MODULE: m1-common
// FILE: common.kt
interface Foo {
fun foo()
}
expect <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class ImplicitFoo<!> : Foo
expect class ExplicitFoo : Foo {
override fun foo()
}
expect <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class ImplicitFooCheck<!> : Foo
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual class ImplicitFoo : Foo {
override fun foo() {}
}
actual class ExplicitFoo : Foo {
actual override fun foo() {}
}
actual <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class ImplicitFooCheck<!> : Foo
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
@@ -6,13 +5,13 @@ interface Foo {
fun foo() fun foo()
} }
expect class ImplicitFoo : Foo expect <!ABSTRACT_MEMBER_NOT_IMPLEMENTED, ABSTRACT_MEMBER_NOT_IMPLEMENTED{JVM}!>class ImplicitFoo<!> : Foo
expect class ExplicitFoo : Foo { expect class ExplicitFoo : Foo {
override fun foo() override fun foo()
} }
expect class ImplicitFooCheck : Foo expect <!ABSTRACT_MEMBER_NOT_IMPLEMENTED, ABSTRACT_MEMBER_NOT_IMPLEMENTED{JVM}!>class ImplicitFooCheck<!> : Foo
// MODULE: m2-jvm()()(m1-common) // MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt // FILE: jvm.kt
@@ -4,9 +4,9 @@
<!NO_ACTUAL_FOR_EXPECT!>expect abstract class BaseA() { <!NO_ACTUAL_FOR_EXPECT!>expect abstract class BaseA() {
abstract fun foo() abstract fun foo()
}<!> }<!>
<!NO_ACTUAL_FOR_EXPECT!>expect open class BaseAImpl() : BaseA<!> <!NO_ACTUAL_FOR_EXPECT!>expect open <!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class BaseAImpl<!>() : BaseA<!>
class DerivedA1 : BaseAImpl() <!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class DerivedA1<!> : BaseAImpl()
class DerivedA2 : BaseAImpl() { class DerivedA2 : BaseAImpl() {
override fun foo() = super.<!ABSTRACT_SUPER_CALL!>foo<!>() override fun foo() = super.<!ABSTRACT_SUPER_CALL!>foo<!>()
} }
@@ -16,9 +16,9 @@ class DerivedA2 : BaseAImpl() {
<!NO_ACTUAL_FOR_EXPECT!>expect interface BaseB { <!NO_ACTUAL_FOR_EXPECT!>expect interface BaseB {
fun foo() fun foo()
}<!> }<!>
<!NO_ACTUAL_FOR_EXPECT!>expect open class BaseBImpl() : BaseB<!> <!NO_ACTUAL_FOR_EXPECT!>expect open <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class BaseBImpl<!>() : BaseB<!>
class DerivedB1 : BaseBImpl() <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class DerivedB1<!> : BaseBImpl()
class DerivedB2 : BaseBImpl() { class DerivedB2 : BaseBImpl() {
override fun foo() = super.<!ABSTRACT_SUPER_CALL!>foo<!>() override fun foo() = super.<!ABSTRACT_SUPER_CALL!>foo<!>()
} }
@@ -30,7 +30,7 @@ class DerivedB2 : BaseBImpl() {
}<!> }<!>
<!NO_ACTUAL_FOR_EXPECT!>expect abstract class BaseCImpl() : BaseC<!> <!NO_ACTUAL_FOR_EXPECT!>expect abstract class BaseCImpl() : BaseC<!>
class DerivedC1 : BaseCImpl() <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class DerivedC1<!> : BaseCImpl()
class DerivedC2 : BaseCImpl() { class DerivedC2 : BaseCImpl() {
override fun foo() = super.<!ABSTRACT_SUPER_CALL!>foo<!>() override fun foo() = super.<!ABSTRACT_SUPER_CALL!>foo<!>()
} }
@@ -58,4 +58,14 @@ sealed class BaseEImpl() : BaseE {
<!NO_ACTUAL_FOR_EXPECT!>expect interface BaseF { <!NO_ACTUAL_FOR_EXPECT!>expect interface BaseF {
fun foo() fun foo()
}<!> }<!>
<!NO_ACTUAL_FOR_EXPECT!>expect class BaseFImpl() : BaseF<!> <!NO_ACTUAL_FOR_EXPECT!>expect <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class BaseFImpl<!>() : BaseF<!>
<!NO_ACTUAL_FOR_EXPECT!>expect abstract class BaseG() {
abstract fun foo()
}<!>
<!NO_ACTUAL_FOR_EXPECT!>expect open class BaseGImpl() : BaseG {
override fun foo()
}<!>
class DerivedG1 : BaseGImpl()
@@ -4,9 +4,9 @@
expect abstract class BaseA() { expect abstract class BaseA() {
abstract fun foo() abstract fun foo()
} }
expect open class BaseAImpl() : BaseA expect open <!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class BaseAImpl<!>() : BaseA
class DerivedA1 : BaseAImpl() <!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class DerivedA1<!> : BaseAImpl()
class DerivedA2 : BaseAImpl() { class DerivedA2 : BaseAImpl() {
override fun foo() = super.foo() override fun foo() = super.foo()
} }
@@ -16,7 +16,7 @@ class DerivedA2 : BaseAImpl() {
expect interface BaseB { expect interface BaseB {
fun foo() fun foo()
} }
expect open class BaseBImpl() : BaseB expect open <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class BaseBImpl<!>() : BaseB
class DerivedB1 : BaseBImpl() class DerivedB1 : BaseBImpl()
class DerivedB2 : BaseBImpl() { class DerivedB2 : BaseBImpl() {
@@ -58,4 +58,14 @@ sealed class BaseEImpl() : BaseE {
expect interface BaseF { expect interface BaseF {
fun foo() fun foo()
} }
expect class BaseFImpl() : BaseF expect <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class BaseFImpl<!>() : BaseF
expect abstract class BaseG() {
abstract fun foo()
}
expect open class BaseGImpl() : BaseG {
override fun foo()
}
class DerivedG1 : BaseGImpl()
@@ -93,6 +93,22 @@ public final expect class BaseFImpl : BaseF {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
public abstract expect class BaseG {
public constructor BaseG()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract expect fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open expect class BaseGImpl : BaseG {
public constructor BaseGImpl()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open expect override /*1*/ fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class DerivedA1 : BaseAImpl { public final class DerivedA1 : BaseAImpl {
public constructor DerivedA1() public constructor DerivedA1()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -141,3 +157,11 @@ public final class DerivedC2 : BaseCImpl {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
public final class DerivedG1 : BaseGImpl {
public constructor DerivedG1()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open expect override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -5,7 +5,7 @@ expect abstract class Base {
abstract fun foo() abstract fun foo()
} }
expect class DerivedImplicit : Base expect <!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class DerivedImplicit<!> : Base
expect class DerivedExplicit : Base { expect class DerivedExplicit : Base {
override fun foo() override fun foo()
@@ -5,7 +5,7 @@ expect abstract class Base {
abstract fun foo() abstract fun foo()
} }
expect class DerivedImplicit : Base expect <!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED, ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED{JVM}!>class DerivedImplicit<!> : Base
expect class DerivedExplicit : Base { expect class DerivedExplicit : Base {
override fun foo() override fun foo()
@@ -19,6 +19,7 @@ expect class FastArrayList<E> : MutableListEx<E>, RandomAccess {
constructor(elements: Collection<E>) constructor(elements: Collection<E>)
fun trimToSize() fun trimToSize()
override fun removeRange(fromIndex: Int, toIndex: Int)
fun ensureCapacity(minCapacity: Int) fun ensureCapacity(minCapacity: Int)
override val size: Int override val size: Int
override fun isEmpty(): Boolean override fun isEmpty(): Boolean
@@ -66,7 +67,7 @@ public actual open class FastArrayList<E> internal constructor(
actual override fun addAll(index: Int, elements: Collection<E>): Boolean = true actual override fun addAll(index: Int, elements: Collection<E>): Boolean = true
actual override fun remove(element: E): Boolean = true actual override fun remove(element: E): Boolean = true
@Suppress("UNCHECKED_CAST") actual override fun removeAt(index: Int): E = array[0] as E @Suppress("UNCHECKED_CAST") actual override fun removeAt(index: Int): E = array[0] as E
override fun removeRange(fromIndex: Int, toIndex: Int) {} actual override fun removeRange(fromIndex: Int, toIndex: Int) {}
override fun setAll(index: Int, elements: FastArrayList<E>, offset: Int, size: Int) {} override fun setAll(index: Int, elements: FastArrayList<E>, offset: Int, size: Int) {}
override fun addAll(elements: FastArrayList<E>, offset: Int, size: Int) {} override fun addAll(elements: FastArrayList<E>, offset: Int, size: Int) {}
actual override fun clear() {} actual override fun clear() {}
@@ -43,6 +43,8 @@ FILE fqName:<root> fileName:/common.kt
public open fun toString (): kotlin.String declared in kotlin.Any public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any $this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS CLASS name:C modality:FINAL visibility:public [expect] superTypes:[<root>.I1; <root>.I2] CLASS CLASS name:C modality:FINAL visibility:public [expect] superTypes:[<root>.I1; <root>.I2]
annotations:
Suppress(names = ['ABSTRACT_MEMBER_NOT_IMPLEMENTED'])
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.C $this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.C
CONSTRUCTOR visibility:public <> () returnType:<root>.C [primary,expect] CONSTRUCTOR visibility:public <> () returnType:<root>.C [primary,expect]
FUN FAKE_OVERRIDE name:f visibility:public modality:ABSTRACT <> ($this:<root>.I1) returnType:kotlin.String [expect,fake_override] FUN FAKE_OVERRIDE name:f visibility:public modality:ABSTRACT <> ($this:<root>.I1) returnType:kotlin.String [expect,fake_override]
@@ -17,6 +17,7 @@ interface I2 {
val p: Int val p: Int
} }
@Suppress("ABSTRACT_MEMBER_NOT_IMPLEMENTED") // Workaround for KT-60390
expect class C() : I1, I2 expect class C() : I1, I2
// MODULE: platform()()(common) // MODULE: platform()()(common)
@@ -17,6 +17,7 @@ interface I2 {
} }
@Suppress(names = ["ABSTRACT_MEMBER_NOT_IMPLEMENTED"])
expect class C : I1, I2 { expect class C : I1, I2 {
expect constructor() /* primary */ expect constructor() /* primary */
@@ -2,4 +2,6 @@ expect abstract class Base {
abstract fun foo() abstract fun foo()
} }
expect class DerivedImplicit : Base expect class DerivedImplicit : Base {
override fun foo()
}
@@ -3,5 +3,5 @@ actual abstract class Base {
} }
actual class DerivedImplicit : Base() { actual class DerivedImplicit : Base() {
override fun foo() {} actual override fun foo() {}
} }
@@ -26,8 +26,7 @@ enum class ImplementationStatus {
ALREADY_IMPLEMENTED, ALREADY_IMPLEMENTED,
/** /**
* The symbol is not implemented in the class and it cannot be implemented. For example, it's final in super classes or the current * The symbol is not implemented in the class, and it cannot be implemented. For example, it's final in super classes.
* class is `expect`.
*/ */
CANNOT_BE_IMPLEMENTED; CANNOT_BE_IMPLEMENTED;
@@ -505,10 +505,6 @@ public class DescriptorUtils {
UnsignedTypes.INSTANCE.isUnsignedType(type); UnsignedTypes.INSTANCE.isUnsignedType(type);
} }
public static boolean classCanHaveAbstractFakeOverride(@NotNull ClassDescriptor classDescriptor) {
return classCanHaveAbstractDeclaration(classDescriptor) || classDescriptor.isExpect();
}
public static boolean classCanHaveAbstractDeclaration(@NotNull ClassDescriptor classDescriptor) { public static boolean classCanHaveAbstractDeclaration(@NotNull ClassDescriptor classDescriptor) {
return classDescriptor.getModality() == Modality.ABSTRACT return classDescriptor.getModality() == Modality.ABSTRACT
|| isSealedClass(classDescriptor) || isSealedClass(classDescriptor)
@@ -25,13 +25,19 @@ import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.Severity import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.CommonPlatforms import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
import org.jetbrains.kotlin.psi.psiUtil.isAbstract
import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.CompilerEnvironment import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
@@ -95,7 +101,14 @@ class InlineSourceBuilderImpl(private val disposable: Disposable) : InlineSource
environment.createPackagePartProvider(content.moduleContentScope) environment.createPackagePartProvider(content.moduleContentScope)
} }
val errorDiagnostics = analysisResult.bindingContext.diagnostics.noSuppression().filter { it.severity == Severity.ERROR } val errorDiagnostics = analysisResult.bindingContext.diagnostics.noSuppression()
.filter { it.severity == Severity.ERROR }
.filterNot { diagnostic ->
val psiElement = diagnostic.psiElement
// Mute KT-60378 problem
psiElement is KtClass && psiElement.hasExpectModifier() && !psiElement.hasModifier(KtTokens.OPEN_KEYWORD) &&
diagnostic.factory in listOf(Errors.ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED, Errors.ABSTRACT_MEMBER_NOT_IMPLEMENTED)
}
check(errorDiagnostics.isEmpty()) { check(errorDiagnostics.isEmpty()) {
val diagnosticInfos = errorDiagnostics.map { diagnostic -> val diagnosticInfos = errorDiagnostics.map { diagnostic ->
DiagnosticInfo(diagnostic.psiElement, diagnostic.factoryName) DiagnosticInfo(diagnostic.psiElement, diagnostic.factoryName)