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

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

Issue 1459683003: `analyzer_cli` move to SDK. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: master merge Created 5 years, 1 month 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 | « pkg/analyzer_cli/bin/analyzer.dart ('k') | pkg/analyzer_cli/lib/src/bootloader.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library analyzer_cli.src.analyzer_impl;
6
7 import 'dart:collection';
8 import 'dart:io';
9
10 import 'package:analyzer/src/generated/element.dart';
11 import 'package:analyzer/src/generated/engine.dart';
12 import 'package:analyzer/src/generated/error.dart';
13 import 'package:analyzer/src/generated/java_engine.dart';
14 import 'package:analyzer/src/generated/java_io.dart';
15 import 'package:analyzer/src/generated/sdk_io.dart';
16 import 'package:analyzer/src/generated/source.dart';
17 import 'package:analyzer/src/generated/source_io.dart';
18 import 'package:analyzer/src/generated/utilities_general.dart';
19 import 'package:analyzer_cli/src/driver.dart';
20 import 'package:analyzer_cli/src/error_formatter.dart';
21 import 'package:analyzer_cli/src/options.dart';
22
23 DirectoryBasedDartSdk sdk;
24
25 /// The maximum number of sources for which AST structures should be kept in the cache.
26 const int _maxCacheSize = 512;
27
28 int currentTimeMillis() => new DateTime.now().millisecondsSinceEpoch;
29
30 /// Analyzes single library [File].
31 class AnalyzerImpl {
32 final CommandLineOptions options;
33 final int startTime;
34
35 final AnalysisContext context;
36 final Source librarySource;
37
38 /// All [Source]s references by the analyzed library.
39 final Set<Source> sources = new Set<Source>();
40
41 /// All [AnalysisErrorInfo]s in the analyzed library.
42 final List<AnalysisErrorInfo> errorInfos = new List<AnalysisErrorInfo>();
43
44 /// [HashMap] between sources and analysis error infos.
45 final HashMap<Source, AnalysisErrorInfo> sourceErrorsMap =
46 new HashMap<Source, AnalysisErrorInfo>();
47
48 /// If the file specified on the command line is part of a package, the name
49 /// of that package. Otherwise `null`. This allows us to analyze the file
50 /// specified on the command line as though it is reached via a "package:"
51 /// URI, but avoid suppressing its output in the event that the user has not
52 /// specified the "--package-warnings" option.
53 String _selfPackageName;
54
55 AnalyzerImpl(this.context, this.librarySource, this.options, this.startTime);
56
57 /// Returns the maximal [ErrorSeverity] of the recorded errors.
58 ErrorSeverity get maxErrorSeverity {
59 var status = ErrorSeverity.NONE;
60 for (AnalysisErrorInfo errorInfo in errorInfos) {
61 for (AnalysisError error in errorInfo.errors) {
62 if (!_isDesiredError(error)) {
63 continue;
64 }
65 var severity = computeSeverity(error, options);
66 status = status.max(severity);
67 }
68 }
69 return status;
70 }
71
72 void addCompilationUnitSource(CompilationUnitElement unit,
73 Set<LibraryElement> libraries, Set<CompilationUnitElement> units) {
74 if (unit == null || units.contains(unit)) {
75 return;
76 }
77 units.add(unit);
78 sources.add(unit.source);
79 }
80
81 void addLibrarySources(LibraryElement library, Set<LibraryElement> libraries,
82 Set<CompilationUnitElement> units) {
83 if (library == null || !libraries.add(library)) {
84 return;
85 }
86 // Maybe skip library.
87 {
88 UriKind uriKind = library.source.uriKind;
89 // Optionally skip package: libraries.
90 if (!options.showPackageWarnings && _isOtherPackage(library.source.uri)) {
91 return;
92 }
93 // Optionally skip SDK libraries.
94 if (!options.showSdkWarnings && uriKind == UriKind.DART_URI) {
95 return;
96 }
97 }
98 // Add compilation units.
99 addCompilationUnitSource(library.definingCompilationUnit, libraries, units);
100 for (CompilationUnitElement child in library.parts) {
101 addCompilationUnitSource(child, libraries, units);
102 }
103 // Add referenced libraries.
104 for (LibraryElement child in library.importedLibraries) {
105 addLibrarySources(child, libraries, units);
106 }
107 for (LibraryElement child in library.exportedLibraries) {
108 addLibrarySources(child, libraries, units);
109 }
110 }
111
112 /// Treats the [sourcePath] as the top level library and analyzes it using a
113 /// synchronous algorithm over the analysis engine. If [printMode] is `0`,
114 /// then no error or performance information is printed. If [printMode] is `1` ,
115 /// then both will be printed. If [printMode] is `2`, then only performance
116 /// information will be printed, and it will be marked as being for a cold VM.
117 ErrorSeverity analyzeSync({int printMode: 1}) {
118 setupForAnalysis();
119 return _analyzeSync(printMode);
120 }
121
122 /// Fills [errorInfos] using [sources].
123 void prepareErrors() {
124 for (Source source in sources) {
125 context.computeErrors(source);
126
127 errorInfos.add(context.getErrors(source));
128 }
129 }
130
131 /// Fills [sources].
132 void prepareSources(LibraryElement library) {
133 var units = new Set<CompilationUnitElement>();
134 var libraries = new Set<LibraryElement>();
135 addLibrarySources(library, libraries, units);
136 }
137
138 /// Setup local fields such as the analysis context for analysis.
139 void setupForAnalysis() {
140 sources.clear();
141 errorInfos.clear();
142 Uri libraryUri = librarySource.uri;
143 if (libraryUri.scheme == 'package' && libraryUri.pathSegments.length > 0) {
144 _selfPackageName = libraryUri.pathSegments[0];
145 }
146 }
147
148 /// The sync version of analysis.
149 ErrorSeverity _analyzeSync(int printMode) {
150 // Don't try to analyze parts.
151 if (context.computeKindOf(librarySource) == SourceKind.PART) {
152 stderr.writeln("Only libraries can be analyzed.");
153 stderr.writeln(
154 "${librarySource.fullName} is a part and can not be analyzed.");
155 return ErrorSeverity.ERROR;
156 }
157 // Resolve library.
158 var libraryElement = context.computeLibraryElement(librarySource);
159 // Prepare source and errors.
160 prepareSources(libraryElement);
161 prepareErrors();
162
163 // Print errors and performance numbers.
164 if (printMode == 1) {
165 _printErrorsAndPerf();
166 } else if (printMode == 2) {
167 _printColdPerf();
168 }
169
170 // Compute max severity and set exitCode.
171 ErrorSeverity status = maxErrorSeverity;
172 if (status == ErrorSeverity.WARNING && options.warningsAreFatal) {
173 status = ErrorSeverity.ERROR;
174 }
175 return status;
176 }
177
178 bool _isDesiredError(AnalysisError error) {
179 if (error.errorCode.type == ErrorType.TODO) {
180 return false;
181 }
182 if (computeSeverity(error, options) == ErrorSeverity.INFO &&
183 options.disableHints) {
184 return false;
185 }
186 return true;
187 }
188
189 /// Determine whether the given URI refers to a package other than the package
190 /// being analyzed.
191 bool _isOtherPackage(Uri uri) {
192 if (uri.scheme != 'package') {
193 return false;
194 }
195 if (_selfPackageName != null &&
196 uri.pathSegments.length > 0 &&
197 uri.pathSegments[0] == _selfPackageName) {
198 return false;
199 }
200 return true;
201 }
202
203 _printColdPerf() {
204 // Print cold VM performance numbers.
205 int totalTime = currentTimeMillis() - startTime;
206 int otherTime = totalTime;
207 for (PerformanceTag tag in PerformanceTag.all) {
208 if (tag != PerformanceTag.UNKNOWN) {
209 int tagTime = tag.elapsedMs;
210 outSink.writeln('${tag.label}-cold:$tagTime');
211 otherTime -= tagTime;
212 }
213 }
214 outSink.writeln('other-cold:$otherTime');
215 outSink.writeln("total-cold:$totalTime");
216 }
217
218 _printErrorsAndPerf() {
219 // The following is a hack. We currently print out to stderr to ensure that
220 // when in batch mode we print to stderr, this is because the prints from
221 // batch are made to stderr. The reason that options.shouldBatch isn't used
222 // is because when the argument flags are constructed in BatchRunner and
223 // passed in from batch mode which removes the batch flag to prevent the
224 // "cannot have the batch flag and source file" error message.
225 StringSink sink = options.machineFormat ? errorSink : outSink;
226
227 // Print errors.
228 ErrorFormatter formatter =
229 new ErrorFormatter(sink, options, _isDesiredError);
230 formatter.formatErrors(errorInfos);
231 }
232
233 /// Compute the severity of the error; however:
234 /// * if [options.enableTypeChecks] is false, then de-escalate checked-mode
235 /// compile time errors to a severity of [ErrorSeverity.INFO].
236 /// * if [options.hintsAreFatal] is true, escalate hints to errors.
237 static ErrorSeverity computeSeverity(
238 AnalysisError error, CommandLineOptions options) {
239 if (!options.enableTypeChecks &&
240 error.errorCode.type == ErrorType.CHECKED_MODE_COMPILE_TIME_ERROR) {
241 return ErrorSeverity.INFO;
242 }
243 if (options.hintsAreFatal && error.errorCode is HintCode) {
244 return ErrorSeverity.ERROR;
245 }
246 return error.errorCode.errorSeverity;
247 }
248
249 /// Return the corresponding package directory or `null` if none is found.
250 static JavaFile getPackageDirectoryFor(JavaFile sourceFile) {
251 // We are going to ask parent file, so get absolute path.
252 sourceFile = sourceFile.getAbsoluteFile();
253 // Look in the containing directories.
254 JavaFile dir = sourceFile.getParentFile();
255 while (dir != null) {
256 JavaFile packagesDir = new JavaFile.relative(dir, "packages");
257 if (packagesDir.exists()) {
258 return packagesDir;
259 }
260 dir = dir.getParentFile();
261 }
262 // Not found.
263 return null;
264 }
265 }
266
267 /// This [Logger] prints out information comments to [outSink] and error message s
268 /// to [errorSink].
269 class StdLogger extends Logger {
270 StdLogger();
271
272 @override
273 void logError(String message, [CaughtException exception]) {
274 errorSink.writeln(message);
275 if (exception != null) {
276 errorSink.writeln(exception);
277 }
278 }
279
280 @override
281 void logError2(String message, Object exception) {
282 errorSink.writeln(message);
283 if (exception != null) {
284 errorSink.writeln(exception.toString());
285 }
286 }
287
288 @override
289 void logInformation(String message, [CaughtException exception]) {
290 outSink.writeln(message);
291 if (exception != null) {
292 outSink.writeln(exception);
293 }
294 }
295
296 @override
297 void logInformation2(String message, Object exception) {
298 outSink.writeln(message);
299 if (exception != null) {
300 outSink.writeln(exception.toString());
301 }
302 }
303 }
OLDNEW
« no previous file with comments | « pkg/analyzer_cli/bin/analyzer.dart ('k') | pkg/analyzer_cli/lib/src/bootloader.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698