Skip to content

Commit

Permalink
Use of Tree line tracker in incremental mode
Browse files Browse the repository at this point in the history
Fix #426

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Jun 18, 2019
1 parent ca21f48 commit 4ecfce9
Show file tree
Hide file tree
Showing 5 changed files with 1,786 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*******************************************************************************
* Copyright (c) 2000, 2009 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.lsp4xml.commons;
//package org.eclipse.jface.text;

import org.eclipse.lsp4j.Position;

/**
* A line tracker maps character positions to line numbers and vice versa.
* Initially the line tracker is informed about its underlying text in order to
* initialize the mapping information. After that, the line tracker is informed
* about all changes of the underlying text allowing for incremental updates of
* the mapping information. It is the client's responsibility to actively inform
* the line tacker about text changes. For example, when using a line tracker in
* combination with a document the document controls the line tracker.
* <p>
* In order to provide backward compatibility for clients of <code>ILineTracker</code>, extension
* interfaces are used to provide a means of evolution. The following extension interfaces
* exist:
* <ul>
* <li> {@link org.eclipse.jface.text.ILineTrackerExtension} since version 3.1 introducing the concept
* of rewrite sessions.</li>
* </ul>
* <p>
* Clients may implement this interface or use the standard implementation
* </p>
* {@link org.eclipse.jface.text.DefaultLineTracker}or
* {@link org.eclipse.jface.text.ConfigurableLineTracker}.
*/
public interface ILineTracker {

/**
* Returns the line delimiter of the specified line. Returns <code>null</code> if the
* line is not closed with a line delimiter.
*
* @param line the line whose line delimiter is queried
* @return the line's delimiter or <code>null</code> if line does not have a delimiter
* @exception BadLocationException if the line number is invalid in this tracker's line structure
*/
String getLineDelimiter(int line) throws BadLocationException;

/**
* Computes the number of lines in the given text.
*
* @param text the text whose number of lines should be computed
* @return the number of lines in the given text
*/
int computeNumberOfLines(String text);

/**
* Returns the number of lines.
* <p>
* Note that a document always has at least one line.
* </p>
*
* @return the number of lines in this tracker's line structure
*/
int getNumberOfLines();

/**
* Returns the number of lines which are occupied by a given text range.
*
* @param offset the offset of the specified text range
* @param length the length of the specified text range
* @return the number of lines occupied by the specified range
* @exception BadLocationException if specified range is unknown to this tracker
*/
int getNumberOfLines(int offset, int length) throws BadLocationException;

/**
* Returns the position of the first character of the specified line.
*
* @param line the line of interest
* @return offset of the first character of the line
* @exception BadLocationException if the line is unknown to this tracker
*/
int getLineOffset(int line) throws BadLocationException;

/**
* Returns length of the specified line including the line's delimiter.
*
* @param line the line of interest
* @return the length of the line
* @exception BadLocationException if line is unknown to this tracker
*/
int getLineLength(int line) throws BadLocationException;

/**
* Returns the line number the character at the given offset belongs to.
*
* @param offset the offset whose line number to be determined
* @return the number of the line the offset is on
* @exception BadLocationException if the offset is invalid in this tracker
*/
int getLineNumberOfOffset(int offset) throws BadLocationException;

/**
* Returns a line description of the line at the given offset.
* The description contains the start offset and the length of the line
* excluding the line's delimiter.
*
* @param offset the offset whose line should be described
* @return a region describing the line
* @exception BadLocationException if offset is invalid in this tracker
*/
Line getLineInformationOfOffset(int offset) throws BadLocationException;

/**
* Returns a line description of the given line. The description
* contains the start offset and the length of the line excluding the line's
* delimiter.
*
* @param line the line that should be described
* @return a region describing the line
* @exception BadLocationException if line is unknown to this tracker
*/
Line getLineInformation(int line) throws BadLocationException;

/**
* Informs the line tracker about the specified change in the tracked text.
*
* @param offset the offset of the replaced text
* @param length the length of the replaced text
* @param text the substitution text
* @exception BadLocationException if specified range is unknown to this tracker
*/
void replace(int offset, int length, String text) throws BadLocationException;

/**
* Sets the tracked text to the specified text.
*
* @param text the new tracked text
*/
void set(String text);

Position getPositionAt(int position) throws BadLocationException;

int getOffsetAt(Position position) throws BadLocationException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
*
* @since 3.2
*/
class ListLineTracker /* implements ILineTracker */ {
class ListLineTracker implements ILineTracker {

/** The predefined delimiters of this tracker */
public final static String[] DELIMITERS = { "\r", "\n", "\r\n" }; //$NON-NLS-3$ //$NON-NLS-1$ //$NON-NLS-2$
Expand Down Expand Up @@ -120,7 +120,53 @@ public final Position getPositionAt(int offset) throws BadLocationException {
return new Position(lineNumber, character);
}

private final int getLineNumberOfOffset(int position) throws BadLocationException {

/**
* Returns the number of lines covered by the specified text range.
*
* @param startLine the line where the text range starts
* @param offset the start offset of the text range
* @param length the length of the text range
* @return the number of lines covered by this text range
* @exception BadLocationException if range is undefined in this tracker
*/
private int getNumberOfLines(int startLine, int offset, int length) throws BadLocationException {

if (length == 0)
return 1;

int target= offset + length;

Line l= fLines.get(startLine);

if (l.delimiter == null)
return 1;

if (l.offset + l.length > target)
return 1;

if (l.offset + l.length == target)
return 2;

return getLineNumberOfOffset(target) - startLine + 1;
}

@Override
public final int getLineLength(int line) throws BadLocationException {
int lines= fLines.size();

if (line < 0 || line > lines)
throw new BadLocationException();

if (lines == 0 || lines == line)
return 0;

Line l= fLines.get(line);
return l.length;
}

@Override
public final int getLineNumberOfOffset(int position) throws BadLocationException {
if (position < 0) {
throw new BadLocationException("Negative offset : " + position); //$NON-NLS-1$
} else if (position > fTextLength) {
Expand All @@ -140,6 +186,7 @@ private final int getLineNumberOfOffset(int position) throws BadLocationExceptio
return findLine(position);
}

@Override
public int getOffsetAt(Position position) throws BadLocationException {
int line = position.getLine();
int lines = fLines.size();
Expand Down Expand Up @@ -172,6 +219,23 @@ public int getOffsetAt(Position position) throws BadLocationException {
return offset;
}

@Override
public final Line getLineInformationOfOffset(int position) throws BadLocationException {
if (position > fTextLength)
throw new BadLocationException("Offset > length: " + position + " > " + fTextLength); //$NON-NLS-1$//$NON-NLS-2$

if (position == fTextLength) {
int size= fLines.size();
if (size == 0)
return new Line(0, 0);
Line l= fLines.get(size - 1);
return (l.delimiter != null ? new Line(fTextLength, 0) : new Line(fTextLength - l.length, l.length));
}

return getLineInformation(findLine(position));
}

@Override
public final Line getLineInformation(int line) throws BadLocationException {
int lines = fLines.size();

Expand All @@ -190,7 +254,7 @@ public final Line getLineInformation(int line) throws BadLocationException {
return (l.delimiter != null ? new Line(l.offset, l.length - l.delimiter.length()) : l);
}

// @Override
@Override
public final int getLineOffset(int line) throws BadLocationException {
int lines = fLines.size();

Expand All @@ -211,7 +275,7 @@ public final int getLineOffset(int line) throws BadLocationException {
return l.offset;
}

// @Override
@Override
public final int getNumberOfLines() {
int lines = fLines.size();

Expand All @@ -221,26 +285,31 @@ public final int getNumberOfLines() {
Line l = fLines.get(lines - 1);
return (l.delimiter != null ? lines + 1 : lines);
}

@Override
public final int getNumberOfLines(int position, int length) throws BadLocationException {

/*
* @Override public final int getNumberOfLines(int position, int length) throws
* BadLocationException {
*
* if (position < 0 || position + length > fTextLength) throw new
* BadLocationException();
*
* if (length == 0) // optimization return 1;
*
* return getNumberOfLines(getLineNumberOfOffset(position), position, length); }
*/
if (position < 0 || position + length > fTextLength)
throw new BadLocationException();

/*
* @Override public final int computeNumberOfLines(String text) { int count= 0;
* int start= 0; DelimiterInfo delimiterInfo= nextDelimiterInfo(text, start);
* while (delimiterInfo != null && delimiterInfo.delimiterIndex > -1) { ++count;
* start= delimiterInfo.delimiterIndex + delimiterInfo.delimiterLength;
* delimiterInfo= nextDelimiterInfo(text, start); } return count; }
*/
if (length == 0) // optimization
return 1;

return getNumberOfLines(getLineNumberOfOffset(position), position, length);
}

@Override
public final int computeNumberOfLines(String text) {
int count= 0;
int start= 0;
DelimiterInfo delimiterInfo= nextDelimiterInfo(text, start);
while (delimiterInfo != null && delimiterInfo.delimiterIndex > -1) {
++count;
start= delimiterInfo.delimiterIndex + delimiterInfo.delimiterLength;
delimiterInfo= nextDelimiterInfo(text, start);
}
return count;
}

public final String getLineDelimiter(int line) throws BadLocationException {
int lines = fLines.size();
Expand Down Expand Up @@ -348,7 +417,12 @@ private int createLines(String text, int insertPosition, int offset) {
return count;
}

// @Override
@Override
public final void replace(int position, int length, String text) throws BadLocationException {
throw new UnsupportedOperationException();
}

@Override
public final void set(String text) {
fLines.clear();
if (text != null) {
Expand Down
Loading

0 comments on commit 4ecfce9

Please sign in to comment.