Search in sources :

Example 11 with NoChangeEvent

use of org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent in project webtools.sourceediting by eclipse.

the class StructuredDocumentReParser method regionCheck.

/**
 * If only one node is involved, sees how many regions are changed. If
 * only one, then its a 'regionChanged' event ... if more than one, its a
 * 'regionsReplaced' event.
 */
protected StructuredDocumentEvent regionCheck(IStructuredDocumentRegion oldNode, IStructuredDocumentRegion newNode) {
    // 
    StructuredDocumentEvent result = null;
    ITextRegionList oldRegions = oldNode.getRegions();
    ITextRegionList newRegions = newNode.getRegions();
    ITextRegion[] oldRegionsArray = oldRegions.toArray();
    ITextRegion[] newRegionsArray = newRegions.toArray();
    // 
    // for the 'regionsReplaced' event, we don't care if
    // the regions changed due to type, or text,
    // we'll just collect all those that are not equal
    // into the old and new region lists.
    // Note: we, of course, assume that old and new regions
    // are basically contiguous -- and we force it to be so,
    // even if not literally so, by starting at beginning to
    // find first difference, and then starting at end to find
    // last difference. Everything in between we assume is different.
    // 
    // going up is easy, we start at zero in each, and continue
    // till regions are not the same.
    int startOfDifferences = _computeStartOfDifferences(oldNode, oldRegions, newNode, newRegions);
    int endOfDifferencesOld = -1;
    int endOfDifferencesNew = -1;
    // then some portion of the lists are identical
    if ((startOfDifferences >= oldRegions.size()) || (startOfDifferences >= newRegions.size())) {
        if (oldRegions.size() < newRegions.size()) {
            // INSERT CASE
            // then there are new regions to add
            // these lengths will cause the vector of old ones to not
            // have any elements, and the vector of new regions to have
            // just the new ones.
            startOfDifferences = oldRegionsArray.length;
            endOfDifferencesOld = oldRegionsArray.length - 1;
            endOfDifferencesNew = newRegionsArray.length - 1;
        } else {
            if (oldRegions.size() > newRegions.size()) {
                // DELETE CASE
                // then there are old regions to delete
                // these lengths will cause the vector of old regions to
                // contain the ones to delete, and the vector of new
                // regions
                // not have any elements
                startOfDifferences = newRegionsArray.length;
                endOfDifferencesOld = oldRegionsArray.length - 1;
                endOfDifferencesNew = newRegionsArray.length - 1;
            } else {
                // else the lists are identical!
                // unlikely event, probably error in current design, since
                // we check for identity at the very beginning of
                // reparsing.
                result = new NoChangeEvent(fStructuredDocument, fRequester, fChanges, fStart, fLengthToReplace);
            }
        }
    } else {
        if ((startOfDifferences > -1) && (endOfDifferencesOld < 0) && (endOfDifferencesNew < 0)) {
            // We found a normal startOfDiffernces, but have not yet found
            // the ends.
            // We'll look for the end of differences by going backwards
            // down the two lists.
            // Here we need a seperate index for each array, since they
            // may
            // be (and
            // probably are) of different lengths.
            int indexOld = oldRegionsArray.length - 1;
            int indexNew = newRegionsArray.length - 1;
            while ((indexOld >= startOfDifferences) && (_greaterThanEffectedRegion(oldNode, oldRegionsArray[indexOld]))) {
                if ((!(oldNode.sameAs(oldRegionsArray[indexOld], newNode, newRegionsArray[indexNew], fLengthDifference)))) {
                    // endOfDifferencesNew = indexTwo;
                    break;
                }
                indexOld--;
                indexNew--;
            }
            endOfDifferencesOld = indexOld;
            endOfDifferencesNew = indexNew;
        }
    }
    // result != null means the impossible case above occurred
    if (result == null) {
        // Now form the two vectors of different regions
        ITextRegionList holdOldRegions = new TextRegionListImpl();
        ITextRegionList holdNewRegions = new TextRegionListImpl();
        if (startOfDifferences > -1 && endOfDifferencesOld > -1) {
            for (int i = startOfDifferences; i <= endOfDifferencesOld; i++) {
                holdOldRegions.add(oldRegionsArray[i]);
            }
        }
        if (startOfDifferences > -1 && endOfDifferencesNew > -1) {
            for (int i = startOfDifferences; i <= endOfDifferencesNew; i++) {
                holdNewRegions.add(newRegionsArray[i]);
            }
        }
        if (holdOldRegions.size() == 0 && holdNewRegions.size() == 0) {
            // then this means the regions were identical, which means
            // someone
            // pasted exactly the same thing they had selected, or !!!
            // someone deleted the end bracket of the tag. !!!?
            result = new NoChangeEvent(fStructuredDocument, fRequester, fChanges, fStart, fLengthToReplace);
        } else {
            // old instance of old node
            if ((holdOldRegions.size() == 1) && (holdNewRegions.size() == 1) && _regionsSameKind((holdNewRegions.get(0)), (holdOldRegions.get(0)))) {
                ITextRegion newOldRegion = swapNewForOldRegion(oldNode, holdOldRegions.get(0), newNode, holdNewRegions.get(0));
                // -- need to update any down stream regions, within this
                // 'oldNode'
                updateDownStreamRegions(oldNode, newOldRegion);
                result = new RegionChangedEvent(fStructuredDocument, fRequester, oldNode, newOldRegion, fChanges, fStart, fLengthToReplace);
            } else {
                replaceRegions(oldNode, holdOldRegions, newNode, holdNewRegions);
                // -- need to update any down stream regions, within this
                // 'oldNode'
                // don't need with the way replaceRegions is implemented.
                // It handles.
                // if(holdNewRegions.size() > 0)
                // updateDownStreamRegions(oldNode, (ITextRegion)
                // holdNewRegions.lastElement());
                result = new RegionsReplacedEvent(fStructuredDocument, fRequester, oldNode, holdOldRegions, holdNewRegions, fChanges, fStart, fLengthToReplace);
            }
        }
    }
    return result;
}
Also used : StructuredDocumentEvent(org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentEvent) ITextRegionList(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList) RegionChangedEvent(org.eclipse.wst.sse.core.internal.provisional.events.RegionChangedEvent) ITextRegion(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion) RegionsReplacedEvent(org.eclipse.wst.sse.core.internal.provisional.events.RegionsReplacedEvent) StructuredDocumentRegionsReplacedEvent(org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentRegionsReplacedEvent) NoChangeEvent(org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent)

Example 12 with NoChangeEvent

use of org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent in project webtools.sourceediting by eclipse.

the class StructuredDocumentReParser method minimumEvent.

/**
 * The minimization algorithm simply checks the old nodes to see if any of
 * them "survived" the rescan and are unchanged. If so, the instance of
 * the old node is used instead of the new node. Before the requested
 * change, need to check type, offsets, and text to determine if the same.
 * After the requested change, need to check type and text, but adjust the
 * offsets to what ever the change was.
 */
protected StructuredDocumentEvent minimumEvent(CoreNodeList oldNodes, CoreNodeList newNodes) {
    StructuredDocumentEvent event = null;
    CoreNodeList minimalOldNodes = null;
    CoreNodeList minimalNewNodes = null;
    // To minimize nodes, we'll collect all those
    // that are not equal into old and new lists
    // Note: we assume that old and new nodes
    // are basically contiguous -- and we force it to be so,
    // by starting at the beginning to
    // find first difference, and then starting at the end to find
    // last difference. Everything in between we assume is different.
    // 
    // 
    // 
    // startOfDifferences is the index into the core node list where the
    // first difference
    // occurs. But it may point into the old or the new list.
    int startOfDifferences = _computeStartOfDifferences(oldNodes, newNodes);
    int endOfDifferencesOld = -1;
    int endOfDifferencesNew = -1;
    // then some portion of the lists are identical
    if ((startOfDifferences >= oldNodes.getLength()) || (startOfDifferences >= newNodes.getLength())) {
        if (oldNodes.getLength() < newNodes.getLength()) {
            // Then there are new regions to add
            // these lengths will cause the vector of old ones to not
            // have any elements, and the vector of new regions to have
            // just the new ones not in common with the old ones
            // startOfDifferences should equal oldNodes.getLength(),
            // calculated above on _computeStartOfDifferences
            minimalOldNodes = EMPTY_LIST;
            endOfDifferencesNew = newNodes.getLength() - 1;
            minimalNewNodes = _formMinimumList(newNodes, startOfDifferences, endOfDifferencesNew);
        } else {
            if (oldNodes.getLength() > newNodes.getLength()) {
                // delete old
                // then there are old regions to delete
                // these lengths will cause the vector of old regions to
                // contain the ones to delete, and the vector of new
                // regions
                // not have any elements
                // startOfDifferences should equal newNodes.getLength(),
                // calculated above on _computeStartOfDifferences
                endOfDifferencesOld = oldNodes.getLength() - 1;
                minimalOldNodes = _formMinimumList(oldNodes, startOfDifferences, endOfDifferencesOld);
                minimalNewNodes = EMPTY_LIST;
            } else
                // unlikely event
                event = new NoChangeEvent(fStructuredDocument, fRequester, fChanges, fStart, fLengthToReplace);
        }
    } else {
        // We found a normal startOfDiffernces, but have not yet found the
        // ends.
        // We'll look for the end of differences by going backwards down
        // the two lists.
        // Here we need a seperate index for each array, since they may be
        // (and
        // probably are) of different lengths.
        int indexOld = oldNodes.getLength() - 1;
        int indexNew = newNodes.getLength() - 1;
        // so that the subsequent oldNodes.item(indexOld) is always valid.
        while ((indexOld >= startOfDifferences) && (_greaterThanEffectedRegion(oldNodes.item(indexOld)))) {
            if (!(oldNodes.item(indexOld).sameAs(newNodes.item(indexNew), fLengthDifference))) {
                break;
            } else {
                // if they are equal, then we will be keeping the old one,
                // so
                // we need to be sure its parentDocument is set back to
                // the
                // right instance
                oldNodes.item(indexOld).setParentDocument(fStructuredDocument);
            }
            indexOld--;
            indexNew--;
        }
        endOfDifferencesOld = indexOld;
        endOfDifferencesNew = indexNew;
        minimalOldNodes = _formMinimumList(oldNodes, startOfDifferences, endOfDifferencesOld);
        minimalNewNodes = _formMinimumList(newNodes, startOfDifferences, endOfDifferencesNew);
    }
    // ///////////////////////////////////////
    // 
    IStructuredDocumentRegion firstDownStreamNode = null;
    event = regionCheck(minimalOldNodes, minimalNewNodes);
    if (event != null) {
        firstDownStreamNode = minimalOldNodes.item(0).getNext();
        if (firstDownStreamNode != null && fLengthDifference != 0) {
            // if
            // firstDownStream
            // is
            // null,
            // then
            // we're
            // at
            // the
            // end
            // of
            // the
            // document
            StructuredDocumentRegionIterator.adjustStart(firstDownStreamNode, fLengthDifference);
        }
    // 
    } else {
        event = nodesReplacedCheck(minimalOldNodes, minimalNewNodes);
        // remembered as a tiny optimization.
        if (minimalOldNodes.getLength() == 0 && minimalNewNodes.getLength() > 0) {
            // if no old nodes are being deleted, then use the
            // the newNodes offset (minus one) to find the point to
            // update downstream nodes, and after updating downstream
            // nodes postions, insert the new ones.
            int insertOffset = minimalNewNodes.item(0).getStartOffset();
            IStructuredDocumentRegion lastOldUnchangedNode = null;
            if (insertOffset > 0) {
                lastOldUnchangedNode = fStructuredDocument.getRegionAtCharacterOffset(insertOffset - 1);
                firstDownStreamNode = lastOldUnchangedNode.getNext();
            } else {
                // we're inserting at very beginning
                firstDownStreamNode = fStructuredDocument.getFirstStructuredDocumentRegion();
                // SIDE EFFECT: change the firstNode pointer if we're
                // inserting at beginning
                fStructuredDocument.setFirstDocumentRegion(minimalNewNodes.item(0));
            }
            StructuredDocumentRegionIterator.adjustStart(firstDownStreamNode, fLengthDifference);
            insertNodes(lastOldUnchangedNode, firstDownStreamNode, minimalNewNodes);
            // this (nodes replaced) is the only case where we need to
            // update the cached Node
            reSetCachedNode(minimalOldNodes, minimalNewNodes);
        } else {
            firstDownStreamNode = switchNodeLists(minimalOldNodes, minimalNewNodes);
            // --- adjustment moved to calling method.
            if (firstDownStreamNode != null) {
                // && event != null
                StructuredDocumentRegionIterator.adjustStart(firstDownStreamNode, fLengthDifference);
            }
            // 
            // this (nodes replaced) is the only case where we need to
            // update the cached Node
            reSetCachedNode(minimalOldNodes, minimalNewNodes);
        }
    }
    return event;
}
Also used : StructuredDocumentEvent(org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentEvent) IStructuredDocumentRegion(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion) NoChangeEvent(org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent)

Aggregations

NoChangeEvent (org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent)12 StructuredDocumentEvent (org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentEvent)6 RegionChangedEvent (org.eclipse.wst.sse.core.internal.provisional.events.RegionChangedEvent)3 RegionsReplacedEvent (org.eclipse.wst.sse.core.internal.provisional.events.RegionsReplacedEvent)3 StructuredDocumentRegionsReplacedEvent (org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentRegionsReplacedEvent)3 BadPositionCategoryException (org.eclipse.jface.text.BadPositionCategoryException)2 Position (org.eclipse.jface.text.Position)2 IExecutionDelegate (org.eclipse.wst.sse.core.internal.IExecutionDelegate)2 IStructuredDocumentRegion (org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion)2 ITextRegion (org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion)2 Iterator (java.util.Iterator)1 BadLocationException (org.eclipse.jface.text.BadLocationException)1 DocumentEvent (org.eclipse.jface.text.DocumentEvent)1 NewDocumentEvent (org.eclipse.wst.sse.core.internal.provisional.events.NewDocumentEvent)1 IStructuredDocument (org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument)1 IStructuredDocumentRegionList (org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegionList)1 ITextRegionList (org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList)1