Пример #1
0
  private void detectAndDisconnectLoops(@NotNull TopDownAnalysisContext c) {
    // Loop detection and disconnection
    List<Runnable> tasks = new ArrayList<Runnable>();
    for (final MutableClassDescriptorLite klass : c.getClassesTopologicalOrder()) {
      for (final JetType supertype : klass.getSupertypes()) {
        ClassifierDescriptor supertypeDescriptor =
            supertype.getConstructor().getDeclarationDescriptor();
        if (supertypeDescriptor instanceof MutableClassDescriptorLite) {
          MutableClassDescriptorLite superclass = (MutableClassDescriptorLite) supertypeDescriptor;
          if (isReachable(superclass, klass, new HashSet<ClassDescriptor>())) {
            tasks.add(
                new Runnable() {
                  @Override
                  public void run() {
                    klass.getSupertypes().remove(supertype);
                  }
                });
            reportCyclicInheritanceHierarchyError(trace, klass, superclass);
          }
        }
      }
    }

    for (Runnable task : tasks) {
      task.run();
    }
  }
Пример #2
0
 // Temporary. Duplicates logic from LazyClassTypeConstructor.isReachable
 private static boolean isReachable(
     MutableClassDescriptorLite from,
     MutableClassDescriptorLite to,
     Set<ClassDescriptor> visited) {
   if (!visited.add(from)) return false;
   for (JetType supertype : from.getSupertypes()) {
     TypeConstructor supertypeConstructor = supertype.getConstructor();
     if (supertypeConstructor.getDeclarationDescriptor() == to) {
       return true;
     }
     ClassifierDescriptor superclass = supertypeConstructor.getDeclarationDescriptor();
     if (superclass instanceof MutableClassDescriptorLite
         && isReachable((MutableClassDescriptorLite) superclass, to, visited)) {
       return true;
     }
   }
   return false;
 }