/** * Finds the differences among three <code>IRangeComparator</code>s. In contrast to <code> * findDifferences</code>, the result contains <code>RangeDifference</code> elements for * non-differing ranges too. If the ancestor range comparator is <code>null</code>, a two-way * comparison is performed. * * @param pm if not <code>null</code> used to report progress * @param ancestor the ancestor range comparator or <code>null</code> * @param left the left range comparator * @param right the right range comparator * @return an array of range differences * @since 2.0 */ public static RangeDifference[] findRanges( IProgressMonitor pm, LCSSettings settings, IRangeComparator ancestor, IRangeComparator left, IRangeComparator right) { if (ancestor == null) return findRanges(pm, settings, left, right); RangeDifference[] in = findDifferences(pm, settings, ancestor, left, right); List out = new ArrayList(); RangeDifference rd; int mstart = 0; int ystart = 0; int astart = 0; for (int i = 0; i < in.length; i++) { RangeDifference es = in[i]; rd = new RangeDifference( RangeDifference.NOCHANGE, mstart, es.rightStart() - mstart, ystart, es.leftStart() - ystart, astart, es.ancestorStart() - astart); if (rd.maxLength() > 0) out.add(rd); out.add(es); mstart = es.rightEnd(); ystart = es.leftEnd(); astart = es.ancestorEnd(); } rd = new RangeDifference( RangeDifference.NOCHANGE, mstart, right.getRangeCount() - mstart, ystart, left.getRangeCount() - ystart, astart, ancestor.getRangeCount() - astart); if (rd.maxLength() > 0) out.add(rd); return (RangeDifference[]) out.toArray(EMPTY_RESULT); }
/* * Creates a <code>RangeDifference3</code> given the state of two * DifferenceIterators. */ private static RangeDifference createRangeDifference3( DifferencesIterator myIter, DifferencesIterator yourIter, List diff3, IRangeComparator right, IRangeComparator left, int changeRangeStart, int changeRangeEnd) { int rightStart, rightEnd; int leftStart, leftEnd; int kind = RangeDifference.ERROR; RangeDifference last = (RangeDifference) diff3.get(diff3.size() - 1); Assert.isTrue((myIter.getCount() != 0 || yourIter.getCount() != 0)); // At // least // one // range // array // must // be // non-empty // // find corresponding lines to fChangeRangeStart/End in right and left // if (myIter.getCount() == 0) { // only left changed rightStart = changeRangeStart - last.ancestorEnd() + last.rightEnd(); rightEnd = changeRangeEnd - last.ancestorEnd() + last.rightEnd(); kind = RangeDifference.LEFT; } else { RangeDifference f = (RangeDifference) myIter.fRange.get(0); RangeDifference l = (RangeDifference) myIter.fRange.get(myIter.fRange.size() - 1); rightStart = changeRangeStart - f.fLeftStart + f.fRightStart; rightEnd = changeRangeEnd - l.leftEnd() + l.rightEnd(); } if (yourIter.getCount() == 0) { // only right changed leftStart = changeRangeStart - last.ancestorEnd() + last.leftEnd(); leftEnd = changeRangeEnd - last.ancestorEnd() + last.leftEnd(); kind = RangeDifference.RIGHT; } else { RangeDifference f = (RangeDifference) yourIter.fRange.get(0); RangeDifference l = (RangeDifference) yourIter.fRange.get(yourIter.fRange.size() - 1); leftStart = changeRangeStart - f.fLeftStart + f.fRightStart; leftEnd = changeRangeEnd - l.leftEnd() + l.rightEnd(); } if (kind == RangeDifference.ERROR) { // overlapping change (conflict) // -> compare the changed ranges if (rangeSpansEqual( right, rightStart, rightEnd - rightStart, left, leftStart, leftEnd - leftStart)) kind = RangeDifference.ANCESTOR; else kind = RangeDifference.CONFLICT; } return new RangeDifference( kind, rightStart, rightEnd - rightStart, leftStart, leftEnd - leftStart, changeRangeStart, changeRangeEnd - changeRangeStart); }