示例#1
0
  public void ensureRefreshedTypeHierarchy(final IRubyElement element, IRunnableContext context)
      throws InvocationTargetException, InterruptedException {
    if (element == null || !element.exists()) {
      freeHierarchy();
      return;
    }
    boolean hierachyCreationNeeded = (fHierarchy == null || !element.equals(fInputElement));

    if (hierachyCreationNeeded || fHierarchyRefreshNeeded) {

      IRunnableWithProgress op =
          new IRunnableWithProgress() {
            public void run(IProgressMonitor pm)
                throws InvocationTargetException, InterruptedException {
              try {
                doHierarchyRefresh(element, pm);
              } catch (RubyModelException e) {
                throw new InvocationTargetException(e);
              } catch (OperationCanceledException e) {
                throw new InterruptedException();
              }
            }
          };
      fHierarchyRefreshNeeded = true;
      context.run(true, true, op);
      fHierarchyRefreshNeeded = false;
    }
  }
 /* package */ void handleAffectedChildren(IRubyElementDelta delta, IRubyElement element)
     throws RubyModelException {
   IRubyElementDelta[] affectedChildren = delta.getAffectedChildren();
   if (affectedChildren.length > 1) {
     // a package fragment might become non empty refresh from the parent
     if (element instanceof ISourceFolder) {
       IRubyElement parent = (IRubyElement) internalGetParent(element);
       if (parent instanceof ISourceFolderRoot) {
         parent = (IRubyElement) internalGetParent(parent);
       }
       // 1GE8SI6: ITPJUI:WIN98 - Rename is not shown in Packages View
       // avoid posting a refresh to an unvisible parent
       if (element.equals(fInput)) {
         postRefresh(element, ORIGINAL, element);
       } else {
         postRefresh(parent, PARENT, element);
       }
       return;
     }
     // more than one child changed, refresh from here downwards
     if (element instanceof ISourceFolderRoot) {
       Object toRefresh = skipProjectSourceFolderRoot((ISourceFolderRoot) element);
       postRefresh(toRefresh, ORIGINAL, toRefresh);
     } else {
       postRefresh(element, ORIGINAL, element);
     }
     return;
   }
   processAffectedChildren(affectedChildren);
 }
示例#3
0
 /**
  * Returns if the text selection is a valid method or not
  *
  * @param selection the text selection
  * @param part the associated workbench part
  * @return true if the selection is a valid method, false otherwise
  */
 private boolean isMethod(ITextSelection selection, IWorkbenchPart part) {
   ITextEditor editor = getTextEditor(part);
   if (editor != null) {
     IRubyElement element = getRubyElement(editor.getEditorInput());
     if (element != null) {
       try {
         if (element instanceof IRubyScript) {
           element = ((IRubyScript) element).getElementAt(selection.getOffset());
         }
         return element != null && element.getElementType() == IRubyElement.METHOD;
       } catch (RubyModelException e) {
         return false;
       }
     }
   }
   return false;
 }
示例#4
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;
    }
  }
示例#5
0
 public synchronized void doHierarchyRefresh(IRubyElement element, IProgressMonitor pm)
     throws RubyModelException {
   boolean hierachyCreationNeeded = (fHierarchy == null || !element.equals(fInputElement));
   // to ensure the order of the two listeners always remove / add listeners on operations
   // on type hierarchies
   if (fHierarchy != null) {
     fHierarchy.removeTypeHierarchyChangedListener(this);
     RubyCore.removeElementChangedListener(this);
   }
   if (hierachyCreationNeeded) {
     fHierarchy = createTypeHierarchy(element, pm);
     if (pm != null && pm.isCanceled()) {
       throw new OperationCanceledException();
     }
     fInputElement = element;
   } else {
     fHierarchy.refresh(pm);
   }
   if (fHierarchy != null) {
     fHierarchy.addTypeHierarchyChangedListener(this);
     RubyCore.addElementChangedListener(this);
     fHierarchyRefreshNeeded = false;
   }
 }
示例#6
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);
   }
 }
  /**
   * 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);
  }