mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:37:53 +00:00
Analyzer: add ignore_for_file comment that ignores a type of problem for the whole file; add tests.
BUG= R=brianwilkerson@google.com Review-Url: https://codereview.chromium.org/2888953002 .
This commit is contained in:
parent
5182eeab26
commit
32c4094d04
|
@ -3005,7 +3005,8 @@ class GenerateLintsTask extends SourceBasedAnalysisTask {
|
|||
}
|
||||
|
||||
/**
|
||||
* Information about analysis `//ignore:` comments within a source file.
|
||||
* Information about analysis `//ignore:` and `//ignore_for_file` comments
|
||||
* within a source file.
|
||||
*/
|
||||
class IgnoreInfo {
|
||||
/**
|
||||
|
@ -3024,18 +3025,36 @@ class IgnoreInfo {
|
|||
static final RegExp _IGNORE_MATCHER =
|
||||
new RegExp(r'//[ ]*ignore:(.*)$', multiLine: true);
|
||||
|
||||
/**
|
||||
* A regular expression for matching 'ignore_for_file' comments. Produces
|
||||
* matches containing 2 groups. For example:
|
||||
*
|
||||
* * ['//ignore_for_file: error_code', 'error_code']
|
||||
*
|
||||
* Resulting codes may be in a list ('error_code_1,error_code2').
|
||||
*/
|
||||
static final RegExp _IGNORE_FOR_FILE_MATCHER =
|
||||
new RegExp(r'//[ ]*ignore_for_file:(.*)$', multiLine: true);
|
||||
|
||||
final Map<int, List<String>> _ignoreMap = new HashMap<int, List<String>>();
|
||||
|
||||
final Set<String> _ignoreForFileSet = new HashSet<String>();
|
||||
|
||||
/**
|
||||
* Whether this info object defines any ignores.
|
||||
*/
|
||||
bool get hasIgnores => ignores.isNotEmpty;
|
||||
bool get hasIgnores => ignores.isNotEmpty || _ignoreForFileSet.isNotEmpty;
|
||||
|
||||
/**
|
||||
* Map of line numbers to associated ignored error codes.
|
||||
*/
|
||||
Map<int, Iterable<String>> get ignores => _ignoreMap;
|
||||
|
||||
/**
|
||||
* Iterable of error codes ignored for the whole file.
|
||||
*/
|
||||
Iterable<String> get ignoreForFiles => _ignoreForFileSet;
|
||||
|
||||
/**
|
||||
* Ignore this [errorCode] at [line].
|
||||
*/
|
||||
|
@ -3050,10 +3069,18 @@ class IgnoreInfo {
|
|||
_ignoreMap.putIfAbsent(line, () => new List<String>()).addAll(errorCodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore these [errorCodes] in the whole file.
|
||||
*/
|
||||
void addAllForFile(Iterable<String> errorCodes) {
|
||||
_ignoreForFileSet.addAll(errorCodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether this [errorCode] is ignored at the given [line].
|
||||
*/
|
||||
bool ignoredAt(String errorCode, int line) =>
|
||||
_ignoreForFileSet.contains(errorCode) ||
|
||||
_ignoreMap[line]?.contains(errorCode) == true;
|
||||
|
||||
/**
|
||||
|
@ -3061,7 +3088,8 @@ class IgnoreInfo {
|
|||
*/
|
||||
static IgnoreInfo calculateIgnores(String content, LineInfo info) {
|
||||
Iterable<Match> matches = _IGNORE_MATCHER.allMatches(content);
|
||||
if (matches.isEmpty) {
|
||||
Iterable<Match> fileMatches = _IGNORE_FOR_FILE_MATCHER.allMatches(content);
|
||||
if (matches.isEmpty && fileMatches.isEmpty) {
|
||||
return _EMPTY_INFO;
|
||||
}
|
||||
|
||||
|
@ -3074,6 +3102,13 @@ class IgnoreInfo {
|
|||
.map((String code) => code.trim().toLowerCase());
|
||||
ignoreInfo.addAll(info.getLocation(match.start).lineNumber, codes);
|
||||
}
|
||||
for (Match match in fileMatches) {
|
||||
Iterable<String> codes = match
|
||||
.group(1)
|
||||
.split(',')
|
||||
.map((String code) => code.trim().toLowerCase());
|
||||
ignoreInfo.addAllForFile(codes);
|
||||
}
|
||||
return ignoreInfo;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,4 +195,35 @@ const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
|||
CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
]);
|
||||
}
|
||||
|
||||
test_ignore_for_file() async {
|
||||
Source source = addSource('''
|
||||
int x = ''; //INVALID_ASSIGNMENT
|
||||
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
// ignore_for_file: invalid_assignment
|
||||
''');
|
||||
await computeAnalysisResult(source);
|
||||
assertErrors(source,
|
||||
[CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
|
||||
}
|
||||
|
||||
test_multiple_ignore_for_files() async {
|
||||
Source source = addSource('''
|
||||
int x = ''; //INVALID_ASSIGNMENT
|
||||
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
// ignore_for_file: invalid_assignment,const_initialized_with_non_constant_value
|
||||
''');
|
||||
await computeAnalysisResult(source);
|
||||
assertErrors(source, []);
|
||||
}
|
||||
|
||||
test_ignore_for_file_whitespace_variant() async {
|
||||
Source source = addSource('''
|
||||
//ignore_for_file: const_initialized_with_non_constant_value , invalid_assignment
|
||||
int x = ''; //INVALID_ASSIGNMENT
|
||||
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
''');
|
||||
await computeAnalysisResult(source);
|
||||
assertErrors(source, []);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4360,16 +4360,20 @@ class ScanDartTaskTest extends _AbstractDartTaskTest {
|
|||
test_ignore_info() {
|
||||
_performScanTask('''
|
||||
//ignore: error_code
|
||||
//ignore_for_file: error_code
|
||||
var x = '';
|
||||
foo(); // ignore: error_code_2
|
||||
bar(); //ignore: error_code, error_code_2
|
||||
// ignore_for_file: error_code_2, error_code_3
|
||||
''');
|
||||
|
||||
IgnoreInfo info = outputs[IGNORE_INFO];
|
||||
expect(info.ignores.keys, hasLength(3));
|
||||
expect(info.ignores[1].first, 'error_code');
|
||||
expect(info.ignores[3].first, 'error_code_2');
|
||||
expect(info.ignores[4], unorderedEquals(['error_code', 'error_code_2']));
|
||||
expect(info.ignores[4].first, 'error_code_2');
|
||||
expect(info.ignores[5], unorderedEquals(['error_code', 'error_code_2']));
|
||||
expect(info.ignoreForFiles,
|
||||
unorderedEquals(['error_code', 'error_code_2', 'error_code_3']));
|
||||
}
|
||||
|
||||
test_perform_errors() {
|
||||
|
|
Loading…
Reference in a new issue