private Object[] rootsAndContainers(IRubyProject project, Object[] roots)
      throws RubyModelException {
    List result = new ArrayList(roots.length);
    Set containers = new HashSet(roots.length);
    Set containedRoots = new HashSet(roots.length);

    ILoadpathEntry[] entries = project.getRawLoadpath();
    for (int i = 0; i < entries.length; i++) {
      ILoadpathEntry entry = entries[i];
      if (entry != null && entry.getEntryKind() == ILoadpathEntry.CPE_CONTAINER) {
        ISourceFolderRoot[] roots1 = project.findSourceFolderRoots(entry);
        containedRoots.addAll(Arrays.asList(roots1));
        containers.add(entry);
      }
    }
    for (int i = 0; i < roots.length; i++) {
      if (roots[i] instanceof ISourceFolderRoot) {
        if (!containedRoots.contains(roots[i])) {
          result.add(roots[i]);
        }
      } else {
        result.add(roots[i]);
      }
    }
    for (Iterator each = containers.iterator(); each.hasNext(); ) {
      ILoadpathEntry element = (ILoadpathEntry) each.next();
      result.add(new LoadPathContainer(project, element));
    }
    return result.toArray();
  }
 protected Object internalGetParent(Object element) {
   // since we insert logical package containers we have to fix
   // up the parent for package fragment roots so that they refer
   // to the container and containers refere to the project
   //
   if (element instanceof ISourceFolderRoot) {
     ISourceFolderRoot root = (ISourceFolderRoot) element;
     IRubyProject project = root.getRubyProject();
     try {
       ILoadpathEntry[] entries = project.getRawLoadpath();
       for (int i = 0; i < entries.length; i++) {
         ILoadpathEntry entry = entries[i];
         if (entry.getEntryKind() == ILoadpathEntry.CPE_CONTAINER) {
           if (LoadPathContainer.contains(project, entry, root))
             return new LoadPathContainer(project, entry);
         }
       }
     } catch (RubyModelException e) {
       // fall through
     }
   }
   if (element instanceof LoadPathContainer) {
     return ((LoadPathContainer) element).getRubyProject();
   }
   return super.internalGetParent(element);
 }
예제 #3
0
 private ITypeHierarchy createTypeHierarchy(IRubyElement element, IProgressMonitor pm)
     throws RubyModelException {
   if (element.getElementType() == IRubyElement.TYPE) {
     IType type = (IType) element;
     type = getLogicalType(type, type.getFullyQualifiedName());
     if (fIsSuperTypesOnly) {
       return type.newSupertypeHierarchy(pm);
     } else {
       return type.newTypeHierarchy(pm);
     }
   } else {
     IRegion region = RubyCore.newRegion();
     if (element.getElementType() == IRubyElement.RUBY_PROJECT) {
       // for projects only add the contained source folders
       ISourceFolderRoot[] roots = ((IRubyProject) element).getSourceFolderRoots();
       for (int i = 0; i < roots.length; i++) {
         if (!roots[i].isExternal()) {
           region.add(roots[i]);
         }
       }
     } else if (element.getElementType() == IRubyElement.SOURCE_FOLDER) {
       ISourceFolderRoot[] roots = element.getRubyProject().getSourceFolderRoots();
       String name = element.getElementName();
       for (int i = 0; i < roots.length; i++) {
         ISourceFolder pack = roots[i].getSourceFolder(name);
         if (pack.exists()) {
           region.add(pack);
         }
       }
     } else {
       region.add(element);
     }
     IRubyProject jproject = element.getRubyProject();
     return jproject.newTypeHierarchy(region, pm);
   }
 }
 private boolean isOnClassPath(IRubyScript element) {
   IRubyProject project = element.getRubyProject();
   if (project == null || !project.exists()) return false;
   return project.isOnLoadpath(element);
 }
  /**
   * Processes a delta recursively. When more than two children are affected the tree is fully
   * refreshed starting at this node. The delta is processed in the current thread but the viewer
   * updates are posted to the UI thread.
   */
  private void processDelta(IRubyElementDelta delta) throws RubyModelException {

    int kind = delta.getKind();
    int flags = delta.getFlags();
    IRubyElement element = delta.getElement();
    int elementType = element.getElementType();

    if (elementType != IRubyElement.RUBY_MODEL && elementType != IRubyElement.RUBY_PROJECT) {
      IRubyProject proj = element.getRubyProject();
      if (proj == null
          || !proj.getProject()
              .isOpen()) // TODO: Not needed if parent already did the 'open' check!
      return;
    }

    if (!fIsFlatLayout && elementType == IRubyElement.SOURCE_FOLDER) {
      fSourceFolderProvider.processDelta(delta);
      if (processResourceDeltas(delta.getResourceDeltas(), element)) return;
      handleAffectedChildren(delta, element);
      return;
    }

    if (elementType == IRubyElement.SCRIPT) {
      IRubyScript cu = (IRubyScript) element;
      if (!RubyModelUtil.isPrimary(cu)) {
        return;
      }

      if (!getProvideMembers() && cu.isWorkingCopy() && kind == IRubyElementDelta.CHANGED) {
        return;
      }

      if ((kind == IRubyElementDelta.CHANGED) && !isStructuralCUChange(flags)) {
        return; // test moved ahead
      }

      if (!isOnClassPath(
          cu)) { // TODO: isOnClassPath expensive! Should be put after all cheap tests
        return;
      }
    }

    if (elementType == IRubyElement.RUBY_PROJECT) {
      // handle open and closing of a project
      if ((flags & (IRubyElementDelta.F_CLOSED | IRubyElementDelta.F_OPENED)) != 0) {
        postRefresh(element, ORIGINAL, element);
        return;
      }
      // if the raw class path has changed we refresh the entire project
      if ((flags & IRubyElementDelta.F_CLASSPATH_CHANGED) != 0) {
        postRefresh(element, ORIGINAL, element);
        return;
      }
    }

    if (kind == IRubyElementDelta.REMOVED) {
      Object parent = internalGetParent(element);
      if (element instanceof ISourceFolder) {
        // refresh package fragment root to allow filtering empty (parent) packages: bug 72923
        if (fViewer.testFindItem(parent) != null) postRefresh(parent, PARENT, element);
        return;
      }

      postRemove(element);
      if (parent instanceof ISourceFolder) postUpdateIcon((ISourceFolder) parent);
      // we are filtering out empty subpackages, so we
      // a package becomes empty we remove it from the viewer.
      if (isSourceFolderEmpty(element.getParent())) {
        if (fViewer.testFindItem(parent) != null)
          postRefresh(internalGetParent(parent), GRANT_PARENT, element);
      }
      return;
    }

    if (kind == IRubyElementDelta.ADDED) {
      Object parent = internalGetParent(element);
      // we are filtering out empty subpackages, so we
      // have to handle additions to them specially.
      if (parent instanceof ISourceFolder) {
        Object grandparent = internalGetParent(parent);
        if (((ISourceFolder) parent).isDefaultPackage()) {
          parent = grandparent;
          grandparent = internalGetParent(parent);
        }
        // 1GE8SI6: ITPJUI:WIN98 - Rename is not shown in Packages View
        // avoid posting a refresh to an unvisible parent
        if (parent.equals(fInput)) {
          postRefresh(parent, PARENT, element);
        } else {
          // refresh from grandparent if parent isn't visible yet
          if (fViewer.testFindItem(parent) == null) postRefresh(grandparent, GRANT_PARENT, element);
          else {
            postRefresh(parent, PARENT, element);
          }
        }
        return;
      } else {
        if ((flags & IRubyElementDelta.F_MOVED_FROM) != 0) {
          postRemove(delta.getMovedFromElement());
        }
        postAdd(parent, element);
      }
    }

    if (elementType == IRubyElement.SCRIPT) {
      if (kind == IRubyElementDelta.CHANGED) {
        // isStructuralCUChange already performed above
        postRefresh(element, ORIGINAL, element);
        updateSelection(delta);
      }
      return;
    }

    if (elementType == IRubyElement.SOURCE_FOLDER_ROOT) {
      // the contents of an external JAR has changed
      if ((flags & IRubyElementDelta.F_ARCHIVE_CONTENT_CHANGED) != 0) {
        postRefresh(element, ORIGINAL, element);
        return;
      }
      // the source attachment of a JAR has changed
      if ((flags & (IRubyElementDelta.F_SOURCEATTACHED | IRubyElementDelta.F_SOURCEDETACHED)) != 0)
        postUpdateIcon(element);

      if (isClassPathChange(delta)) {
        // throw the towel and do a full refresh of the affected java project.
        postRefresh(element.getRubyProject(), PROJECT, element);
        return;
      }
    }

    if (processResourceDeltas(delta.getResourceDeltas(), element)) return;

    handleAffectedChildren(delta, element);
  }