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; }
/* 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); }
/* * 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); }
private void processChildrenDelta(IRubyElementDelta delta, ArrayList changedTypes) { IRubyElementDelta[] children = delta.getAffectedChildren(); for (int i = 0; i < children.length; i++) { processDelta(children[i], changedTypes); // recursive } }