Prohibit inheritance loops through containing classes
Example
class A : B {
trait C
}
class B : A.C
Here we have a loop in the hierarchy: A -> B -> A.C => A
"=>" represents class nesting
This commit is contained in:
+21
-5
@@ -327,7 +327,8 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
public Boolean invoke(JetClassObject classObject) {
|
public Boolean invoke(JetClassObject classObject) {
|
||||||
return classObject != declarationProvider.getOwnerInfo().getClassObject();
|
return classObject != declarationProvider.getOwnerInfo().getClassObject();
|
||||||
}
|
}
|
||||||
}),
|
}
|
||||||
|
),
|
||||||
new Function1<JetClassObject, ClassDescriptor>() {
|
new Function1<JetClassObject, ClassDescriptor>() {
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor invoke(JetClassObject classObject) {
|
public ClassDescriptor invoke(JetClassObject classObject) {
|
||||||
@@ -551,10 +552,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
|
|
||||||
private boolean isReachable(TypeConstructor from, TypeConstructor to, Set<TypeConstructor> visited) {
|
private boolean isReachable(TypeConstructor from, TypeConstructor to, Set<TypeConstructor> visited) {
|
||||||
if (!visited.add(from)) return false;
|
if (!visited.add(from)) return false;
|
||||||
Collection<JetType> supertypes = from instanceof LazyClassTypeConstructor
|
for (JetType supertype : getNeighbors(from)) {
|
||||||
? ((LazyClassTypeConstructor) from).supertypes.invoke().getAllSupertypes()
|
|
||||||
: from.getSupertypes();
|
|
||||||
for (JetType supertype : supertypes) {
|
|
||||||
TypeConstructor supertypeConstructor = supertype.getConstructor();
|
TypeConstructor supertypeConstructor = supertype.getConstructor();
|
||||||
if (supertypeConstructor == to) {
|
if (supertypeConstructor == to) {
|
||||||
return true;
|
return true;
|
||||||
@@ -566,6 +564,24 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Collection<JetType> getNeighbors(TypeConstructor from) {
|
||||||
|
// Supertypes + type for container
|
||||||
|
Collection<JetType> neighbours = new ArrayList<JetType>(
|
||||||
|
from instanceof LazyClassTypeConstructor
|
||||||
|
? ((LazyClassTypeConstructor) from).supertypes.invoke().getAllSupertypes()
|
||||||
|
: from.getSupertypes()
|
||||||
|
);
|
||||||
|
|
||||||
|
ClassifierDescriptor fromDescriptor = from.getDeclarationDescriptor();
|
||||||
|
if (fromDescriptor != null) {
|
||||||
|
DeclarationDescriptor container = fromDescriptor.getContainingDeclaration();
|
||||||
|
if (container instanceof ClassDescriptor) {
|
||||||
|
neighbours.add(((ClassDescriptor) container).getDefaultType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return neighbours;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFinal() {
|
public boolean isFinal() {
|
||||||
return !getModality().isOverridable();
|
return !getModality().isOverridable();
|
||||||
|
|||||||
Reference in New Issue
Block a user