/* |
|
* Copyright (C) 2007-2010 Júlio Vilmar Gesser. |
|
* Copyright (C) 2011, 2013-2021 The JavaParser Team. |
|
* |
|
* This file is part of JavaParser. |
|
* |
|
* JavaParser can be used either under the terms of |
|
* a) the GNU Lesser General Public License as published by |
|
* the Free Software Foundation, either version 3 of the License, or |
|
* (at your option) any later version. |
|
* b) the terms of the Apache License |
|
* |
|
* You should have received a copy of both licenses in LICENCE.LGPL and |
|
* LICENCE.APACHE. Please refer to those files for details. |
|
* |
|
* JavaParser is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU Lesser General Public License for more details. |
|
*/ |
|
package com.github.javaparser; |
|
import static com.github.javaparser.Position.pos; |
|
/** |
|
* A range of characters in a source file, from "begin" to "end", including the characters at "begin" and "end". |
|
*/ |
|
public class Range { |
|
public final Position begin; |
|
public final Position end; |
|
/** |
|
* A range of characters in a source file, from "begin" to "end". |
|
* This range is inclusive of the characters at the "begin" and "end" positions. |
|
* <p> |
|
* Note that if the given parameters are reversed (i.e. the end is earlier than begin, then the values are swapped. |
|
* |
|
* @param begin The starting position of the range. |
|
* @param end The end position of the range. |
|
*/ |
|
public Range(Position begin, Position end) { |
|
if (begin == null) { |
|
throw new IllegalArgumentException("begin can't be null"); |
|
} |
|
if (end == null) { |
|
throw new IllegalArgumentException("end can't be null"); |
|
} |
|
// Force `begin` to be the position that is earliest within the document: |
|
if (begin.isBefore(end)) { |
|
this.begin = begin; |
|
this.end = end; |
|
} else { |
|
this.begin = end; |
|
this.end = begin; |
|
} |
|
} |
|
/** |
|
* Create a new `Range` object using the given begin and end position. |
|
* |
|
* @param begin The starting position of the range. |
|
* @param end The end position of the range. |
|
* @return A new `Range` object with the given start/end position. |
|
*/ |
|
public static Range range(Position begin, Position end) { |
|
return new Range(begin, end); |
|
} |
|
/** |
|
* Create a new `Range` object using the given begin and end line/column values. |
|
* Valid values for each parameter are per the constructor of{@link Position}. |
|
* |
|
* @param beginLine The start line of the range. |
|
* @param beginColumn The start line column of the range. |
|
* @param endLine The end line of the range. |
|
* @param endColumn The end column of the range. |
|
* @return A new `Range` object with the given start/end position. |
|
*/ |
|
public static Range range(int beginLine, int beginColumn, int endLine, int endColumn) { |
|
return new Range(new Position(beginLine, beginColumn), new Position(endLine, endColumn)); |
|
} |
|
/** |
|
* @param beginColumn The value used to replace the current begin column number. |
|
* Valid values are per the constructor of{@link Position}. |
|
* @return A copy of this `Range` object, but with the begin column number replaced with the given column number. |
|
*/ |
|
public Range withBeginColumn(int beginColumn) { |
|
return range(begin.withColumn(beginColumn), end); |
|
} |
|
/** |
|
* @param beginLine The value used to replace the current begin line number. |
|
* Valid values are per the constructor of{@link Position}. |
|
* @return A copy of this `Range` object, but with the begin line number replaced with the given line number. |
|
*/ |
|
public Range withBeginLine(int beginLine) { |
|
return range(begin.withLine(beginLine), end); |
|
} |
|
/** |
|
* @param endColumn The value used to replace the current end column number. |
|
* Valid values are per the constructor of{@link Position}. |
|
* @return A copy of this `Range` object, but with the end column number replaced with the given line column. |
|
*/ |
|
public Range withEndColumn(int endColumn) { |
|
return range(begin, end.withColumn(endColumn)); |
|
} |
|
/** |
|
* @param endLine The value used to replace the current end line number. |
|
* Valid values are per the constructor of{@link Position}. |
|
* @return A copy of this `Range` object, but with the end line number replaced with the given line number. |
|
*/ |
|
public Range withEndLine(int endLine) { |
|
return range(begin, end.withLine(endLine)); |
|
} |
|
/** |
|
* @param begin The value used to replace the current begin position. |
|
* @return A copy of this `Range` object, but with the begin position replaced with the given position. |
|
*/ |
|
public Range withBegin(Position begin) { |
|
return range(begin, this.end); |
|
} |
|
/** |
|
* @param end The value used to replace the current end position. |
|
* @return A copy of this `Range` object, but with the end position replaced with the given position. |
|
*/ |
|
public Range withEnd(Position end) { |
|
return range(this.begin, end); |
|
} |
|
/** |
|
* Does this loosely contain the other range? |
|
* <p> |
|
* As {@link #strictlyContains(Range)}, but also allow ranges which have an equal start and/or end position. |
|
* In these cases, the `other` range is not strictly "inside" of this range. |
|
*/ |
|
public boolean contains(Range other) { |
|
boolean beginResult = (begin.isBeforeOrEqual(other.begin)); |
|
boolean endResult = (end.isAfterOrEqual(other.end)); |
|
return beginResult && endResult; |
|
} |
|
/** |
|
* Does this loosely contain the other range? |
|
* <p> |
|
* As {@link #strictlyContains(Position)}, but a position that is on the "edge" of this range will also pass. |
|
* <p> |
|
* For example, if the given position is equal to the start or end position of this range. |
|
* In these cases, the `other` range is not strictly "inside" of this range. |
|
*/ |
|
public boolean contains(Position position) { |
|
return strictlyContains(position) || begin.equals(position) || end.equals(position); |
|
} |
|
/** |
|
* Does this strictly contain the other range? |
|
* <p> |
|
* It means that this has to be larger than other and it has to start before other and end after other. |
|
*/ |
|
public boolean strictlyContains(Range other) { |
|
boolean beginResult = (begin.isBefore(other.begin)); |
|
boolean endResult = (end.isAfter(other.end)); |
|
return beginResult && endResult; |
|
} |
|
/** |
|
* Does this strictly contain position. |
|
* <p> |
|
* It means that the position is after the begin of this range and before the end of this range. |
|
*/ |
|
public boolean strictlyContains(Position position) { |
|
return position.isAfter(begin) && position.isBefore(end); |
|
} |
|
/** |
|
* Does the other 'Range' overlap with this 'Range'? |
|
* <p> |
|
* If two ranges overlap, this range or the other range contains the begin or the end of the other range. |
|
* <p> |
|
* Note that if the ends are "touching" (i.e. a begin position == end position), this counts as an overlap |
|
* because the positions refer to characters, as opposed to boundary between characters. |
|
* <p> |
|
* For example, there is an overlap at "C" in the following ranges, with "C" existing within both ranges: |
|
* <pre> |
|
* Range 1: ABC |
|
* Range 2: CDE</pre> |
|
*/ |
|
public boolean overlapsWith(Range other) { |
|
return (contains(other.begin) || contains(other.end)) || |
|
(other.contains(begin) || other.contains(end)); |
|
} |
|
/** |
|
* @param position The position to compare against. |
|
* @return True if the end of this range is before (but not equal to) the given position to compare against. |
|
*/ |
|
public boolean isBefore(Position position) { |
|
return end.isBefore(position); |
|
} |
|
/** |
|
* @param position The position to compare against. |
|
* @return True if the start of this range is after (but not equal to) the given position to compare against. |
|
*/ |
|
public boolean isAfter(Position position) { |
|
return begin.isAfter(position); |
|
} |
|
@Override |
|
public boolean equals(Object o) { |
|
if (this == o) return true; |
|
if (o == null || getClass() != o.getClass()) return false; |
|
Range range = (Range) o; |
|
return begin.equals(range.begin) && end.equals(range.end); |
|
} |
|
@Override |
|
public int hashCode() { |
|
return 31 * begin.hashCode() + end.hashCode(); |
|
} |
|
@Override |
|
public String toString() { |
|
return begin + "-" + end; |
|
} |
|
/** |
|
* @return The number of lines that this range represents. |
|
* <p> |
|
* If the start line and end line are the same, this range is limited to just one line. |
|
*/ |
|
public int getLineCount() { |
|
return end.line - begin.line + 1; |
|
} |
|
} |