| 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:collection'; | 8 import 'dart:collection'; | 
| 8 import 'dart:io'; | 9 import 'dart:io'; | 
| 9 | 10 | 
| 10 import 'package:analyzer/dart/element/element.dart'; | 11 import 'package:analyzer/dart/element/element.dart'; | 
| 11 import 'package:analyzer/error/error.dart'; | 12 import 'package:analyzer/error/error.dart'; | 
| 12 import 'package:analyzer/exception/exception.dart'; | 13 import 'package:analyzer/exception/exception.dart'; | 
| 13 import 'package:analyzer/source/error_processor.dart'; | 14 import 'package:analyzer/source/error_processor.dart'; | 
| 14 import 'package:analyzer/src/error/codes.dart'; | 15 import 'package:analyzer/src/error/codes.dart'; | 
| 15 import 'package:analyzer/src/generated/engine.dart'; | 16 import 'package:analyzer/src/generated/engine.dart'; | 
| 16 import 'package:analyzer/src/generated/java_io.dart'; | 17 import 'package:analyzer/src/generated/java_io.dart'; | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 30 /// Analyzes single library [File]. | 31 /// Analyzes single library [File]. | 
| 31 class AnalyzerImpl { | 32 class AnalyzerImpl { | 
| 32   static final PerformanceTag _prepareErrorsTag = | 33   static final PerformanceTag _prepareErrorsTag = | 
| 33       new PerformanceTag("AnalyzerImpl.prepareErrors"); | 34       new PerformanceTag("AnalyzerImpl.prepareErrors"); | 
| 34   static final PerformanceTag _resolveLibraryTag = | 35   static final PerformanceTag _resolveLibraryTag = | 
| 35       new PerformanceTag("AnalyzerImpl._resolveLibrary"); | 36       new PerformanceTag("AnalyzerImpl._resolveLibrary"); | 
| 36 | 37 | 
| 37   final CommandLineOptions options; | 38   final CommandLineOptions options; | 
| 38   final int startTime; | 39   final int startTime; | 
| 39 | 40 | 
|  | 41   final AnalysisOptions analysisOptions; | 
| 40   final AnalysisContext context; | 42   final AnalysisContext context; | 
| 41 | 43 | 
| 42   /// Accumulated analysis statistics. | 44   /// Accumulated analysis statistics. | 
| 43   final AnalysisStats stats; | 45   final AnalysisStats stats; | 
| 44 | 46 | 
| 45   final Source librarySource; | 47   final Source librarySource; | 
| 46 | 48 | 
| 47   /// All [Source]s references by the analyzed library. | 49   /// All [Source]s references by the analyzed library. | 
| 48   final Set<Source> sources = new Set<Source>(); | 50   final Set<Source> sources = new Set<Source>(); | 
| 49 | 51 | 
| 50   /// All [AnalysisErrorInfo]s in the analyzed library. | 52   /// All [AnalysisErrorInfo]s in the analyzed library. | 
| 51   final List<AnalysisErrorInfo> errorInfos = new List<AnalysisErrorInfo>(); | 53   final List<AnalysisErrorInfo> errorInfos = new List<AnalysisErrorInfo>(); | 
| 52 | 54 | 
| 53   /// [HashMap] between sources and analysis error infos. | 55   /// [HashMap] between sources and analysis error infos. | 
| 54   final HashMap<Source, AnalysisErrorInfo> sourceErrorsMap = | 56   final HashMap<Source, AnalysisErrorInfo> sourceErrorsMap = | 
| 55       new HashMap<Source, AnalysisErrorInfo>(); | 57       new HashMap<Source, AnalysisErrorInfo>(); | 
| 56 | 58 | 
| 57   /// If the file specified on the command line is part of a package, the name | 59   /// If the file specified on the command line is part of a package, the name | 
| 58   /// of that package.  Otherwise `null`.  This allows us to analyze the file | 60   /// of that package.  Otherwise `null`.  This allows us to analyze the file | 
| 59   /// specified on the command line as though it is reached via a "package:" | 61   /// specified on the command line as though it is reached via a "package:" | 
| 60   /// URI, but avoid suppressing its output in the event that the user has not | 62   /// URI, but avoid suppressing its output in the event that the user has not | 
| 61   /// specified the "--package-warnings" option. | 63   /// specified the "--package-warnings" option. | 
| 62   String _selfPackageName; | 64   String _selfPackageName; | 
| 63 | 65 | 
| 64   AnalyzerImpl(this.context, this.librarySource, this.options, this.stats, | 66   AnalyzerImpl(this.analysisOptions, this.context, this.librarySource, | 
| 65       this.startTime); | 67       this.options, this.stats, this.startTime); | 
| 66 | 68 | 
| 67   /// Returns the maximal [ErrorSeverity] of the recorded errors. | 69   /// Returns the maximal [ErrorSeverity] of the recorded errors. | 
| 68   ErrorSeverity get maxErrorSeverity { | 70   ErrorSeverity get maxErrorSeverity { | 
| 69     var status = ErrorSeverity.NONE; | 71     var status = ErrorSeverity.NONE; | 
| 70     for (AnalysisErrorInfo errorInfo in errorInfos) { | 72     for (AnalysisErrorInfo errorInfo in errorInfos) { | 
| 71       for (AnalysisError error in errorInfo.errors) { | 73       for (AnalysisError error in errorInfo.errors) { | 
| 72         if (_processError(error) == null) { | 74         if (_processError(error) == null) { | 
| 73           continue; | 75           continue; | 
| 74         } | 76         } | 
| 75         var severity = computeSeverity(error, options); | 77         var severity = computeSeverity(error, options); | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 104     } | 106     } | 
| 105     // Add referenced libraries. | 107     // Add referenced libraries. | 
| 106     for (LibraryElement child in library.importedLibraries) { | 108     for (LibraryElement child in library.importedLibraries) { | 
| 107       addLibrarySources(child, libraries, units); | 109       addLibrarySources(child, libraries, units); | 
| 108     } | 110     } | 
| 109     for (LibraryElement child in library.exportedLibraries) { | 111     for (LibraryElement child in library.exportedLibraries) { | 
| 110       addLibrarySources(child, libraries, units); | 112       addLibrarySources(child, libraries, units); | 
| 111     } | 113     } | 
| 112   } | 114   } | 
| 113 | 115 | 
| 114   /// Treats the [sourcePath] as the top level library and analyzes it using a | 116   /// Treats the [sourcePath] as the top level library and analyzes it using | 
| 115   /// synchronous algorithm over the analysis engine. If [printMode] is `0`, | 117   /// the analysis engine. If [printMode] is `0`, then no error or performance | 
| 116   /// then no error or performance information is printed. If [printMode] is `1`
     , | 118   /// information is printed. If [printMode] is `1`, then both will be printed. | 
| 117   /// then both will be printed. If [printMode] is `2`, then only performance | 119   /// If [printMode] is `2`, then only performance information will be printed, | 
| 118   /// information will be printed, and it will be marked as being for a cold VM. | 120   /// and it will be marked as being for a cold VM. | 
| 119   ErrorSeverity analyzeSync({int printMode: 1}) { | 121   Future<ErrorSeverity> analyze({int printMode: 1}) async { | 
| 120     setupForAnalysis(); | 122     setupForAnalysis(); | 
| 121     return _analyzeSync(printMode); | 123     return await _analyze(printMode); | 
| 122   } | 124   } | 
| 123 | 125 | 
| 124   /// Fills [errorInfos] using [sources]. | 126   /// Fills [errorInfos] using [sources]. | 
| 125   void prepareErrors() { | 127   Future<Null> prepareErrors() async { | 
| 126     return _prepareErrorsTag.makeCurrentWhile(() { | 128     PerformanceTag previous = _prepareErrorsTag.makeCurrent(); | 
|  | 129     try { | 
| 127       for (Source source in sources) { | 130       for (Source source in sources) { | 
| 128         context.computeErrors(source); | 131         context.computeErrors(source); | 
| 129         errorInfos.add(context.getErrors(source)); | 132         errorInfos.add(context.getErrors(source)); | 
| 130       } | 133       } | 
| 131     }); | 134     } finally { | 
|  | 135       previous.makeCurrent(); | 
|  | 136     } | 
| 132   } | 137   } | 
| 133 | 138 | 
| 134   /// Fills [sources]. | 139   /// Fills [sources]. | 
| 135   void prepareSources(LibraryElement library) { | 140   void prepareSources(LibraryElement library) { | 
| 136     var units = new Set<CompilationUnitElement>(); | 141     var units = new Set<CompilationUnitElement>(); | 
| 137     var libraries = new Set<LibraryElement>(); | 142     var libraries = new Set<LibraryElement>(); | 
| 138     addLibrarySources(library, libraries, units); | 143     addLibrarySources(library, libraries, units); | 
| 139   } | 144   } | 
| 140 | 145 | 
| 141   /// Setup local fields such as the analysis context for analysis. | 146   /// Setup local fields such as the analysis context for analysis. | 
| 142   void setupForAnalysis() { | 147   void setupForAnalysis() { | 
| 143     sources.clear(); | 148     sources.clear(); | 
| 144     errorInfos.clear(); | 149     errorInfos.clear(); | 
| 145     Uri libraryUri = librarySource.uri; | 150     Uri libraryUri = librarySource.uri; | 
| 146     if (libraryUri.scheme == 'package' && libraryUri.pathSegments.length > 0) { | 151     if (libraryUri.scheme == 'package' && libraryUri.pathSegments.length > 0) { | 
| 147       _selfPackageName = libraryUri.pathSegments[0]; | 152       _selfPackageName = libraryUri.pathSegments[0]; | 
| 148     } | 153     } | 
| 149   } | 154   } | 
| 150 | 155 | 
| 151   /// The sync version of analysis. | 156   Future<ErrorSeverity> _analyze(int printMode) async { | 
| 152   ErrorSeverity _analyzeSync(int printMode) { |  | 
| 153     // Don't try to analyze parts. | 157     // Don't try to analyze parts. | 
| 154     if (context.computeKindOf(librarySource) == SourceKind.PART) { | 158     if (context.computeKindOf(librarySource) == SourceKind.PART) { | 
| 155       stderr.writeln("Only libraries can be analyzed."); | 159       stderr.writeln("Only libraries can be analyzed."); | 
| 156       stderr.writeln( | 160       stderr.writeln( | 
| 157           "${librarySource.fullName} is a part and can not be analyzed."); | 161           "${librarySource.fullName} is a part and can not be analyzed."); | 
| 158       return ErrorSeverity.ERROR; | 162       return ErrorSeverity.ERROR; | 
| 159     } | 163     } | 
| 160     var libraryElement = _resolveLibrary(); | 164     LibraryElement libraryElement = await _resolveLibrary(); | 
| 161     prepareSources(libraryElement); | 165     prepareSources(libraryElement); | 
| 162     prepareErrors(); | 166     await prepareErrors(); | 
| 163 | 167 | 
| 164     // Print errors and performance numbers. | 168     // Print errors and performance numbers. | 
| 165     if (printMode == 1) { | 169     if (printMode == 1) { | 
| 166       _printErrors(); | 170       _printErrors(); | 
| 167     } else if (printMode == 2) { | 171     } else if (printMode == 2) { | 
| 168       _printColdPerf(); | 172       _printColdPerf(); | 
| 169     } | 173     } | 
| 170 | 174 | 
| 171     // Compute max severity and set exitCode. | 175     // Compute max severity and set exitCode. | 
| 172     ErrorSeverity status = maxErrorSeverity; | 176     ErrorSeverity status = maxErrorSeverity; | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 233     // "cannot have the batch flag and source file" error message. | 237     // "cannot have the batch flag and source file" error message. | 
| 234     StringSink sink = options.machineFormat ? errorSink : outSink; | 238     StringSink sink = options.machineFormat ? errorSink : outSink; | 
| 235 | 239 | 
| 236     // Print errors. | 240     // Print errors. | 
| 237     ErrorFormatter formatter = | 241     ErrorFormatter formatter = | 
| 238         new ErrorFormatter(sink, options, stats, _processError); | 242         new ErrorFormatter(sink, options, stats, _processError); | 
| 239     formatter.formatErrors(errorInfos); | 243     formatter.formatErrors(errorInfos); | 
| 240   } | 244   } | 
| 241 | 245 | 
| 242   ProcessedSeverity _processError(AnalysisError error) => | 246   ProcessedSeverity _processError(AnalysisError error) => | 
| 243       processError(error, options, context); | 247       processError(error, options, analysisOptions); | 
| 244 | 248 | 
| 245   LibraryElement _resolveLibrary() { | 249   Future<LibraryElement> _resolveLibrary() async { | 
| 246     return _resolveLibraryTag.makeCurrentWhile(() { | 250     PerformanceTag previous = _resolveLibraryTag.makeCurrent(); | 
|  | 251     try { | 
| 247       return context.computeLibraryElement(librarySource); | 252       return context.computeLibraryElement(librarySource); | 
| 248     }); | 253     } finally { | 
|  | 254       previous.makeCurrent(); | 
|  | 255     } | 
| 249   } | 256   } | 
| 250 | 257 | 
| 251   /// Compute the severity of the error; however: | 258   /// Compute the severity of the error; however: | 
| 252   ///   * if [options.enableTypeChecks] is false, then de-escalate checked-mode | 259   ///   * if [options.enableTypeChecks] is false, then de-escalate checked-mode | 
| 253   ///   compile time errors to a severity of [ErrorSeverity.INFO]. | 260   ///   compile time errors to a severity of [ErrorSeverity.INFO]. | 
| 254   ///   * if [options.hintsAreFatal] is true, escalate hints to errors. | 261   ///   * if [options.hintsAreFatal] is true, escalate hints to errors. | 
| 255   ///   * if [options.lintsAreFatal] is true, escalate lints to errors. | 262   ///   * if [options.lintsAreFatal] is true, escalate lints to errors. | 
| 256   static ErrorSeverity computeSeverity( | 263   static ErrorSeverity computeSeverity( | 
| 257       AnalysisError error, CommandLineOptions options, | 264       AnalysisError error, CommandLineOptions options, | 
| 258       [AnalysisContext context]) { | 265       [AnalysisOptions analysisOptions]) { | 
| 259     if (context != null) { | 266     if (analysisOptions != null) { | 
| 260       ErrorProcessor processor = | 267       ErrorProcessor processor = | 
| 261           ErrorProcessor.getProcessor(context.analysisOptions, error); | 268           ErrorProcessor.getProcessor(analysisOptions, error); | 
| 262       // If there is a processor for this error, defer to it. | 269       // If there is a processor for this error, defer to it. | 
| 263       if (processor != null) { | 270       if (processor != null) { | 
| 264         return processor.severity; | 271         return processor.severity; | 
| 265       } | 272       } | 
| 266     } | 273     } | 
| 267 | 274 | 
| 268     if (!options.enableTypeChecks && | 275     if (!options.enableTypeChecks && | 
| 269         error.errorCode.type == ErrorType.CHECKED_MODE_COMPILE_TIME_ERROR) { | 276         error.errorCode.type == ErrorType.CHECKED_MODE_COMPILE_TIME_ERROR) { | 
| 270       return ErrorSeverity.INFO; | 277       return ErrorSeverity.INFO; | 
| 271     } else if (options.hintsAreFatal && error.errorCode is HintCode) { | 278     } else if (options.hintsAreFatal && error.errorCode is HintCode) { | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 289       } | 296       } | 
| 290       dir = dir.getParentFile(); | 297       dir = dir.getParentFile(); | 
| 291     } | 298     } | 
| 292     // Not found. | 299     // Not found. | 
| 293     return null; | 300     return null; | 
| 294   } | 301   } | 
| 295 | 302 | 
| 296   /// Check various configuration options to get a desired severity for this | 303   /// Check various configuration options to get a desired severity for this | 
| 297   /// [error] (or `null` if it's to be suppressed). | 304   /// [error] (or `null` if it's to be suppressed). | 
| 298   static ProcessedSeverity processError(AnalysisError error, | 305   static ProcessedSeverity processError(AnalysisError error, | 
| 299       CommandLineOptions options, AnalysisContext context) { | 306       CommandLineOptions options, AnalysisOptions analysisOptions) { | 
| 300     ErrorSeverity severity = computeSeverity(error, options, context); | 307     ErrorSeverity severity = computeSeverity(error, options, analysisOptions); | 
| 301     bool isOverridden = false; | 308     bool isOverridden = false; | 
| 302 | 309 | 
| 303     // Skip TODOs categorically (unless escalated to ERROR or HINT.) | 310     // Skip TODOs categorically (unless escalated to ERROR or HINT.) | 
| 304     // https://github.com/dart-lang/sdk/issues/26215 | 311     // https://github.com/dart-lang/sdk/issues/26215 | 
| 305     if (error.errorCode.type == ErrorType.TODO && | 312     if (error.errorCode.type == ErrorType.TODO && | 
| 306         severity == ErrorSeverity.INFO) { | 313         severity == ErrorSeverity.INFO) { | 
| 307       return null; | 314       return null; | 
| 308     } | 315     } | 
| 309 | 316 | 
| 310     // First check for a filter. | 317     // First check for a filter. | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 355   } | 362   } | 
| 356 | 363 | 
| 357   @override | 364   @override | 
| 358   void logInformation(String message, [CaughtException exception]) { | 365   void logInformation(String message, [CaughtException exception]) { | 
| 359     outSink.writeln(message); | 366     outSink.writeln(message); | 
| 360     if (exception != null) { | 367     if (exception != null) { | 
| 361       outSink.writeln(exception); | 368       outSink.writeln(exception); | 
| 362     } | 369     } | 
| 363   } | 370   } | 
| 364 } | 371 } | 
| OLD | NEW | 
|---|