mirror of
https://github.com/dart-lang/sdk
synced 2024-10-03 02:42:05 +00:00
analyzer: Remove deprecated IgnoreInfo API and refactor
* Change `IgnoreInfo.ignoredAt` to accept an error code name, case- insensitive, and allow short-circuiting to a "no this is not ignored" if the file has no //ignore_for_file comments, and if the relevant line has no //ignore comments. I think this accounts for the vast majority of diagnostics (both IDE, code-in-development, and "final" code). * This also improves `uniqueName != name` checking, which I think was previously _always_ comparing a lower case string to an upper case string. :/ * Remove the deprecated `IgnoreInfo()` constructor. * Remove the deprecated `IgnoreInfo.calculateIgnores` method. * This allows us to remove the capture groups on IgnoreInfo.IGNORE_MATCHER and IgnoreInfo.IGNORE_FOR_FILE_MATCHER. Change-Id: I6617e65e5c2063769dbe9d922740d20b6fba219d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210800 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
parent
2a8f3d5fd5
commit
4bff21f56c
|
@ -430,9 +430,8 @@ class LibraryAnalyzer {
|
|||
unignorableCodes.contains(code.name.toUpperCase())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int errorLine = lineInfo.getLocation(error.offset).lineNumber;
|
||||
String name = code.name.toLowerCase();
|
||||
String name = code.name;
|
||||
if (ignoreInfo.ignoredAt(name, errorLine)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -441,8 +440,7 @@ class LibraryAnalyzer {
|
|||
if (period >= 0) {
|
||||
uniqueName = uniqueName.substring(period + 1);
|
||||
}
|
||||
return uniqueName != name &&
|
||||
ignoreInfo.ignoredAt(uniqueName.toLowerCase(), errorLine);
|
||||
return uniqueName != name && ignoreInfo.ignoredAt(uniqueName, errorLine);
|
||||
}
|
||||
|
||||
return errors.where((AnalysisError e) => !isIgnored(e)).toList();
|
||||
|
|
|
@ -413,8 +413,7 @@ class LibraryAnalyzer {
|
|||
|
||||
bool isIgnored(AnalysisError error) {
|
||||
int errorLine = lineInfo.getLocation(error.offset).lineNumber;
|
||||
String errorCode = error.errorCode.name.toLowerCase();
|
||||
return ignoreInfo.ignoredAt(errorCode, errorLine);
|
||||
return ignoreInfo.ignoredAt(error.errorCode.name, errorLine);
|
||||
}
|
||||
|
||||
return errors.where((AnalysisError e) => !isIgnored(e)).toList();
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/dart/ast/token.dart';
|
||||
import 'package:analyzer/source/line_info.dart';
|
||||
import 'package:analyzer/src/dart/ast/token.dart';
|
||||
|
||||
/// The name and location of a diagnostic name in an ignore comment.
|
||||
|
@ -26,27 +25,16 @@ class DiagnosticName {
|
|||
/// Information about analysis `//ignore:` and `//ignore_for_file` comments
|
||||
/// within a source file.
|
||||
class IgnoreInfo {
|
||||
/// Instance shared by all cases without matches.
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
static final IgnoreInfo _EMPTY_INFO = IgnoreInfo();
|
||||
|
||||
/// A regular expression for matching 'ignore' comments. Produces matches
|
||||
/// containing 2 groups. For example:
|
||||
///
|
||||
/// * ['//ignore: error_code', 'error_code']
|
||||
/// A regular expression for matching 'ignore' comments.
|
||||
///
|
||||
/// Resulting codes may be in a list ('error_code_1,error_code2').
|
||||
static final RegExp IGNORE_MATCHER =
|
||||
RegExp(r'//+[ ]*ignore:(.*)$', multiLine: true);
|
||||
static final RegExp IGNORE_MATCHER = RegExp(r'//+[ ]*ignore:');
|
||||
|
||||
/// A regular expression for matching 'ignore_for_file' comments. Produces
|
||||
/// matches containing 2 groups. For example:
|
||||
///
|
||||
/// * ['//ignore_for_file: error_code', 'error_code']
|
||||
/// A regular expression for matching 'ignore_for_file' comments.
|
||||
///
|
||||
/// Resulting codes may be in a list ('error_code_1,error_code2').
|
||||
static final RegExp IGNORE_FOR_FILE_MATCHER =
|
||||
RegExp(r'//[ ]*ignore_for_file:(.*)$', multiLine: true);
|
||||
RegExp(r'//[ ]*ignore_for_file:');
|
||||
|
||||
/// A table mapping line numbers to the diagnostics that are ignored on that
|
||||
/// line.
|
||||
|
@ -56,9 +44,6 @@ class IgnoreInfo {
|
|||
/// file.
|
||||
final List<DiagnosticName> _ignoredForFile = [];
|
||||
|
||||
@Deprecated('Use the constructor IgnoreInfo.forDart')
|
||||
IgnoreInfo();
|
||||
|
||||
/// Initialize a newly created instance of this class to represent the ignore
|
||||
/// comments in the given compilation [unit].
|
||||
IgnoreInfo.forDart(CompilationUnit unit, String content) {
|
||||
|
@ -68,11 +53,9 @@ class IgnoreInfo {
|
|||
if (lexeme.contains('ignore:')) {
|
||||
var location = lineInfo.getLocation(comment.offset);
|
||||
var lineNumber = location.lineNumber;
|
||||
String beforeMatch = content.substring(
|
||||
lineInfo.getOffsetOfLine(lineNumber - 1),
|
||||
lineInfo.getOffsetOfLine(lineNumber - 1) +
|
||||
location.columnNumber -
|
||||
1);
|
||||
var offsetOfLine = lineInfo.getOffsetOfLine(lineNumber - 1);
|
||||
var beforeMatch = content.substring(
|
||||
offsetOfLine, offsetOfLine + location.columnNumber - 1);
|
||||
if (beforeMatch.trim().isEmpty) {
|
||||
// The comment is on its own line, so it refers to the next line.
|
||||
lineNumber++;
|
||||
|
@ -104,78 +87,21 @@ class IgnoreInfo {
|
|||
return ignoredOnLine;
|
||||
}
|
||||
|
||||
/// Return `true` if the [errorCode] is ignored at the given [line].
|
||||
/// Return `true` if the [errorCode] (case-insensitive) is ignored at the
|
||||
/// given [line].
|
||||
bool ignoredAt(String errorCode, int line) {
|
||||
for (var name in _ignoredForFile) {
|
||||
if (name.matches(errorCode)) {
|
||||
return true;
|
||||
}
|
||||
var ignoredDiagnostics = _ignoredOnLine[line];
|
||||
if (ignoredForFile.isEmpty && ignoredDiagnostics == null) {
|
||||
return false;
|
||||
}
|
||||
var ignoredOnLine = _ignoredOnLine[line];
|
||||
if (ignoredOnLine != null) {
|
||||
for (var name in ignoredOnLine) {
|
||||
if (name.matches(errorCode)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
errorCode = errorCode.toLowerCase();
|
||||
if (ignoredForFile.any((name) => name.matches(errorCode))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Ignore these [errorCodes] at [line].
|
||||
void _addAll(int line, Iterable<DiagnosticName> errorCodes) {
|
||||
_ignoredOnLine.putIfAbsent(line, () => []).addAll(errorCodes);
|
||||
}
|
||||
|
||||
/// Ignore these [errorCodes] in the whole file.
|
||||
void _addAllForFile(Iterable<DiagnosticName> errorCodes) {
|
||||
_ignoredForFile.addAll(errorCodes);
|
||||
}
|
||||
|
||||
/// Calculate ignores for the given [content] with line [info].
|
||||
@Deprecated('Use the constructor IgnoreInfo.forDart')
|
||||
static IgnoreInfo calculateIgnores(String content, LineInfo info) {
|
||||
Iterable<Match> matches = IGNORE_MATCHER.allMatches(content);
|
||||
Iterable<Match> fileMatches = IGNORE_FOR_FILE_MATCHER.allMatches(content);
|
||||
if (matches.isEmpty && fileMatches.isEmpty) {
|
||||
return _EMPTY_INFO;
|
||||
if (ignoredDiagnostics == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IgnoreInfo ignoreInfo = IgnoreInfo();
|
||||
for (Match match in matches) {
|
||||
// See _IGNORE_MATCHER for format --- note the possibility of error lists.
|
||||
// Note that the offsets are not being computed here. This shouldn't
|
||||
// affect older clients of this class because none of the previous APIs
|
||||
// depended on having offsets.
|
||||
Iterable<DiagnosticName> codes = match
|
||||
.group(1)!
|
||||
.split(',')
|
||||
.map((String code) => DiagnosticName(code.trim().toLowerCase(), -1));
|
||||
var 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);
|
||||
}
|
||||
}
|
||||
// Note that the offsets are not being computed here. This shouldn't affect
|
||||
// older clients of this class because none of the previous APIs depended on
|
||||
// having offsets.
|
||||
for (Match match in fileMatches) {
|
||||
Iterable<DiagnosticName> codes = match
|
||||
.group(1)!
|
||||
.split(',')
|
||||
.map((String code) => DiagnosticName(code.trim().toLowerCase(), -1));
|
||||
ignoreInfo._addAllForFile(codes);
|
||||
}
|
||||
return ignoreInfo;
|
||||
return ignoredDiagnostics.any((name) => name.matches(errorCode));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,14 +112,10 @@ extension on CompilationUnit {
|
|||
var comment = currentToken.precedingComments;
|
||||
while (comment != null) {
|
||||
var lexeme = comment.lexeme;
|
||||
var match = IgnoreInfo.IGNORE_MATCHER.matchAsPrefix(lexeme);
|
||||
if (match != null) {
|
||||
if (lexeme.startsWith(IgnoreInfo.IGNORE_MATCHER)) {
|
||||
yield comment;
|
||||
} else if (lexeme.startsWith(IgnoreInfo.IGNORE_FOR_FILE_MATCHER)) {
|
||||
yield comment;
|
||||
} else {
|
||||
match = IgnoreInfo.IGNORE_FOR_FILE_MATCHER.matchAsPrefix(lexeme);
|
||||
if (match != null) {
|
||||
yield comment;
|
||||
}
|
||||
}
|
||||
comment = comment.next as CommentToken?;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue