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