'override' checks changed; tests added
This commit is contained in:
@@ -142,6 +142,9 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
substitutedReturnType,
|
||||
modality
|
||||
);
|
||||
for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
|
||||
substitutedDescriptor.addOverriddenFunction(overriddenFunction);
|
||||
}
|
||||
return substitutedDescriptor;
|
||||
}
|
||||
|
||||
|
||||
@@ -127,9 +127,15 @@ public class BodyResolver {
|
||||
return;
|
||||
}
|
||||
Set<FunctionDescriptor> allOverriddenFunctions = Sets.newHashSet();
|
||||
for (FunctionDescriptor declaredFunction : classDescriptor.getFunctions()) {
|
||||
for (FunctionDescriptor overriddenDescriptor : declaredFunction.getOverriddenDescriptors()) {
|
||||
allOverriddenFunctions.add(overriddenDescriptor.getOriginal());
|
||||
Collection<DeclarationDescriptor> allDescriptors = classDescriptor.getDefaultType().getMemberScope().getAllDescriptors();
|
||||
for (DeclarationDescriptor descriptor : allDescriptors) {
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||
if (functionDescriptor.getModality() != Modality.ABSTRACT) {
|
||||
for (FunctionDescriptor overriddenDescriptor : functionDescriptor.getOverriddenDescriptors()) {
|
||||
allOverriddenFunctions.add(overriddenDescriptor.getOriginal());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean foundError = false;
|
||||
@@ -137,19 +143,17 @@ public class BodyResolver {
|
||||
if (klass instanceof JetClass) {
|
||||
nameIdentifier = ((JetClass) klass).getNameIdentifier();
|
||||
}
|
||||
else if (klass instanceof JetObjectDeclaration) {
|
||||
else if (klass instanceof JetObjectDeclaration) {
|
||||
nameIdentifier = ((JetObjectDeclaration) klass).getNameIdentifier();
|
||||
}
|
||||
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
|
||||
Collection<DeclarationDescriptor> allDescriptors = supertype.getMemberScope().getAllDescriptors();
|
||||
for (DeclarationDescriptor descriptor : allDescriptors) {
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||
if (functionDescriptor.getModality() == Modality.ABSTRACT && !allOverriddenFunctions.contains(functionDescriptor.getOriginal()) && !foundError && nameIdentifier != null) {
|
||||
DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor();
|
||||
assert declarationDescriptor != null;
|
||||
for (DeclarationDescriptor descriptor : allDescriptors) {
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||
if (functionDescriptor.getModality() == Modality.ABSTRACT && !allOverriddenFunctions.contains(functionDescriptor.getOriginal()) && !foundError && nameIdentifier != null) {
|
||||
DeclarationDescriptor declarationDescriptor = functionDescriptor.getContainingDeclaration();
|
||||
if (declarationDescriptor != classDescriptor) {
|
||||
context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), "Class '" + klass.getName() + "' must be declared abstract or implement abstract method '" +
|
||||
functionDescriptor.getName() + "' in " + declarationDescriptor.getName());
|
||||
functionDescriptor.getName() + "' in " + declarationDescriptor.getName());
|
||||
foundError = true;
|
||||
}
|
||||
}
|
||||
@@ -180,7 +184,7 @@ public class BodyResolver {
|
||||
if (!hasOverrideModifier && declaredFunction.getOverriddenDescriptors().size() > 0 && nameIdentifier != null) {
|
||||
FunctionDescriptor overriddenMethod = declaredFunction.getOverriddenDescriptors().iterator().next();
|
||||
context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(),
|
||||
"Method " + declaredFunction.getName() + " overrides method " + overriddenMethod.getName() + " in class " +
|
||||
"Method '" + declaredFunction.getName() + "' overrides method '" + overriddenMethod.getName() + "' in class " +
|
||||
overriddenMethod.getContainingDeclaration().getName() + " and needs 'override' modifier");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
namespace override
|
||||
|
||||
namespace normal {
|
||||
trait MyTrait {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
abstract class MyAbstractClass {
|
||||
abstract fun bar()
|
||||
}
|
||||
|
||||
open class MyClass : MyTrait, MyAbstractClass {
|
||||
override fun foo() {}
|
||||
override fun bar() {}
|
||||
}
|
||||
|
||||
class MyChildClass : MyClass {}
|
||||
|
||||
class <error>MyIllegalClass</error> : MyTrait, MyAbstractClass {}
|
||||
|
||||
class <error>MyIllegalClass2</error> : MyTrait, MyAbstractClass {
|
||||
override fun foo() {}
|
||||
}
|
||||
|
||||
class <error>MyIllegalClass3</error> : MyTrait, MyAbstractClass {
|
||||
override fun bar() {}
|
||||
}
|
||||
|
||||
class <error>MyIllegalClass4</error> : MyTrait, MyAbstractClass {
|
||||
fun <error>foo</error>() {}
|
||||
<error>override</error> fun other() {}
|
||||
}
|
||||
|
||||
class MyChildClass1 : MyClass {
|
||||
fun <error>foo</error>() {}
|
||||
override fun bar() {}
|
||||
}
|
||||
}
|
||||
|
||||
namespace generics {
|
||||
trait MyTrait<T> {
|
||||
fun foo(t: T) : T
|
||||
}
|
||||
|
||||
abstract class MyAbstractClass<T> {
|
||||
abstract fun bar(t: T) : T
|
||||
}
|
||||
|
||||
open class MyGenericClass<T> : MyTrait<T>, MyAbstractClass<T> {
|
||||
override fun foo(t: T) = t
|
||||
override fun bar(t: T) = t
|
||||
}
|
||||
|
||||
class MyChildClass : MyGenericClass<Int> {}
|
||||
class MyChildClass1<T> : MyGenericClass<T> {}
|
||||
class MyChildClass2<T> : MyGenericClass<T> {
|
||||
fun <error>foo</error>(t: T) = t
|
||||
override fun bar(t: T) = t
|
||||
}
|
||||
|
||||
open class MyClass : MyTrait<Int>, MyAbstractClass<String> {
|
||||
override fun foo(i: Int) = i
|
||||
override fun bar(s: String) = s
|
||||
}
|
||||
|
||||
class <error>MyIllegalGenericClass1</error><T> : MyTrait<T>, MyAbstractClass<T> {}
|
||||
class <error>MyIllegalGenericClass2</error><T, R> : MyTrait<T>, MyAbstractClass<R> {
|
||||
<error>override</error> fun foo(r: R) = r
|
||||
}
|
||||
class <error>MyIllegalClass1</error> : MyTrait<Int>, MyAbstractClass<String> {}
|
||||
|
||||
class <error>MyIllegalClass2</error><T> : MyTrait<Int>, MyAbstractClass<Int> {
|
||||
fun foo(t: T) = t
|
||||
fun bar(t: T) = t
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user