Chromium Code Reviews| 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 25869790caff6a02573857541e5d2e9e348341db..467bac3c9e0f212cb9f1f684ee52787d5e6f4a4b 100644 |
| --- a/pkg/analyzer/lib/src/task/dart.dart |
| +++ b/pkg/analyzer/lib/src/task/dart.dart |
| @@ -7,6 +7,7 @@ library analyzer.src.task.dart; |
| import 'dart:collection'; |
| import 'package:analyzer/dart/ast/ast.dart'; |
| +import 'package:analyzer/dart/ast/token.dart'; |
| import 'package:analyzer/dart/ast/visitor.dart'; |
| import 'package:analyzer/dart/element/element.dart'; |
| import 'package:analyzer/dart/element/type.dart'; |
| @@ -15,6 +16,8 @@ import 'package:analyzer/src/context/context.dart'; |
| import 'package:analyzer/src/dart/ast/utilities.dart'; |
| import 'package:analyzer/src/dart/element/builder.dart'; |
| import 'package:analyzer/src/dart/element/element.dart'; |
| +import 'package:analyzer/src/dart/scanner/reader.dart'; |
| +import 'package:analyzer/src/dart/scanner/scanner.dart'; |
| import 'package:analyzer/src/generated/constant.dart'; |
| import 'package:analyzer/src/generated/engine.dart'; |
| import 'package:analyzer/src/generated/error.dart'; |
| @@ -23,11 +26,9 @@ import 'package:analyzer/src/generated/incremental_resolver.dart'; |
| import 'package:analyzer/src/generated/java_engine.dart'; |
| import 'package:analyzer/src/generated/parser.dart'; |
| import 'package:analyzer/src/generated/resolver.dart'; |
| -import 'package:analyzer/dart/ast/token.dart'; |
| -import 'package:analyzer/src/dart/scanner/scanner.dart'; |
| -import 'package:analyzer/src/dart/scanner/reader.dart'; |
| import 'package:analyzer/src/generated/sdk.dart'; |
| import 'package:analyzer/src/generated/source.dart'; |
| +import 'package:analyzer/src/generated/utilities_dart.dart'; |
| import 'package:analyzer/src/generated/visitors.dart'; |
| import 'package:analyzer/src/plugin/engine_plugin.dart'; |
| import 'package:analyzer/src/services/lint.dart'; |
| @@ -41,7 +42,6 @@ import 'package:analyzer/src/task/strong_mode.dart'; |
| import 'package:analyzer/task/dart.dart'; |
| import 'package:analyzer/task/general.dart'; |
| import 'package:analyzer/task/model.dart'; |
| -import 'package:analyzer/src/generated/utilities_dart.dart'; |
| /** |
| * The [ResultCachingPolicy] for ASTs. |
| @@ -2224,6 +2224,9 @@ class DartErrorsTask extends SourceBasedAnalysisTask { |
| static final TaskDescriptor DESCRIPTOR = new TaskDescriptor('DartErrorsTask', |
| createTask, buildInputs, <ResultDescriptor>[DART_ERRORS]); |
| + // Prefix for comments ignoring error codes. |
| + static const String _normaledIgnorePrefix = '//#ignore:'; |
|
Brian Wilkerson
2016/02/16 21:39:05
"normaled"?!? :-) Did you mean "normalized"?
pquitslund
2016/02/16 21:51:42
:)
Done.
|
| + |
| DartErrorsTask(InternalAnalysisContext context, AnalysisTarget target) |
| : super(context, target); |
| @@ -2248,12 +2251,93 @@ class DartErrorsTask extends SourceBasedAnalysisTask { |
| errorLists.add(errors); |
| } |
| } |
| + |
| + // |
| + // Filter ignored errors. |
| + // |
| + List<AnalysisError> errors = |
| + _filterIgnores(AnalysisError.mergeLists(errorLists)); |
| + |
| // |
| // Record outputs. |
| // |
| - outputs[DART_ERRORS] = AnalysisError.mergeLists(errorLists); |
| + outputs[DART_ERRORS] = errors; |
| } |
| + List<AnalysisError> _filterIgnores(List<AnalysisError> errors) { |
| + if (errors.isEmpty) { |
| + return errors; |
| + } |
| + |
| + List<AnalysisError> filtered = <AnalysisError>[]; |
| + |
| + // Sort errors. |
| + errors.sort((AnalysisError e1, AnalysisError e2) => e1.offset - e2.offset); |
| + |
| + Source source = target; |
| + String contents = context.getContents(source).data; |
| + Scanner scanner = new Scanner(source, new CharSequenceReader(contents), |
| + AnalysisErrorListener.NULL_LISTENER); |
| + |
| + // Scan. |
| + Token token = scanner.tokenize(); |
| + LineInfo lineInfo = new LineInfo(scanner.lineStarts); |
|
Brian Wilkerson
2016/02/16 21:39:05
Ah! I didn't realize when I looked at this before
pquitslund
2016/02/16 21:51:42
Ah! This is great. I'll follow-up with a CL to r
|
| + |
| + int errorIndex = 0; |
| + |
| + // Step through tokens looking for comments. |
| + while (errorIndex < errors.length && token.type != TokenType.EOF) { |
| + // Find leading comment. |
| + Token comments = token.precedingComments; |
| + while (comments?.next != null) { |
| + comments = comments.next; |
| + } |
| + |
| + // Normalize content. |
| + String comment = |
| + comments?.lexeme?.toLowerCase()?.replaceAll(new RegExp(r'\s+'), ''); |
| + |
| + // Check for ignores. |
| + if (comment != null && comment.startsWith(_normaledIgnorePrefix)) { |
| + int affectedLine = lineInfo.getLocation(token.offset).lineNumber; |
| + |
| + // Process all affected errors. |
| + while (errorIndex < errors.length) { |
| + AnalysisError currentError = errors[errorIndex++]; |
| + int errorLine = lineInfo.getLocation(currentError.offset).lineNumber; |
| + if (errorLine < affectedLine) { |
| + filtered.add(currentError); |
| + } else if (errorLine == affectedLine) { |
| + // Check for an ignore. |
| + if (_isIgnoredBy(currentError, comment)) { |
| + // Skip! |
| + } else { |
| + filtered.add(currentError); |
|
Brian Wilkerson
2016/02/16 21:39:05
Or just reverse the condition and put this in the
pquitslund
2016/02/16 21:51:42
Done.
|
| + } |
| + } else { |
| + // Back up index and break. |
| + --errorIndex; |
| + break; |
| + } |
| + } |
| + } |
| + |
| + token = token.next; |
| + } |
| + |
| + // Add remaining errors. |
| + if (errorIndex < errors.length) { |
| + filtered.addAll(errors.sublist(errorIndex)); |
| + } |
| + |
| + return filtered; |
| + } |
| + |
| + bool _isIgnoredBy(AnalysisError error, String comment) => comment |
| + .substring(_normaledIgnorePrefix.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 |