CallableMemberDescriptor.isOverridable / ClassDescriptor.isFinal refactoring
Extra JvmField and integer constants tests
This commit is contained in:
@@ -611,9 +611,10 @@ public class ControlFlowInformationProvider {
|
||||
assert descriptor instanceof FunctionDescriptor : owner.getText();
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||
String functionName = functionDescriptor.getName().asString();
|
||||
KtFunction function = (KtFunction) owner;
|
||||
if (isMain
|
||||
|| ModalityKt.isOverridable(functionDescriptor)
|
||||
|| !functionDescriptor.getOverriddenDescriptors().isEmpty()
|
||||
|| ModalityKt.isOverridableOrOverrides(functionDescriptor)
|
||||
|| function.hasModifier(KtTokens.OVERRIDE_KEYWORD)
|
||||
|| "getValue".equals(functionName) || "setValue".equals(functionName)
|
||||
|| "propertyDelegated".equals(functionName)
|
||||
) {
|
||||
|
||||
@@ -483,13 +483,14 @@ public class BodyResolver {
|
||||
trace.report(SUPERTYPE_APPEARS_TWICE.on(typeReference));
|
||||
}
|
||||
|
||||
if (classDescriptor != null && classDescriptor.getKind().isSingleton()) {
|
||||
if (classDescriptor == null) return;
|
||||
if (classDescriptor.getKind().isSingleton()) {
|
||||
if (!DescriptorUtils.isEnumEntry(classDescriptor)) {
|
||||
trace.report(SINGLETON_IN_SUPERTYPE.on(typeReference));
|
||||
}
|
||||
}
|
||||
else if (!allowedFinalSupertypes.contains(constructor)) {
|
||||
if (classDescriptor != null && classDescriptor.getModality() == Modality.SEALED) {
|
||||
if (classDescriptor.getModality() == Modality.SEALED) {
|
||||
DeclarationDescriptor containingDescriptor = supertypeOwner.getContainingDeclaration();
|
||||
while (containingDescriptor != null && containingDescriptor != classDescriptor) {
|
||||
containingDescriptor = containingDescriptor.getContainingDeclaration();
|
||||
@@ -501,7 +502,7 @@ public class BodyResolver {
|
||||
trace.report(SEALED_SUPERTYPE_IN_LOCAL_CLASS.on(typeReference));
|
||||
}
|
||||
}
|
||||
else if (constructor.isFinal()) {
|
||||
else if (ModalityKt.isFinalOrEnum(classDescriptor)) {
|
||||
trace.report(FINAL_SUPERTYPE.on(typeReference));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,10 +712,7 @@ class DeclarationsChecker(
|
||||
reportVisibilityModifierDiagnostics(tokens.values, Errors.PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY)
|
||||
}
|
||||
else {
|
||||
val parentDescriptor = propertyDescriptor.containingDeclaration
|
||||
if (parentDescriptor !is ClassDescriptor || !parentDescriptor.isFinal) {
|
||||
reportVisibilityModifierDiagnostics(tokens.values, Errors.PRIVATE_SETTER_FOR_OPEN_PROPERTY)
|
||||
}
|
||||
reportVisibilityModifierDiagnostics(tokens.values, Errors.PRIVATE_SETTER_FOR_OPEN_PROPERTY)
|
||||
}
|
||||
}
|
||||
else if (propertyDescriptor.isLateInit && accessorDescriptor.visibility != propertyDescriptor.visibility) {
|
||||
|
||||
+1
-15
@@ -395,7 +395,7 @@ public class DataFlowValueFactory {
|
||||
|
||||
private static Kind propertyKind(@NotNull PropertyDescriptor propertyDescriptor, @Nullable ModuleDescriptor usageModule) {
|
||||
if (propertyDescriptor.isVar()) return MUTABLE_PROPERTY;
|
||||
if (!isFinal(propertyDescriptor)) return PROPERTY_WITH_GETTER;
|
||||
if (ModalityKt.isOverridable(propertyDescriptor)) return PROPERTY_WITH_GETTER;
|
||||
if (!hasDefaultGetter(propertyDescriptor)) return PROPERTY_WITH_GETTER;
|
||||
if (!invisibleFromOtherModules(propertyDescriptor)) {
|
||||
ModuleDescriptor declarationModule = DescriptorUtils.getContainingModule(propertyDescriptor);
|
||||
@@ -464,20 +464,6 @@ public class DataFlowValueFactory {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isFinal(PropertyDescriptor propertyDescriptor) {
|
||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||
if (containingDeclaration instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
||||
if (!ModalityKt.isFinal(classDescriptor) && ModalityKt.isOverridable(propertyDescriptor)) return false;
|
||||
}
|
||||
else {
|
||||
if (ModalityKt.isOverridable(propertyDescriptor)) {
|
||||
throw new IllegalStateException("Property outside a class must not be overridable: " + propertyDescriptor.getName());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean invisibleFromOtherModules(@NotNull DeclarationDescriptorWithVisibility descriptor) {
|
||||
if (Visibilities.INVISIBLE_FROM_OTHER_MODULES.contains(descriptor.getVisibility())) return true;
|
||||
|
||||
|
||||
+2
-1
@@ -531,7 +531,8 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
if (resolvedCall != null) {
|
||||
val callableDescriptor = resolvedCall.resultingDescriptor
|
||||
if (callableDescriptor is VariableDescriptor) {
|
||||
if (callableDescriptor is PropertyDescriptor && callableDescriptor.isOverridable) return null
|
||||
// TODO: FIXME: see KT-10425
|
||||
if (callableDescriptor is PropertyDescriptor && callableDescriptor.modality != Modality.FINAL) return null
|
||||
|
||||
val variableInitializer = callableDescriptor.compileTimeInitializer ?: return null
|
||||
|
||||
|
||||
+2
-2
@@ -9,8 +9,8 @@ class MyClass() {
|
||||
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>var b: Int<!> private set
|
||||
var b1: Int = 0; private set
|
||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> var b2: Int <!PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY!>private<!> set
|
||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> var b3: Int = 0; <!PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY!>private<!> set
|
||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> var b2: Int private set
|
||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> var b3: Int = 0; private set
|
||||
|
||||
<!MUST_BE_INITIALIZED!>var c: Int<!> set(v: Int) { field = v }
|
||||
var c1: Int = 0; set(v: Int) { field = v }
|
||||
|
||||
Vendored
+18
@@ -65,12 +65,30 @@ class H {
|
||||
}
|
||||
|
||||
interface K {
|
||||
|
||||
val i: Int
|
||||
val j: Int
|
||||
|
||||
companion object {
|
||||
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||
var c = 3
|
||||
}
|
||||
}
|
||||
|
||||
class KK : K {
|
||||
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||
override val i: Int = 0
|
||||
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||
override final val j: Int = 0
|
||||
}
|
||||
|
||||
open class KKK : K {
|
||||
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||
override val i: Int = 0
|
||||
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||
override final val j: Int = 0
|
||||
}
|
||||
|
||||
object O {
|
||||
@JvmField
|
||||
val c = 3
|
||||
|
||||
Vendored
+20
@@ -54,6 +54,8 @@ public interface I {
|
||||
}
|
||||
|
||||
public interface K {
|
||||
public abstract val i: kotlin.Int
|
||||
public abstract val j: kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
@@ -67,6 +69,24 @@ public interface K {
|
||||
}
|
||||
}
|
||||
|
||||
public final class KK : K {
|
||||
public constructor KK()
|
||||
@kotlin.jvm.JvmField() public open override /*1*/ val i: kotlin.Int = 0
|
||||
@kotlin.jvm.JvmField() public final override /*1*/ val j: kotlin.Int = 0
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class KKK : K {
|
||||
public constructor KKK()
|
||||
@kotlin.jvm.JvmField() public open override /*1*/ val i: kotlin.Int = 0
|
||||
@kotlin.jvm.JvmField() public final override /*1*/ val j: kotlin.Int = 0
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public object O {
|
||||
private constructor O()
|
||||
@kotlin.jvm.JvmField() public final val c: kotlin.Int = 3
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
// For sealed classes, isOverridable is false but isOverridableByMembers is true
|
||||
enum class Modality {
|
||||
// THE ORDER OF ENTRIES MATTERS HERE
|
||||
@@ -37,7 +39,13 @@ enum class Modality {
|
||||
}
|
||||
|
||||
val CallableMemberDescriptor.isOverridable: Boolean
|
||||
get() = modality != Modality.FINAL
|
||||
get() = modality != Modality.FINAL && (containingDeclaration as? ClassDescriptor)?.isFinal != true
|
||||
|
||||
val CallableMemberDescriptor.isOverridableOrOverrides: Boolean
|
||||
get() = isOverridable || DescriptorUtils.isOverride(this)
|
||||
|
||||
val ClassDescriptor.isFinal: Boolean
|
||||
get() = modality == Modality.FINAL && kind != ClassKind.ENUM_CLASS
|
||||
|
||||
val ClassDescriptor.isFinalOrEnum: Boolean
|
||||
get() = modality == Modality.FINAL
|
||||
|
||||
Vendored
+2
-2
@@ -10,8 +10,8 @@ class MyClass() {
|
||||
|
||||
<error>var b: Int</error> private set
|
||||
var b1: Int = 0; private set
|
||||
<error>abstract</error> var b2: Int <error>private</error> set
|
||||
<error>abstract</error> var b3: Int = 0; <error>private</error> set
|
||||
<error>abstract</error> var b2: Int private set
|
||||
<error>abstract</error> var b3: Int = 0; private set
|
||||
|
||||
<error>var c: Int</error> set(v: Int) { field = v }
|
||||
var c1: Int = 0; set(v: Int) { field = v }
|
||||
|
||||
@@ -151,7 +151,7 @@ public final class JsDescriptorUtils {
|
||||
return !isExtension(propertyDescriptor) &&
|
||||
isDefaultAccessor(propertyDescriptor.getGetter()) &&
|
||||
isDefaultAccessor(propertyDescriptor.getSetter()) &&
|
||||
!ModalityKt.isOverridable(propertyDescriptor);
|
||||
!ModalityKt.isOverridableOrOverrides(propertyDescriptor);
|
||||
}
|
||||
|
||||
public static boolean isBuiltin(@NotNull DeclarationDescriptor descriptor) {
|
||||
|
||||
@@ -86,7 +86,7 @@ public class ManglingUtils {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
||||
|
||||
// Use stable mangling when it's inside an overridable declaration to avoid clashing names on inheritance.
|
||||
if (!ModalityKt.isFinal(classDescriptor)) {
|
||||
if (!ModalityKt.isFinalOrEnum(classDescriptor)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user