Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(545)

Unified Diff: pkg/analyzer/lib/src/task/dart.dart

Issue 2011183004: Precompute `IgnoreInfo` in Scanner. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/lib/src/task/dart.dart
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 3d9d552329932b3980bcfe8b95d5800764b49440..a9ad9633c3110dd2575a519e6d5be61f26501f75 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -2520,8 +2520,6 @@ class DartDelta extends Delta {
* of errors.
*/
class DartErrorsTask extends SourceBasedAnalysisTask {
- static final RegExp spacesRegExp = new RegExp(r'\s+');
-
/**
* The task descriptor describing this kind of task.
*/
@@ -2529,17 +2527,14 @@ class DartErrorsTask extends SourceBasedAnalysisTask {
createTask, buildInputs, <ResultDescriptor>[DART_ERRORS]);
/**
- * The name of the [LINE_INFO_INPUT] input.
+ * The name of the [IGNORE_INFO_INPUT] input.
*/
- static const String LINE_INFO_INPUT = 'LINE_INFO_INPUT';
+ static const String IGNORE_INFO_INPUT = 'IGNORE_INFO_INPUT';
/**
- * The name of the [PARSED_UNIT_INPUT] input.
+ * The name of the [LINE_INFO_INPUT] input.
*/
- static const String PARSED_UNIT_INPUT = 'PARSED_UNIT_INPUT';
-
- // Prefix for comments ignoring error codes.
- static const String _normalizedIgnorePrefix = '//ignore:';
+ static const String LINE_INFO_INPUT = 'LINE_INFO_INPUT';
DartErrorsTask(InternalAnalysisContext context, AnalysisTarget target)
: super(context, target);
@@ -2584,71 +2579,29 @@ class DartErrorsTask extends SourceBasedAnalysisTask {
outputs[DART_ERRORS] = errors;
}
- Token _advanceToLine(Token token, LineInfo lineInfo, int line) {
- int offset = lineInfo.getOffsetOfLine(line - 1); // 0-based
- while (token.offset < offset) {
- token = token.next;
- }
- return token;
- }
-
List<AnalysisError> _filterIgnores(List<AnalysisError> errors) {
if (errors.isEmpty) {
return errors;
}
- // Sort errors.
- errors.sort((AnalysisError e1, AnalysisError e2) => e1.offset - e2.offset);
+ IgnoreInfo ignoreInfo = getRequiredInput(IGNORE_INFO_INPUT);
+ if (!ignoreInfo.hasIgnores) {
+ return errors;
+ }
- CompilationUnit cu = getRequiredInput(PARSED_UNIT_INPUT);
- Token token = cu.beginToken;
LineInfo lineInfo = getRequiredInput(LINE_INFO_INPUT);
bool isIgnored(AnalysisError error) {
int errorLine = lineInfo.getLocation(error.offset).lineNumber;
- token = _advanceToLine(token, lineInfo, errorLine);
-
- //Check for leading comment.
- Token comments = token.precedingComments;
- while (comments?.next != null) {
- comments = comments.next;
- }
- if (_isIgnoredBy(error, comments)) {
- return true;
- }
-
- //Check for trailing comment.
- int lineNumber = errorLine + 1;
- if (lineNumber <= lineInfo.lineCount) {
- Token nextLine = _advanceToLine(token, lineInfo, lineNumber);
- comments = nextLine.precedingComments;
- if (comments != null && nextLine.previous.type != TokenType.EOF) {
- int commentLine = lineInfo.getLocation(comments.offset).lineNumber;
- if (commentLine == errorLine) {
- return _isIgnoredBy(error, comments);
- }
- }
- }
-
- return false;
+ 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 errors.where((AnalysisError e) => !isIgnored(e)).toList();
}
- bool _isIgnoredBy(AnalysisError error, Token comment) {
- //Normalize first.
- String contents =
- comment?.lexeme?.toLowerCase()?.replaceAll(spacesRegExp, '');
- if (contents == null || !contents.startsWith(_normalizedIgnorePrefix)) {
- return false;
- }
- return contents
- .substring(_normalizedIgnorePrefix.length)
- .split(',')
- .contains(error.errorCode.name.toLowerCase());
- }
-
/**
* Return a map from the names of the inputs of this kind of task to the task
* input descriptors describing those inputs for a task with the
@@ -2658,7 +2611,7 @@ class DartErrorsTask extends SourceBasedAnalysisTask {
Source source = target;
Map<String, TaskInput> inputs = <String, TaskInput>{};
inputs[LINE_INFO_INPUT] = LINE_INFO.of(source);
- inputs[PARSED_UNIT_INPUT] = PARSED_UNIT.of(source);
+ inputs[IGNORE_INFO_INPUT] = IGNORE_INFO.of(source);
EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin;
// for Source
List<ResultDescriptor> errorsForSource = enginePlugin.dartErrorsForSource;
@@ -5429,10 +5382,21 @@ class ScanDartTask extends SourceBasedAnalysisTask {
'ScanDartTask',
createTask,
buildInputs,
- <ResultDescriptor>[LINE_INFO, SCAN_ERRORS, TOKEN_STREAM],
+ <ResultDescriptor>[LINE_INFO, IGNORE_INFO, SCAN_ERRORS, TOKEN_STREAM],
scheglov 2016/05/27 18:05:47 We try to keep these sorted. IGNORE_INFO would be
pquitslund 2016/05/27 21:50:53 Done.
suitabilityFor: suitabilityFor);
/**
+ * A regular expression for matching 'ignore' comments. Produces matches
+ * containing 3 groups. For example:
+ *
+ * * ['//ignore: error_code', '//ignore:', 'error_code']
+ *
+ * Resulting codes may be in a list ('error_code_1,error_code2').
+ */
+ static final RegExp _IGNORE_MATCHER =
+ new RegExp(r'(//[ ]*ignore:)(.*)$', multiLine: true);
scheglov 2016/05/27 18:05:47 Do we use the (//ignore:) group? I don't know whet
pquitslund 2016/05/27 21:50:53 Ah! Yea. Great catch. No need for that first gr
+
+ /**
* Initialize a newly created task to access the content of the source
* associated with the given [target] in the given [context].
*/
@@ -5482,8 +5446,11 @@ class ScanDartTask extends SourceBasedAnalysisTask {
scanner.preserveComments = context.analysisOptions.preserveComments;
scanner.scanGenericMethodComments = context.analysisOptions.strongMode;
+ LineInfo lineInfo = new LineInfo(scanner.lineStarts);
+
outputs[TOKEN_STREAM] = scanner.tokenize();
- outputs[LINE_INFO] = new LineInfo(scanner.lineStarts);
+ outputs[LINE_INFO] = lineInfo;
+ outputs[IGNORE_INFO] = calculateIgnores(fragment.content, lineInfo);
outputs[SCAN_ERRORS] = getUniqueErrors(errorListener.errors);
} else if (target is Source) {
String content = getRequiredInput(CONTENT_INPUT_NAME);
@@ -5493,8 +5460,11 @@ class ScanDartTask extends SourceBasedAnalysisTask {
scanner.preserveComments = context.analysisOptions.preserveComments;
scanner.scanGenericMethodComments = context.analysisOptions.strongMode;
+ LineInfo lineInfo = new LineInfo(scanner.lineStarts);
+
outputs[TOKEN_STREAM] = scanner.tokenize();
- outputs[LINE_INFO] = new LineInfo(scanner.lineStarts);
+ outputs[LINE_INFO] = lineInfo;
+ outputs[IGNORE_INFO] = calculateIgnores(content, lineInfo);
outputs[SCAN_ERRORS] = getUniqueErrors(errorListener.errors);
} else {
throw new AnalysisException(
@@ -5528,6 +5498,23 @@ class ScanDartTask extends SourceBasedAnalysisTask {
}
/**
+ * Calculate ignores for the given [content] with line [info].
+ */
+ static IgnoreInfo calculateIgnores(String content, LineInfo info) {
Brian Wilkerson 2016/05/27 18:21:18 This could be a static method on IgnoreInfo.
pquitslund 2016/05/27 21:50:53 Done.
+ IgnoreInfo ignoreInfo = new IgnoreInfo();
+ for (Match match in _IGNORE_MATCHER.allMatches(content)) {
+ // Matches contain 3 groups:
+ // ['//ignore: error_code', '//ignore:', 'error_code']
+ // And resulting codes may be in a list.
+ List<String> codes = match.group(2).split(',');
+ for (String code in codes) {
+ ignoreInfo.add(info.getLocation(match.start).lineNumber, code.trim());
Brian Wilkerson 2016/05/27 18:21:18 It would be more efficient to define LineInfo.addA
pquitslund 2016/05/27 21:50:53 Done.
+ }
+ }
+ return ignoreInfo;
Brian Wilkerson 2016/05/27 18:21:18 For memory efficiency, it would be good to use a s
pquitslund 2016/05/27 21:50:53 Good idea. Done
+ }
+
+ /**
* Create a [ScanDartTask] based on the given [target] in the given [context].
*/
static ScanDartTask createTask(

Powered by Google App Engine
This is Rietveld 408576698