Allow error test expectations to omit the implicit line.

Error tests with explicit line/column markers, like
 [error line 123, column 456]
currently require both "line" and "column".
All existing occurrences of `[error line 123, column 456]` always
refer to the most recent non-comment line *just like* the `// ^^` lines,
so omitting the line, and having the most recent non-comment line
as the *default* line, seems reasonable.

This CL makes the line optional, the new format without a "line" entry
will be just `[error column 456]`.

This allows files to change the number of lines in the code without
invalidating any later expectations.
(Or, say, remove a comment line at the top of the file!)

Omits the line entry by default when writing/updating expectations.

Change-Id: Ia0c95bf804a1c6b11c0c1621bfd481e43f8fa0c0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/200429
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
This commit is contained in:
Lasse R.H. Nielsen 2021-06-14 12:00:13 +00:00 committed by commit-bot@chromium.org
parent 2951e33b24
commit e85042b403
3 changed files with 34 additions and 30 deletions

View file

@ -455,15 +455,23 @@ class _ErrorExpectationParser {
/// Matches an explicit error location with a length, like:
///
/// // [error line 1, column 17, length 3]
static final _explicitLocationAndLengthRegExp =
RegExp(r"^\s*//\s*\[\s*error line\s+(\d+)\s*,\s*column\s+(\d+)\s*,\s*"
r"length\s+(\d+)\s*\]\s*$");
///
/// or implicitly on the previous line
///
/// // [error column 17, length 3]
static final _explicitLocationAndLengthRegExp = RegExp(
r"^\s*//\s*\[\s*error (?:line\s+(\d+)\s*,)?\s*column\s+(\d+)\s*,\s*"
r"length\s+(\d+)\s*\]\s*$");
/// Matches an explicit error location without a length, like:
///
/// // [error line 1, column 17]
static final _explicitLocationRegExp =
RegExp(r"^\s*//\s*\[\s*error line\s+(\d+)\s*,\s*column\s+(\d+)\s*\]\s*$");
///
/// or implicitly on the previous line.
///
/// // [error column 17]
static final _explicitLocationRegExp = RegExp(
r"^\s*//\s*\[\s*error (?:line\s+(\d+)\s*,)?\s*column\s+(\d+)\s*\]\s*$");
/// Matches the beginning of an error message, like `// [analyzer]`.
///
@ -518,25 +526,28 @@ class _ErrorExpectationParser {
_parseErrors(
line: _lastRealLine,
column: sourceLine.indexOf("^") + 1,
length: match.group(1).length);
length: match[1].length);
_advance();
continue;
}
match = _explicitLocationAndLengthRegExp.firstMatch(sourceLine);
if (match != null) {
var lineCapture = match[1];
_parseErrors(
line: int.parse(match.group(1)),
column: int.parse(match.group(2)),
length: int.parse(match.group(3)));
line: lineCapture == null ? _lastRealLine : int.parse(lineCapture),
column: int.parse(match[2]),
length: int.parse(match[3]));
_advance();
continue;
}
match = _explicitLocationRegExp.firstMatch(sourceLine);
if (match != null) {
var lineCapture = match[1];
_parseErrors(
line: int.parse(match.group(1)), column: int.parse(match.group(2)));
line: lineCapture == null ? _lastRealLine : int.parse(lineCapture),
column: int.parse(match[2]));
_advance();
continue;
}
@ -559,16 +570,16 @@ class _ErrorExpectationParser {
var match = _errorMessageRegExp.firstMatch(_peek(1));
if (match == null) break;
var number = match.group(2) != null ? int.parse(match.group(2)) : null;
var number = match[2] != null ? int.parse(match[2]) : null;
var sourceName = match.group(1);
var sourceName = match[1];
var source = ErrorSource.find(sourceName);
if (source == null) _fail("Unknown front end '[$sourceName]'.");
if (source == ErrorSource.context && number == null) {
_fail("Context messages must have an error number.");
}
var message = match.group(3);
var message = match[3];
_advance();
var sourceLines = {locationLine, _currentLine};
@ -587,7 +598,7 @@ class _ErrorExpectationParser {
var messageMatch = _errorMessageRestRegExp.firstMatch(nextLine);
if (messageMatch == null) break;
message += "\n" + messageMatch.group(1);
message += "\n" + messageMatch[1];
_advance();
sourceLines.add(_currentLine);
}

View file

@ -85,19 +85,12 @@ String updateErrorExpectations(String source, List<StaticError> errors,
// Rebuild the source file a line at a time.
var previousIndent = 0;
var codeLine = 1;
var result = <String>[];
for (var i = 0; i < lines.length; i++) {
// Keep the code.
if (lines[i] != null) {
result.add(lines[i]);
previousIndent = _countIndentation(lines[i]);
// Keep track of the resulting line number of the last line containing
// real code. We use this when outputting explicit line numbers instead
// the error's reported line to compensate for added or removed lines
// above the error.
codeLine = result.length;
}
// Add expectations for any errors reported on this line.
@ -124,13 +117,13 @@ String updateErrorExpectations(String source, List<StaticError> errors,
error.length != null &&
error.length != previousLength)) {
// If the error can't fit in a line comment, or no source location is
// sepcified, use an explicit location.
// specified, use an explicit location.
if (error.column <= 2 || error.length == 0) {
if (error.length == null) {
result.add("$comment [error line $codeLine, column "
result.add("$comment [error column "
"${error.column}]");
} else {
result.add("$comment [error line $codeLine, column "
result.add("$comment [error column "
"${error.column}, length ${error.length}]");
}
} else {

View file

@ -268,12 +268,12 @@ int j =
], expected: """
int i =
"bad";
/\/ [error line 2, column 1, length 5]
/\/ [error column 1, length 5]
/\/ [analyzer] updated.error
int j =
"bad";
/\/ [error line 7, column 1, length 5]
/\/ [error column 1, length 5]
/\/ [cfe] Error.
""");
@ -293,7 +293,7 @@ int i =
""", errors: [makeError(line: 2, column: 1, cfeError: "Error.")], expected: """
int i =
"bad";
/\/ [error line 2, column 1]
/\/ [error column 1]
/\/ [cfe] Error.
""");
@ -314,9 +314,9 @@ Error here;
main() {
}
Error here;
/\/ [error line 3, column 1, length 5]
/\/ [error column 1, length 5]
/\/ [analyzer] NEW.ERROR
/\/ [error line 3, column 2, length 3]
/\/ [error column 2, length 3]
/\/ [cfe] Error.
""");
@ -400,7 +400,7 @@ x
makeError(line: 1, column: 1, length: 0, cfeError: "Foo"),
], expected: """
x
// [error line 1, column 1, length 0]
// [error column 1, length 0]
// [cfe] Foo""");
contextMessages();