public LeafIterator(AbstractTraceRegion root) { current = root; expectedOffset = root.getMyOffset(); expectedLine = root.getMyLineNumber(); }
@Override public String toString() { List<AbstractTraceRegion> nested = getNestedRegions(); String nestedText; if (nested.isEmpty()) nestedText = ""; else nestedText = " nestedRegions={\n " + Joiner.on("\n").join(nested).replace("\n", "\n ") + "\n}"; List<ILocationData> associated = getAssociatedLocations(); String associatedText; if (associated.isEmpty()) associatedText = ""; else associatedText = " associations={\n " + Joiner.on("\n").join(associated).replace("\n", "\n ") + "\n}"; return getClass().getSimpleName() + " [myOffset=" + getMyOffset() + ", myLength=" + getMyLength() + "]" + associatedText + nestedText; }
protected AbstractTraceRegion firstLeafOfCurrent() { while(!current.getNestedRegions().isEmpty()) { AbstractTraceRegion next = current.getNestedRegions().get(0); if (next.getMyOffset() != current.getMyOffset()) { AbstractTraceRegion result = new TemporaryTraceRegion( current.getMyOffset(), next.getMyOffset() - current.getMyOffset(), current.getMyLineNumber(), next.getMyLineNumber(), current.getAssociatedLocations(), current); traversalIndizes.add(-1); expectedOffset = next.getMyOffset(); expectedLine = next.getMyLineNumber(); return result; } traversalIndizes.add(0); current = next; } expectedOffset = current.getMyOffset() + current.getMyLength(); expectedLine = current.getMyEndLineNumber(); return current; } }
private int doAnnotateTrace(String input, StringBuilder result, int nextOffset) { if (nextOffset < getMyOffset()) { result.append(input.substring(nextOffset, getMyOffset())); nextOffset = getMyOffset(); } result.append('<'); List<ILocationData> associatedLocations = getAssociatedLocations(); for(int i = 0; i < associatedLocations.size(); i++) { if (i != 0) result.append("/"); ILocationData associatedLocation = associatedLocations.get(i); result.append(associatedLocation.getOffset()).append(':').append(associatedLocation.getLength()); } result.append("["); for(AbstractTraceRegion nested: getNestedRegions()) { nextOffset = nested.doAnnotateTrace(input, result, nextOffset); } if (nextOffset < getMyOffset() + getMyLength()) { result.append(input.substring(nextOffset, getMyOffset() + getMyLength())); nextOffset = getMyOffset() + getMyLength(); } result.append(']'); return nextOffset; }
/** * Calculate whether the given {@code region} encloses the offset. * @param region the region to be checked. May not be <code>null</code>. * @param offset the offset that should be enclosed by the region. * @param includeRegionEnd whether a region is enclosing the offset if it ends at that location. * @return <code>true</true> if the given region encloses the offset. */ public boolean encloses(AbstractTraceRegion region, int offset, boolean includeRegionEnd) { return encloses(region.getMyOffset(), region.getMyLength(), offset, includeRegionEnd); }
protected boolean isConsistentWithParent() { AbstractTraceRegion parent = getParent(); if (parent == null) return true; if (parent.getMyOffset() > getMyOffset()) return false; if (parent.getMyOffset() + parent.getMyLength() < getMyOffset() + getMyLength()) return false; if (parent.getMyLineNumber() > getMyLineNumber()) return false; if (parent.getMyEndLineNumber() < getMyEndLineNumber()) return false; List<AbstractTraceRegion> siblings = parent.getNestedRegions(); if (siblings.size() >= 2 && siblings.get(siblings.size() - 1) == this) { AbstractTraceRegion prev = siblings.get(siblings.size() - 2); if (prev.getMyEndLineNumber() > getMyLineNumber()) { return false; } } return true; }
@Nullable protected AbstractTraceRegion findTraceRegionAt(int offset, boolean includeRegionEnd) { AbstractTraceRegion candidate = getRootTraceRegion(); if (candidate == null || !encloses(candidate, offset, includeRegionEnd)) { // we have an inconsistent state - no candidate matches return null; } outer: while(candidate != null) { List<? extends AbstractTraceRegion> children = candidate.getNestedRegions(); if (children.isEmpty()) { return candidate; } for(AbstractTraceRegion child: children) { if (encloses(child, offset, includeRegionEnd)) { candidate = child; continue outer; } else { if (child.getMyOffset() > offset) { return candidate; } } } return candidate; } return null; }
public ITextRegionWithLineInformation getMyRegion() { return new TextRegionWithLineInformation(getMyOffset(), getMyLength(), getMyLineNumber(), getMyEndLineNumber()); }
@Override protected AbstractTraceRegion computeNext() { if (current.getMyOffset() == expectedOffset) { return firstLeafOfCurrent(); } else { int idx = traversalIndizes.removeLast(); while(idx == current.getNestedRegions().size() - 1) { if (expectedOffset != current.getMyOffset() + current.getMyLength()) { traversalIndizes.add(idx); AbstractTraceRegion result = new TemporaryTraceRegion( expectedOffset, current.getMyOffset() + current.getMyLength() - expectedOffset, expectedLine, current.getMyEndLineNumber(), current.getAssociatedLocations(), current); expectedOffset = current.getMyOffset() + current.getMyLength(); expectedLine = current.getMyEndLineNumber(); return result; if (next.getMyOffset() < expectedOffset) { return endOfData(); } else if (next.getMyOffset() == expectedOffset) { current = next; traversalIndizes.add(idx + 1); final AbstractTraceRegion parent = current; AbstractTraceRegion result = new TemporaryTraceRegion( expectedOffset, next.getMyOffset() - expectedOffset, expectedLine, next.getMyLineNumber(), current.getAssociatedLocations(), parent); traversalIndizes.add(idx);
public LocationData createLocationData(AbstractTraceRegion region, URI myPath) { return new LocationData(region.getMyOffset(), region.getMyLength(), region.getMyLineNumber(), region.getMyEndLineNumber(), myPath); }
/** * Returns the hash code value for this region. The hash code * of a trace region <code>r</code> is defined to be: <pre> * r.getMyOffset() * ^ r.getMyLength() * ^ r.getAssociatedOffset() * ^ r.getAssociatedLength() * ^ (r.getParent() == null ? 0 : r.getParent().hashCode()) * </pre> * This ensures that <tt>r1.equals(r2)</tt> implies that * <tt>r1.hashCode()==r2.hashCode()</tt> for any two {@link AbstractTraceRegion} * <tt>r1</tt> and <tt>r2</tt>, as required by the general * contract of <tt>Object.hashCode</tt>. * * @return the hash code value for this trace region * @see Object#hashCode() * @see Object#equals(Object) * @see #equals(Object) */ @Override public int hashCode() { AbstractTraceRegion parent = getParent(); return getMyOffset() ^ getMyLength() ^ getAssociatedLocations().hashCode() ^ (parent == null ? 0 : parent.hashCode()); }
if (getMyLength() != other.getMyLength()) return false; if (getMyOffset() != other.getMyOffset()) return false; if (!getAssociatedLocations().equals(other.getAssociatedLocations()))
ITextRegionWithLineInformation associated = ITextRegionWithLineInformation.EMPTY_REGION; for(AbstractTraceRegion child: result) { rootLocation = rootLocation.merge(new TextRegionWithLineInformation(child.getMyOffset(), child.getMyLength(), child.getMyLineNumber(), child.getMyEndLineNumber())); ILocationData childAssociation = child.getMergedAssociatedLocation(); if (childAssociation != null)
public void writeRegion(AbstractTraceRegion region, Callback<AbstractTraceRegion, ILocationData> callback) throws IOException { callback.doWriteRegion(region.getMyOffset(), region.getMyLength(), region.getMyLineNumber(), region.getMyEndLineNumber(), region.getAssociatedLocations(), region.getNestedRegions()); }
@Nullable public ILocationInResource getBestAssociatedLocation(ITextRegion region) { AbstractTraceRegion right = findTraceRegionAtRightOffset(region.getOffset() + region.getLength()); if (right != null && encloses(right, region.getOffset(), true)) { if (right.getMyOffset() + right.getMyLength() == region.getOffset() + region.getLength()) return getMergedLocationInResource(right); } AbstractTraceRegion left = findTraceRegionAtLeftOffset(region.getOffset()); return mergeRegions(left, right); }