protected AbstractTokensTaskTaggerSnapshot( @NonNull AbstractTokensTaskTaggerSnapshot<TState> reference, @NonNull DocumentSnapshot snapshot) { Parameters.notNull("reference", reference); Parameters.notNull("snapshot", snapshot); if (!snapshot.getVersionedDocument().equals(reference.snapshot.getVersionedDocument())) { throw new IllegalArgumentException("The target snapshot is not from the same document."); } if (snapshot.getVersion().getVersionNumber() <= reference.snapshot.getVersion().getVersionNumber()) { throw new UnsupportedOperationException( "The target snapshot must be a future version of the reference document."); } this.snapshot = snapshot; this.lineStates.addAll(reference.lineStates); this.firstDirtyLine = reference.firstDirtyLine; this.lastDirtyLine = reference.lastDirtyLine; Integer firstChangedLine = null; Integer lastChangedLine = null; for (DocumentVersion version = reference.snapshot.getVersion(); version != null && version.getVersionNumber() < snapshot.getVersion().getVersionNumber(); version = version.getNext()) { DocumentSnapshot source = version.getSnapshot(); DocumentVersion targetVersion = version.getNext(); assert targetVersion != null; DocumentSnapshot target = targetVersion.getSnapshot(); NormalizedDocumentChangeCollection changes = version.getChanges(); assert changes != null; for (int i = changes.size() - 1; i >= 0; i--) { DocumentChange change = changes.get(i); int lineCountDelta = change.getLineCountDelta(); int oldOffset = change.getOldOffset(); int oldLength = change.getOldLength(); int newOffset = change.getNewOffset(); int newLength = change.getNewLength(); /* processChange */ int oldStartLine = source.findLineNumber(oldOffset); int oldEndLine = oldLength == 0 ? oldStartLine : source.findLineNumber(oldOffset + oldLength - 1); if (lineCountDelta < 0) { lineStates.subList(oldStartLine, oldStartLine + Math.abs(lineCountDelta)).clear(); } else if (lineCountDelta > 0) { TState endLineState = lineStates.get(oldStartLine); ArrayList<TState> insertedElements = new ArrayList<>(); for (int j = 0; j < lineCountDelta; j++) { insertedElements.add(endLineState); } lineStates.addAll(oldStartLine, insertedElements); } if (lastDirtyLine != null && lastDirtyLine > oldStartLine) { lastDirtyLine += lineCountDelta; } if (lastChangedLine != null && lastChangedLine > oldStartLine) { lastChangedLine += lineCountDelta; } for (int j = oldStartLine; j <= oldEndLine + lineCountDelta; j++) { TState state = lineStates.get(i); lineStates.set(j, state.createDirtyState()); } firstChangedLine = firstChangedLine != null ? Math.min(firstChangedLine, oldStartLine) : oldStartLine; lastChangedLine = lastChangedLine != null ? Math.max(lastChangedLine, oldEndLine) : oldEndLine; /* processAfterChange */ if (firstChangedLine != null && lastChangedLine != null) { int startLine = firstChangedLine; int endLineInclusive = Math.min(lastChangedLine, source.getLineCount() - 1); firstChangedLine = null; lastChangedLine = null; /* forceRehighlightLines(startRehighlightLine, endRehighlightLine); */ firstDirtyLine = firstDirtyLine != null ? Math.min(firstDirtyLine, startLine) : startLine; lastDirtyLine = lastDirtyLine != null ? Math.max(lastDirtyLine, endLineInclusive) : endLineInclusive; // int start = // currentSnapshot.findLineFromLineNumber(startLine).getStart().getOffset(); // int end = (endLineInclusive == lineStates.size() - 1) ? // currentSnapshot.length() : currentSnapshot.findLineFromLineNumber(endLineInclusive + // 1).getStart().getOffset(); // if (FIX_HIGHLIGHTER_UPDATE_BUG) { // fireHighlightsChange(start, document.getLength()); // } else { // fireHighlightsChange(start, end); // } } } } firstDirtyLine = Math.min(firstDirtyLine, snapshot.getLineCount() - 1); lastDirtyLine = Math.min(lastDirtyLine, snapshot.getLineCount() - 1); }