Analyzer: fix 'ignore:' comments at the end of a line.

'//ignore:' comments that sit next to code should not invalidate errors on the
next line.

Fixes https://github.com/dart-lang/sdk/issues/28467

Bug: https://github.com/dart-lang/sdk/issues/28467
Change-Id: I15b1787e5fe4dadcdc72c18409e0b82df11060af
Reviewed-on: https://dart-review.googlesource.com/29548
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Sam Rawlins 2017-12-18 20:07:56 +00:00 committed by commit-bot@chromium.org
parent b04e75d2bf
commit b32a56235e
5 changed files with 35 additions and 9 deletions

View file

@ -462,9 +462,7 @@ class LibraryAnalyzer {
bool isIgnored(AnalysisError error) {
int errorLine = lineInfo.getLocation(error.offset).lineNumber;
String errorCode = error.errorCode.name.toLowerCase();
// Ignores can be on the line or just preceding the error.
return ignoreInfo.ignoredAt(errorCode, errorLine) ||
ignoreInfo.ignoredAt(errorCode, errorLine - 1);
return ignoreInfo.ignoredAt(errorCode, errorLine);
}
return errors.where((AnalysisError e) => !isIgnored(e)).toList();

View file

@ -2575,9 +2575,7 @@ class DartErrorsTask extends SourceBasedAnalysisTask {
bool isIgnored(AnalysisError error) {
int errorLine = lineInfo.getLocation(error.offset).lineNumber;
String errorCode = error.errorCode.name.toLowerCase();
// Ignores can be on the line or just preceding the error.
return ignoreInfo.ignoredAt(errorCode, errorLine) ||
ignoreInfo.ignoredAt(errorCode, errorLine - 1);
return ignoreInfo.ignoredAt(errorCode, errorLine);
}
return errors.where((AnalysisError e) => !isIgnored(e)).toList();
@ -3007,7 +3005,7 @@ class IgnoreInfo {
* Resulting codes may be in a list ('error_code_1,error_code2').
*/
static final RegExp _IGNORE_MATCHER =
new RegExp(r'//[ ]*ignore:(.*)$', multiLine: true);
new RegExp(r'//+[ ]*ignore:(.*)$', multiLine: true);
/**
* A regular expression for matching 'ignore_for_file' comments. Produces
@ -3084,7 +3082,19 @@ class IgnoreInfo {
.group(1)
.split(',')
.map((String code) => code.trim().toLowerCase());
ignoreInfo.addAll(info.getLocation(match.start).lineNumber, codes);
LineInfo_Location location = info.getLocation(match.start);
int lineNumber = location.lineNumber;
String beforeMatch = content.substring(
info.getOffsetOfLine(lineNumber - 1),
info.getOffsetOfLine(lineNumber - 1) + location.columnNumber - 1);
if (beforeMatch.trim().isEmpty) {
// The comment is on its own line, so it refers to the next line.
ignoreInfo.addAll(lineNumber + 1, codes);
} else {
// The comment sits next to code, so it refers to its own line.
ignoreInfo.addAll(lineNumber, codes);
}
}
for (Match match in fileMatches) {
Iterable<String> codes = match

View file

@ -134,4 +134,11 @@ class ErrorSuppressionTest_Kernel extends ErrorSuppressionTest_Driver {
// 1 errors of type CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, found 0
await super.test_no_ignores();
}
@override
@failingTest
test_trailing_not_above() async {
// Expected 1 errors of type StaticTypeWarningCode.INVALID_ASSIGNMENT, found 0
await super.test_trailing_not_above();
}
}

View file

@ -215,6 +215,17 @@ const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VA
assertErrors(source, []);
}
test_trailing_not_above() async {
Source source = addSource('''
int x = ''; // ignore: invalid_assignment
int y = '';
''');
await computeAnalysisResult(source);
assertErrors(source, [
StaticTypeWarningCode.INVALID_ASSIGNMENT,
]);
}
test_no_ignores() async {
Source source = addSource('''
int x = ''; //INVALID_ASSIGNMENT

View file

@ -4098,7 +4098,7 @@ bar(); //ignore: error_code, error_code_2
IgnoreInfo info = outputs[IGNORE_INFO];
expect(info.ignores.keys, hasLength(3));
expect(info.ignores[1].first, 'error_code');
expect(info.ignores[2].first, 'error_code');
expect(info.ignores[4].first, 'error_code_2');
expect(info.ignores[5], unorderedEquals(['error_code', 'error_code_2']));
expect(info.ignoreForFiles,