diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt index 77456d9fca8..998457505e0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt @@ -114,7 +114,6 @@ class SyntheticClassOrObjectDescriptor( private inner class SyntheticTypeConstructor(storageManager: StorageManager) : AbstractClassTypeConstructor(storageManager) { override fun getParameters(): List = emptyList() - override fun isFinal(): Boolean = true override fun isDenotable(): Boolean = true override fun getDeclarationDescriptor(): ClassDescriptor = thisDescriptor override fun computeSupertypes(): Collection = syntheticSupertypes diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java index cad3b30e81b..5787eace720 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -650,11 +650,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes return parameters.invoke(); } - @Override - public boolean isFinal() { - return getModality() == Modality.FINAL; - } - @Override public boolean isDenotable() { return true; diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/implOpenClass.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/implOpenClass.kt index 38b52c8c35d..f115edd5638 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/headerClass/implOpenClass.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/implOpenClass.kt @@ -6,6 +6,8 @@ expect class Foo expect fun getFoo(): Foo +fun bar() {} // no "Foo is final" warning should be here + // MODULE: m2-jvm(m1-common) // FILE: jvm.kt diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/implOpenClass.txt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/implOpenClass.txt index d3e6ab1ee58..aa39846925c 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/headerClass/implOpenClass.txt +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/implOpenClass.txt @@ -1,6 +1,7 @@ // -- Module: -- package +public fun bar(): kotlin.Unit public expect fun getFoo(): Foo public final expect class Foo { @@ -13,6 +14,7 @@ public final expect class Foo { // -- Module: -- package +public fun bar(): kotlin.Unit public actual fun getFoo(): Foo public final class Bar : Foo { diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/smartCastOnExpectClass.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/smartCastOnExpectClass.kt new file mode 100644 index 00000000000..bb2649aa8ee --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/smartCastOnExpectClass.kt @@ -0,0 +1,13 @@ +// !LANGUAGE: +MultiPlatformProjects +// MODULE: m1-common +// FILE: common.kt + +expect class Foo { // also, it's important that Foo doesn't override equals + fun foo() +} + +fun check(x1: Foo, x: Any) { + if (x1 == x) { + x.foo() + } +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/smartCastOnExpectClass.txt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/smartCastOnExpectClass.txt new file mode 100644 index 00000000000..009c7d5f169 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/smartCastOnExpectClass.txt @@ -0,0 +1,10 @@ +package + +public fun check(/*0*/ x1: Foo, /*1*/ x: kotlin.Any): kotlin.Unit + +public final expect class Foo { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index e5c95f6b46f..82dc833001f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -14241,6 +14241,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("smartCastOnExpectClass.kt") + public void testSmartCastOnExpectClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/smartCastOnExpectClass.kt"); + doTest(fileName); + } + @TestMetadata("superClass.kt") public void testSuperClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/superClass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 584f3f19608..29938795d1f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -14241,6 +14241,12 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing doTest(fileName); } + @TestMetadata("smartCastOnExpectClass.kt") + public void testSmartCastOnExpectClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/smartCastOnExpectClass.kt"); + doTest(fileName); + } + @TestMetadata("superClass.kt") public void testSuperClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/superClass.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt index 06893292249..8303a709939 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt @@ -255,8 +255,6 @@ class LazyJavaClassDescriptor( override val supertypeLoopChecker: SupertypeLoopChecker get() = c.components.supertypeLoopChecker - override fun isFinal(): Boolean = isFinalClass - override fun isDenotable(): Boolean = true override fun getDeclarationDescriptor(): ClassDescriptor = this@LazyJavaClassDescriptor diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt index eb94b2fa084..d1be8c85ddb 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt @@ -152,7 +152,6 @@ class FunctionClassDescriptor( override fun getDeclarationDescriptor() = this@FunctionClassDescriptor override fun isDenotable() = true - override fun isFinal() = false override fun toString() = declarationDescriptor.toString() diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/AbstractClassTypeConstructor.java b/core/descriptors/src/org/jetbrains/kotlin/types/AbstractClassTypeConstructor.java index 06d6842b59a..7da3630411c 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/AbstractClassTypeConstructor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/AbstractClassTypeConstructor.java @@ -53,6 +53,12 @@ public abstract class AbstractClassTypeConstructor extends AbstractTypeConstruct @Override public abstract ClassDescriptor getDeclarationDescriptor(); + @Override + public final boolean isFinal() { + ClassDescriptor descriptor = getDeclarationDescriptor(); + return descriptor.getModality() == Modality.FINAL && !descriptor.isExpect(); + } + @NotNull @Override public KotlinBuiltIns getBuiltIns() { diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/ClassTypeConstructorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/types/ClassTypeConstructorImpl.java index fb46eea230b..2bc7d47fda0 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/ClassTypeConstructorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/ClassTypeConstructorImpl.java @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.types; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.descriptors.ClassDescriptor; -import org.jetbrains.kotlin.descriptors.Modality; import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker; import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; import org.jetbrains.kotlin.resolve.DescriptorUtils; @@ -56,11 +55,6 @@ public class ClassTypeConstructorImpl extends AbstractClassTypeConstructor imple return DescriptorUtils.getFqName(classDescriptor).asString(); } - @Override - public boolean isFinal() { - return classDescriptor.getModality() == Modality.FINAL; - } - @Override public boolean isDenotable() { return true; diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index d5366a71664..ecb4131ad5e 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -195,8 +195,6 @@ class DeserializedClassDescriptor( override fun getParameters() = parameters() - override fun isFinal(): Boolean = isFinalClass - override fun isDenotable() = true override fun getDeclarationDescriptor() = this@DeserializedClassDescriptor