LR: Detecting and disconnecting loops in type hierarchy
This commit is contained in:
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.lazy;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
@@ -39,10 +40,7 @@ import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeConstructor;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -326,13 +324,38 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
.resolveSupertypes(getScopeForClassHeaderResolution(),
|
||||
classOrObject,
|
||||
resolveSession.getTrace());
|
||||
this.supertypes = Collections2.filter(allSupertypes, VALID_SUPERTYPE);
|
||||
List<JetType> validSupertypes = Lists.newArrayList(Collections2.filter(allSupertypes, VALID_SUPERTYPE));
|
||||
this.supertypes = validSupertypes;
|
||||
findAndDisconnectLoopsInTypeHierarchy(validSupertypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
return supertypes;
|
||||
}
|
||||
|
||||
private void findAndDisconnectLoopsInTypeHierarchy(List<JetType> supertypes) {
|
||||
for (Iterator<JetType> iterator = supertypes.iterator(); iterator.hasNext(); ) {
|
||||
JetType supertype = iterator.next();
|
||||
if (isReachable(supertype.getConstructor(), this, new HashSet<TypeConstructor>())) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isReachable(TypeConstructor from, TypeConstructor to, Set<TypeConstructor> visited) {
|
||||
if (!visited.add(from)) return false;
|
||||
for (JetType supertype : from.getSupertypes()) {
|
||||
TypeConstructor supertypeConstructor = supertype.getConstructor();
|
||||
if (supertypeConstructor == to) {
|
||||
return true;
|
||||
}
|
||||
if (isReachable(supertypeConstructor, to, visited)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSealed() {
|
||||
return !getModality().isOverridable();
|
||||
|
||||
Reference in New Issue
Block a user