From b2ea2e1a15c3db5eedf7be409d4a63e46e0d0bb8 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 14 Apr 2014 19:52:14 +0400 Subject: [PATCH] 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 --- .../lazy/descriptors/LazyClassDescriptor.java | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java index 709c8b3aa4b..df5bfbb573c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -327,7 +327,8 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes public Boolean invoke(JetClassObject classObject) { return classObject != declarationProvider.getOwnerInfo().getClassObject(); } - }), + } + ), new Function1() { @Override public ClassDescriptor invoke(JetClassObject classObject) { @@ -551,10 +552,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes private boolean isReachable(TypeConstructor from, TypeConstructor to, Set visited) { if (!visited.add(from)) return false; - Collection supertypes = from instanceof LazyClassTypeConstructor - ? ((LazyClassTypeConstructor) from).supertypes.invoke().getAllSupertypes() - : from.getSupertypes(); - for (JetType supertype : supertypes) { + for (JetType supertype : getNeighbors(from)) { TypeConstructor supertypeConstructor = supertype.getConstructor(); if (supertypeConstructor == to) { return true; @@ -566,6 +564,24 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes return false; } + private Collection getNeighbors(TypeConstructor from) { + // Supertypes + type for container + Collection neighbours = new ArrayList( + 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 public boolean isFinal() { return !getModality().isOverridable();