Fix diagnostic messages for properties.
Fix IDE tests. Update quick fixes in IDE (TODO: review new inheritance-related diagnostics with regards to quick fixes)
This commit is contained in:
@@ -323,11 +323,15 @@ public interface Errors {
|
||||
DiagnosticFactory2.create(ERROR, DECLARATION_RETURN_TYPE);
|
||||
DiagnosticFactory2<KtNamedDeclaration, CallableMemberDescriptor, CallableMemberDescriptor> PROPERTY_TYPE_MISMATCH_ON_OVERRIDE =
|
||||
DiagnosticFactory2.create(ERROR, DECLARATION_RETURN_TYPE);
|
||||
DiagnosticFactory2<KtNamedDeclaration, CallableMemberDescriptor, CallableMemberDescriptor> VAR_TYPE_MISMATCH_ON_OVERRIDE =
|
||||
DiagnosticFactory2.create(ERROR, DECLARATION_RETURN_TYPE);
|
||||
|
||||
DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> RETURN_TYPE_MISMATCH_ON_INHERITANCE =
|
||||
DiagnosticFactory2.create(ERROR, DECLARATION_NAME);
|
||||
DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> PROPERTY_TYPE_MISMATCH_ON_INHERITANCE =
|
||||
DiagnosticFactory2.create(ERROR, DECLARATION_NAME);
|
||||
DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> VAR_TYPE_MISMATCH_ON_INHERITANCE =
|
||||
DiagnosticFactory2.create(ERROR, DECLARATION_NAME);
|
||||
|
||||
DiagnosticFactory2<KtClassOrObject, CallableMemberDescriptor, CallableMemberDescriptor> OVERRIDING_FINAL_MEMBER_BY_DELEGATION =
|
||||
DiagnosticFactory2.create(ERROR, DECLARATION_NAME);
|
||||
|
||||
+5
-1
@@ -558,10 +558,14 @@ public class DefaultErrorMessages {
|
||||
MAP.put(RETURN_TYPE_MISMATCH_ON_INHERITANCE, "''{0}'' clashes with ''{1}'': return types are incompatible",
|
||||
SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
|
||||
|
||||
MAP.put(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE, "Type of ''{0}'' doesn''t match the type of the overridden var-property ''{1}''",
|
||||
MAP.put(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE, "Type of ''{0}'' is not a subtype of the overridden property ''{1}''",
|
||||
NAME, FQ_NAMES_IN_TYPES);
|
||||
MAP.put(VAR_TYPE_MISMATCH_ON_OVERRIDE, "Type of ''{0}'' doesn''t match the type of the overridden var-property ''{1}''",
|
||||
NAME, FQ_NAMES_IN_TYPES);
|
||||
MAP.put(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, "''{0}'' clashes with ''{1}'': property types are incompatible",
|
||||
SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
|
||||
MAP.put(VAR_TYPE_MISMATCH_ON_INHERITANCE, "''{0}'' clashes with ''{1}'': property types do not match",
|
||||
SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
|
||||
|
||||
MAP.put(OVERRIDING_FINAL_MEMBER_BY_DELEGATION, "''{0}'' implicitly overrides a final member ''{1}'' by delegation",
|
||||
SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
|
||||
|
||||
@@ -286,7 +286,7 @@ public class OverrideResolver {
|
||||
void multipleImplementationsMemberNotImplemented(CallableMemberDescriptor descriptor);
|
||||
void conflictingInterfaceMemberNotImplemented(CallableMemberDescriptor descriptor);
|
||||
void returnTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2);
|
||||
void propertyTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2);
|
||||
void propertyTypeMismatchOnInheritance(PropertyDescriptor descriptor1, PropertyDescriptor descriptor2);
|
||||
}
|
||||
|
||||
private static class CollectMissingImplementationsStrategy implements CheckInheritedSignaturesReportStrategy {
|
||||
@@ -318,7 +318,7 @@ public class OverrideResolver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
|
||||
public void propertyTypeMismatchOnInheritance(PropertyDescriptor descriptor1, PropertyDescriptor descriptor2) {
|
||||
// don't care
|
||||
}
|
||||
}
|
||||
@@ -373,11 +373,16 @@ public class OverrideResolver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyTypeMismatchOnInheritance(CallableMemberDescriptor descriptor1, CallableMemberDescriptor descriptor2) {
|
||||
public void propertyTypeMismatchOnInheritance(PropertyDescriptor descriptor1, PropertyDescriptor descriptor2) {
|
||||
conflictingReturnTypes.add(descriptor1);
|
||||
conflictingReturnTypes.add(descriptor2);
|
||||
|
||||
reportInheritanceConflictIfRequired(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
|
||||
if (descriptor1.isVar() || descriptor2.isVar()) {
|
||||
reportInheritanceConflictIfRequired(VAR_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
|
||||
}
|
||||
else {
|
||||
reportInheritanceConflictIfRequired(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2);
|
||||
}
|
||||
}
|
||||
|
||||
private void reportInheritanceConflictIfRequired(
|
||||
@@ -406,8 +411,8 @@ public class OverrideResolver {
|
||||
|
||||
@Override
|
||||
public void propertyTypeMismatchOnOverride(
|
||||
@NotNull CallableMemberDescriptor overriding,
|
||||
@NotNull CallableMemberDescriptor overridden
|
||||
@NotNull PropertyDescriptor overriding,
|
||||
@NotNull PropertyDescriptor overridden
|
||||
) {
|
||||
// Always reported as PROPERTY_TYPE_MISMATCH_ON_INHERITANCE
|
||||
}
|
||||
@@ -732,7 +737,7 @@ public class OverrideResolver {
|
||||
private interface CheckOverrideReportStrategy {
|
||||
void overridingFinalMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
|
||||
void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
|
||||
void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
|
||||
void propertyTypeMismatchOnOverride(@NotNull PropertyDescriptor overriding, @NotNull PropertyDescriptor overridden);
|
||||
void varOverriddenByVal(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden);
|
||||
void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor invisibleOverridden);
|
||||
void nothingToOverride(@NotNull CallableMemberDescriptor overriding);
|
||||
@@ -782,10 +787,15 @@ public class OverrideResolver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
|
||||
public void propertyTypeMismatchOnOverride(@NotNull PropertyDescriptor overriding, @NotNull PropertyDescriptor overridden) {
|
||||
if (!typeMismatchError) {
|
||||
typeMismatchError = true;
|
||||
trace.report(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
|
||||
if (overridden.isVar()) {
|
||||
trace.report(VAR_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
|
||||
}
|
||||
else {
|
||||
trace.report(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -829,7 +839,7 @@ public class OverrideResolver {
|
||||
PropertyDescriptor inheritedPropertyDescriptor = (PropertyDescriptor) inheritedDescriptor;
|
||||
|
||||
if (!isPropertyTypeOkForOverride(inheritedPropertyDescriptor, mostSpecificProperty)) {
|
||||
reportingStrategy.propertyTypeMismatchOnInheritance(mostSpecific, inheritedDescriptor);
|
||||
reportingStrategy.propertyTypeMismatchOnInheritance(mostSpecificProperty, inheritedPropertyDescriptor);
|
||||
}
|
||||
}
|
||||
else if (!isReturnTypeOkForOverride(inheritedDescriptor, mostSpecific)) {
|
||||
@@ -868,6 +878,9 @@ public class OverrideResolver {
|
||||
@NotNull Collection<? extends CallableMemberDescriptor> overriddenDescriptors,
|
||||
@NotNull CheckOverrideReportStrategy reportError
|
||||
) {
|
||||
PropertyDescriptor propertyMemberDescriptor =
|
||||
memberDescriptor instanceof PropertyDescriptor ? (PropertyDescriptor) memberDescriptor : null;
|
||||
|
||||
for (CallableMemberDescriptor overridden : overriddenDescriptors) {
|
||||
if (overridden == null) continue;
|
||||
|
||||
@@ -875,9 +888,12 @@ public class OverrideResolver {
|
||||
reportError.overridingFinalMember(memberDescriptor, overridden);
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof PropertyDescriptor &&
|
||||
!isPropertyTypeOkForOverride((PropertyDescriptor) overridden, (PropertyDescriptor) memberDescriptor)) {
|
||||
reportError.propertyTypeMismatchOnOverride(memberDescriptor, overridden);
|
||||
if (propertyMemberDescriptor != null) {
|
||||
assert overridden instanceof PropertyDescriptor : overridden + " is overridden by property " + propertyMemberDescriptor;
|
||||
PropertyDescriptor overriddenProperty = (PropertyDescriptor) overridden;
|
||||
if (!isPropertyTypeOkForOverride(overriddenProperty, propertyMemberDescriptor)) {
|
||||
reportError.propertyTypeMismatchOnOverride(propertyMemberDescriptor, overriddenProperty);
|
||||
}
|
||||
}
|
||||
else if (!isReturnTypeOkForOverride(overridden, memberDescriptor)) {
|
||||
reportError.returnTypeMismatchOnOverride(memberDescriptor, overridden);
|
||||
@@ -966,7 +982,7 @@ public class OverrideResolver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overriding, @NotNull CallableMemberDescriptor overridden) {
|
||||
public void propertyTypeMismatchOnOverride(@NotNull PropertyDescriptor overriding, @NotNull PropertyDescriptor overridden) {
|
||||
throw new IllegalStateException("Component functions are not properties");
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -4,6 +4,6 @@ abstract class A {
|
||||
}
|
||||
|
||||
abstract class C : A() {
|
||||
override abstract var x: <!PROPERTY_TYPE_MISMATCH_ON_OVERRIDE!>String<!> =<!SYNTAX!><!> <!SYNTAX!>?<!>
|
||||
override abstract var x: <!VAR_TYPE_MISMATCH_ON_OVERRIDE!>String<!> =<!SYNTAX!><!> <!SYNTAX!>?<!>
|
||||
override abstract fun foo(): <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>String<!> =<!SYNTAX!><!> <!SYNTAX!>?<!>
|
||||
}
|
||||
|
||||
+6
-6
@@ -14,16 +14,16 @@ interface IGA<T> {
|
||||
var foo: T
|
||||
}
|
||||
|
||||
<!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class B1<!>: A(), IA
|
||||
<!VAR_TYPE_MISMATCH_ON_INHERITANCE!>class B1<!>: A(), IA
|
||||
|
||||
<!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class B2<!>: A(), IA, IAA
|
||||
<!VAR_TYPE_MISMATCH_ON_INHERITANCE!>class B2<!>: A(), IA, IAA
|
||||
|
||||
abstract <!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class B3<!>: IA, IAA
|
||||
abstract <!VAR_TYPE_MISMATCH_ON_INHERITANCE!>class B3<!>: IA, IAA
|
||||
|
||||
class BS1: A(), IGA<Boolean>
|
||||
|
||||
<!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class BS2<!>: A(), IGA<Any>
|
||||
<!VAR_TYPE_MISMATCH_ON_INHERITANCE!>class BS2<!>: A(), IGA<Any>
|
||||
|
||||
<!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class BS3<!>: A(), IGA<String>
|
||||
<!VAR_TYPE_MISMATCH_ON_INHERITANCE!>class BS3<!>: A(), IGA<String>
|
||||
|
||||
<!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class BG1<!><T>: A(), IGA<T>
|
||||
<!VAR_TYPE_MISMATCH_ON_INHERITANCE!>class BG1<!><T>: A(), IGA<T>
|
||||
|
||||
+1
-1
@@ -4,6 +4,6 @@ interface Super {
|
||||
}
|
||||
|
||||
class Sub: Super {
|
||||
override var v: <!PROPERTY_TYPE_MISMATCH_ON_OVERRIDE!>String<!> = "fail"
|
||||
override var v: <!VAR_TYPE_MISMATCH_ON_OVERRIDE!>String<!> = "fail"
|
||||
override val v2: String = "ok"
|
||||
}
|
||||
@@ -99,13 +99,19 @@ public class IdeErrorMessages {
|
||||
MAP.put(RETURN_TYPE_MISMATCH_ON_INHERITANCE, "<html>Return types of inherited members are incompatible:<br/>{0},<br/>{1}</html>",
|
||||
DescriptorRenderer.HTML, DescriptorRenderer.HTML);
|
||||
|
||||
MAP.put(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE, "<html>Var-property type is ''{0}'', which is not a type of overridden<br/>" +
|
||||
MAP.put(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE, "<html>Property type is ''{0}'', which is not a subtype type of overridden<br/>" +
|
||||
"{1}</html>", HTML_RENDER_RETURN_TYPE, DescriptorRenderer.HTML);
|
||||
MAP.put(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, "<html>Property types of inherited members are incompatible:<br/>{0},<br/>{1}</html>",
|
||||
MAP.put(VAR_TYPE_MISMATCH_ON_OVERRIDE, "<html>Var-property type is ''{0}'', which is not a type of overridden<br/>" +
|
||||
"{1}</html>", HTML_RENDER_RETURN_TYPE, DescriptorRenderer.HTML);
|
||||
MAP.put(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, "<html>Types of inherited properties are incompatible:<br/>{0},<br/>{1}</html>",
|
||||
DescriptorRenderer.HTML, DescriptorRenderer.HTML);
|
||||
MAP.put(VAR_TYPE_MISMATCH_ON_INHERITANCE, "<html>Types of inherited var-properties do not match:<br/>{0},<br/>{1}</html>",
|
||||
DescriptorRenderer.HTML, DescriptorRenderer.HTML);
|
||||
|
||||
MAP.put(VAR_OVERRIDDEN_BY_VAL, "<html>Val-property cannot override var-property<br />" +
|
||||
"{1}</html>", DescriptorRenderer.HTML, DescriptorRenderer.HTML);
|
||||
MAP.put(VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION, "<html>Val-property cannot override var-property<br />" +
|
||||
"{1}</html>", DescriptorRenderer.HTML, DescriptorRenderer.HTML);
|
||||
|
||||
MAP.put(ABSTRACT_MEMBER_NOT_IMPLEMENTED, "<html>{0} must be declared abstract or implement abstract member<br/>" +
|
||||
"{1}</html>", RENDER_CLASS_OR_OBJECT,
|
||||
|
||||
@@ -215,6 +215,7 @@ public class QuickFixRegistrar : QuickFixContributor {
|
||||
val changeVariableTypeFix = ChangeVariableTypeFix.createFactoryForPropertyOrReturnTypeMismatchOnOverride()
|
||||
RETURN_TYPE_MISMATCH_ON_OVERRIDE.registerFactory(changeVariableTypeFix)
|
||||
PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.registerFactory(changeVariableTypeFix)
|
||||
VAR_TYPE_MISMATCH_ON_OVERRIDE.registerFactory(changeVariableTypeFix)
|
||||
COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.registerFactory(ChangeVariableTypeFix.createFactoryForComponentFunctionReturnTypeMismatch())
|
||||
|
||||
val changeFunctionReturnTypeFix = ChangeFunctionReturnTypeFix.createFactoryForChangingReturnTypeToUnit()
|
||||
|
||||
+3
-4
@@ -1,12 +1,11 @@
|
||||
interface Base {
|
||||
fun foo(): Int
|
||||
|
||||
var bar: Int
|
||||
val qux: Int
|
||||
}
|
||||
|
||||
class Derived : Base {
|
||||
|
||||
override fun foo(): <error descr="[RETURN_TYPE_MISMATCH_ON_OVERRIDE] Return type of 'foo' is not a subtype of the return type of the overridden member 'public abstract fun foo(): kotlin.Int defined in Base'">String</error> = ""
|
||||
|
||||
override var bar: <error descr="[PROPERTY_TYPE_MISMATCH_ON_OVERRIDE] Type of 'bar' doesn't match the type of the overridden var-property 'public abstract var bar: kotlin.Int defined in Base'">String</error> = ""
|
||||
override var bar: <error descr="[VAR_TYPE_MISMATCH_ON_OVERRIDE] Type of 'bar' doesn't match the type of the overridden var-property 'public abstract var bar: kotlin.Int defined in Base'">String</error> = ""
|
||||
override val qux: <error descr="[PROPERTY_TYPE_MISMATCH_ON_OVERRIDE] Type of 'qux' is not a subtype of the overridden property 'public abstract val qux: kotlin.Int defined in Base'">String</error> = ""
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// "Change 'A.x' type to '(Int) -> Int'" "false"
|
||||
// ACTION: Change 'C.x' type to '(String) -> Int'
|
||||
// ERROR: Return type of 'x' is not a subtype of the return type of the overridden member 'public abstract val x: (kotlin.String) -> kotlin.Int defined in A'
|
||||
// ERROR: Type of 'x' is not a subtype of the overridden property 'public abstract val x: (kotlin.String) -> kotlin.Int defined in A'
|
||||
interface A {
|
||||
val x: (String) -> Int
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// "Change 'B.x' type to '(String) -> [ERROR : Ay]'" "false"
|
||||
// ACTION: Change 'A.x' type to '(Int) -> Int'
|
||||
// ERROR: Return type of 'x' is not a subtype of the return type of the overridden member 'public abstract val x: (kotlin.String) -> [ERROR : Ay] defined in A'
|
||||
// ERROR: Type of 'x' is not a subtype of the overridden property 'public abstract val x: (kotlin.String) -> [ERROR : Ay] defined in A'
|
||||
// ERROR: Unresolved reference: Ay
|
||||
interface A {
|
||||
val x: (String) -> Ay
|
||||
|
||||
Reference in New Issue
Block a user