CallableMemberDescriptor.isOverridable / ClassDescriptor.isFinal refactoring

Extra JvmField and integer constants tests
This commit is contained in:
Mikhail Glukhikh
2015-12-11 19:17:15 +03:00
parent 91621704a2
commit f5989aa4f2
12 changed files with 64 additions and 32 deletions
@@ -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) {
@@ -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;
@@ -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
View File
@@ -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 }
@@ -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
@@ -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
+2 -2
View File
@@ -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;
}