Fixed test by topologically sorting classes in OverrideResolver.

This commit is contained in:
Evgeny Gerashchenko
2013-01-16 15:26:55 +04:00
parent 44580406ec
commit 739acbcf01
3 changed files with 27 additions and 17 deletions
@@ -86,8 +86,10 @@ public class OverrideResolver {
Set<ClassifierDescriptor> processed = new HashSet<ClassifierDescriptor>(); Set<ClassifierDescriptor> processed = new HashSet<ClassifierDescriptor>();
for (MutableClassDescriptor clazz : ourClasses) { for (MutableClassDescriptorLite klass : ContainerUtil.reverse(context.getClassesTopologicalOrder())) {
generateOverridesAndDelegationInAClass(clazz, processed, ourClasses); if (klass instanceof MutableClassDescriptor && ourClasses.contains(klass)) {
generateOverridesAndDelegationInAClass((MutableClassDescriptor) klass, processed, ourClasses);
}
} }
} }
@@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import javax.inject.Inject; import javax.inject.Inject;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map; import java.util.Map;
public class TopDownAnalysisContext implements BodiesResolveContext { public class TopDownAnalysisContext implements BodiesResolveContext {
@@ -37,6 +38,7 @@ public class TopDownAnalysisContext implements BodiesResolveContext {
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap(); private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap(); private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap();
protected final Map<JetFile, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap(); protected final Map<JetFile, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
private List<MutableClassDescriptorLite> classesTopologicalOrder = null;
private final Map<JetDeclaration, JetScope> declaringScopes = Maps.newHashMap(); private final Map<JetDeclaration, JetScope> declaringScopes = Maps.newHashMap();
private final Map<JetNamedFunction, SimpleFunctionDescriptor> functions = Maps.newLinkedHashMap(); private final Map<JetNamedFunction, SimpleFunctionDescriptor> functions = Maps.newLinkedHashMap();
@@ -165,4 +167,13 @@ public class TopDownAnalysisContext implements BodiesResolveContext {
} }
return members; return members;
} }
@NotNull
public List<MutableClassDescriptorLite> getClassesTopologicalOrder() {
return classesTopologicalOrder;
}
public void setClassesTopologicalOrder(@NotNull List<MutableClassDescriptorLite> classesTopologicalOrder) {
this.classesTopologicalOrder = classesTopologicalOrder;
}
} }
@@ -62,9 +62,6 @@ public class TypeHierarchyResolver {
@NotNull @NotNull
private BindingTrace trace; private BindingTrace trace;
// state
private List<MutableClassDescriptor> topologicalOrder;
@Inject @Inject
public void setContext(@NotNull TopDownAnalysisContext context) { public void setContext(@NotNull TopDownAnalysisContext context) {
this.context = context; this.context = context;
@@ -138,7 +135,7 @@ public class TypeHierarchyResolver {
createTypeConstructors(); // create type constructors for classes and generic parameters, supertypes are not filled in createTypeConstructors(); // create type constructors for classes and generic parameters, supertypes are not filled in
resolveTypesInClassHeaders(); // Generic bounds and types in supertype lists (no expressions or constructor resolution) resolveTypesInClassHeaders(); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
topologicalOrder = topologicallySortClassesAndObjects(); context.setClassesTopologicalOrder(topologicallySortClassesAndObjects());
// Detect and disconnect all loops in the hierarchy // Detect and disconnect all loops in the hierarchy
detectAndDisconnectLoops(); detectAndDisconnectLoops();
@@ -245,20 +242,20 @@ public class TypeHierarchyResolver {
} }
} }
private List<MutableClassDescriptor> topologicallySortClassesAndObjects() { private List<MutableClassDescriptorLite> topologicallySortClassesAndObjects() {
// A topsort is needed only for better diagnostics: // A topsort is needed only for better diagnostics:
// edges that get removed to disconnect loops are more reasonable in this case // edges that get removed to disconnect loops are more reasonable in this case
return DFS.topologicalOrder( return DFS.topologicalOrder(
ContainerUtil.<MutableClassDescriptor>concat(context.getClasses().values(), context.getObjects().values()), ContainerUtil.<MutableClassDescriptorLite>concat(context.getClasses().values(), context.getObjects().values()),
new DFS.Neighbors<MutableClassDescriptor>() { new DFS.Neighbors<MutableClassDescriptorLite>() {
@NotNull @NotNull
@Override @Override
public Iterable<MutableClassDescriptor> getNeighbors(MutableClassDescriptor current) { public Iterable<MutableClassDescriptorLite> getNeighbors(MutableClassDescriptorLite current) {
List<MutableClassDescriptor> result = Lists.newArrayList(); List<MutableClassDescriptorLite> result = Lists.newArrayList();
for (JetType supertype : current.getSupertypes()) { for (JetType supertype : current.getSupertypes()) {
DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor(); DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor();
if (declarationDescriptor instanceof MutableClassDescriptor) { if (declarationDescriptor instanceof MutableClassDescriptorLite) {
MutableClassDescriptor classDescriptor = (MutableClassDescriptor) declarationDescriptor; MutableClassDescriptorLite classDescriptor = (MutableClassDescriptorLite) declarationDescriptor;
result.add(classDescriptor); result.add(classDescriptor);
} }
} }
@@ -273,13 +270,13 @@ public class TypeHierarchyResolver {
Set<ClassDescriptor> visited = Sets.newHashSet(); Set<ClassDescriptor> visited = Sets.newHashSet();
Set<ClassDescriptor> beingProcessed = Sets.newHashSet(); Set<ClassDescriptor> beingProcessed = Sets.newHashSet();
List<ClassDescriptor> currentPath = Lists.newArrayList(); List<ClassDescriptor> currentPath = Lists.newArrayList();
for (MutableClassDescriptor mutableClassDescriptor : topologicalOrder) { for (MutableClassDescriptorLite klass : context.getClassesTopologicalOrder()) {
traverseTypeHierarchy(mutableClassDescriptor, visited, beingProcessed, currentPath); traverseTypeHierarchy(klass, visited, beingProcessed, currentPath);
} }
} }
private void traverseTypeHierarchy( private void traverseTypeHierarchy(
MutableClassDescriptor currentClass, MutableClassDescriptorLite currentClass,
Set<ClassDescriptor> visited, Set<ClassDescriptor> visited,
Set<ClassDescriptor> beingProcessed, Set<ClassDescriptor> beingProcessed,
List<ClassDescriptor> currentPath List<ClassDescriptor> currentPath
@@ -355,7 +352,7 @@ public class TypeHierarchyResolver {
} }
private void checkSupertypesForConsistency() { private void checkSupertypesForConsistency() {
for (MutableClassDescriptor mutableClassDescriptor : topologicalOrder) { for (MutableClassDescriptorLite mutableClassDescriptor : context.getClassesTopologicalOrder()) {
Multimap<TypeConstructor, TypeProjection> multimap = SubstitutionUtils Multimap<TypeConstructor, TypeProjection> multimap = SubstitutionUtils
.buildDeepSubstitutionMultimap(mutableClassDescriptor.getDefaultType()); .buildDeepSubstitutionMultimap(mutableClassDescriptor.getDefaultType());
for (Map.Entry<TypeConstructor, Collection<TypeProjection>> entry : multimap.asMap().entrySet()) { for (Map.Entry<TypeConstructor, Collection<TypeProjection>> entry : multimap.asMap().entrySet()) {