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_cli.src.analyzer_impl; | 5 library analyzer_cli.src.analyzer_impl; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 import 'dart:io'; | 9 import 'dart:io'; |
| 10 | 10 |
| 11 import 'package:analyzer/dart/element/element.dart'; | 11 import 'package:analyzer/dart/element/element.dart'; |
| 12 import 'package:analyzer/error/error.dart'; | 12 import 'package:analyzer/error/error.dart'; |
| 13 import 'package:analyzer/exception/exception.dart'; | 13 import 'package:analyzer/exception/exception.dart'; |
| 14 import 'package:analyzer/source/error_processor.dart'; | |
| 15 import 'package:analyzer/src/dart/analysis/driver.dart'; | 14 import 'package:analyzer/src/dart/analysis/driver.dart'; |
| 16 import 'package:analyzer/src/error/codes.dart'; | |
| 17 import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult; | 15 import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult; |
| 18 import 'package:analyzer/src/generated/java_io.dart'; | 16 import 'package:analyzer/src/generated/java_io.dart'; |
| 19 import 'package:analyzer/src/generated/source.dart'; | 17 import 'package:analyzer/src/generated/source.dart'; |
| 20 import 'package:analyzer/src/generated/source_io.dart'; | 18 import 'package:analyzer/src/generated/source_io.dart'; |
| 21 import 'package:analyzer/src/generated/utilities_general.dart'; | 19 import 'package:analyzer/src/generated/utilities_general.dart'; |
| 22 import 'package:analyzer_cli/src/driver.dart'; | 20 import 'package:path/path.dart' as path; |
| 23 import 'package:analyzer_cli/src/error_formatter.dart'; | |
| 24 import 'package:analyzer_cli/src/options.dart'; | |
| 25 import 'package:path/path.dart' as pathos; | |
| 26 | 21 |
| 27 /// The maximum number of sources for which AST structures should be kept in the cache. | 22 import 'driver.dart'; |
| 28 const int _maxCacheSize = 512; | 23 import 'error_formatter.dart'; |
| 24 import 'error_severity.dart'; | |
| 25 import 'options.dart'; | |
|
Brian Wilkerson
2017/02/19 22:52:17
Import directives inside a package that reference
devoncarew
2017/02/21 04:30:47
That's true for things outside of 'lib' (like tool
| |
| 29 | 26 |
| 30 int currentTimeMillis() => new DateTime.now().millisecondsSinceEpoch; | 27 int get currentTimeMillis => new DateTime.now().millisecondsSinceEpoch; |
| 31 | 28 |
| 32 /// Analyzes single library [File]. | 29 /// Analyzes single library [File]. |
| 33 class AnalyzerImpl { | 30 class AnalyzerImpl { |
| 34 static final PerformanceTag _prepareErrorsTag = | 31 static final PerformanceTag _prepareErrorsTag = |
| 35 new PerformanceTag("AnalyzerImpl.prepareErrors"); | 32 new PerformanceTag("AnalyzerImpl.prepareErrors"); |
| 36 static final PerformanceTag _resolveLibraryTag = | 33 static final PerformanceTag _resolveLibraryTag = |
| 37 new PerformanceTag("AnalyzerImpl._resolveLibrary"); | 34 new PerformanceTag("AnalyzerImpl._resolveLibrary"); |
| 38 | 35 |
| 39 final CommandLineOptions options; | 36 final CommandLineOptions options; |
| 40 final int startTime; | 37 final int startTime; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 110 for (LibraryElement child in library.importedLibraries) { | 107 for (LibraryElement child in library.importedLibraries) { |
| 111 addLibrarySources(child, libraries, units); | 108 addLibrarySources(child, libraries, units); |
| 112 } | 109 } |
| 113 for (LibraryElement child in library.exportedLibraries) { | 110 for (LibraryElement child in library.exportedLibraries) { |
| 114 addLibrarySources(child, libraries, units); | 111 addLibrarySources(child, libraries, units); |
| 115 } | 112 } |
| 116 } | 113 } |
| 117 | 114 |
| 118 /// Treats the [sourcePath] as the top level library and analyzes it using | 115 /// Treats the [sourcePath] as the top level library and analyzes it using |
| 119 /// the analysis engine. If [printMode] is `0`, then no error or performance | 116 /// the analysis engine. If [printMode] is `0`, then no error or performance |
| 120 /// information is printed. If [printMode] is `1`, then both will be printed. | 117 /// information is printed. If [printMode] is `1`, then errors will be printed . |
| 121 /// If [printMode] is `2`, then only performance information will be printed, | 118 /// If [printMode] is `2`, then performance information will be printed, and |
| 122 /// and it will be marked as being for a cold VM. | 119 /// it will be marked as being for a cold VM. |
| 123 Future<ErrorSeverity> analyze({int printMode: 1}) async { | 120 Future<ErrorSeverity> analyze({int printMode: 1}) async { |
| 124 setupForAnalysis(); | 121 setupForAnalysis(); |
| 125 return await _analyze(printMode); | 122 return await _analyze(printMode); |
| 126 } | 123 } |
| 127 | 124 |
| 128 /// Fills [errorInfos] using [sources]. | 125 /// Fills [errorInfos] using [sources]. |
| 129 Future<Null> prepareErrors() async { | 126 Future<Null> prepareErrors() async { |
| 130 PerformanceTag previous = _prepareErrorsTag.makeCurrent(); | 127 PerformanceTag previous = _prepareErrorsTag.makeCurrent(); |
| 131 try { | 128 try { |
| 132 for (Source source in sources) { | 129 for (Source source in sources) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 220 return true; | 217 return true; |
| 221 } else if (!options.showPackageWarnings) { | 218 } else if (!options.showPackageWarnings) { |
| 222 return false; | 219 return false; |
| 223 } else if (options.showPackageWarningsPrefix == null) { | 220 } else if (options.showPackageWarningsPrefix == null) { |
| 224 return true; | 221 return true; |
| 225 } else { | 222 } else { |
| 226 return packageName.startsWith(options.showPackageWarningsPrefix); | 223 return packageName.startsWith(options.showPackageWarningsPrefix); |
| 227 } | 224 } |
| 228 } | 225 } |
| 229 | 226 |
| 230 _printColdPerf() { | 227 // TODO(devoncarew): This is never called. |
|
Brian Wilkerson
2017/02/19 22:52:17
Then it should be removed, unless someone knows of
| |
| 228 void _printColdPerf() { | |
| 231 // Print cold VM performance numbers. | 229 // Print cold VM performance numbers. |
| 232 int totalTime = currentTimeMillis() - startTime; | 230 int totalTime = currentTimeMillis - startTime; |
| 233 int otherTime = totalTime; | 231 int otherTime = totalTime; |
| 234 for (PerformanceTag tag in PerformanceTag.all) { | 232 for (PerformanceTag tag in PerformanceTag.all) { |
| 235 if (tag != PerformanceTag.UNKNOWN) { | 233 if (tag != PerformanceTag.UNKNOWN) { |
| 236 int tagTime = tag.elapsedMs; | 234 int tagTime = tag.elapsedMs; |
| 237 outSink.writeln('${tag.label}-cold:$tagTime'); | 235 outSink.writeln('${tag.label}-cold:$tagTime'); |
| 238 otherTime -= tagTime; | 236 otherTime -= tagTime; |
| 239 } | 237 } |
| 240 } | 238 } |
| 241 outSink.writeln('other-cold:$otherTime'); | 239 outSink.writeln('other-cold:$otherTime'); |
| 242 outSink.writeln("total-cold:$totalTime"); | 240 outSink.writeln("total-cold:$totalTime"); |
| 243 } | 241 } |
| 244 | 242 |
| 245 _printErrors() { | 243 void _printErrors() { |
| 246 // The following is a hack. We currently print out to stderr to ensure that | 244 // The following is a hack. We currently print out to stderr to ensure that |
| 247 // when in batch mode we print to stderr, this is because the prints from | 245 // when in batch mode we print to stderr, this is because the prints from |
| 248 // batch are made to stderr. The reason that options.shouldBatch isn't used | 246 // batch are made to stderr. The reason that options.shouldBatch isn't used |
| 249 // is because when the argument flags are constructed in BatchRunner and | 247 // is because when the argument flags are constructed in BatchRunner and |
| 250 // passed in from batch mode which removes the batch flag to prevent the | 248 // passed in from batch mode which removes the batch flag to prevent the |
| 251 // "cannot have the batch flag and source file" error message. | 249 // "cannot have the batch flag and source file" error message. |
| 252 StringSink sink = options.machineFormat ? errorSink : outSink; | 250 StringSink sink = options.machineFormat ? errorSink : outSink; |
| 253 | 251 |
| 254 // Print errors. | 252 // Print errors. |
| 255 ErrorFormatter formatter = | 253 ErrorFormatter formatter = |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 270 await analysisDriver.getUnitElement(path); | 268 await analysisDriver.getUnitElement(path); |
| 271 return elementResult.element.library; | 269 return elementResult.element.library; |
| 272 } else { | 270 } else { |
| 273 return context.computeLibraryElement(librarySource); | 271 return context.computeLibraryElement(librarySource); |
| 274 } | 272 } |
| 275 } finally { | 273 } finally { |
| 276 previous.makeCurrent(); | 274 previous.makeCurrent(); |
| 277 } | 275 } |
| 278 } | 276 } |
| 279 | 277 |
| 280 /// Compute the severity of the error; however: | |
| 281 /// * if [options.enableTypeChecks] is false, then de-escalate checked-mode | |
| 282 /// compile time errors to a severity of [ErrorSeverity.INFO]. | |
| 283 /// * if [options.hintsAreFatal] is true, escalate hints to errors. | |
| 284 /// * if [options.lintsAreFatal] is true, escalate lints to errors. | |
| 285 static ErrorSeverity computeSeverity( | |
| 286 AnalysisError error, CommandLineOptions options, | |
| 287 [AnalysisOptions analysisOptions]) { | |
| 288 if (analysisOptions != null) { | |
| 289 ErrorProcessor processor = | |
| 290 ErrorProcessor.getProcessor(analysisOptions, error); | |
| 291 // If there is a processor for this error, defer to it. | |
| 292 if (processor != null) { | |
| 293 return processor.severity; | |
| 294 } | |
| 295 } | |
| 296 | |
| 297 if (!options.enableTypeChecks && | |
| 298 error.errorCode.type == ErrorType.CHECKED_MODE_COMPILE_TIME_ERROR) { | |
| 299 return ErrorSeverity.INFO; | |
| 300 } else if (options.hintsAreFatal && error.errorCode is HintCode) { | |
| 301 return ErrorSeverity.ERROR; | |
| 302 } else if (options.lintsAreFatal && error.errorCode is LintCode) { | |
| 303 return ErrorSeverity.ERROR; | |
| 304 } | |
| 305 return error.errorCode.errorSeverity; | |
| 306 } | |
| 307 | |
| 308 /// Return the corresponding package directory or `null` if none is found. | 278 /// Return the corresponding package directory or `null` if none is found. |
| 309 static JavaFile getPackageDirectoryFor(JavaFile sourceFile) { | 279 static JavaFile getPackageDirectoryFor(JavaFile sourceFile) { |
| 310 // We are going to ask parent file, so get absolute path. | 280 // We are going to ask parent file, so get absolute path. |
| 311 sourceFile = sourceFile.getAbsoluteFile(); | 281 sourceFile = sourceFile.getAbsoluteFile(); |
| 312 // Look in the containing directories. | 282 // Look in the containing directories. |
| 313 JavaFile dir = sourceFile.getParentFile(); | 283 JavaFile dir = sourceFile.getParentFile(); |
| 314 while (dir != null) { | 284 while (dir != null) { |
| 315 JavaFile packagesDir = new JavaFile.relative(dir, "packages"); | 285 JavaFile packagesDir = new JavaFile.relative(dir, "packages"); |
| 316 if (packagesDir.exists()) { | 286 if (packagesDir.exists()) { |
| 317 return packagesDir; | 287 return packagesDir; |
| 318 } | 288 } |
| 319 dir = dir.getParentFile(); | 289 dir = dir.getParentFile(); |
| 320 } | 290 } |
| 321 // Not found. | 291 // Not found. |
| 322 return null; | 292 return null; |
| 323 } | 293 } |
| 324 | 294 |
| 325 /// Check various configuration options to get a desired severity for this | 295 /// Return `true` if the given [pathName] is in the Pub cache. |
| 326 /// [error] (or `null` if it's to be suppressed). | 296 static bool _isPathInPubCache(String pathName) { |
| 327 static ProcessedSeverity processError(AnalysisError error, | 297 List<String> parts = path.split(pathName); |
| 328 CommandLineOptions options, AnalysisOptions analysisOptions) { | |
| 329 ErrorSeverity severity = computeSeverity(error, options, analysisOptions); | |
| 330 bool isOverridden = false; | |
| 331 | |
| 332 // Skip TODOs categorically (unless escalated to ERROR or HINT.) | |
| 333 // https://github.com/dart-lang/sdk/issues/26215 | |
| 334 if (error.errorCode.type == ErrorType.TODO && | |
| 335 severity == ErrorSeverity.INFO) { | |
| 336 return null; | |
| 337 } | |
| 338 | |
| 339 // First check for a filter. | |
| 340 if (severity == null) { | |
| 341 // Null severity means the error has been explicitly ignored. | |
| 342 return null; | |
| 343 } else { | |
| 344 isOverridden = true; | |
| 345 } | |
| 346 | |
| 347 // If not overridden, some "natural" severities get globally filtered. | |
| 348 if (!isOverridden) { | |
| 349 // Check for global hint filtering. | |
| 350 if (severity == ErrorSeverity.INFO && options.disableHints) { | |
| 351 return null; | |
| 352 } | |
| 353 } | |
| 354 | |
| 355 return new ProcessedSeverity(severity, isOverridden); | |
| 356 } | |
| 357 | |
| 358 /// Return `true` if the given [path] is in the Pub cache. | |
| 359 static bool _isPathInPubCache(String path) { | |
| 360 List<String> parts = pathos.split(path); | |
| 361 if (parts.contains('.pub-cache')) { | 298 if (parts.contains('.pub-cache')) { |
| 362 return true; | 299 return true; |
| 363 } | 300 } |
| 364 for (int i = 0; i < parts.length - 2; i++) { | 301 for (int i = 0; i < parts.length - 2; i++) { |
| 365 if (parts[i] == 'Pub' && parts[i + 1] == 'Cache') { | 302 if (parts[i] == 'Pub' && parts[i + 1] == 'Cache') { |
| 366 return true; | 303 return true; |
| 367 } | 304 } |
| 368 } | 305 } |
| 369 return false; | 306 return false; |
| 370 } | 307 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 384 } | 321 } |
| 385 | 322 |
| 386 @override | 323 @override |
| 387 void logInformation(String message, [CaughtException exception]) { | 324 void logInformation(String message, [CaughtException exception]) { |
| 388 outSink.writeln(message); | 325 outSink.writeln(message); |
| 389 if (exception != null) { | 326 if (exception != null) { |
| 390 outSink.writeln(exception); | 327 outSink.writeln(exception); |
| 391 } | 328 } |
| 392 } | 329 } |
| 393 } | 330 } |
| OLD | NEW |