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

Side by Side Diff: pkg/analyzer_cli/lib/src/analyzer_impl.dart

Issue 2659463003: Make analyzer_cli batch mode asynchronous. (Closed)
Patch Set: Created 3 years, 11 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 unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analyzer_cli/lib/src/build_mode.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer_cli/lib/src/build_mode.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698