position property
inherited
The current position of the scanner in the string, in characters.
Implementation
int get position => _position;
override
Implementation
@override
set position(int newPosition) {
if (newPosition == position) {
return;
}
final oldPosition = position;
super.position = newPosition;
if (newPosition == 0) {
_line = 0;
_column = 0;
} else if (newPosition > oldPosition) {
final newlines = _newlinesIn(string.substring(oldPosition, newPosition),
endPosition: newPosition);
_line += newlines.length;
if (newlines.isEmpty) {
_column += newPosition - oldPosition;
} else {
// The regex got a substring, so we need to account for where it started
// in the string.
final offsetOfLastNewline = oldPosition + newlines.last.end;
_column = newPosition - offsetOfLastNewline;
}
} else if (newPosition < oldPosition) {
final newlines = _newlinesIn(string.substring(newPosition, oldPosition),
endPosition: oldPosition);
_line -= newlines.length;
if (newlines.isEmpty) {
_column -= oldPosition - newPosition;
} else {
// To compute the new column, we need to locate the last newline before
// the new position. When searching, we must exclude the CR if we're
// between a CRLF because it's not considered a newline.
final crOffset = _betweenCRLF ? -1 : 0;
// Additionally, if we use newPosition as the end of the search and the
// character at that position itself (the next character) is a newline
// we should not use it, so also offset to account for that.
const currentCharOffset = -1;
final lastNewline = string.lastIndexOf(
_newlineRegExp, newPosition + currentCharOffset + crOffset);
// Now we need to know the offset after the newline. This is the index
// above plus the length of the newline (eg. if we found `\r\n`) we need
// to add two. However if no newline was found, that index is 0.
final offsetAfterLastNewline = lastNewline == -1
? 0
: string[lastNewline] == '\r' && string[lastNewline + 1] == '\n'
? lastNewline + 2
: lastNewline + 1;
_column = newPosition - offsetAfterLastNewline;
}
}
}