private IRubyElement findAddedElement(IRubyElementDelta delta) {
    if (delta.getKind() == IRubyElementDelta.ADDED) return delta.getElement();

    IRubyElementDelta[] affectedChildren = delta.getAffectedChildren();
    for (int i = 0; i < affectedChildren.length; i++) return findAddedElement(affectedChildren[i]);

    return null;
  }
Пример #2
0
  /*
   * Assume that the hierarchy is intact (no refresh needed)
   */
  private void processDelta(IRubyElementDelta delta, ArrayList changedTypes) {
    IRubyElement element = delta.getElement();
    switch (element.getElementType()) {
      case IRubyElement.TYPE:
        processTypeDelta((IType) element, changedTypes);
        processChildrenDelta(delta, changedTypes); // (inner types)
        break;
      case IRubyElement.RUBY_MODEL:
      case IRubyElement.RUBY_PROJECT:
      case IRubyElement.SOURCE_FOLDER_ROOT:
      case IRubyElement.SOURCE_FOLDER:
        processChildrenDelta(delta, changedTypes);
        break;
      case IRubyElement.SCRIPT:
        IRubyScript cu = (IRubyScript) element;
        if (!RubyModelUtil.isPrimary(cu)) {
          return;
        }

        if (delta.getKind() == IRubyElementDelta.CHANGED
            && isPossibleStructuralChange(delta.getFlags())) {
          try {
            if (cu.exists()) {
              IType[] types = cu.getAllTypes();
              for (int i = 0; i < types.length; i++) {
                processTypeDelta(types[i], changedTypes);
              }
            }
          } catch (RubyModelException e) {
            RubyPlugin.log(e);
          }
        } else {
          processChildrenDelta(delta, changedTypes);
        }
        break;
    }
  }
  /**
   * 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);
  }