Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer.src.task.dart; | 5 library analyzer.src.task.dart; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart'; | |
| 10 import 'package:analyzer/dart/ast/visitor.dart'; | 11 import 'package:analyzer/dart/ast/visitor.dart'; |
| 11 import 'package:analyzer/dart/element/element.dart'; | 12 import 'package:analyzer/dart/element/element.dart'; |
| 12 import 'package:analyzer/dart/element/type.dart'; | 13 import 'package:analyzer/dart/element/type.dart'; |
| 13 import 'package:analyzer/src/context/cache.dart'; | 14 import 'package:analyzer/src/context/cache.dart'; |
| 14 import 'package:analyzer/src/context/context.dart'; | 15 import 'package:analyzer/src/context/context.dart'; |
| 15 import 'package:analyzer/src/dart/ast/utilities.dart'; | 16 import 'package:analyzer/src/dart/ast/utilities.dart'; |
| 16 import 'package:analyzer/src/dart/element/builder.dart'; | 17 import 'package:analyzer/src/dart/element/builder.dart'; |
| 17 import 'package:analyzer/src/dart/element/element.dart'; | 18 import 'package:analyzer/src/dart/element/element.dart'; |
| 19 import 'package:analyzer/src/dart/scanner/reader.dart'; | |
| 20 import 'package:analyzer/src/dart/scanner/scanner.dart'; | |
| 18 import 'package:analyzer/src/generated/constant.dart'; | 21 import 'package:analyzer/src/generated/constant.dart'; |
| 19 import 'package:analyzer/src/generated/engine.dart'; | 22 import 'package:analyzer/src/generated/engine.dart'; |
| 20 import 'package:analyzer/src/generated/error.dart'; | 23 import 'package:analyzer/src/generated/error.dart'; |
| 21 import 'package:analyzer/src/generated/error_verifier.dart'; | 24 import 'package:analyzer/src/generated/error_verifier.dart'; |
| 22 import 'package:analyzer/src/generated/incremental_resolver.dart'; | 25 import 'package:analyzer/src/generated/incremental_resolver.dart'; |
| 23 import 'package:analyzer/src/generated/java_engine.dart'; | 26 import 'package:analyzer/src/generated/java_engine.dart'; |
| 24 import 'package:analyzer/src/generated/parser.dart'; | 27 import 'package:analyzer/src/generated/parser.dart'; |
| 25 import 'package:analyzer/src/generated/resolver.dart'; | 28 import 'package:analyzer/src/generated/resolver.dart'; |
| 26 import 'package:analyzer/dart/ast/token.dart'; | |
| 27 import 'package:analyzer/src/dart/scanner/scanner.dart'; | |
| 28 import 'package:analyzer/src/dart/scanner/reader.dart'; | |
| 29 import 'package:analyzer/src/generated/sdk.dart'; | 29 import 'package:analyzer/src/generated/sdk.dart'; |
| 30 import 'package:analyzer/src/generated/source.dart'; | 30 import 'package:analyzer/src/generated/source.dart'; |
| 31 import 'package:analyzer/src/generated/utilities_dart.dart'; | |
| 31 import 'package:analyzer/src/generated/visitors.dart'; | 32 import 'package:analyzer/src/generated/visitors.dart'; |
| 32 import 'package:analyzer/src/plugin/engine_plugin.dart'; | 33 import 'package:analyzer/src/plugin/engine_plugin.dart'; |
| 33 import 'package:analyzer/src/services/lint.dart'; | 34 import 'package:analyzer/src/services/lint.dart'; |
| 34 import 'package:analyzer/src/task/driver.dart'; | 35 import 'package:analyzer/src/task/driver.dart'; |
| 35 import 'package:analyzer/src/task/general.dart'; | 36 import 'package:analyzer/src/task/general.dart'; |
| 36 import 'package:analyzer/src/task/html.dart'; | 37 import 'package:analyzer/src/task/html.dart'; |
| 37 import 'package:analyzer/src/task/inputs.dart'; | 38 import 'package:analyzer/src/task/inputs.dart'; |
| 38 import 'package:analyzer/src/task/model.dart'; | 39 import 'package:analyzer/src/task/model.dart'; |
| 39 import 'package:analyzer/src/task/strong/checker.dart'; | 40 import 'package:analyzer/src/task/strong/checker.dart'; |
| 40 import 'package:analyzer/src/task/strong_mode.dart'; | 41 import 'package:analyzer/src/task/strong_mode.dart'; |
| 41 import 'package:analyzer/task/dart.dart'; | 42 import 'package:analyzer/task/dart.dart'; |
| 42 import 'package:analyzer/task/general.dart'; | 43 import 'package:analyzer/task/general.dart'; |
| 43 import 'package:analyzer/task/model.dart'; | 44 import 'package:analyzer/task/model.dart'; |
| 44 import 'package:analyzer/src/generated/utilities_dart.dart'; | |
| 45 | 45 |
| 46 /** | 46 /** |
| 47 * The [ResultCachingPolicy] for ASTs. | 47 * The [ResultCachingPolicy] for ASTs. |
| 48 */ | 48 */ |
| 49 const ResultCachingPolicy AST_CACHING_POLICY = | 49 const ResultCachingPolicy AST_CACHING_POLICY = |
| 50 const SimpleResultCachingPolicy(8192, 8192); | 50 const SimpleResultCachingPolicy(8192, 8192); |
| 51 | 51 |
| 52 /** | 52 /** |
| 53 * The [ResultCachingPolicy] for [Element]s. | 53 * The [ResultCachingPolicy] for [Element]s. |
| 54 */ | 54 */ |
| (...skipping 2162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2217 * A task that merges all of the errors for a single source into a single list | 2217 * A task that merges all of the errors for a single source into a single list |
| 2218 * of errors. | 2218 * of errors. |
| 2219 */ | 2219 */ |
| 2220 class DartErrorsTask extends SourceBasedAnalysisTask { | 2220 class DartErrorsTask extends SourceBasedAnalysisTask { |
| 2221 /** | 2221 /** |
| 2222 * The task descriptor describing this kind of task. | 2222 * The task descriptor describing this kind of task. |
| 2223 */ | 2223 */ |
| 2224 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor('DartErrorsTask', | 2224 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor('DartErrorsTask', |
| 2225 createTask, buildInputs, <ResultDescriptor>[DART_ERRORS]); | 2225 createTask, buildInputs, <ResultDescriptor>[DART_ERRORS]); |
| 2226 | 2226 |
| 2227 // Prefix for comments ignoring error codes. | |
| 2228 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.
| |
| 2229 | |
| 2227 DartErrorsTask(InternalAnalysisContext context, AnalysisTarget target) | 2230 DartErrorsTask(InternalAnalysisContext context, AnalysisTarget target) |
| 2228 : super(context, target); | 2231 : super(context, target); |
| 2229 | 2232 |
| 2230 @override | 2233 @override |
| 2231 TaskDescriptor get descriptor => DESCRIPTOR; | 2234 TaskDescriptor get descriptor => DESCRIPTOR; |
| 2232 | 2235 |
| 2233 @override | 2236 @override |
| 2234 void internalPerform() { | 2237 void internalPerform() { |
| 2235 List<List<AnalysisError>> errorLists = <List<AnalysisError>>[]; | 2238 List<List<AnalysisError>> errorLists = <List<AnalysisError>>[]; |
| 2236 // | 2239 // |
| 2237 // Prepare inputs. | 2240 // Prepare inputs. |
| 2238 // | 2241 // |
| 2239 EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin; | 2242 EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin; |
| 2240 for (ResultDescriptor result in enginePlugin.dartErrorsForSource) { | 2243 for (ResultDescriptor result in enginePlugin.dartErrorsForSource) { |
| 2241 String inputName = result.name + '_input'; | 2244 String inputName = result.name + '_input'; |
| 2242 errorLists.add(getRequiredInput(inputName)); | 2245 errorLists.add(getRequiredInput(inputName)); |
| 2243 } | 2246 } |
| 2244 for (ResultDescriptor result in enginePlugin.dartErrorsForUnit) { | 2247 for (ResultDescriptor result in enginePlugin.dartErrorsForUnit) { |
| 2245 String inputName = result.name + '_input'; | 2248 String inputName = result.name + '_input'; |
| 2246 Map<Source, List<AnalysisError>> errorMap = getRequiredInput(inputName); | 2249 Map<Source, List<AnalysisError>> errorMap = getRequiredInput(inputName); |
| 2247 for (List<AnalysisError> errors in errorMap.values) { | 2250 for (List<AnalysisError> errors in errorMap.values) { |
| 2248 errorLists.add(errors); | 2251 errorLists.add(errors); |
| 2249 } | 2252 } |
| 2250 } | 2253 } |
| 2254 | |
| 2255 // | |
| 2256 // Filter ignored errors. | |
| 2257 // | |
| 2258 List<AnalysisError> errors = | |
| 2259 _filterIgnores(AnalysisError.mergeLists(errorLists)); | |
| 2260 | |
| 2251 // | 2261 // |
| 2252 // Record outputs. | 2262 // Record outputs. |
| 2253 // | 2263 // |
| 2254 outputs[DART_ERRORS] = AnalysisError.mergeLists(errorLists); | 2264 outputs[DART_ERRORS] = errors; |
| 2255 } | 2265 } |
| 2256 | 2266 |
| 2267 List<AnalysisError> _filterIgnores(List<AnalysisError> errors) { | |
| 2268 if (errors.isEmpty) { | |
| 2269 return errors; | |
| 2270 } | |
| 2271 | |
| 2272 List<AnalysisError> filtered = <AnalysisError>[]; | |
| 2273 | |
| 2274 // Sort errors. | |
| 2275 errors.sort((AnalysisError e1, AnalysisError e2) => e1.offset - e2.offset); | |
| 2276 | |
| 2277 Source source = target; | |
| 2278 String contents = context.getContents(source).data; | |
| 2279 Scanner scanner = new Scanner(source, new CharSequenceReader(contents), | |
| 2280 AnalysisErrorListener.NULL_LISTENER); | |
| 2281 | |
| 2282 // Scan. | |
| 2283 Token token = scanner.tokenize(); | |
| 2284 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
| |
| 2285 | |
| 2286 int errorIndex = 0; | |
| 2287 | |
| 2288 // Step through tokens looking for comments. | |
| 2289 while (errorIndex < errors.length && token.type != TokenType.EOF) { | |
| 2290 // Find leading comment. | |
| 2291 Token comments = token.precedingComments; | |
| 2292 while (comments?.next != null) { | |
| 2293 comments = comments.next; | |
| 2294 } | |
| 2295 | |
| 2296 // Normalize content. | |
| 2297 String comment = | |
| 2298 comments?.lexeme?.toLowerCase()?.replaceAll(new RegExp(r'\s+'), ''); | |
| 2299 | |
| 2300 // Check for ignores. | |
| 2301 if (comment != null && comment.startsWith(_normaledIgnorePrefix)) { | |
| 2302 int affectedLine = lineInfo.getLocation(token.offset).lineNumber; | |
| 2303 | |
| 2304 // Process all affected errors. | |
| 2305 while (errorIndex < errors.length) { | |
| 2306 AnalysisError currentError = errors[errorIndex++]; | |
| 2307 int errorLine = lineInfo.getLocation(currentError.offset).lineNumber; | |
| 2308 if (errorLine < affectedLine) { | |
| 2309 filtered.add(currentError); | |
| 2310 } else if (errorLine == affectedLine) { | |
| 2311 // Check for an ignore. | |
| 2312 if (_isIgnoredBy(currentError, comment)) { | |
| 2313 // Skip! | |
| 2314 } else { | |
| 2315 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.
| |
| 2316 } | |
| 2317 } else { | |
| 2318 // Back up index and break. | |
| 2319 --errorIndex; | |
| 2320 break; | |
| 2321 } | |
| 2322 } | |
| 2323 } | |
| 2324 | |
| 2325 token = token.next; | |
| 2326 } | |
| 2327 | |
| 2328 // Add remaining errors. | |
| 2329 if (errorIndex < errors.length) { | |
| 2330 filtered.addAll(errors.sublist(errorIndex)); | |
| 2331 } | |
| 2332 | |
| 2333 return filtered; | |
| 2334 } | |
| 2335 | |
| 2336 bool _isIgnoredBy(AnalysisError error, String comment) => comment | |
| 2337 .substring(_normaledIgnorePrefix.length) | |
| 2338 .split(',') | |
| 2339 .contains(error.errorCode.name.toLowerCase()); | |
| 2340 | |
| 2257 /** | 2341 /** |
| 2258 * Return a map from the names of the inputs of this kind of task to the task | 2342 * Return a map from the names of the inputs of this kind of task to the task |
| 2259 * input descriptors describing those inputs for a task with the | 2343 * input descriptors describing those inputs for a task with the |
| 2260 * given [target]. | 2344 * given [target]. |
| 2261 */ | 2345 */ |
| 2262 static Map<String, TaskInput> buildInputs(AnalysisTarget target) { | 2346 static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
| 2263 Source source = target; | 2347 Source source = target; |
| 2264 Map<String, TaskInput> inputs = <String, TaskInput>{}; | 2348 Map<String, TaskInput> inputs = <String, TaskInput>{}; |
| 2265 EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin; | 2349 EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin; |
| 2266 // for Source | 2350 // for Source |
| (...skipping 3025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5292 | 5376 |
| 5293 @override | 5377 @override |
| 5294 bool moveNext() { | 5378 bool moveNext() { |
| 5295 if (_newSources.isEmpty) { | 5379 if (_newSources.isEmpty) { |
| 5296 return false; | 5380 return false; |
| 5297 } | 5381 } |
| 5298 currentTarget = _newSources.removeLast(); | 5382 currentTarget = _newSources.removeLast(); |
| 5299 return true; | 5383 return true; |
| 5300 } | 5384 } |
| 5301 } | 5385 } |
| OLD | NEW |