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

Side by Side Diff: pkg/analyzer_experimental/lib/src/generated/engine.dart

Issue 45573002: Rename analyzer_experimental to analyzer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Tweaks before publishing. Created 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // This code was auto-generated, is not intended to be edited, and is subject to
2 // significant change. Please see the README file for more information.
3 library engine;
4 import 'java_core.dart';
5 import 'java_engine.dart';
6 import 'utilities_collection.dart';
7 import 'utilities_general.dart';
8 import 'instrumentation.dart';
9 import 'error.dart';
10 import 'source.dart';
11 import 'scanner.dart' show Token, Scanner, CharSequenceReader;
12 import 'ast.dart';
13 import 'parser.dart' show Parser;
14 import 'sdk.dart' show DartSdk;
15 import 'element.dart';
16 import 'resolver.dart';
17 import 'html.dart' show XmlTagNode, XmlAttributeNode, RecursiveXmlVisitor, HtmlS canner, HtmlScanResult, HtmlParser, HtmlParseResult, HtmlUnit;
18 /**
19 * The unique instance of the class `AnalysisEngine` serves as the entry point f or the
20 * functionality provided by the analysis engine.
21 *
22 * @coverage dart.engine
23 */
24 class AnalysisEngine {
25
26 /**
27 * The suffix used for Dart source files.
28 */
29 static String SUFFIX_DART = "dart";
30
31 /**
32 * The short suffix used for HTML files.
33 */
34 static String SUFFIX_HTM = "htm";
35
36 /**
37 * The long suffix used for HTML files.
38 */
39 static String SUFFIX_HTML = "html";
40
41 /**
42 * The unique instance of this class.
43 */
44 static final AnalysisEngine instance = new AnalysisEngine();
45
46 /**
47 * Return `true` if the given file name is assumed to contain Dart source code .
48 *
49 * @param fileName the name of the file being tested
50 * @return `true` if the given file name is assumed to contain Dart source cod e
51 */
52 static bool isDartFileName(String fileName) {
53 if (fileName == null) {
54 return false;
55 }
56 return javaStringEqualsIgnoreCase(FileNameUtilities.getExtension(fileName), SUFFIX_DART);
57 }
58
59 /**
60 * Return `true` if the given file name is assumed to contain HTML.
61 *
62 * @param fileName the name of the file being tested
63 * @return `true` if the given file name is assumed to contain HTML
64 */
65 static bool isHtmlFileName(String fileName) {
66 if (fileName == null) {
67 return false;
68 }
69 String extension = FileNameUtilities.getExtension(fileName);
70 return javaStringEqualsIgnoreCase(extension, SUFFIX_HTML) || javaStringEqual sIgnoreCase(extension, SUFFIX_HTM);
71 }
72
73 /**
74 * The logger that should receive information about errors within the analysis engine.
75 */
76 Logger _logger = Logger.NULL;
77
78 /**
79 * Create a new context in which analysis can be performed.
80 *
81 * @return the analysis context that was created
82 */
83 AnalysisContext createAnalysisContext() {
84 if (Instrumentation.isNullLogger) {
85 return new DelegatingAnalysisContextImpl();
86 }
87 return new InstrumentedAnalysisContextImpl.con1(new DelegatingAnalysisContex tImpl());
88 }
89
90 /**
91 * Return the logger that should receive information about errors within the a nalysis engine.
92 *
93 * @return the logger that should receive information about errors within the analysis engine
94 */
95 Logger get logger => _logger;
96
97 /**
98 * Set the logger that should receive information about errors within the anal ysis engine to the
99 * given logger.
100 *
101 * @param logger the logger that should receive information about errors withi n the analysis
102 * engine
103 */
104 void set logger(Logger logger) {
105 this._logger = logger == null ? Logger.NULL : logger;
106 }
107 }
108 /**
109 * Container with statistics about the [AnalysisContext].
110 */
111 abstract class AnalysisContentStatistics {
112
113 /**
114 * Return the exceptions that caused some entries to have a state of [CacheSta te#ERROR].
115 *
116 * @return the exceptions that caused some entries to have a state of [CacheSt ate#ERROR]
117 */
118 List<AnalysisException> get exceptions;
119
120 /**
121 * Return the statistics for each kind of cached data.
122 *
123 * @return the statistics for each kind of cached data
124 */
125 List<AnalysisContentStatistics_CacheRow> get cacheRows;
126 }
127 /**
128 * Information about single item in the cache.
129 */
130 abstract class AnalysisContentStatistics_CacheRow {
131 int get errorCount;
132 int get flushedCount;
133 int get inProcessCount;
134 int get invalidCount;
135 String get name;
136 int get validCount;
137 }
138 /**
139 * The interface `AnalysisContext` defines the behavior of objects that represen t a context in
140 * which a single analysis can be performed and incrementally maintained. The co ntext includes such
141 * information as the version of the SDK being analyzed against as well as the p ackage-root used to
142 * resolve 'package:' URI's. (Both of which are known indirectly through the [So urceFactory
143 ].)
144 *
145 * An analysis context also represents the state of the analysis, which includes knowing which
146 * sources have been included in the analysis (either directly or indirectly) an d the results of the
147 * analysis. Sources must be added and removed from the context using the method
148 * [applyChanges], which is also used to notify the context when sources have be en
149 * modified and, consequently, previously known results might have been invalida ted.
150 *
151 * There are two ways to access the results of the analysis. The most common is to use one of the
152 * 'get' methods to access the results. The 'get' methods have the advantage tha t they will always
153 * return quickly, but have the disadvantage that if the results are not current ly available they
154 * will return either nothing or in some cases an incomplete result. The second way to access
155 * results is by using one of the 'compute' methods. The 'compute' methods will always attempt to
156 * compute the requested results but might block the caller for a significant pe riod of time.
157 *
158 * When results have been invalidated, have never been computed (as is the case for newly added
159 * sources), or have been removed from the cache, they are <b>not</b> automatica lly recreated. They
160 * will only be recreated if one of the 'compute' methods is invoked.
161 *
162 * However, this is not always acceptable. Some clients need to keep the analysi s results
163 * up-to-date. For such clients there is a mechanism that allows them to increme ntally perform
164 * needed analysis and get notified of the consequent changes to the analysis re sults. This
165 * mechanism is realized by the method [performAnalysisTask].
166 *
167 * Analysis engine allows for having more than one context. This can be used, fo r example, to
168 * perform one analysis based on the state of files on disk and a separate analy sis based on the
169 * state of those files in open editors. It can also be used to perform an analy sis based on a
170 * proposed future state, such as the state after a refactoring.
171 */
172 abstract class AnalysisContext {
173
174 /**
175 * Apply the changes specified by the given change set to this context. Any an alysis results that
176 * have been invalidated by these changes will be removed.
177 *
178 * @param changeSet a description of the changes that are to be applied
179 */
180 void applyChanges(ChangeSet changeSet);
181
182 /**
183 * Return the documentation comment for the given element as it appears in the original source
184 * (complete with the beginning and ending delimiters), or `null` if the eleme nt does not
185 * have a documentation comment associated with it. This can be a long-running operation if the
186 * information needed to access the comment is not cached.
187 *
188 * @param element the element whose documentation comment is to be returned
189 * @return the element's documentation comment
190 * @throws AnalysisException if the documentation comment could not be determi ned because the
191 * analysis could not be performed
192 */
193 String computeDocumentationComment(Element element);
194
195 /**
196 * Return an array containing all of the errors associated with the given sour ce. If the errors
197 * are not already known then the source will be analyzed in order to determin e the errors
198 * associated with it.
199 *
200 * @param source the source whose errors are to be returned
201 * @return all of the errors associated with the given source
202 * @throws AnalysisException if the errors could not be determined because the analysis could not
203 * be performed
204 * @see #getErrors(Source)
205 */
206 List<AnalysisError> computeErrors(Source source);
207
208 /**
209 * Return the element model corresponding to the HTML file defined by the give n source. If the
210 * element model does not yet exist it will be created. The process of creatin g an element model
211 * for an HTML file can long-running, depending on the size of the file and th e number of
212 * libraries that are defined in it (via script tags) that also need to have a model built for
213 * them.
214 *
215 * @param source the source defining the HTML file whose element model is to b e returned
216 * @return the element model corresponding to the HTML file defined by the giv en source
217 * @throws AnalysisException if the element model could not be determined beca use the analysis
218 * could not be performed
219 * @see #getHtmlElement(Source)
220 */
221 HtmlElement computeHtmlElement(Source source);
222
223 /**
224 * Return the kind of the given source, computing it's kind if it is not alrea dy known. Return
225 * [SourceKind#UNKNOWN] if the source is not contained in this context.
226 *
227 * @param source the source whose kind is to be returned
228 * @return the kind of the given source
229 * @see #getKindOf(Source)
230 */
231 SourceKind computeKindOf(Source source);
232
233 /**
234 * Return the element model corresponding to the library defined by the given source. If the
235 * element model does not yet exist it will be created. The process of creatin g an element model
236 * for a library can long-running, depending on the size of the library and th e number of
237 * libraries that are imported into it that also need to have a model built fo r them.
238 *
239 * @param source the source defining the library whose element model is to be returned
240 * @return the element model corresponding to the library defined by the given source
241 * @throws AnalysisException if the element model could not be determined beca use the analysis
242 * could not be performed
243 * @see #getLibraryElement(Source)
244 */
245 LibraryElement computeLibraryElement(Source source);
246
247 /**
248 * Return the line information for the given source, or `null` if the source i s not of a
249 * recognized kind (neither a Dart nor HTML file). If the line information was not previously
250 * known it will be created. The line information is used to map offsets from the beginning of the
251 * source to line and column pairs.
252 *
253 * @param source the source whose line information is to be returned
254 * @return the line information for the given source
255 * @throws AnalysisException if the line information could not be determined b ecause the analysis
256 * could not be performed
257 * @see #getLineInfo(Source)
258 */
259 LineInfo computeLineInfo(Source source);
260
261 /**
262 * Create a new context in which analysis can be performed. Any sources in the specified container
263 * will be removed from this context and added to the newly created context.
264 *
265 * @param container the container containing sources that should be removed fr om this context and
266 * added to the returned context
267 * @return the analysis context that was created
268 */
269 AnalysisContext extractContext(SourceContainer container);
270
271 /**
272 * Return the set of analysis options controlling the behavior of this context . Clients should not
273 * modify the returned set of options. The options should only be set by invok ing the method
274 * [setAnalysisOptions].
275 *
276 * @return the set of analysis options controlling the behavior of this contex t
277 */
278 AnalysisOptions get analysisOptions;
279
280 /**
281 * Return the element referenced by the given location, or `null` if the eleme nt is not
282 * immediately available or if there is no element with the given location. Th e latter condition
283 * can occur, for example, if the location describes an element from a differe nt context or if the
284 * element has been removed from this context as a result of some change since it was originally
285 * obtained.
286 *
287 * @param location the reference describing the element to be returned
288 * @return the element referenced by the given location
289 */
290 Element getElement(ElementLocation location);
291
292 /**
293 * Return an analysis error info containing the array of all of the errors and the line info
294 * associated with the given source. The array of errors will be empty if the source is not known
295 * to this context or if there are no errors in the source. The errors contain ed in the array can
296 * be incomplete.
297 *
298 * @param source the source whose errors are to be returned
299 * @return all of the errors associated with the given source and the line inf o
300 * @see #computeErrors(Source)
301 */
302 AnalysisErrorInfo getErrors(Source source);
303
304 /**
305 * Return the element model corresponding to the HTML file defined by the give n source, or
306 * `null` if the source does not represent an HTML file, the element represent ing the file
307 * has not yet been created, or the analysis of the HTML file failed for some reason.
308 *
309 * @param source the source defining the HTML file whose element model is to b e returned
310 * @return the element model corresponding to the HTML file defined by the giv en source
311 * @see #computeHtmlElement(Source)
312 */
313 HtmlElement getHtmlElement(Source source);
314
315 /**
316 * Return the sources for the HTML files that reference the given compilation unit. If the source
317 * does not represent a Dart source or is not known to this context, the retur ned array will be
318 * empty. The contents of the array can be incomplete.
319 *
320 * @param source the source referenced by the returned HTML files
321 * @return the sources for the HTML files that reference the given compilation unit
322 */
323 List<Source> getHtmlFilesReferencing(Source source);
324
325 /**
326 * Return an array containing all of the sources known to this context that re present HTML files.
327 * The contents of the array can be incomplete.
328 *
329 * @return the sources known to this context that represent HTML files
330 */
331 List<Source> get htmlSources;
332
333 /**
334 * Return the kind of the given source, or `null` if the kind is not known to this context.
335 *
336 * @param source the source whose kind is to be returned
337 * @return the kind of the given source
338 * @see #computeKindOf(Source)
339 */
340 SourceKind getKindOf(Source source);
341
342 /**
343 * Return an array containing all of the sources known to this context that re present the defining
344 * compilation unit of a library that can be run within a browser. The sources that are returned
345 * represent libraries that have a 'main' method and are either referenced by an HTML file or
346 * import, directly or indirectly, a client-only library. The contents of the array can be
347 * incomplete.
348 *
349 * @return the sources known to this context that represent the defining compi lation unit of a
350 * library that can be run within a browser
351 */
352 List<Source> get launchableClientLibrarySources;
353
354 /**
355 * Return an array containing all of the sources known to this context that re present the defining
356 * compilation unit of a library that can be run outside of a browser. The con tents of the array
357 * can be incomplete.
358 *
359 * @return the sources known to this context that represent the defining compi lation unit of a
360 * library that can be run outside of a browser
361 */
362 List<Source> get launchableServerLibrarySources;
363
364 /**
365 * Return the sources for the defining compilation units of any libraries of w hich the given
366 * source is a part. The array will normally contain a single library because most Dart sources
367 * are only included in a single library, but it is possible to have a part th at is contained in
368 * multiple identically named libraries. If the source represents the defining compilation unit of
369 * a library, then the returned array will contain the given source as its onl y element. If the
370 * source does not represent a Dart source or is not known to this context, th e returned array
371 * will be empty. The contents of the array can be incomplete.
372 *
373 * @param source the source contained in the returned libraries
374 * @return the sources for the libraries containing the given source
375 */
376 List<Source> getLibrariesContaining(Source source);
377
378 /**
379 * Return the sources for the defining compilation units of any libraries that depend on the given
380 * library. One library depends on another if it either imports or exports tha t library.
381 *
382 * @param librarySource the source for the defining compilation unit of the li brary being depended
383 * on
384 * @return the sources for the libraries that depend on the given library
385 */
386 List<Source> getLibrariesDependingOn(Source librarySource);
387
388 /**
389 * Return the element model corresponding to the library defined by the given source, or
390 * `null` if the element model does not currently exist or if the library cann ot be analyzed
391 * for some reason.
392 *
393 * @param source the source defining the library whose element model is to be returned
394 * @return the element model corresponding to the library defined by the given source
395 */
396 LibraryElement getLibraryElement(Source source);
397
398 /**
399 * Return an array containing all of the sources known to this context that re present the defining
400 * compilation unit of a library. The contents of the array can be incomplete.
401 *
402 * @return the sources known to this context that represent the defining compi lation unit of a
403 * library
404 */
405 List<Source> get librarySources;
406
407 /**
408 * Return the line information for the given source, or `null` if the line inf ormation is
409 * not known. The line information is used to map offsets from the beginning o f the source to line
410 * and column pairs.
411 *
412 * @param source the source whose line information is to be returned
413 * @return the line information for the given source
414 * @see #computeLineInfo(Source)
415 */
416 LineInfo getLineInfo(Source source);
417
418 /**
419 * Return an array containing all of the sources known to this context and the ir resolution state
420 * is not valid or flush. So, these sources are not safe to update during refa ctoring, because we
421 * may be don't know all the references in them.
422 *
423 * @return the sources known to this context and are not safe for refactoring
424 */
425 List<Source> get refactoringUnsafeSources;
426
427 /**
428 * Return a fully resolved AST for a single compilation unit within the given library, or
429 * `null` if the resolved AST is not already computed.
430 *
431 * @param unitSource the source of the compilation unit
432 * @param library the library containing the compilation unit
433 * @return a fully resolved AST for the compilation unit
434 * @see #resolveCompilationUnit(Source, LibraryElement)
435 */
436 CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement l ibrary);
437
438 /**
439 * Return a fully resolved AST for a single compilation unit within the given library, or
440 * `null` if the resolved AST is not already computed.
441 *
442 * @param unitSource the source of the compilation unit
443 * @param librarySource the source of the defining compilation unit of the lib rary containing the
444 * compilation unit
445 * @return a fully resolved AST for the compilation unit
446 * @see #resolveCompilationUnit(Source, Source)
447 */
448 CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source libraryS ource);
449
450 /**
451 * Return the source factory used to create the sources that can be analyzed i n this context.
452 *
453 * @return the source factory used to create the sources that can be analyzed in this context
454 */
455 SourceFactory get sourceFactory;
456
457 /**
458 * Return `true` if the given source is known to be the defining compilation u nit of a
459 * library that can be run on a client (references 'dart:html', either directl y or indirectly).
460 *
461 * <b>Note:</b> In addition to the expected case of returning `false` if the s ource is known
462 * to be a library that cannot be run on a client, this method will also retur n `false` if
463 * the source is not known to be a library or if we do not know whether it can be run on a client.
464 *
465 * @param librarySource the source being tested
466 * @return `true` if the given source is known to be a library that can be run on a client
467 */
468 bool isClientLibrary(Source librarySource);
469
470 /**
471 * Return `true` if the given source is known to be the defining compilation u nit of a
472 * library that can be run on the server (does not reference 'dart:html', eith er directly or
473 * indirectly).
474 *
475 * <b>Note:</b> In addition to the expected case of returning `false` if the s ource is known
476 * to be a library that cannot be run on the server, this method will also ret urn `false` if
477 * the source is not known to be a library or if we do not know whether it can be run on the
478 * server.
479 *
480 * @param librarySource the source being tested
481 * @return `true` if the given source is known to be a library that can be run on the server
482 */
483 bool isServerLibrary(Source librarySource);
484
485 /**
486 * Add the sources contained in the specified context to this context's collec tion of sources.
487 * This method is called when an existing context's pubspec has been removed, and the contained
488 * sources should be reanalyzed as part of this context.
489 *
490 * @param context the context being merged
491 */
492 void mergeContext(AnalysisContext context);
493
494 /**
495 * Parse a single source to produce an AST structure. The resulting AST struct ure may or may not
496 * be resolved, and may have a slightly different structure depending upon whe ther it is resolved.
497 *
498 * @param source the source to be parsed
499 * @return the AST structure representing the content of the source
500 * @throws AnalysisException if the analysis could not be performed
501 */
502 CompilationUnit parseCompilationUnit(Source source);
503
504 /**
505 * Parse a single HTML source to produce an AST structure. The resulting HTML AST structure may or
506 * may not be resolved, and may have a slightly different structure depending upon whether it is
507 * resolved.
508 *
509 * @param source the HTML source to be parsed
510 * @return the parse result (not `null`)
511 * @throws AnalysisException if the analysis could not be performed
512 */
513 HtmlUnit parseHtmlUnit(Source source);
514
515 /**
516 * Perform the next unit of work required to keep the analysis results up-to-d ate and return
517 * information about the consequent changes to the analysis results. This meth od can be long
518 * running.
519 *
520 * @return the results of performing the analysis
521 */
522 AnalysisResult performAnalysisTask();
523
524 /**
525 * Parse and resolve a single source within the given context to produce a ful ly resolved AST.
526 *
527 * @param unitSource the source to be parsed and resolved
528 * @param library the library containing the source to be resolved
529 * @return the result of resolving the AST structure representing the content of the source in the
530 * context of the given library
531 * @throws AnalysisException if the analysis could not be performed
532 * @see #getResolvedCompilationUnit(Source, LibraryElement)
533 */
534 CompilationUnit resolveCompilationUnit(Source unitSource, LibraryElement libra ry);
535
536 /**
537 * Parse and resolve a single source within the given context to produce a ful ly resolved AST.
538 * Return the resolved AST structure, or `null` if the source could not be eit her parsed or
539 * resolved.
540 *
541 * @param unitSource the source to be parsed and resolved
542 * @param librarySource the source of the defining compilation unit of the lib rary containing the
543 * source to be resolved
544 * @return the result of resolving the AST structure representing the content of the source in the
545 * context of the given library
546 * @throws AnalysisException if the analysis could not be performed
547 * @see #getResolvedCompilationUnit(Source, Source)
548 */
549 CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySourc e);
550
551 /**
552 * Parse and resolve a single source within the given context to produce a ful ly resolved AST.
553 *
554 * @param htmlSource the source to be parsed and resolved
555 * @return the result of resolving the AST structure representing the content of the source
556 * @throws AnalysisException if the analysis could not be performed
557 */
558 HtmlUnit resolveHtmlUnit(Source htmlSource);
559
560 /**
561 * Set the set of analysis options controlling the behavior of this context to the given options.
562 * Clients can safely assume that all necessary analysis results have been inv alidated.
563 *
564 * @param options the set of analysis options that will control the behavior o f this context
565 */
566 void set analysisOptions(AnalysisOptions options);
567
568 /**
569 * Set the order in which sources will be analyzed by [performAnalysisTask] to match the
570 * order of the sources in the given list. If a source that needs to be analyz ed is not contained
571 * in the list, then it will be treated as if it were at the end of the list. If the list is empty
572 * (or `null`) then no sources will be given priority over other sources.
573 *
574 * Changes made to the list after this method returns will <b>not</b> be refle cted in the priority
575 * order.
576 *
577 * @param sources the sources to be given priority over other sources
578 */
579 void set analysisPriorityOrder(List<Source> sources);
580
581 /**
582 * Set the contents of the given source to the given contents and mark the sou rce as having
583 * changed. The additional offset and length information is used by the contex t to determine what
584 * reanalysis is necessary.
585 *
586 * @param source the source whose contents are being overridden
587 * @param contents the text to replace the range in the current contents
588 * @param offset the offset into the current contents
589 * @param oldLength the number of characters in the original contents that wer e replaced
590 * @param newLength the number of characters in the replacement text
591 */
592 void setChangedContents(Source source, String contents, int offset, int oldLen gth, int newLength);
593
594 /**
595 * Set the contents of the given source to the given contents and mark the sou rce as having
596 * changed. This has the effect of overriding the default contents of the sour ce. If the contents
597 * are `null` the override is removed so that the default contents will be ret urned.
598 *
599 * @param source the source whose contents are being overridden
600 * @param contents the new contents of the source
601 */
602 void setContents(Source source, String contents);
603
604 /**
605 * Set the source factory used to create the sources that can be analyzed in t his context to the
606 * given source factory. Clients can safely assume that all analysis results h ave been
607 * invalidated.
608 *
609 * @param factory the source factory used to create the sources that can be an alyzed in this
610 * context
611 */
612 void set sourceFactory(SourceFactory factory);
613
614 /**
615 * Given a collection of sources with content that has changed, return an [Ite rable]
616 * identifying the sources that need to be resolved.
617 *
618 * @param changedSources an array of sources (not `null`, contains no `null`s)
619 * @return An iterable returning the sources to be resolved
620 */
621 Iterable<Source> sourcesToResolve(List<Source> changedSources);
622 }
623 /**
624 * The interface `AnalysisErrorInfo` contains the analysis errors and line infor mation for the
625 * errors.
626 */
627 abstract class AnalysisErrorInfo {
628
629 /**
630 * Return the errors that as a result of the analysis, or `null` if there were no errors.
631 *
632 * @return the errors as a result of the analysis
633 */
634 List<AnalysisError> get errors;
635
636 /**
637 * Return the line information associated with the errors, or `null` if there were no
638 * errors.
639 *
640 * @return the line information associated with the errors
641 */
642 LineInfo get lineInfo;
643 }
644 /**
645 * Instances of the class `AnalysisException` represent an exception that occurr ed during the
646 * analysis of one or more sources.
647 *
648 * @coverage dart.engine
649 */
650 class AnalysisException extends JavaException {
651
652 /**
653 * Initialize a newly created exception.
654 */
655 AnalysisException() : super();
656
657 /**
658 * Initialize a newly created exception to have the given message.
659 *
660 * @param message the message associated with the exception
661 */
662 AnalysisException.con1(String message) : super(message);
663
664 /**
665 * Initialize a newly created exception to have the given message and cause.
666 *
667 * @param message the message associated with the exception
668 * @param cause the underlying exception that caused this exception
669 */
670 AnalysisException.con2(String message, Exception cause) : super(message, cause );
671
672 /**
673 * Initialize a newly created exception to have the given cause.
674 *
675 * @param cause the underlying exception that caused this exception
676 */
677 AnalysisException.con3(Exception cause) : super.withCause(cause);
678 }
679 /**
680 * The interface `AnalysisOptions` defines the behavior of objects that provide access to a
681 * set of analysis options used to control the behavior of an analysis context.
682 */
683 abstract class AnalysisOptions {
684
685 /**
686 * Return the maximum number of sources for which AST structures should be kep t in the cache.
687 *
688 * @return the maximum number of sources for which AST structures should be ke pt in the cache
689 */
690 int get cacheSize;
691
692 /**
693 * Return `true` if analysis is to generate dart2js related hint results.
694 *
695 * @return `true` if analysis is to generate dart2js related hint results
696 */
697 bool get dart2jsHint;
698
699 /**
700 * Return `true` if analysis is to generate hint results (e.g. type inference based
701 * information and pub best practices).
702 *
703 * @return `true` if analysis is to generate hint results
704 */
705 bool get hint;
706
707 /**
708 * Return `true` if analysis is to use strict mode. In strict mode, error repo rting is based
709 * exclusively on the static type information.
710 *
711 * @return `true` if analysis is to use strict mode
712 */
713 bool get strictMode;
714 }
715 /**
716 * Instances of the class `AnalysisResult`
717 */
718 class AnalysisResult {
719
720 /**
721 * The change notices associated with this result, or `null` if there were no changes and
722 * there is no more work to be done.
723 */
724 List<ChangeNotice> changeNotices;
725
726 /**
727 * The number of milliseconds required to determine which task was to be perfo rmed.
728 */
729 int getTime = 0;
730
731 /**
732 * The name of the class of the task that was performed.
733 */
734 String taskClassName;
735
736 /**
737 * The number of milliseconds required to perform the task.
738 */
739 int performTime = 0;
740
741 /**
742 * Initialize a newly created analysis result to have the given values.
743 *
744 * @param notices the change notices associated with this result
745 * @param getTime the number of milliseconds required to determine which task was to be performed
746 * @param taskClassName the name of the class of the task that was performed
747 * @param performTime the number of milliseconds required to perform the task
748 */
749 AnalysisResult(List<ChangeNotice> notices, int getTime, String taskClassName, int performTime) {
750 this.changeNotices = notices;
751 this.getTime = getTime;
752 this.taskClassName = taskClassName;
753 this.performTime = performTime;
754 }
755 }
756 /**
757 * The interface `ChangeNotice` defines the behavior of objects that represent a change to the
758 * analysis results associated with a given source.
759 *
760 * @coverage dart.engine
761 */
762 abstract class ChangeNotice implements AnalysisErrorInfo {
763
764 /**
765 * Return the fully resolved AST that changed as a result of the analysis, or `null` if the
766 * AST was not changed.
767 *
768 * @return the fully resolved AST that changed as a result of the analysis
769 */
770 CompilationUnit get compilationUnit;
771
772 /**
773 * Return the source for which the result is being reported.
774 *
775 * @return the source for which the result is being reported
776 */
777 Source get source;
778 }
779 /**
780 * Instances of the class `ChangeSet` indicate what sources have been added, cha nged, or
781 * removed.
782 *
783 * @coverage dart.engine
784 */
785 class ChangeSet {
786
787 /**
788 * A list containing the sources that have been added.
789 */
790 final List<Source> added3 = new List<Source>();
791
792 /**
793 * A list containing the sources that have been changed.
794 */
795 final List<Source> changed3 = new List<Source>();
796
797 /**
798 * A list containing the sources that have been removed.
799 */
800 final List<Source> removed3 = new List<Source>();
801
802 /**
803 * A list containing the source containers specifying additional sources that have been removed.
804 */
805 final List<SourceContainer> removedContainers = new List<SourceContainer>();
806
807 /**
808 * Record that the specified source has been added and that it's content is th e default contents
809 * of the source.
810 *
811 * @param source the source that was added
812 */
813 void added(Source source) {
814 added3.add(source);
815 }
816
817 /**
818 * Record that the specified source has been changed and that it's content is the default contents
819 * of the source.
820 *
821 * @param source the source that was changed
822 */
823 void changed(Source source) {
824 changed3.add(source);
825 }
826
827 /**
828 * Return `true` if this change set does not contain any changes.
829 *
830 * @return `true` if this change set does not contain any changes
831 */
832 bool get isEmpty => added3.isEmpty && changed3.isEmpty && removed3.isEmpty && removedContainers.isEmpty;
833
834 /**
835 * Record that the specified source has been removed.
836 *
837 * @param source the source that was removed
838 */
839 void removed(Source source) {
840 if (source != null) {
841 removed3.add(source);
842 }
843 }
844
845 /**
846 * Record that the specified source container has been removed.
847 *
848 * @param container the source container that was removed
849 */
850 void removedContainer(SourceContainer container) {
851 if (container != null) {
852 removedContainers.add(container);
853 }
854 }
855 String toString() {
856 JavaStringBuilder builder = new JavaStringBuilder();
857 bool needsSeparator = appendSources(builder, added3, false, "added");
858 needsSeparator = appendSources(builder, changed3, needsSeparator, "changed") ;
859 appendSources(builder, removed3, needsSeparator, "removed");
860 int count = removedContainers.length;
861 if (count > 0) {
862 if (removed3.isEmpty) {
863 if (needsSeparator) {
864 builder.append("; ");
865 }
866 builder.append("removed: from ");
867 builder.append(count);
868 builder.append(" containers");
869 } else {
870 builder.append(", and more from ");
871 builder.append(count);
872 builder.append(" containers");
873 }
874 }
875 return builder.toString();
876 }
877
878 /**
879 * Append the given sources to the given builder, prefixed with the given labe l and possibly a
880 * separator.
881 *
882 * @param builder the builder to which the sources are to be appended
883 * @param sources the sources to be appended
884 * @param needsSeparator `true` if a separator is needed before the label
885 * @param label the label used to prefix the sources
886 * @return `true` if future lists of sources will need a separator
887 */
888 bool appendSources(JavaStringBuilder builder, List<Source> sources, bool needs Separator, String label) {
889 if (sources.isEmpty) {
890 return needsSeparator;
891 }
892 if (needsSeparator) {
893 builder.append("; ");
894 }
895 builder.append(label);
896 String prefix = " ";
897 for (Source source in sources) {
898 builder.append(prefix);
899 builder.append(source.fullName);
900 prefix = ", ";
901 }
902 return true;
903 }
904 }
905 /**
906 * Instances of the class `AnalysisCache` implement an LRU cache of information related to
907 * analysis.
908 */
909 class AnalysisCache {
910
911 /**
912 * A table mapping the sources known to the context to the information known a bout the source.
913 */
914 Map<Source, SourceEntry> _sourceMap = new Map<Source, SourceEntry>();
915
916 /**
917 * The maximum number of sources for which AST structures should be kept in th e cache.
918 */
919 int _maxCacheSize = 0;
920
921 /**
922 * The policy used to determine which pieces of data to remove from the cache.
923 */
924 CacheRetentionPolicy _retentionPolicy;
925
926 /**
927 * A list containing the most recently accessed sources with the most recently used at the end of
928 * the list. When more sources are added than the maximum allowed then the lea st recently used
929 * source will be removed and will have it's cached AST structure flushed.
930 */
931 List<Source> _recentlyUsed;
932
933 /**
934 * Initialize a newly created cache to maintain at most the given number of AS T structures in the
935 * cache.
936 *
937 * @param maxCacheSize the maximum number of sources for which AST structures should be kept in
938 * the cache
939 * @param retentionPolicy the policy used to determine which pieces of data to remove from the
940 * cache
941 */
942 AnalysisCache(int maxCacheSize, CacheRetentionPolicy retentionPolicy) {
943 this._maxCacheSize = maxCacheSize;
944 this._retentionPolicy = retentionPolicy;
945 _recentlyUsed = new List<Source>();
946 }
947
948 /**
949 * Record that the given source was just accessed.
950 *
951 * @param source the source that was accessed
952 */
953 void accessed(Source source) {
954 if (_recentlyUsed.remove(source)) {
955 _recentlyUsed.add(source);
956 return;
957 }
958 while (_recentlyUsed.length >= _maxCacheSize) {
959 if (!flushAstFromCache()) {
960 break;
961 }
962 }
963 _recentlyUsed.add(source);
964 }
965
966 /**
967 * Return a collection containing all of the map entries mapping sources to ca che entries. Clients
968 * should not modify the returned collection.
969 *
970 * @return a collection containing all of the map entries mapping sources to c ache entries
971 */
972 Iterable<MapEntry<Source, SourceEntry>> entrySet() => getMapEntrySet(_sourceMa p);
973
974 /**
975 * Return the entry associated with the given source.
976 *
977 * @param source the source whose entry is to be returned
978 * @return the entry associated with the given source
979 */
980 SourceEntry get(Source source) => _sourceMap[source];
981
982 /**
983 * Associate the given entry with the given source.
984 *
985 * @param source the source with which the entry is to be associated
986 * @param entry the entry to be associated with the source
987 */
988 void put(Source source, SourceEntry entry) {
989 _sourceMap[source] = entry;
990 }
991
992 /**
993 * Remove all information related to the given source from this cache.
994 *
995 * @param source the source to be removed
996 */
997 void remove(Source source) {
998 _sourceMap.remove(source);
999 }
1000
1001 /**
1002 * Set the maximum size of the cache to the given size.
1003 *
1004 * @param size the maximum number of sources for which AST structures should b e kept in the cache
1005 */
1006 void set maxCacheSize(int size) {
1007 _maxCacheSize = size;
1008 while (_recentlyUsed.length > _maxCacheSize) {
1009 if (!flushAstFromCache()) {
1010 break;
1011 }
1012 }
1013 }
1014
1015 /**
1016 * Return the number of sources that are mapped to cache entries.
1017 *
1018 * @return the number of sources that are mapped to cache entries
1019 */
1020 int size() => _sourceMap.length;
1021
1022 /**
1023 * Attempt to flush one AST structure from the cache.
1024 *
1025 * @return `true` if a structure was flushed
1026 */
1027 bool flushAstFromCache() {
1028 Source removedSource = removeAstToFlush();
1029 if (removedSource == null) {
1030 return false;
1031 }
1032 SourceEntry sourceEntry = _sourceMap[removedSource];
1033 if (sourceEntry is HtmlEntry) {
1034 HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
1035 htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.FLUSHED);
1036 _sourceMap[removedSource] = htmlCopy;
1037 } else if (sourceEntry is DartEntry) {
1038 DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
1039 dartCopy.flushAstStructures();
1040 _sourceMap[removedSource] = dartCopy;
1041 }
1042 return true;
1043 }
1044
1045 /**
1046 * Remove and return one source from the list of recently used sources whose A ST structure can be
1047 * flushed from the cache. The source that will be returned will be the source that has been
1048 * unreferenced for the longest period of time but that is not a priority for analysis.
1049 *
1050 * @return the source that was removed
1051 */
1052 Source removeAstToFlush() {
1053 int sourceToRemove = -1;
1054 for (int i = 0; i < _recentlyUsed.length; i++) {
1055 Source source = _recentlyUsed[i];
1056 RetentionPriority priority = _retentionPolicy.getAstPriority(source, _sour ceMap[source]);
1057 if (identical(priority, RetentionPriority.LOW)) {
1058 return _recentlyUsed.removeAt(i);
1059 } else if (identical(priority, RetentionPriority.MEDIUM) && sourceToRemove < 0) {
1060 sourceToRemove = i;
1061 }
1062 }
1063 if (sourceToRemove < 0) {
1064 AnalysisEngine.instance.logger.logError2("Internal error: Could not flush data from the cache", new JavaException());
1065 return null;
1066 }
1067 return _recentlyUsed.removeAt(sourceToRemove);
1068 }
1069 }
1070 /**
1071 * Instances of the class `CacheRetentionPolicy` define the behavior of objects that determine
1072 * how important it is for data to be retained in the analysis cache.
1073 */
1074 abstract class CacheRetentionPolicy {
1075
1076 /**
1077 * Return the priority of retaining the AST structure for the given source.
1078 *
1079 * @param source the source whose AST structure is being considered for remova l
1080 * @param sourceEntry the entry representing the source
1081 * @return the priority of retaining the AST structure for the given source
1082 */
1083 RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry);
1084 }
1085 /**
1086 * The enumeration `CacheState` defines the possible states of cached data.
1087 */
1088 class CacheState extends Enum<CacheState> {
1089
1090 /**
1091 * The data is not in the cache and the last time an attempt was made to compu te the data an
1092 * exception occurred, making it pointless to attempt.
1093 *
1094 * Valid Transitions:
1095 *
1096 * * [INVALID] if a source was modified that might cause the data to be comput able
1097 *
1098 */
1099 static final CacheState ERROR = new CacheState('ERROR', 0);
1100
1101 /**
1102 * The data is not in the cache because it was flushed from the cache in order to control memory
1103 * usage. If the data is recomputed, results do not need to be reported.
1104 *
1105 * Valid Transitions:
1106 *
1107 * * [IN_PROCESS] if the data is being recomputed
1108 * * [INVALID] if a source was modified that causes the data to need to be rec omputed
1109 *
1110 */
1111 static final CacheState FLUSHED = new CacheState('FLUSHED', 1);
1112
1113 /**
1114 * The data might or might not be in the cache but is in the process of being recomputed.
1115 *
1116 * Valid Transitions:
1117 *
1118 * * [ERROR] if an exception occurred while trying to compute the data
1119 * * [VALID] if the data was successfully computed and stored in the cache
1120 *
1121 */
1122 static final CacheState IN_PROCESS = new CacheState('IN_PROCESS', 2);
1123
1124 /**
1125 * The data is not in the cache and needs to be recomputed so that results can be reported.
1126 *
1127 * Valid Transitions:
1128 *
1129 * * [IN_PROCESS] if an attempt is being made to recompute the data
1130 *
1131 */
1132 static final CacheState INVALID = new CacheState('INVALID', 3);
1133
1134 /**
1135 * The data is in the cache and up-to-date.
1136 *
1137 * Valid Transitions:
1138 *
1139 * * [FLUSHED] if the data is removed in order to manage memory usage
1140 * * [INVALID] if a source was modified in such a way as to invalidate the pre vious data
1141 *
1142 */
1143 static final CacheState VALID = new CacheState('VALID', 4);
1144 static final List<CacheState> values = [ERROR, FLUSHED, IN_PROCESS, INVALID, V ALID];
1145 CacheState(String name, int ordinal) : super(name, ordinal);
1146 }
1147 /**
1148 * The interface `DartEntry` defines the behavior of objects that maintain the i nformation
1149 * cached by an analysis context about an individual Dart file.
1150 *
1151 * @coverage dart.engine
1152 */
1153 abstract class DartEntry implements SourceEntry {
1154
1155 /**
1156 * The data descriptor representing the library element for the library. This data is only
1157 * available for Dart files that are the defining compilation unit of a librar y.
1158 */
1159 static final DataDescriptor<LibraryElement> ELEMENT = new DataDescriptor<Libra ryElement>("DartEntry.ELEMENT");
1160
1161 /**
1162 * The data descriptor representing the list of exported libraries. This data is only available
1163 * for Dart files that are the defining compilation unit of a library.
1164 */
1165 static final DataDescriptor<List<Source>> EXPORTED_LIBRARIES = new DataDescrip tor<List<Source>>("DartEntry.EXPORTED_LIBRARIES");
1166
1167 /**
1168 * The data descriptor representing the hints resulting from auditing the sour ce.
1169 */
1170 static final DataDescriptor<List<AnalysisError>> HINTS = new DataDescriptor<Li st<AnalysisError>>("DartEntry.HINTS");
1171
1172 /**
1173 * The data descriptor representing the list of imported libraries. This data is only available
1174 * for Dart files that are the defining compilation unit of a library.
1175 */
1176 static final DataDescriptor<List<Source>> IMPORTED_LIBRARIES = new DataDescrip tor<List<Source>>("DartEntry.IMPORTED_LIBRARIES");
1177
1178 /**
1179 * The data descriptor representing the list of included parts. This data is o nly available for
1180 * Dart files that are the defining compilation unit of a library.
1181 */
1182 static final DataDescriptor<List<Source>> INCLUDED_PARTS = new DataDescriptor< List<Source>>("DartEntry.INCLUDED_PARTS");
1183
1184 /**
1185 * The data descriptor representing the client flag. This data is only availab le for Dart files
1186 * that are the defining compilation unit of a library.
1187 */
1188 static final DataDescriptor<bool> IS_CLIENT = new DataDescriptor<bool>("DartEn try.IS_CLIENT");
1189
1190 /**
1191 * The data descriptor representing the launchable flag. This data is only ava ilable for Dart
1192 * files that are the defining compilation unit of a library.
1193 */
1194 static final DataDescriptor<bool> IS_LAUNCHABLE = new DataDescriptor<bool>("Da rtEntry.IS_LAUNCHABLE");
1195
1196 /**
1197 * The data descriptor representing the errors resulting from parsing the sour ce.
1198 */
1199 static final DataDescriptor<List<AnalysisError>> PARSE_ERRORS = new DataDescri ptor<List<AnalysisError>>("DartEntry.PARSE_ERRORS");
1200
1201 /**
1202 * The data descriptor representing the parsed AST structure.
1203 */
1204 static final DataDescriptor<CompilationUnit> PARSED_UNIT = new DataDescriptor< CompilationUnit>("DartEntry.PARSED_UNIT");
1205
1206 /**
1207 * The data descriptor representing the public namespace of the library. This data is only
1208 * available for Dart files that are the defining compilation unit of a librar y.
1209 */
1210 static final DataDescriptor<Namespace> PUBLIC_NAMESPACE = new DataDescriptor<N amespace>("DartEntry.PUBLIC_NAMESPACE");
1211
1212 /**
1213 * The data descriptor representing the errors resulting from resolving the so urce.
1214 */
1215 static final DataDescriptor<List<AnalysisError>> RESOLUTION_ERRORS = new DataD escriptor<List<AnalysisError>>("DartEntry.RESOLUTION_ERRORS");
1216
1217 /**
1218 * The data descriptor representing the resolved AST structure.
1219 */
1220 static final DataDescriptor<CompilationUnit> RESOLVED_UNIT = new DataDescripto r<CompilationUnit>("DartEntry.RESOLVED_UNIT");
1221
1222 /**
1223 * The data descriptor representing the source kind.
1224 */
1225 static final DataDescriptor<SourceKind> SOURCE_KIND = new DataDescriptor<Sourc eKind>("DartEntry.SOURCE_KIND");
1226
1227 /**
1228 * The data descriptor representing the errors resulting from verifying the so urce.
1229 */
1230 static final DataDescriptor<List<AnalysisError>> VERIFICATION_ERRORS = new Dat aDescriptor<List<AnalysisError>>("DartEntry.VERIFICATION_ERRORS");
1231
1232 /**
1233 * Return all of the errors associated with the compilation unit that are curr ently cached.
1234 *
1235 * @return all of the errors associated with the compilation unit
1236 */
1237 List<AnalysisError> get allErrors;
1238
1239 /**
1240 * Return a valid parsed compilation unit, either an unresolved AST structure or the result of
1241 * resolving the AST structure in the context of some library, or `null` if th ere is no
1242 * parsed compilation unit available.
1243 *
1244 * @return a valid parsed compilation unit
1245 */
1246 CompilationUnit get anyParsedCompilationUnit;
1247
1248 /**
1249 * Return the result of resolving the compilation unit as part of any library, or `null` if
1250 * there is no cached resolved compilation unit.
1251 *
1252 * @return any resolved compilation unit
1253 */
1254 CompilationUnit get anyResolvedCompilationUnit;
1255
1256 /**
1257 * Return the state of the data represented by the given descriptor in the con text of the given
1258 * library.
1259 *
1260 * @param descriptor the descriptor representing the data whose state is to be returned
1261 * @param librarySource the source of the defining compilation unit of the lib rary that is the
1262 * context for the data
1263 * @return the value of the data represented by the given descriptor and libra ry
1264 */
1265 CacheState getState2(DataDescriptor descriptor, Source librarySource);
1266
1267 /**
1268 * Return the value of the data represented by the given descriptor in the con text of the given
1269 * library, or `null` if the data represented by the descriptor is not in the cache.
1270 *
1271 * @param descriptor the descriptor representing which data is to be returned
1272 * @param librarySource the source of the defining compilation unit of the lib rary that is the
1273 * context for the data
1274 * @return the value of the data represented by the given descriptor and libra ry
1275 */
1276 Object getValue2(DataDescriptor descriptor, Source librarySource);
1277 DartEntryImpl get writableCopy;
1278
1279 /**
1280 * Return `true` if the data represented by the given descriptor is marked as being invalid.
1281 * If the descriptor represents library-specific data then this method will re turn `true` if
1282 * the data associated with any library it marked as invalid.
1283 *
1284 * @param descriptor the descriptor representing which data is being tested
1285 * @return `true` if the data is marked as being invalid
1286 */
1287 bool hasInvalidData(DataDescriptor descriptor);
1288
1289 /**
1290 * Return `true` if this data is safe to use in refactoring.
1291 */
1292 bool get isRefactoringSafe;
1293 }
1294 /**
1295 * Instances of the class `DartEntryImpl` implement a [DartEntry].
1296 *
1297 * @coverage dart.engine
1298 */
1299 class DartEntryImpl extends SourceEntryImpl implements DartEntry {
1300
1301 /**
1302 * The state of the cached source kind.
1303 */
1304 CacheState _sourceKindState = CacheState.INVALID;
1305
1306 /**
1307 * The kind of this source.
1308 */
1309 SourceKind _sourceKind = SourceKind.UNKNOWN;
1310
1311 /**
1312 * The state of the cached parsed compilation unit.
1313 */
1314 CacheState _parsedUnitState = CacheState.INVALID;
1315
1316 /**
1317 * A flag indicating whether the parsed AST structure has been accessed since it was set. This is
1318 * used to determine whether the structure needs to be copied before it is res olved.
1319 */
1320 bool _parsedUnitAccessed = false;
1321
1322 /**
1323 * The parsed compilation unit, or `null` if the parsed compilation unit is no t currently
1324 * cached.
1325 */
1326 CompilationUnit _parsedUnit;
1327
1328 /**
1329 * The state of the cached parse errors.
1330 */
1331 CacheState _parseErrorsState = CacheState.INVALID;
1332
1333 /**
1334 * The errors produced while scanning and parsing the compilation unit, or `nu ll` if the
1335 * errors are not currently cached.
1336 */
1337 List<AnalysisError> _parseErrors = AnalysisError.NO_ERRORS;
1338
1339 /**
1340 * The state of the cached list of imported libraries.
1341 */
1342 CacheState _importedLibrariesState = CacheState.INVALID;
1343
1344 /**
1345 * The list of libraries imported by the library, or an empty array if the lis t is not currently
1346 * cached. The list will be empty if the Dart file is a part rather than a lib rary.
1347 */
1348 List<Source> _importedLibraries = Source.EMPTY_ARRAY;
1349
1350 /**
1351 * The state of the cached list of exported libraries.
1352 */
1353 CacheState _exportedLibrariesState = CacheState.INVALID;
1354
1355 /**
1356 * The list of libraries exported by the library, or an empty array if the lis t is not currently
1357 * cached. The list will be empty if the Dart file is a part rather than a lib rary.
1358 */
1359 List<Source> _exportedLibraries = Source.EMPTY_ARRAY;
1360
1361 /**
1362 * The state of the cached list of included parts.
1363 */
1364 CacheState _includedPartsState = CacheState.INVALID;
1365
1366 /**
1367 * The list of parts included in the library, or an empty array if the list is not currently
1368 * cached. The list will be empty if the Dart file is a part rather than a lib rary.
1369 */
1370 List<Source> _includedParts = Source.EMPTY_ARRAY;
1371
1372 /**
1373 * The information known as a result of resolving this compilation unit as par t of the library
1374 * that contains this unit. This field will never be `null`.
1375 */
1376 DartEntryImpl_ResolutionState _resolutionState = new DartEntryImpl_ResolutionS tate();
1377
1378 /**
1379 * The state of the cached library element.
1380 */
1381 CacheState _elementState = CacheState.INVALID;
1382
1383 /**
1384 * The element representing the library, or `null` if the element is not curre ntly cached.
1385 */
1386 LibraryElement _element;
1387
1388 /**
1389 * The state of the cached public namespace.
1390 */
1391 CacheState _publicNamespaceState = CacheState.INVALID;
1392
1393 /**
1394 * The public namespace of the library, or `null` if the namespace is not curr ently cached.
1395 */
1396 Namespace _publicNamespace;
1397
1398 /**
1399 * The state of the cached client/ server flag.
1400 */
1401 CacheState _clientServerState = CacheState.INVALID;
1402
1403 /**
1404 * The state of the cached launchable flag.
1405 */
1406 CacheState _launchableState = CacheState.INVALID;
1407
1408 /**
1409 * An integer holding bit masks such as [LAUNCHABLE] and [CLIENT_CODE].
1410 */
1411 int _bitmask = 0;
1412
1413 /**
1414 * The index of the bit in the [bitmask] indicating that this library is launc hable: that
1415 * the file has a main method.
1416 */
1417 static int _LAUNCHABLE_INDEX = 1;
1418
1419 /**
1420 * The index of the bit in the [bitmask] indicating that the library is client code: that
1421 * the library depends on the html library. If the library is not "client code ", then it is
1422 * referred to as "server code".
1423 */
1424 static int _CLIENT_CODE_INDEX = 2;
1425
1426 /**
1427 * Flush any AST structures being maintained by this entry.
1428 */
1429 void flushAstStructures() {
1430 if (identical(_parsedUnitState, CacheState.VALID)) {
1431 _parsedUnitState = CacheState.FLUSHED;
1432 _parsedUnitAccessed = false;
1433 _parsedUnit = null;
1434 }
1435 _resolutionState.flushAstStructures();
1436 }
1437 List<AnalysisError> get allErrors {
1438 List<AnalysisError> errors = new List<AnalysisError>();
1439 for (AnalysisError error in _parseErrors) {
1440 errors.add(error);
1441 }
1442 DartEntryImpl_ResolutionState state = _resolutionState;
1443 while (state != null) {
1444 for (AnalysisError error in state._resolutionErrors) {
1445 errors.add(error);
1446 }
1447 for (AnalysisError error in state._verificationErrors) {
1448 errors.add(error);
1449 }
1450 for (AnalysisError error in state._hints) {
1451 errors.add(error);
1452 }
1453 state = state._nextState;
1454 }
1455 ;
1456 if (errors.length == 0) {
1457 return AnalysisError.NO_ERRORS;
1458 }
1459 return new List.from(errors);
1460 }
1461 CompilationUnit get anyParsedCompilationUnit {
1462 if (identical(_parsedUnitState, CacheState.VALID)) {
1463 _parsedUnitAccessed = true;
1464 return _parsedUnit;
1465 }
1466 return anyResolvedCompilationUnit;
1467 }
1468 CompilationUnit get anyResolvedCompilationUnit {
1469 DartEntryImpl_ResolutionState state = _resolutionState;
1470 while (state != null) {
1471 if (identical(state._resolvedUnitState, CacheState.VALID)) {
1472 return state._resolvedUnit;
1473 }
1474 state = state._nextState;
1475 }
1476 ;
1477 return null;
1478 }
1479 SourceKind get kind => _sourceKind;
1480
1481 /**
1482 * Answer an array of library sources containing the receiver's source.
1483 */
1484 List<Source> get librariesContaining {
1485 DartEntryImpl_ResolutionState state = _resolutionState;
1486 List<Source> result = new List<Source>();
1487 while (state != null) {
1488 if (state._librarySource != null) {
1489 result.add(state._librarySource);
1490 }
1491 state = state._nextState;
1492 }
1493 return new List.from(result);
1494 }
1495
1496 /**
1497 * Return a compilation unit that has not been accessed by any other client an d can therefore
1498 * safely be modified by the reconciler.
1499 *
1500 * @return a compilation unit that can be modified by the reconciler
1501 */
1502 CompilationUnit get resolvableCompilationUnit {
1503 if (identical(_parsedUnitState, CacheState.VALID)) {
1504 if (_parsedUnitAccessed) {
1505 return _parsedUnit.accept(new ASTCloner()) as CompilationUnit;
1506 }
1507 CompilationUnit unit = _parsedUnit;
1508 _parsedUnitState = CacheState.FLUSHED;
1509 _parsedUnitAccessed = false;
1510 _parsedUnit = null;
1511 return unit;
1512 }
1513 DartEntryImpl_ResolutionState state = _resolutionState;
1514 while (state != null) {
1515 if (identical(state._resolvedUnitState, CacheState.VALID)) {
1516 return state._resolvedUnit.accept(new ASTCloner()) as CompilationUnit;
1517 }
1518 state = state._nextState;
1519 }
1520 ;
1521 return null;
1522 }
1523 CacheState getState(DataDescriptor descriptor) {
1524 if (identical(descriptor, DartEntry.ELEMENT)) {
1525 return _elementState;
1526 } else if (identical(descriptor, DartEntry.EXPORTED_LIBRARIES)) {
1527 return _exportedLibrariesState;
1528 } else if (identical(descriptor, DartEntry.IMPORTED_LIBRARIES)) {
1529 return _importedLibrariesState;
1530 } else if (identical(descriptor, DartEntry.INCLUDED_PARTS)) {
1531 return _includedPartsState;
1532 } else if (identical(descriptor, DartEntry.IS_CLIENT)) {
1533 return _clientServerState;
1534 } else if (identical(descriptor, DartEntry.IS_LAUNCHABLE)) {
1535 return _launchableState;
1536 } else if (identical(descriptor, DartEntry.PARSE_ERRORS)) {
1537 return _parseErrorsState;
1538 } else if (identical(descriptor, DartEntry.PARSED_UNIT)) {
1539 return _parsedUnitState;
1540 } else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) {
1541 return _publicNamespaceState;
1542 } else if (identical(descriptor, DartEntry.SOURCE_KIND)) {
1543 return _sourceKindState;
1544 } else {
1545 return super.getState(descriptor);
1546 }
1547 }
1548 CacheState getState2(DataDescriptor descriptor, Source librarySource) {
1549 DartEntryImpl_ResolutionState state = _resolutionState;
1550 while (state != null) {
1551 if (librarySource == state._librarySource) {
1552 if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
1553 return state._resolutionErrorsState;
1554 } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
1555 return state._resolvedUnitState;
1556 } else if (identical(descriptor, DartEntry.VERIFICATION_ERRORS)) {
1557 return state._verificationErrorsState;
1558 } else if (identical(descriptor, DartEntry.HINTS)) {
1559 return state._hintsState;
1560 } else {
1561 throw new IllegalArgumentException("Invalid descriptor: ${descriptor}" );
1562 }
1563 }
1564 state = state._nextState;
1565 }
1566 ;
1567 if (identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descript or, DartEntry.RESOLVED_UNIT) || identical(descriptor, DartEntry.VERIFICATION_ERR ORS) || identical(descriptor, DartEntry.HINTS)) {
1568 return CacheState.INVALID;
1569 } else {
1570 throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
1571 }
1572 }
1573 Object getValue(DataDescriptor descriptor) {
1574 if (identical(descriptor, DartEntry.ELEMENT)) {
1575 return _element as Object;
1576 } else if (identical(descriptor, DartEntry.EXPORTED_LIBRARIES)) {
1577 return _exportedLibraries as Object;
1578 } else if (identical(descriptor, DartEntry.IMPORTED_LIBRARIES)) {
1579 return _importedLibraries as Object;
1580 } else if (identical(descriptor, DartEntry.INCLUDED_PARTS)) {
1581 return _includedParts as Object;
1582 } else if (identical(descriptor, DartEntry.IS_CLIENT)) {
1583 return (BooleanArray.get2(_bitmask, _CLIENT_CODE_INDEX) as bool) as Object ;
1584 } else if (identical(descriptor, DartEntry.IS_LAUNCHABLE)) {
1585 return (BooleanArray.get2(_bitmask, _LAUNCHABLE_INDEX) as bool) as Object;
1586 } else if (identical(descriptor, DartEntry.PARSE_ERRORS)) {
1587 return _parseErrors as Object;
1588 } else if (identical(descriptor, DartEntry.PARSED_UNIT)) {
1589 _parsedUnitAccessed = true;
1590 return _parsedUnit as Object;
1591 } else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) {
1592 return _publicNamespace as Object;
1593 } else if (identical(descriptor, DartEntry.SOURCE_KIND)) {
1594 return _sourceKind as Object;
1595 }
1596 return super.getValue(descriptor);
1597 }
1598 Object getValue2(DataDescriptor descriptor, Source librarySource) {
1599 DartEntryImpl_ResolutionState state = _resolutionState;
1600 while (state != null) {
1601 if (librarySource == state._librarySource) {
1602 if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
1603 return state._resolutionErrors as Object;
1604 } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
1605 return state._resolvedUnit as Object;
1606 } else if (identical(descriptor, DartEntry.VERIFICATION_ERRORS)) {
1607 return state._verificationErrors as Object;
1608 } else if (identical(descriptor, DartEntry.HINTS)) {
1609 return state._hints as Object;
1610 } else {
1611 throw new IllegalArgumentException("Invalid descriptor: ${descriptor}" );
1612 }
1613 }
1614 state = state._nextState;
1615 }
1616 ;
1617 if (identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descript or, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
1618 return AnalysisError.NO_ERRORS as Object;
1619 } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
1620 return null;
1621 } else {
1622 throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
1623 }
1624 }
1625 DartEntryImpl get writableCopy {
1626 DartEntryImpl copy = new DartEntryImpl();
1627 copy.copyFrom(this);
1628 return copy;
1629 }
1630 bool hasInvalidData(DataDescriptor descriptor) {
1631 if (identical(descriptor, DartEntry.ELEMENT)) {
1632 return identical(_elementState, CacheState.INVALID);
1633 } else if (identical(descriptor, DartEntry.EXPORTED_LIBRARIES)) {
1634 return identical(_exportedLibrariesState, CacheState.INVALID);
1635 } else if (identical(descriptor, DartEntry.IMPORTED_LIBRARIES)) {
1636 return identical(_importedLibrariesState, CacheState.INVALID);
1637 } else if (identical(descriptor, DartEntry.INCLUDED_PARTS)) {
1638 return identical(_includedPartsState, CacheState.INVALID);
1639 } else if (identical(descriptor, DartEntry.IS_CLIENT)) {
1640 return identical(_clientServerState, CacheState.INVALID);
1641 } else if (identical(descriptor, DartEntry.IS_LAUNCHABLE)) {
1642 return identical(_launchableState, CacheState.INVALID);
1643 } else if (identical(descriptor, DartEntry.PARSE_ERRORS)) {
1644 return identical(_parseErrorsState, CacheState.INVALID);
1645 } else if (identical(descriptor, DartEntry.PARSED_UNIT)) {
1646 return identical(_parsedUnitState, CacheState.INVALID);
1647 } else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) {
1648 return identical(_publicNamespaceState, CacheState.INVALID);
1649 } else if (identical(descriptor, DartEntry.SOURCE_KIND)) {
1650 return identical(_sourceKindState, CacheState.INVALID);
1651 } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(d escriptor, DartEntry.RESOLVED_UNIT) || identical(descriptor, DartEntry.VERIFICAT ION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
1652 DartEntryImpl_ResolutionState state = _resolutionState;
1653 while (state != null) {
1654 if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
1655 return identical(state._resolutionErrorsState, CacheState.INVALID);
1656 } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
1657 return identical(state._resolvedUnitState, CacheState.INVALID);
1658 } else if (identical(descriptor, DartEntry.VERIFICATION_ERRORS)) {
1659 return identical(state._verificationErrorsState, CacheState.INVALID);
1660 } else if (identical(descriptor, DartEntry.HINTS)) {
1661 return identical(state._hintsState, CacheState.INVALID);
1662 }
1663 }
1664 return false;
1665 } else {
1666 return identical(super.getState(descriptor), CacheState.INVALID);
1667 }
1668 }
1669
1670 /**
1671 * Invalidate all of the information associated with the compilation unit.
1672 */
1673 void invalidateAllInformation() {
1674 setState(SourceEntry.LINE_INFO, CacheState.INVALID);
1675 _sourceKind = SourceKind.UNKNOWN;
1676 _sourceKindState = CacheState.INVALID;
1677 _parseErrors = AnalysisError.NO_ERRORS;
1678 _parseErrorsState = CacheState.INVALID;
1679 _parsedUnit = null;
1680 _parsedUnitAccessed = false;
1681 _parsedUnitState = CacheState.INVALID;
1682 discardCachedResolutionInformation();
1683 }
1684
1685 /**
1686 * Invalidate all of the resolution information associated with the compilatio n unit.
1687 */
1688 void invalidateAllResolutionInformation() {
1689 if (identical(_parsedUnitState, CacheState.FLUSHED)) {
1690 DartEntryImpl_ResolutionState state = _resolutionState;
1691 while (state != null) {
1692 if (identical(state._resolvedUnitState, CacheState.VALID)) {
1693 _parsedUnit = state._resolvedUnit;
1694 _parsedUnitAccessed = true;
1695 _parsedUnitState = CacheState.VALID;
1696 break;
1697 }
1698 state = state._nextState;
1699 }
1700 }
1701 discardCachedResolutionInformation();
1702 }
1703 bool get isRefactoringSafe {
1704 DartEntryImpl_ResolutionState state = _resolutionState;
1705 while (state != null) {
1706 CacheState resolvedState = state._resolvedUnitState;
1707 if (resolvedState != CacheState.VALID && resolvedState != CacheState.FLUSH ED) {
1708 return false;
1709 }
1710 state = state._nextState;
1711 }
1712 return true;
1713 }
1714
1715 /**
1716 * Record that an error occurred while attempting to scan or parse the entry r epresented by this
1717 * entry. This will set the state of all information, including any resolution -based information,
1718 * as being in error.
1719 */
1720 void recordParseError() {
1721 setState(SourceEntry.LINE_INFO, CacheState.ERROR);
1722 _sourceKind = SourceKind.UNKNOWN;
1723 _sourceKindState = CacheState.ERROR;
1724 _parseErrors = AnalysisError.NO_ERRORS;
1725 _parseErrorsState = CacheState.ERROR;
1726 _parsedUnit = null;
1727 _parsedUnitAccessed = false;
1728 _parsedUnitState = CacheState.ERROR;
1729 _exportedLibraries = Source.EMPTY_ARRAY;
1730 _exportedLibrariesState = CacheState.ERROR;
1731 _importedLibraries = Source.EMPTY_ARRAY;
1732 _importedLibrariesState = CacheState.ERROR;
1733 _includedParts = Source.EMPTY_ARRAY;
1734 _includedPartsState = CacheState.ERROR;
1735 recordResolutionError();
1736 }
1737
1738 /**
1739 * Record that the parse-related information for the associated source is abou t to be computed by
1740 * the current thread.
1741 */
1742 void recordParseInProcess() {
1743 if (getState(SourceEntry.LINE_INFO) != CacheState.VALID) {
1744 setState(SourceEntry.LINE_INFO, CacheState.IN_PROCESS);
1745 }
1746 if (_sourceKindState != CacheState.VALID) {
1747 _sourceKindState = CacheState.IN_PROCESS;
1748 }
1749 if (_parseErrorsState != CacheState.VALID) {
1750 _parseErrorsState = CacheState.IN_PROCESS;
1751 }
1752 if (_parsedUnitState != CacheState.VALID) {
1753 _parsedUnitState = CacheState.IN_PROCESS;
1754 }
1755 if (_exportedLibrariesState != CacheState.VALID) {
1756 _exportedLibrariesState = CacheState.IN_PROCESS;
1757 }
1758 if (_importedLibrariesState != CacheState.VALID) {
1759 _importedLibrariesState = CacheState.IN_PROCESS;
1760 }
1761 if (_includedPartsState != CacheState.VALID) {
1762 _includedPartsState = CacheState.IN_PROCESS;
1763 }
1764 }
1765
1766 /**
1767 * Record that an in-process parse has stopped without recording results becau se the results were
1768 * invalidated before they could be recorded.
1769 */
1770 void recordParseNotInProcess() {
1771 if (identical(getState(SourceEntry.LINE_INFO), CacheState.IN_PROCESS)) {
1772 setState(SourceEntry.LINE_INFO, CacheState.INVALID);
1773 }
1774 if (identical(_sourceKindState, CacheState.IN_PROCESS)) {
1775 _sourceKindState = CacheState.INVALID;
1776 }
1777 if (identical(_parseErrorsState, CacheState.IN_PROCESS)) {
1778 _parseErrorsState = CacheState.INVALID;
1779 }
1780 if (identical(_parsedUnitState, CacheState.IN_PROCESS)) {
1781 _parsedUnitState = CacheState.INVALID;
1782 }
1783 if (identical(_exportedLibrariesState, CacheState.IN_PROCESS)) {
1784 _exportedLibrariesState = CacheState.INVALID;
1785 }
1786 if (identical(_importedLibrariesState, CacheState.IN_PROCESS)) {
1787 _importedLibrariesState = CacheState.INVALID;
1788 }
1789 if (identical(_includedPartsState, CacheState.IN_PROCESS)) {
1790 _includedPartsState = CacheState.INVALID;
1791 }
1792 }
1793
1794 /**
1795 * Record that an error occurred while attempting to scan or parse the entry r epresented by this
1796 * entry. This will set the state of all resolution-based information as being in error, but will
1797 * not change the state of any parse results.
1798 */
1799 void recordResolutionError() {
1800 _element = null;
1801 _elementState = CacheState.ERROR;
1802 _bitmask = 0;
1803 _clientServerState = CacheState.ERROR;
1804 _launchableState = CacheState.ERROR;
1805 _publicNamespace = null;
1806 _publicNamespaceState = CacheState.ERROR;
1807 _resolutionState.recordResolutionError();
1808 }
1809
1810 /**
1811 * Record that an in-process parse has stopped without recording results becau se the results were
1812 * invalidated before they could be recorded.
1813 */
1814 void recordResolutionNotInProcess() {
1815 if (identical(_elementState, CacheState.IN_PROCESS)) {
1816 _elementState = CacheState.INVALID;
1817 }
1818 if (identical(_clientServerState, CacheState.IN_PROCESS)) {
1819 _clientServerState = CacheState.INVALID;
1820 }
1821 if (identical(_launchableState, CacheState.IN_PROCESS)) {
1822 _launchableState = CacheState.INVALID;
1823 }
1824 if (identical(_publicNamespaceState, CacheState.IN_PROCESS)) {
1825 _publicNamespaceState = CacheState.INVALID;
1826 }
1827 _resolutionState.recordResolutionNotInProcess();
1828 }
1829
1830 /**
1831 * Remove any resolution information associated with this compilation unit bei ng part of the given
1832 * library, presumably because it is no longer part of the library.
1833 *
1834 * @param librarySource the source of the defining compilation unit of the lib rary that used to
1835 * contain this part but no longer does
1836 */
1837 void removeResolution(Source librarySource) {
1838 if (librarySource != null) {
1839 if (librarySource == _resolutionState._librarySource) {
1840 if (_resolutionState._nextState == null) {
1841 _resolutionState.invalidateAllResolutionInformation();
1842 } else {
1843 _resolutionState = _resolutionState._nextState;
1844 }
1845 } else {
1846 DartEntryImpl_ResolutionState priorState = _resolutionState;
1847 DartEntryImpl_ResolutionState state = _resolutionState._nextState;
1848 while (state != null) {
1849 if (librarySource == state._librarySource) {
1850 priorState._nextState = state._nextState;
1851 break;
1852 }
1853 priorState = state;
1854 state = state._nextState;
1855 }
1856 }
1857 }
1858 }
1859
1860 /**
1861 * Set the results of parsing the compilation unit at the given time to the gi ven values.
1862 *
1863 * @param modificationStamp the earliest time at which the source was last mod ified before the
1864 * parsing was started
1865 * @param lineInfo the line information resulting from parsing the compilation unit
1866 * @param unit the AST structure resulting from parsing the compilation unit
1867 * @param errors the parse errors resulting from parsing the compilation unit
1868 */
1869 void setParseResults(int modificationStamp, LineInfo lineInfo, CompilationUnit unit, List<AnalysisError> errors) {
1870 if (getState(SourceEntry.LINE_INFO) != CacheState.VALID) {
1871 setValue(SourceEntry.LINE_INFO, lineInfo);
1872 }
1873 if (_parsedUnitState != CacheState.VALID) {
1874 _parsedUnit = unit;
1875 _parsedUnitAccessed = false;
1876 _parsedUnitState = CacheState.VALID;
1877 }
1878 if (_parseErrorsState != CacheState.VALID) {
1879 _parseErrors = errors == null ? AnalysisError.NO_ERRORS : errors;
1880 _parseErrorsState = CacheState.VALID;
1881 }
1882 }
1883 void setState(DataDescriptor descriptor, CacheState state) {
1884 if (identical(descriptor, DartEntry.ELEMENT)) {
1885 _element = updatedValue(state, _element, null);
1886 _elementState = state;
1887 } else if (identical(descriptor, DartEntry.EXPORTED_LIBRARIES)) {
1888 _exportedLibraries = updatedValue(state, _exportedLibraries, Source.EMPTY_ ARRAY);
1889 _exportedLibrariesState = state;
1890 } else if (identical(descriptor, DartEntry.IMPORTED_LIBRARIES)) {
1891 _importedLibraries = updatedValue(state, _importedLibraries, Source.EMPTY_ ARRAY);
1892 _importedLibrariesState = state;
1893 } else if (identical(descriptor, DartEntry.INCLUDED_PARTS)) {
1894 _includedParts = updatedValue(state, _includedParts, Source.EMPTY_ARRAY);
1895 _includedPartsState = state;
1896 } else if (identical(descriptor, DartEntry.IS_CLIENT)) {
1897 _bitmask = updatedValue2(state, _bitmask, _CLIENT_CODE_INDEX);
1898 _clientServerState = state;
1899 } else if (identical(descriptor, DartEntry.IS_LAUNCHABLE)) {
1900 _bitmask = updatedValue2(state, _bitmask, _LAUNCHABLE_INDEX);
1901 _launchableState = state;
1902 } else if (identical(descriptor, DartEntry.PARSE_ERRORS)) {
1903 _parseErrors = updatedValue(state, _parseErrors, AnalysisError.NO_ERRORS);
1904 _parseErrorsState = state;
1905 } else if (identical(descriptor, DartEntry.PARSED_UNIT)) {
1906 CompilationUnit newUnit = updatedValue(state, _parsedUnit, null);
1907 if (newUnit != _parsedUnit) {
1908 _parsedUnitAccessed = false;
1909 }
1910 _parsedUnit = newUnit;
1911 _parsedUnitState = state;
1912 } else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) {
1913 _publicNamespace = updatedValue(state, _publicNamespace, null);
1914 _publicNamespaceState = state;
1915 } else if (identical(descriptor, DartEntry.SOURCE_KIND)) {
1916 _sourceKind = updatedValue(state, _sourceKind, SourceKind.UNKNOWN);
1917 _sourceKindState = state;
1918 } else {
1919 super.setState(descriptor, state);
1920 }
1921 }
1922
1923 /**
1924 * Set the state of the data represented by the given descriptor in the contex t of the given
1925 * library to the given state.
1926 *
1927 * @param descriptor the descriptor representing the data whose state is to be set
1928 * @param librarySource the source of the defining compilation unit of the lib rary that is the
1929 * context for the data
1930 * @param cacheState the new state of the data represented by the given descri ptor
1931 */
1932 void setState2(DataDescriptor descriptor, Source librarySource, CacheState cac heState) {
1933 DartEntryImpl_ResolutionState state = getOrCreateResolutionState(librarySour ce);
1934 if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
1935 state._resolutionErrors = updatedValue(cacheState, state._resolutionErrors , AnalysisError.NO_ERRORS);
1936 state._resolutionErrorsState = cacheState;
1937 } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
1938 state._resolvedUnit = updatedValue(cacheState, state._resolvedUnit, null);
1939 state._resolvedUnitState = cacheState;
1940 } else if (identical(descriptor, DartEntry.VERIFICATION_ERRORS)) {
1941 state._verificationErrors = updatedValue(cacheState, state._verificationEr rors, AnalysisError.NO_ERRORS);
1942 state._verificationErrorsState = cacheState;
1943 } else if (identical(descriptor, DartEntry.HINTS)) {
1944 state._hints = updatedValue(cacheState, state._hints, AnalysisError.NO_ERR ORS);
1945 state._hintsState = cacheState;
1946 } else {
1947 throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
1948 }
1949 }
1950 void setValue(DataDescriptor descriptor, Object value) {
1951 if (identical(descriptor, DartEntry.ELEMENT)) {
1952 _element = value as LibraryElement;
1953 _elementState = CacheState.VALID;
1954 } else if (identical(descriptor, DartEntry.EXPORTED_LIBRARIES)) {
1955 _exportedLibraries = value == null ? Source.EMPTY_ARRAY : (value as List<S ource>);
1956 _exportedLibrariesState = CacheState.VALID;
1957 } else if (identical(descriptor, DartEntry.IMPORTED_LIBRARIES)) {
1958 _importedLibraries = value == null ? Source.EMPTY_ARRAY : (value as List<S ource>);
1959 _importedLibrariesState = CacheState.VALID;
1960 } else if (identical(descriptor, DartEntry.INCLUDED_PARTS)) {
1961 _includedParts = value == null ? Source.EMPTY_ARRAY : (value as List<Sourc e>);
1962 _includedPartsState = CacheState.VALID;
1963 } else if (identical(descriptor, DartEntry.IS_CLIENT)) {
1964 _bitmask = BooleanArray.set2(_bitmask, _CLIENT_CODE_INDEX, value as bool);
1965 _clientServerState = CacheState.VALID;
1966 } else if (identical(descriptor, DartEntry.IS_LAUNCHABLE)) {
1967 _bitmask = BooleanArray.set2(_bitmask, _LAUNCHABLE_INDEX, value as bool);
1968 _launchableState = CacheState.VALID;
1969 } else if (identical(descriptor, DartEntry.PARSE_ERRORS)) {
1970 _parseErrors = value == null ? AnalysisError.NO_ERRORS : (value as List<An alysisError>);
1971 _parseErrorsState = CacheState.VALID;
1972 } else if (identical(descriptor, DartEntry.PARSED_UNIT)) {
1973 _parsedUnit = value as CompilationUnit;
1974 _parsedUnitAccessed = false;
1975 _parsedUnitState = CacheState.VALID;
1976 } else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) {
1977 _publicNamespace = value as Namespace;
1978 _publicNamespaceState = CacheState.VALID;
1979 } else if (identical(descriptor, DartEntry.SOURCE_KIND)) {
1980 _sourceKind = value as SourceKind;
1981 _sourceKindState = CacheState.VALID;
1982 } else {
1983 super.setValue(descriptor, value);
1984 }
1985 }
1986
1987 /**
1988 * Set the value of the data represented by the given descriptor in the contex t of the given
1989 * library to the given value, and set the state of that data to [CacheState#V ALID].
1990 *
1991 * @param descriptor the descriptor representing which data is to have its val ue set
1992 * @param librarySource the source of the defining compilation unit of the lib rary that is the
1993 * context for the data
1994 * @param value the new value of the data represented by the given descriptor and library
1995 */
1996 void setValue2(DataDescriptor descriptor, Source librarySource, Object value) {
1997 DartEntryImpl_ResolutionState state = getOrCreateResolutionState(librarySour ce);
1998 if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
1999 state._resolutionErrors = value == null ? AnalysisError.NO_ERRORS : (value as List<AnalysisError>);
2000 state._resolutionErrorsState = CacheState.VALID;
2001 } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
2002 state._resolvedUnit = value as CompilationUnit;
2003 state._resolvedUnitState = CacheState.VALID;
2004 } else if (identical(descriptor, DartEntry.VERIFICATION_ERRORS)) {
2005 state._verificationErrors = value == null ? AnalysisError.NO_ERRORS : (val ue as List<AnalysisError>);
2006 state._verificationErrorsState = CacheState.VALID;
2007 } else if (identical(descriptor, DartEntry.HINTS)) {
2008 state._hints = value == null ? AnalysisError.NO_ERRORS : (value as List<An alysisError>);
2009 state._hintsState = CacheState.VALID;
2010 }
2011 }
2012 void copyFrom(SourceEntryImpl entry) {
2013 super.copyFrom(entry);
2014 DartEntryImpl other = entry as DartEntryImpl;
2015 _sourceKindState = other._sourceKindState;
2016 _sourceKind = other._sourceKind;
2017 _parsedUnitState = other._parsedUnitState;
2018 _parsedUnit = other._parsedUnit;
2019 _parsedUnitAccessed = other._parsedUnitAccessed;
2020 _parseErrorsState = other._parseErrorsState;
2021 _parseErrors = other._parseErrors;
2022 _includedPartsState = other._includedPartsState;
2023 _includedParts = other._includedParts;
2024 _exportedLibrariesState = other._exportedLibrariesState;
2025 _exportedLibraries = other._exportedLibraries;
2026 _importedLibrariesState = other._importedLibrariesState;
2027 _importedLibraries = other._importedLibraries;
2028 _resolutionState.copyFrom(other._resolutionState);
2029 _elementState = other._elementState;
2030 _element = other._element;
2031 _publicNamespaceState = other._publicNamespaceState;
2032 _publicNamespace = other._publicNamespace;
2033 _clientServerState = other._clientServerState;
2034 _launchableState = other._launchableState;
2035 _bitmask = other._bitmask;
2036 }
2037 void writeOn(JavaStringBuilder builder) {
2038 builder.append("Dart: ");
2039 super.writeOn(builder);
2040 builder.append("; sourceKind = ");
2041 builder.append(_sourceKindState);
2042 builder.append("; parsedUnit = ");
2043 builder.append(_parsedUnitState);
2044 builder.append(" (");
2045 builder.append(_parsedUnitAccessed ? "T" : "F");
2046 builder.append("); parseErrors = ");
2047 builder.append(_parseErrorsState);
2048 builder.append("; exportedLibraries = ");
2049 builder.append(_exportedLibrariesState);
2050 builder.append("; importedLibraries = ");
2051 builder.append(_importedLibrariesState);
2052 builder.append("; includedParts = ");
2053 builder.append(_includedPartsState);
2054 builder.append("; element = ");
2055 builder.append(_elementState);
2056 builder.append("; publicNamespace = ");
2057 builder.append(_publicNamespaceState);
2058 builder.append("; clientServer = ");
2059 builder.append(_clientServerState);
2060 builder.append("; launchable = ");
2061 builder.append(_launchableState);
2062 _resolutionState.writeOn(builder);
2063 }
2064
2065 /**
2066 * Invalidate all of the resolution information associated with the compilatio n unit.
2067 */
2068 void discardCachedResolutionInformation() {
2069 _element = null;
2070 _elementState = CacheState.INVALID;
2071 _includedParts = Source.EMPTY_ARRAY;
2072 _includedPartsState = CacheState.INVALID;
2073 _exportedLibraries = Source.EMPTY_ARRAY;
2074 _exportedLibrariesState = CacheState.INVALID;
2075 _importedLibraries = Source.EMPTY_ARRAY;
2076 _importedLibrariesState = CacheState.INVALID;
2077 _bitmask = 0;
2078 _clientServerState = CacheState.INVALID;
2079 _launchableState = CacheState.INVALID;
2080 _publicNamespace = null;
2081 _publicNamespaceState = CacheState.INVALID;
2082 _resolutionState.invalidateAllResolutionInformation();
2083 }
2084
2085 /**
2086 * Return a resolution state for the specified library, creating one as necess ary.
2087 *
2088 * @param librarySource the library source (not `null`)
2089 * @return the resolution state (not `null`)
2090 */
2091 DartEntryImpl_ResolutionState getOrCreateResolutionState(Source librarySource) {
2092 DartEntryImpl_ResolutionState state = _resolutionState;
2093 if (state._librarySource == null) {
2094 state._librarySource = librarySource;
2095 return state;
2096 }
2097 while (state._librarySource != librarySource) {
2098 if (state._nextState == null) {
2099 DartEntryImpl_ResolutionState newState = new DartEntryImpl_ResolutionSta te();
2100 newState._librarySource = librarySource;
2101 state._nextState = newState;
2102 return newState;
2103 }
2104 state = state._nextState;
2105 }
2106 return state;
2107 }
2108
2109 /**
2110 * Given that one of the flags is being transitioned to the given state, retur n the value of the
2111 * flags that should be kept in the cache.
2112 *
2113 * @param state the state to which the data is being transitioned
2114 * @param currentValue the value of the flags before the transition
2115 * @param bitMask the mask used to access the bit whose state is being set
2116 * @return the value of the data that should be kept in the cache
2117 */
2118 int updatedValue2(CacheState state, int currentValue, int bitIndex) {
2119 if (identical(state, CacheState.VALID)) {
2120 throw new IllegalArgumentException("Use setValue() to set the state to VAL ID");
2121 } else if (identical(state, CacheState.IN_PROCESS)) {
2122 return currentValue;
2123 }
2124 return BooleanArray.set2(currentValue, bitIndex, false);
2125 }
2126 }
2127 /**
2128 * Instances of the class `ResolutionState` represent the information produced b y resolving
2129 * a compilation unit as part of a specific library.
2130 */
2131 class DartEntryImpl_ResolutionState {
2132
2133 /**
2134 * The next resolution state or `null` if none.
2135 */
2136 DartEntryImpl_ResolutionState _nextState;
2137
2138 /**
2139 * The source for the defining compilation unit of the library that contains t his unit. If this
2140 * unit is the defining compilation unit for it's library, then this will be t he source for this
2141 * unit.
2142 */
2143 Source _librarySource;
2144
2145 /**
2146 * The state of the cached resolved compilation unit.
2147 */
2148 CacheState _resolvedUnitState = CacheState.INVALID;
2149
2150 /**
2151 * The resolved compilation unit, or `null` if the resolved compilation unit i s not
2152 * currently cached.
2153 */
2154 CompilationUnit _resolvedUnit;
2155
2156 /**
2157 * The state of the cached resolution errors.
2158 */
2159 CacheState _resolutionErrorsState = CacheState.INVALID;
2160
2161 /**
2162 * The errors produced while resolving the compilation unit, or an empty array if the errors are
2163 * not currently cached.
2164 */
2165 List<AnalysisError> _resolutionErrors = AnalysisError.NO_ERRORS;
2166
2167 /**
2168 * The state of the cached verification errors.
2169 */
2170 CacheState _verificationErrorsState = CacheState.INVALID;
2171
2172 /**
2173 * The errors produced while verifying the compilation unit, or an empty array if the errors are
2174 * not currently cached.
2175 */
2176 List<AnalysisError> _verificationErrors = AnalysisError.NO_ERRORS;
2177
2178 /**
2179 * The state of the cached hints.
2180 */
2181 CacheState _hintsState = CacheState.INVALID;
2182
2183 /**
2184 * The hints produced while auditing the compilation unit, or an empty array i f the hints are
2185 * not currently cached.
2186 */
2187 List<AnalysisError> _hints = AnalysisError.NO_ERRORS;
2188
2189 /**
2190 * Set this state to be exactly like the given state, recursively copying the next state as
2191 * necessary.
2192 *
2193 * @param other the state to be copied
2194 */
2195 void copyFrom(DartEntryImpl_ResolutionState other) {
2196 _librarySource = other._librarySource;
2197 _resolvedUnitState = other._resolvedUnitState;
2198 _resolvedUnit = other._resolvedUnit;
2199 _resolutionErrorsState = other._resolutionErrorsState;
2200 _resolutionErrors = other._resolutionErrors;
2201 _verificationErrorsState = other._verificationErrorsState;
2202 _verificationErrors = other._verificationErrors;
2203 _hintsState = other._hintsState;
2204 _hints = other._hints;
2205 if (other._nextState != null) {
2206 _nextState = new DartEntryImpl_ResolutionState();
2207 _nextState.copyFrom(other._nextState);
2208 }
2209 }
2210
2211 /**
2212 * Flush any AST structures being maintained by this state.
2213 */
2214 void flushAstStructures() {
2215 if (identical(_resolvedUnitState, CacheState.VALID)) {
2216 _resolvedUnitState = CacheState.FLUSHED;
2217 _resolvedUnit = null;
2218 }
2219 if (_nextState != null) {
2220 _nextState.flushAstStructures();
2221 }
2222 }
2223
2224 /**
2225 * Invalidate all of the resolution information associated with the compilatio n unit.
2226 */
2227 void invalidateAllResolutionInformation() {
2228 _nextState = null;
2229 _librarySource = null;
2230 _resolvedUnitState = CacheState.INVALID;
2231 _resolvedUnit = null;
2232 _resolutionErrorsState = CacheState.INVALID;
2233 _resolutionErrors = AnalysisError.NO_ERRORS;
2234 _verificationErrorsState = CacheState.INVALID;
2235 _verificationErrors = AnalysisError.NO_ERRORS;
2236 _hintsState = CacheState.INVALID;
2237 _hints = AnalysisError.NO_ERRORS;
2238 }
2239
2240 /**
2241 * Record that an error occurred while attempting to scan or parse the entry r epresented by this
2242 * entry. This will set the state of all resolution-based information as being in error, but
2243 * will not change the state of any parse results.
2244 */
2245 void recordResolutionError() {
2246 _resolvedUnitState = CacheState.ERROR;
2247 _resolvedUnit = null;
2248 _resolutionErrorsState = CacheState.ERROR;
2249 _resolutionErrors = AnalysisError.NO_ERRORS;
2250 _verificationErrorsState = CacheState.ERROR;
2251 _verificationErrors = AnalysisError.NO_ERRORS;
2252 _hintsState = CacheState.ERROR;
2253 _hints = AnalysisError.NO_ERRORS;
2254 if (_nextState != null) {
2255 _nextState.recordResolutionError();
2256 }
2257 }
2258
2259 /**
2260 * Record that an in-process parse has stopped without recording results becau se the results
2261 * were invalidated before they could be recorded.
2262 */
2263 void recordResolutionNotInProcess() {
2264 if (identical(_resolvedUnitState, CacheState.IN_PROCESS)) {
2265 _resolvedUnitState = CacheState.INVALID;
2266 }
2267 if (identical(_resolutionErrorsState, CacheState.IN_PROCESS)) {
2268 _resolutionErrorsState = CacheState.INVALID;
2269 }
2270 if (identical(_verificationErrorsState, CacheState.IN_PROCESS)) {
2271 _verificationErrorsState = CacheState.INVALID;
2272 }
2273 if (identical(_hintsState, CacheState.IN_PROCESS)) {
2274 _hintsState = CacheState.INVALID;
2275 }
2276 if (_nextState != null) {
2277 _nextState.recordResolutionNotInProcess();
2278 }
2279 }
2280
2281 /**
2282 * Write a textual representation of this state to the given builder. The resu lt will only be
2283 * used for debugging purposes.
2284 *
2285 * @param builder the builder to which the text should be written
2286 */
2287 void writeOn(JavaStringBuilder builder) {
2288 if (_librarySource != null) {
2289 builder.append("; resolvedUnit = ");
2290 builder.append(_resolvedUnitState);
2291 builder.append("; resolutionErrors = ");
2292 builder.append(_resolutionErrorsState);
2293 builder.append("; verificationErrors = ");
2294 builder.append(_verificationErrorsState);
2295 builder.append("; hints = ");
2296 builder.append(_hintsState);
2297 if (_nextState != null) {
2298 _nextState.writeOn(builder);
2299 }
2300 }
2301 }
2302 }
2303 /**
2304 * Instances of the class `DataDescriptor` are immutable constants representing data that can
2305 * be stored in the cache.
2306 */
2307 class DataDescriptor<E> {
2308
2309 /**
2310 * The name of the descriptor, used for debugging purposes.
2311 */
2312 String _name;
2313
2314 /**
2315 * Initialize a newly created descriptor to have the given name.
2316 *
2317 * @param name the name of the descriptor
2318 */
2319 DataDescriptor(String name) {
2320 this._name = name;
2321 }
2322 String toString() => _name;
2323 }
2324 /**
2325 * The interface `HtmlEntry` defines the behavior of objects that maintain the i nformation
2326 * cached by an analysis context about an individual HTML file.
2327 *
2328 * @coverage dart.engine
2329 */
2330 abstract class HtmlEntry implements SourceEntry {
2331
2332 /**
2333 * The data descriptor representing the HTML element.
2334 */
2335 static final DataDescriptor<HtmlElement> ELEMENT = new DataDescriptor<HtmlElem ent>("HtmlEntry.ELEMENT");
2336
2337 /**
2338 * The data descriptor representing the hints resulting from auditing the sour ce.
2339 */
2340 static final DataDescriptor<List<AnalysisError>> HINTS = new DataDescriptor<Li st<AnalysisError>>("DartEntry.HINTS");
2341
2342 /**
2343 * The data descriptor representing the parsed AST structure.
2344 */
2345 static final DataDescriptor<HtmlUnit> PARSED_UNIT = new DataDescriptor<HtmlUni t>("HtmlEntry.PARSED_UNIT");
2346
2347 /**
2348 * The data descriptor representing the list of referenced libraries.
2349 */
2350 static final DataDescriptor<List<Source>> REFERENCED_LIBRARIES = new DataDescr iptor<List<Source>>("HtmlEntry.REFERENCED_LIBRARIES");
2351
2352 /**
2353 * The data descriptor representing the errors resulting from resolving the so urce.
2354 */
2355 static final DataDescriptor<List<AnalysisError>> RESOLUTION_ERRORS = new DataD escriptor<List<AnalysisError>>("HtmlEntry.RESOLUTION_ERRORS");
2356
2357 /**
2358 * Return all of the errors associated with the compilation unit that are curr ently cached.
2359 *
2360 * @return all of the errors associated with the compilation unit
2361 */
2362 List<AnalysisError> get allErrors;
2363 HtmlEntryImpl get writableCopy;
2364 }
2365 /**
2366 * Instances of the class `HtmlEntryImpl` implement an [HtmlEntry].
2367 *
2368 * @coverage dart.engine
2369 */
2370 class HtmlEntryImpl extends SourceEntryImpl implements HtmlEntry {
2371
2372 /**
2373 * The state of the cached parsed (but not resolved) HTML unit.
2374 */
2375 CacheState _parsedUnitState = CacheState.INVALID;
2376
2377 /**
2378 * The parsed HTML unit, or `null` if the parsed HTML unit is not currently ca ched.
2379 */
2380 HtmlUnit _parsedUnit;
2381
2382 /**
2383 * The state of the cached resolution errors.
2384 */
2385 CacheState _resolutionErrorsState = CacheState.INVALID;
2386
2387 /**
2388 * The errors produced while resolving the compilation unit, or `null` if the errors are not
2389 * currently cached.
2390 */
2391 List<AnalysisError> _resolutionErrors = AnalysisError.NO_ERRORS;
2392
2393 /**
2394 * The state of the cached list of referenced libraries.
2395 */
2396 CacheState _referencedLibrariesState = CacheState.INVALID;
2397
2398 /**
2399 * The list of libraries referenced in the HTML, or `null` if the list is not currently
2400 * cached. Note that this list does not include libraries defined directly wit hin the HTML file.
2401 */
2402 List<Source> _referencedLibraries = Source.EMPTY_ARRAY;
2403
2404 /**
2405 * The state of the cached HTML element.
2406 */
2407 CacheState _elementState = CacheState.INVALID;
2408
2409 /**
2410 * The element representing the HTML file, or `null` if the element is not cur rently cached.
2411 */
2412 HtmlElement _element;
2413
2414 /**
2415 * The state of the cached hints.
2416 */
2417 CacheState _hintsState = CacheState.INVALID;
2418
2419 /**
2420 * The hints produced while auditing the compilation unit, or an empty array i f the hints are not
2421 * currently cached.
2422 */
2423 List<AnalysisError> _hints = AnalysisError.NO_ERRORS;
2424 List<AnalysisError> get allErrors {
2425 List<AnalysisError> errors = new List<AnalysisError>();
2426 for (AnalysisError error in _resolutionErrors) {
2427 errors.add(error);
2428 }
2429 for (AnalysisError error in _hints) {
2430 errors.add(error);
2431 }
2432 if (errors.length == 0) {
2433 return AnalysisError.NO_ERRORS;
2434 }
2435 return new List.from(errors);
2436 }
2437 SourceKind get kind => SourceKind.HTML;
2438 CacheState getState(DataDescriptor descriptor) {
2439 if (identical(descriptor, HtmlEntry.ELEMENT)) {
2440 return _elementState;
2441 } else if (identical(descriptor, HtmlEntry.PARSED_UNIT)) {
2442 return _parsedUnitState;
2443 } else if (identical(descriptor, HtmlEntry.REFERENCED_LIBRARIES)) {
2444 return _referencedLibrariesState;
2445 } else if (identical(descriptor, HtmlEntry.RESOLUTION_ERRORS)) {
2446 return _resolutionErrorsState;
2447 } else if (identical(descriptor, HtmlEntry.HINTS)) {
2448 return _hintsState;
2449 }
2450 return super.getState(descriptor);
2451 }
2452 Object getValue(DataDescriptor descriptor) {
2453 if (identical(descriptor, HtmlEntry.ELEMENT)) {
2454 return _element as Object;
2455 } else if (identical(descriptor, HtmlEntry.PARSED_UNIT)) {
2456 return _parsedUnit as Object;
2457 } else if (identical(descriptor, HtmlEntry.REFERENCED_LIBRARIES)) {
2458 return _referencedLibraries as Object;
2459 } else if (identical(descriptor, HtmlEntry.RESOLUTION_ERRORS)) {
2460 return _resolutionErrors as Object;
2461 } else if (identical(descriptor, HtmlEntry.HINTS)) {
2462 return _hints as Object;
2463 }
2464 return super.getValue(descriptor);
2465 }
2466 HtmlEntryImpl get writableCopy {
2467 HtmlEntryImpl copy = new HtmlEntryImpl();
2468 copy.copyFrom(this);
2469 return copy;
2470 }
2471
2472 /**
2473 * Invalidate all of the information associated with the HTML file.
2474 */
2475 void invalidateAllInformation() {
2476 setState(SourceEntry.LINE_INFO, CacheState.INVALID);
2477 _parsedUnit = null;
2478 _parsedUnitState = CacheState.INVALID;
2479 _referencedLibraries = Source.EMPTY_ARRAY;
2480 _referencedLibrariesState = CacheState.INVALID;
2481 invalidateAllResolutionInformation();
2482 }
2483
2484 /**
2485 * Invalidate all of the resolution information associated with the HTML file.
2486 */
2487 void invalidateAllResolutionInformation() {
2488 _element = null;
2489 _elementState = CacheState.INVALID;
2490 _resolutionErrors = AnalysisError.NO_ERRORS;
2491 _resolutionErrorsState = CacheState.INVALID;
2492 _hints = AnalysisError.NO_ERRORS;
2493 _hintsState = CacheState.INVALID;
2494 }
2495
2496 /**
2497 * Record that an error was encountered while attempting to resolve the source associated with
2498 * this entry.
2499 */
2500 void recordResolutionError() {
2501 setState(HtmlEntry.ELEMENT, CacheState.ERROR);
2502 setState(HtmlEntry.RESOLUTION_ERRORS, CacheState.ERROR);
2503 }
2504 void setState(DataDescriptor descriptor, CacheState state) {
2505 if (identical(descriptor, HtmlEntry.ELEMENT)) {
2506 _element = updatedValue(state, _element, null);
2507 _elementState = state;
2508 } else if (identical(descriptor, HtmlEntry.PARSED_UNIT)) {
2509 _parsedUnit = updatedValue(state, _parsedUnit, null);
2510 _parsedUnitState = state;
2511 } else if (identical(descriptor, HtmlEntry.REFERENCED_LIBRARIES)) {
2512 _referencedLibraries = updatedValue(state, _referencedLibraries, Source.EM PTY_ARRAY);
2513 _referencedLibrariesState = state;
2514 } else if (identical(descriptor, HtmlEntry.RESOLUTION_ERRORS)) {
2515 _resolutionErrors = updatedValue(state, _resolutionErrors, AnalysisError.N O_ERRORS);
2516 _resolutionErrorsState = state;
2517 } else if (identical(descriptor, HtmlEntry.HINTS)) {
2518 _hints = updatedValue(state, _hints, AnalysisError.NO_ERRORS);
2519 _hintsState = state;
2520 } else {
2521 super.setState(descriptor, state);
2522 }
2523 }
2524 void setValue(DataDescriptor descriptor, Object value) {
2525 if (identical(descriptor, HtmlEntry.ELEMENT)) {
2526 _element = value as HtmlElement;
2527 _elementState = CacheState.VALID;
2528 } else if (identical(descriptor, HtmlEntry.PARSED_UNIT)) {
2529 _parsedUnit = value as HtmlUnit;
2530 _parsedUnitState = CacheState.VALID;
2531 } else if (identical(descriptor, HtmlEntry.REFERENCED_LIBRARIES)) {
2532 _referencedLibraries = value == null ? Source.EMPTY_ARRAY : (value as List <Source>);
2533 _referencedLibrariesState = CacheState.VALID;
2534 } else if (identical(descriptor, HtmlEntry.RESOLUTION_ERRORS)) {
2535 _resolutionErrors = value as List<AnalysisError>;
2536 _resolutionErrorsState = CacheState.VALID;
2537 } else if (identical(descriptor, HtmlEntry.HINTS)) {
2538 _hints = value as List<AnalysisError>;
2539 _hintsState = CacheState.VALID;
2540 } else {
2541 super.setValue(descriptor, value);
2542 }
2543 }
2544 void copyFrom(SourceEntryImpl entry) {
2545 super.copyFrom(entry);
2546 HtmlEntryImpl other = entry as HtmlEntryImpl;
2547 _parsedUnitState = other._parsedUnitState;
2548 _parsedUnit = other._parsedUnit;
2549 _referencedLibrariesState = other._referencedLibrariesState;
2550 _referencedLibraries = other._referencedLibraries;
2551 _resolutionErrors = other._resolutionErrors;
2552 _resolutionErrorsState = other._resolutionErrorsState;
2553 _elementState = other._elementState;
2554 _element = other._element;
2555 _hints = other._hints;
2556 _hintsState = other._hintsState;
2557 }
2558 void writeOn(JavaStringBuilder builder) {
2559 builder.append("Html: ");
2560 super.writeOn(builder);
2561 builder.append("; parsedUnit = ");
2562 builder.append(_parsedUnitState);
2563 builder.append("; resolutionErrors = ");
2564 builder.append(_resolutionErrorsState);
2565 builder.append("; referencedLibraries = ");
2566 builder.append(_referencedLibrariesState);
2567 builder.append("; element = ");
2568 builder.append(_elementState);
2569 }
2570 }
2571 /**
2572 * The enumerated type `RetentionPriority` represents the priority of data in th e cache in
2573 * terms of the desirability of retaining some specified data about a specified source.
2574 */
2575 class RetentionPriority extends Enum<RetentionPriority> {
2576
2577 /**
2578 * A priority indicating that a given piece of data can be removed from the ca che without
2579 * reservation.
2580 */
2581 static final RetentionPriority LOW = new RetentionPriority('LOW', 0);
2582
2583 /**
2584 * A priority indicating that a given piece of data should not be removed from the cache unless
2585 * there are no sources for which the corresponding data has a lower priority. Currently used for
2586 * data that is needed in order to finish some outstanding analysis task.
2587 */
2588 static final RetentionPriority MEDIUM = new RetentionPriority('MEDIUM', 1);
2589
2590 /**
2591 * A priority indicating that a given piece of data should not be removed from the cache.
2592 * Currently used for data related to a priority source.
2593 */
2594 static final RetentionPriority HIGH = new RetentionPriority('HIGH', 2);
2595 static final List<RetentionPriority> values = [LOW, MEDIUM, HIGH];
2596 RetentionPriority(String name, int ordinal) : super(name, ordinal);
2597 }
2598 /**
2599 * The interface `SourceEntry` defines the behavior of objects that maintain the information
2600 * cached by an analysis context about an individual source, no matter what kind of source it is.
2601 *
2602 * Source entries should be treated as if they were immutable unless a writable copy of the entry
2603 * has been obtained and has not yet been made visible to other threads.
2604 *
2605 * @coverage dart.engine
2606 */
2607 abstract class SourceEntry {
2608
2609 /**
2610 * The data descriptor representing the line information.
2611 */
2612 static final DataDescriptor<LineInfo> LINE_INFO = new DataDescriptor<LineInfo> ("SourceEntry.LINE_INFO");
2613
2614 /**
2615 * Return the exception that caused one or more values to have a state of [Cac heState#ERROR]
2616 * .
2617 *
2618 * @return the exception that caused one or more values to be uncomputable
2619 */
2620 AnalysisException get exception;
2621
2622 /**
2623 * Return the kind of the source, or `null` if the kind is not currently cache d.
2624 *
2625 * @return the kind of the source
2626 */
2627 SourceKind get kind;
2628
2629 /**
2630 * Return the most recent time at which the state of the source matched the st ate represented by
2631 * this entry.
2632 *
2633 * @return the modification time of this entry
2634 */
2635 int get modificationTime;
2636
2637 /**
2638 * Return the state of the data represented by the given descriptor.
2639 *
2640 * @param descriptor the descriptor representing the data whose state is to be returned
2641 * @return the state of the data represented by the given descriptor
2642 */
2643 CacheState getState(DataDescriptor descriptor);
2644
2645 /**
2646 * Return the value of the data represented by the given descriptor, or `null` if the data
2647 * represented by the descriptor is not in the cache.
2648 *
2649 * @param descriptor the descriptor representing which data is to be returned
2650 * @return the value of the data represented by the given descriptor
2651 */
2652 Object getValue(DataDescriptor descriptor);
2653
2654 /**
2655 * Return a new entry that is initialized to the same state as this entry but that can be
2656 * modified.
2657 *
2658 * @return a writable copy of this entry
2659 */
2660 SourceEntryImpl get writableCopy;
2661 }
2662 /**
2663 * Instances of the abstract class `SourceEntryImpl` implement the behavior comm on to all
2664 * [SourceEntry].
2665 *
2666 * @coverage dart.engine
2667 */
2668 abstract class SourceEntryImpl implements SourceEntry {
2669
2670 /**
2671 * The most recent time at which the state of the source matched the state rep resented by this
2672 * entry.
2673 */
2674 int _modificationTime = 0;
2675
2676 /**
2677 * The exception that caused one or more values to have a state of [CacheState #ERROR].
2678 */
2679 AnalysisException _exception;
2680
2681 /**
2682 * The state of the cached line information.
2683 */
2684 CacheState _lineInfoState = CacheState.INVALID;
2685
2686 /**
2687 * The line information computed for the source, or `null` if the line informa tion is not
2688 * currently cached.
2689 */
2690 LineInfo _lineInfo;
2691
2692 /**
2693 * Return the exception that caused one or more values to have a state of [Cac heState#ERROR]
2694 * .
2695 *
2696 * @return the exception that caused one or more values to be uncomputable
2697 */
2698 AnalysisException get exception => _exception;
2699 int get modificationTime => _modificationTime;
2700 CacheState getState(DataDescriptor descriptor) {
2701 if (identical(descriptor, SourceEntry.LINE_INFO)) {
2702 return _lineInfoState;
2703 } else {
2704 throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
2705 }
2706 }
2707 Object getValue(DataDescriptor descriptor) {
2708 if (identical(descriptor, SourceEntry.LINE_INFO)) {
2709 return _lineInfo as Object;
2710 } else {
2711 throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
2712 }
2713 }
2714
2715 /**
2716 * Set the exception that caused one or more values to have a state of [CacheS tate#ERROR] to
2717 * the given exception.
2718 *
2719 * @param exception the exception that caused one or more values to be uncompu table
2720 */
2721 void set exception(AnalysisException exception) {
2722 this._exception = exception;
2723 }
2724
2725 /**
2726 * Set the most recent time at which the state of the source matched the state represented by this
2727 * entry to the given time.
2728 *
2729 * @param time the new modification time of this entry
2730 */
2731 void set modificationTime(int time) {
2732 _modificationTime = time;
2733 }
2734
2735 /**
2736 * Set the state of the data represented by the given descriptor to the given state.
2737 *
2738 * @param descriptor the descriptor representing the data whose state is to be set
2739 * @param the new state of the data represented by the given descriptor
2740 */
2741 void setState(DataDescriptor descriptor, CacheState state) {
2742 if (identical(descriptor, SourceEntry.LINE_INFO)) {
2743 _lineInfo = updatedValue(state, _lineInfo, null);
2744 _lineInfoState = state;
2745 } else {
2746 throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
2747 }
2748 }
2749
2750 /**
2751 * Set the value of the data represented by the given descriptor to the given value.
2752 *
2753 * @param descriptor the descriptor representing the data whose value is to be set
2754 * @param value the new value of the data represented by the given descriptor
2755 */
2756 void setValue(DataDescriptor descriptor, Object value) {
2757 if (identical(descriptor, SourceEntry.LINE_INFO)) {
2758 _lineInfo = value as LineInfo;
2759 _lineInfoState = CacheState.VALID;
2760 } else {
2761 throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
2762 }
2763 }
2764 String toString() {
2765 JavaStringBuilder builder = new JavaStringBuilder();
2766 writeOn(builder);
2767 return builder.toString();
2768 }
2769
2770 /**
2771 * Copy the information from the given cache entry.
2772 *
2773 * @param entry the cache entry from which information will be copied
2774 */
2775 void copyFrom(SourceEntryImpl entry) {
2776 _modificationTime = entry._modificationTime;
2777 _lineInfoState = entry._lineInfoState;
2778 _lineInfo = entry._lineInfo;
2779 }
2780
2781 /**
2782 * Given that some data is being transitioned to the given state, return the v alue that should be
2783 * kept in the cache.
2784 *
2785 * @param state the state to which the data is being transitioned
2786 * @param currentValue the value of the data before the transition
2787 * @param defaultValue the value to be used if the current value is to be remo ved from the cache
2788 * @return the value of the data that should be kept in the cache
2789 */
2790 Object updatedValue(CacheState state, Object currentValue, Object defaultValue ) {
2791 if (identical(state, CacheState.VALID)) {
2792 throw new IllegalArgumentException("Use setValue() to set the state to VAL ID");
2793 } else if (identical(state, CacheState.IN_PROCESS)) {
2794 return currentValue;
2795 }
2796 return defaultValue;
2797 }
2798
2799 /**
2800 * Write a textual representation of this entry to the given builder. The resu lt will only be used
2801 * for debugging purposes.
2802 *
2803 * @param builder the builder to which the text should be written
2804 */
2805 void writeOn(JavaStringBuilder builder) {
2806 builder.append("time = ");
2807 builder.append(_modificationTime.toRadixString(16));
2808 builder.append("; lineInfo = ");
2809 builder.append(_lineInfoState);
2810 }
2811 }
2812 /**
2813 * Implementation of the [AnalysisContentStatistics].
2814 */
2815 class AnalysisContentStatisticsImpl implements AnalysisContentStatistics {
2816 Map<String, AnalysisContentStatistics_CacheRow> _dataMap = new Map<String, Ana lysisContentStatistics_CacheRow>();
2817 Set<AnalysisException> _exceptions = new Set<AnalysisException>();
2818 List<AnalysisContentStatistics_CacheRow> get cacheRows {
2819 Iterable<AnalysisContentStatistics_CacheRow> items = _dataMap.values;
2820 return new List.from(items);
2821 }
2822 List<AnalysisException> get exceptions => new List.from(_exceptions);
2823 void putCacheItem(DartEntry dartEntry, DataDescriptor descriptor) {
2824 putCacheItem3(dartEntry, descriptor, dartEntry.getState(descriptor));
2825 }
2826 void putCacheItem2(DartEntry dartEntry, Source librarySource, DataDescriptor d escriptor) {
2827 putCacheItem3(dartEntry, descriptor, dartEntry.getState2(descriptor, library Source));
2828 }
2829 void putCacheItem3(SourceEntry dartEntry, DataDescriptor rowDesc, CacheState s tate) {
2830 String rowName = rowDesc.toString();
2831 AnalysisContentStatisticsImpl_CacheRowImpl row = _dataMap[rowName] as Analys isContentStatisticsImpl_CacheRowImpl;
2832 if (row == null) {
2833 row = new AnalysisContentStatisticsImpl_CacheRowImpl(rowName);
2834 _dataMap[rowName] = row;
2835 }
2836 row.incState(state);
2837 if (identical(state, CacheState.ERROR)) {
2838 AnalysisException exception = dartEntry.exception;
2839 if (exception != null) {
2840 javaSetAdd(_exceptions, exception);
2841 }
2842 }
2843 }
2844 }
2845 class AnalysisContentStatisticsImpl_CacheRowImpl implements AnalysisContentStati stics_CacheRow {
2846 String _name;
2847 int _errorCount = 0;
2848 int _flushedCount = 0;
2849 int _inProcessCount = 0;
2850 int _invalidCount = 0;
2851 int _validCount = 0;
2852 AnalysisContentStatisticsImpl_CacheRowImpl(String name) {
2853 this._name = name;
2854 }
2855 bool operator ==(Object obj) => obj is AnalysisContentStatisticsImpl_CacheRowI mpl && ((obj as AnalysisContentStatisticsImpl_CacheRowImpl))._name == _name;
2856 int get errorCount => _errorCount;
2857 int get flushedCount => _flushedCount;
2858 int get inProcessCount => _inProcessCount;
2859 int get invalidCount => _invalidCount;
2860 String get name => _name;
2861 int get validCount => _validCount;
2862 int get hashCode => _name.hashCode;
2863 void incState(CacheState state) {
2864 if (identical(state, CacheState.ERROR)) {
2865 _errorCount++;
2866 }
2867 if (identical(state, CacheState.FLUSHED)) {
2868 _flushedCount++;
2869 }
2870 if (identical(state, CacheState.IN_PROCESS)) {
2871 _inProcessCount++;
2872 }
2873 if (identical(state, CacheState.INVALID)) {
2874 _invalidCount++;
2875 }
2876 if (identical(state, CacheState.VALID)) {
2877 _validCount++;
2878 }
2879 }
2880 }
2881 /**
2882 * Instances of the class `AnalysisContextImpl` implement an [AnalysisContext].
2883 *
2884 * @coverage dart.engine
2885 */
2886 class AnalysisContextImpl implements InternalAnalysisContext {
2887
2888 /**
2889 * The difference between the maximum cache size and the maximum priority orde r size. The priority
2890 * list must be capped so that it is less than the cache size. Failure to do s o can result in an
2891 * infinite loop in performAnalysisTask() because re-caching one AST structure can cause another
2892 * priority source's AST structure to be flushed.
2893 */
2894 static int _PRIORITY_ORDER_SIZE_DELTA = 4;
2895
2896 /**
2897 * The set of analysis options controlling the behavior of this context.
2898 */
2899 AnalysisOptionsImpl _options = new AnalysisOptionsImpl();
2900
2901 /**
2902 * The source factory used to create the sources that can be analyzed in this context.
2903 */
2904 SourceFactory _sourceFactory;
2905
2906 /**
2907 * A table mapping the sources known to the context to the information known a bout the source.
2908 */
2909 AnalysisCache _cache;
2910
2911 /**
2912 * An array containing sources for which data should not be flushed.
2913 */
2914 List<Source> _priorityOrder = Source.EMPTY_ARRAY;
2915
2916 /**
2917 * A table mapping sources to the change notices that are waiting to be return ed related to that
2918 * source.
2919 */
2920 Map<Source, ChangeNoticeImpl> _pendingNotices = new Map<Source, ChangeNoticeIm pl>();
2921
2922 /**
2923 * The object used to synchronize access to all of the caches. The rules relat ed to the use of
2924 * this lock object are
2925 *
2926 * * no analysis work is done while holding the lock, and
2927 * * no analysis results can be recorded unless we have obtained the lock and validated that the
2928 * results are for the same version (modification time) of the source as our c urrent cache
2929 * content.
2930 *
2931 */
2932 Object _cacheLock = new Object();
2933
2934 /**
2935 * The object used to record the results of performing an analysis task.
2936 */
2937 AnalysisContextImpl_AnalysisTaskResultRecorder _resultRecorder;
2938
2939 /**
2940 * Cached information used in incremental analysis or `null` if none. Synchron ize against
2941 * [cacheLock] before accessing this field.
2942 */
2943 IncrementalAnalysisCache _incrementalAnalysisCache;
2944
2945 /**
2946 * Initialize a newly created analysis context.
2947 */
2948 AnalysisContextImpl() : super() {
2949 _resultRecorder = new AnalysisContextImpl_AnalysisTaskResultRecorder(this);
2950 _cache = new AnalysisCache(AnalysisOptionsImpl.DEFAULT_CACHE_SIZE, new Analy sisContextImpl_ContextRetentionPolicy(this));
2951 }
2952 void addSourceInfo(Source source, SourceEntry info) {
2953 _cache.put(source, info);
2954 }
2955 void applyChanges(ChangeSet changeSet) {
2956 if (changeSet.isEmpty) {
2957 return;
2958 }
2959 {
2960 List<Source> removedSources = new List<Source>.from(changeSet.removed3);
2961 for (SourceContainer container in changeSet.removedContainers) {
2962 addSourcesInContainer(removedSources, container);
2963 }
2964 bool addedDartSource = false;
2965 for (Source source in changeSet.added3) {
2966 if (sourceAvailable(source)) {
2967 addedDartSource = true;
2968 }
2969 }
2970 for (Source source in changeSet.changed3) {
2971 sourceChanged(source);
2972 }
2973 for (Source source in removedSources) {
2974 sourceRemoved(source);
2975 }
2976 if (addedDartSource) {
2977 for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
2978 SourceEntry sourceEntry = mapEntry.getValue();
2979 if (!mapEntry.getKey().isInSystemLibrary && sourceEntry is DartEntry) {
2980 DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
2981 dartCopy.invalidateAllResolutionInformation();
2982 mapEntry.setValue(dartCopy);
2983 }
2984 }
2985 }
2986 }
2987 }
2988 String computeDocumentationComment(Element element) {
2989 if (element == null) {
2990 return null;
2991 }
2992 Source source = element.source;
2993 if (source == null) {
2994 return null;
2995 }
2996 CompilationUnit unit = parseCompilationUnit(source);
2997 if (unit == null) {
2998 return null;
2999 }
3000 NodeLocator locator = new NodeLocator.con1(element.nameOffset);
3001 ASTNode nameNode = locator.searchWithin(unit);
3002 while (nameNode != null) {
3003 if (nameNode is AnnotatedNode) {
3004 Comment comment = ((nameNode as AnnotatedNode)).documentationComment;
3005 if (comment == null) {
3006 return null;
3007 }
3008 JavaStringBuilder builder = new JavaStringBuilder();
3009 List<Token> tokens = comment.tokens;
3010 for (int i = 0; i < tokens.length; i++) {
3011 if (i > 0) {
3012 builder.append('\n');
3013 }
3014 builder.append(tokens[i].lexeme);
3015 }
3016 return builder.toString();
3017 }
3018 nameNode = nameNode.parent;
3019 }
3020 return null;
3021 }
3022 List<AnalysisError> computeErrors(Source source) {
3023 bool enableHints = _options.hint;
3024 SourceEntry sourceEntry = getReadableSourceEntry(source);
3025 if (sourceEntry is DartEntry) {
3026 List<AnalysisError> errors = new List<AnalysisError>();
3027 DartEntry dartEntry = sourceEntry as DartEntry;
3028 ListUtilities.addAll(errors, getDartParseData(source, dartEntry, DartEntry .PARSE_ERRORS));
3029 dartEntry = getReadableDartEntry(source);
3030 if (identical(dartEntry.getValue(DartEntry.SOURCE_KIND), SourceKind.LIBRAR Y)) {
3031 ListUtilities.addAll(errors, getDartResolutionData(source, source, dartE ntry, DartEntry.RESOLUTION_ERRORS));
3032 ListUtilities.addAll(errors, getDartVerificationData(source, source, dar tEntry, DartEntry.VERIFICATION_ERRORS));
3033 if (enableHints) {
3034 ListUtilities.addAll(errors, getDartHintData(source, source, dartEntry , DartEntry.HINTS));
3035 }
3036 } else {
3037 List<Source> libraries = getLibrariesContaining(source);
3038 for (Source librarySource in libraries) {
3039 ListUtilities.addAll(errors, getDartResolutionData(source, librarySour ce, dartEntry, DartEntry.RESOLUTION_ERRORS));
3040 ListUtilities.addAll(errors, getDartVerificationData(source, librarySo urce, dartEntry, DartEntry.VERIFICATION_ERRORS));
3041 if (enableHints) {
3042 ListUtilities.addAll(errors, getDartHintData(source, librarySource, dartEntry, DartEntry.HINTS));
3043 }
3044 }
3045 }
3046 if (errors.isEmpty) {
3047 return AnalysisError.NO_ERRORS;
3048 }
3049 return new List.from(errors);
3050 } else if (sourceEntry is HtmlEntry) {
3051 HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
3052 return getHtmlResolutionData2(source, htmlEntry, HtmlEntry.RESOLUTION_ERRO RS);
3053 }
3054 return AnalysisError.NO_ERRORS;
3055 }
3056 List<Source> computeExportedLibraries(Source source) => getDartParseData2(sour ce, DartEntry.EXPORTED_LIBRARIES, Source.EMPTY_ARRAY);
3057 HtmlElement computeHtmlElement(Source source) => getHtmlResolutionData(source, HtmlEntry.ELEMENT, null);
3058 List<Source> computeImportedLibraries(Source source) => getDartParseData2(sour ce, DartEntry.IMPORTED_LIBRARIES, Source.EMPTY_ARRAY);
3059 SourceKind computeKindOf(Source source) {
3060 SourceEntry sourceEntry = getReadableSourceEntry(source);
3061 if (sourceEntry == null) {
3062 return SourceKind.UNKNOWN;
3063 } else if (sourceEntry is DartEntry) {
3064 try {
3065 return getDartParseData(source, sourceEntry as DartEntry, DartEntry.SOUR CE_KIND);
3066 } on AnalysisException catch (exception) {
3067 return SourceKind.UNKNOWN;
3068 }
3069 }
3070 return sourceEntry.kind;
3071 }
3072 LibraryElement computeLibraryElement(Source source) => getDartResolutionData2( source, source, DartEntry.ELEMENT, null);
3073 LineInfo computeLineInfo(Source source) {
3074 SourceEntry sourceEntry = getReadableSourceEntry(source);
3075 if (sourceEntry is HtmlEntry) {
3076 return getHtmlParseData(source, SourceEntry.LINE_INFO, null);
3077 } else if (sourceEntry is DartEntry) {
3078 return getDartParseData2(source, SourceEntry.LINE_INFO, null);
3079 }
3080 return null;
3081 }
3082 ResolvableCompilationUnit computeResolvableCompilationUnit(Source source) {
3083 while (true) {
3084 {
3085 DartEntry dartEntry = getReadableDartEntry(source);
3086 if (dartEntry == null) {
3087 throw new AnalysisException.con1("computeResolvableCompilationUnit for non-Dart: ${source.fullName}");
3088 }
3089 if (identical(dartEntry.getState(DartEntry.PARSED_UNIT), CacheState.ERRO R)) {
3090 AnalysisException cause = dartEntry.exception;
3091 if (cause == null) {
3092 throw new AnalysisException.con1("Internal error: computeResolvableC ompilationUnit could not parse ${source.fullName}");
3093 } else {
3094 throw new AnalysisException.con2("Internal error: computeResolvableC ompilationUnit could not parse ${source.fullName}", cause);
3095 }
3096 }
3097 DartEntryImpl dartCopy = dartEntry.writableCopy;
3098 CompilationUnit unit = dartCopy.resolvableCompilationUnit;
3099 if (unit != null) {
3100 _cache.put(source, dartCopy);
3101 return new ResolvableCompilationUnit(dartCopy.modificationTime, unit);
3102 }
3103 }
3104 cacheDartParseData(source, getReadableDartEntry(source), DartEntry.PARSED_ UNIT);
3105 }
3106 }
3107 ResolvableHtmlUnit computeResolvableHtmlUnit(Source source) {
3108 HtmlEntry htmlEntry = getReadableHtmlEntry(source);
3109 if (htmlEntry == null) {
3110 throw new AnalysisException.con1("computeResolvableHtmlUnit invoked for no n-HTML file: ${source.fullName}");
3111 }
3112 htmlEntry = cacheHtmlParseData(source, htmlEntry, HtmlEntry.PARSED_UNIT);
3113 HtmlUnit unit = htmlEntry.getValue(HtmlEntry.PARSED_UNIT);
3114 if (unit == null) {
3115 throw new AnalysisException.con1("Internal error: computeResolvableHtmlUni t could not parse ${source.fullName}");
3116 }
3117 return new ResolvableHtmlUnit(htmlEntry.modificationTime, unit);
3118 }
3119 AnalysisContext extractContext(SourceContainer container) => extractContextInt o(container, AnalysisEngine.instance.createAnalysisContext() as InternalAnalysis Context);
3120 InternalAnalysisContext extractContextInto(SourceContainer container, Internal AnalysisContext newContext) {
3121 List<Source> sourcesToRemove = new List<Source>();
3122 {
3123 for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
3124 Source source = entry.getKey();
3125 if (container.contains(source)) {
3126 sourcesToRemove.add(source);
3127 newContext.addSourceInfo(source, entry.getValue().writableCopy);
3128 }
3129 }
3130 }
3131 return newContext;
3132 }
3133 AnalysisOptions get analysisOptions => _options;
3134 Element getElement(ElementLocation location) {
3135 try {
3136 List<String> components = ((location as ElementLocationImpl)).components;
3137 Source librarySource = computeSourceFromEncoding(components[0]);
3138 ElementImpl element = computeLibraryElement(librarySource) as ElementImpl;
3139 for (int i = 1; i < components.length; i++) {
3140 if (element == null) {
3141 return null;
3142 }
3143 element = element.getChild(components[i]);
3144 }
3145 return element;
3146 } on AnalysisException catch (exception) {
3147 return null;
3148 }
3149 }
3150 AnalysisErrorInfo getErrors(Source source) {
3151 SourceEntry sourceEntry = getReadableSourceEntry(source);
3152 if (sourceEntry is DartEntry) {
3153 DartEntry dartEntry = sourceEntry as DartEntry;
3154 return new AnalysisErrorInfoImpl(dartEntry.allErrors, dartEntry.getValue(S ourceEntry.LINE_INFO));
3155 } else if (sourceEntry is HtmlEntry) {
3156 HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
3157 return new AnalysisErrorInfoImpl(htmlEntry.allErrors, htmlEntry.getValue(S ourceEntry.LINE_INFO));
3158 }
3159 return new AnalysisErrorInfoImpl(AnalysisError.NO_ERRORS, null);
3160 }
3161 HtmlElement getHtmlElement(Source source) {
3162 SourceEntry sourceEntry = getReadableSourceEntry(source);
3163 if (sourceEntry is HtmlEntry) {
3164 return ((sourceEntry as HtmlEntry)).getValue(HtmlEntry.ELEMENT);
3165 }
3166 return null;
3167 }
3168 List<Source> getHtmlFilesReferencing(Source source) {
3169 SourceKind sourceKind = getKindOf(source);
3170 if (sourceKind == null) {
3171 return Source.EMPTY_ARRAY;
3172 }
3173 {
3174 List<Source> htmlSources = new List<Source>();
3175 while (true) {
3176 if (sourceKind == SourceKind.LIBRARY) {
3177 } else if (sourceKind == SourceKind.PART) {
3178 List<Source> librarySources = getLibrariesContaining(source);
3179 for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
3180 SourceEntry sourceEntry = entry.getValue();
3181 if (identical(sourceEntry.kind, SourceKind.HTML)) {
3182 List<Source> referencedLibraries = ((sourceEntry as HtmlEntry)).ge tValue(HtmlEntry.REFERENCED_LIBRARIES);
3183 if (containsAny(referencedLibraries, librarySources)) {
3184 htmlSources.add(entry.getKey());
3185 }
3186 }
3187 }
3188 }
3189 break;
3190 }
3191 if (htmlSources.isEmpty) {
3192 return Source.EMPTY_ARRAY;
3193 }
3194 return new List.from(htmlSources);
3195 }
3196 }
3197 List<Source> get htmlSources => getSources(SourceKind.HTML);
3198 SourceKind getKindOf(Source source) {
3199 SourceEntry sourceEntry = getReadableSourceEntry(source);
3200 if (sourceEntry == null) {
3201 return SourceKind.UNKNOWN;
3202 }
3203 return sourceEntry.kind;
3204 }
3205 List<Source> get launchableClientLibrarySources {
3206 List<Source> sources = new List<Source>();
3207 {
3208 for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
3209 Source source = entry.getKey();
3210 SourceEntry sourceEntry = entry.getValue();
3211 if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSyste mLibrary) {
3212 sources.add(source);
3213 }
3214 }
3215 }
3216 return new List.from(sources);
3217 }
3218 List<Source> get launchableServerLibrarySources {
3219 List<Source> sources = new List<Source>();
3220 {
3221 for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
3222 Source source = entry.getKey();
3223 SourceEntry sourceEntry = entry.getValue();
3224 if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSyste mLibrary) {
3225 sources.add(source);
3226 }
3227 }
3228 }
3229 return new List.from(sources);
3230 }
3231 List<Source> getLibrariesContaining(Source source) {
3232 {
3233 SourceEntry sourceEntry = _cache.get(source);
3234 if (sourceEntry == null || sourceEntry.kind != SourceKind.PART) {
3235 return <Source> [source];
3236 }
3237 List<Source> librarySources = new List<Source>();
3238 for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
3239 sourceEntry = entry.getValue();
3240 if (identical(sourceEntry.kind, SourceKind.LIBRARY)) {
3241 if (contains(((sourceEntry as DartEntry)).getValue(DartEntry.INCLUDED_ PARTS), source)) {
3242 librarySources.add(entry.getKey());
3243 }
3244 }
3245 }
3246 if (librarySources.isEmpty) {
3247 return Source.EMPTY_ARRAY;
3248 }
3249 return new List.from(librarySources);
3250 }
3251 }
3252 List<Source> getLibrariesDependingOn(Source librarySource) {
3253 {
3254 List<Source> dependentLibraries = new List<Source>();
3255 for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
3256 SourceEntry sourceEntry = entry.getValue();
3257 if (identical(sourceEntry.kind, SourceKind.LIBRARY)) {
3258 if (contains(((sourceEntry as DartEntry)).getValue(DartEntry.EXPORTED_ LIBRARIES), librarySource)) {
3259 dependentLibraries.add(entry.getKey());
3260 }
3261 if (contains(((sourceEntry as DartEntry)).getValue(DartEntry.IMPORTED_ LIBRARIES), librarySource)) {
3262 dependentLibraries.add(entry.getKey());
3263 }
3264 }
3265 }
3266 if (dependentLibraries.isEmpty) {
3267 return Source.EMPTY_ARRAY;
3268 }
3269 return new List.from(dependentLibraries);
3270 }
3271 }
3272 LibraryElement getLibraryElement(Source source) {
3273 SourceEntry sourceEntry = getReadableSourceEntry(source);
3274 if (sourceEntry is DartEntry) {
3275 return ((sourceEntry as DartEntry)).getValue(DartEntry.ELEMENT);
3276 }
3277 return null;
3278 }
3279 List<Source> get librarySources => getSources(SourceKind.LIBRARY);
3280 LineInfo getLineInfo(Source source) {
3281 SourceEntry sourceEntry = getReadableSourceEntry(source);
3282 if (sourceEntry != null) {
3283 return sourceEntry.getValue(SourceEntry.LINE_INFO);
3284 }
3285 return null;
3286 }
3287 Namespace getPublicNamespace(LibraryElement library) {
3288 Source source = library.definingCompilationUnit.source;
3289 DartEntry dartEntry = getReadableDartEntry(source);
3290 if (dartEntry == null) {
3291 return null;
3292 }
3293 Namespace namespace = null;
3294 if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
3295 namespace = dartEntry.getValue(DartEntry.PUBLIC_NAMESPACE);
3296 }
3297 if (namespace == null) {
3298 NamespaceBuilder builder = new NamespaceBuilder();
3299 namespace = builder.createPublicNamespace(library);
3300 {
3301 dartEntry = getReadableDartEntry(source);
3302 if (dartEntry == null) {
3303 AnalysisEngine.instance.logger.logError3(new AnalysisException.con1("A Dart file became a non-Dart file: ${source.fullName}"));
3304 return null;
3305 }
3306 if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
3307 DartEntryImpl dartCopy = getReadableDartEntry(source).writableCopy;
3308 dartCopy.setValue(DartEntry.PUBLIC_NAMESPACE, namespace);
3309 _cache.put(source, dartCopy);
3310 }
3311 }
3312 }
3313 return namespace;
3314 }
3315 Namespace getPublicNamespace2(Source source) {
3316 DartEntry dartEntry = getReadableDartEntry(source);
3317 if (dartEntry == null) {
3318 return null;
3319 }
3320 Namespace namespace = dartEntry.getValue(DartEntry.PUBLIC_NAMESPACE);
3321 if (namespace == null) {
3322 LibraryElement library = computeLibraryElement(source);
3323 if (library == null) {
3324 return null;
3325 }
3326 NamespaceBuilder builder = new NamespaceBuilder();
3327 namespace = builder.createPublicNamespace(library);
3328 {
3329 dartEntry = getReadableDartEntry(source);
3330 if (dartEntry == null) {
3331 throw new AnalysisException.con1("A Dart file became a non-Dart file: ${source.fullName}");
3332 }
3333 if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
3334 DartEntryImpl dartCopy = getReadableDartEntry(source).writableCopy;
3335 dartCopy.setValue(DartEntry.PUBLIC_NAMESPACE, namespace);
3336 _cache.put(source, dartCopy);
3337 }
3338 }
3339 }
3340 return namespace;
3341 }
3342 List<Source> get refactoringUnsafeSources {
3343 List<Source> sources = new List<Source>();
3344 {
3345 for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
3346 SourceEntry sourceEntry = entry.getValue();
3347 if (sourceEntry is DartEntry) {
3348 if (!((sourceEntry as DartEntry)).isRefactoringSafe) {
3349 sources.add(entry.getKey());
3350 }
3351 }
3352 }
3353 }
3354 return new List.from(sources);
3355 }
3356 CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement l ibrary) {
3357 if (library == null) {
3358 return null;
3359 }
3360 return getResolvedCompilationUnit2(unitSource, library.source);
3361 }
3362 CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source libraryS ource) {
3363 SourceEntry sourceEntry = getReadableSourceEntry(unitSource);
3364 if (sourceEntry is DartEntry) {
3365 return ((sourceEntry as DartEntry)).getValue2(DartEntry.RESOLVED_UNIT, lib rarySource);
3366 }
3367 return null;
3368 }
3369 SourceFactory get sourceFactory => _sourceFactory;
3370
3371 /**
3372 * Return a list of the sources that would be processed by [performAnalysisTas k]. This
3373 * method duplicates, and must therefore be kept in sync with, [getNextTaskAna lysisTask].
3374 * This method is intended to be used for testing purposes only.
3375 *
3376 * @return a list of the sources that would be processed by [performAnalysisTa sk]
3377 */
3378 List<Source> get sourcesNeedingProcessing {
3379 Set<Source> sources = new Set<Source>();
3380 {
3381 bool hintsEnabled = _options.hint;
3382 for (Source source in _priorityOrder) {
3383 getSourcesNeedingProcessing2(source, _cache.get(source), true, hintsEnab led, sources);
3384 }
3385 for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
3386 getSourcesNeedingProcessing2(entry.getKey(), entry.getValue(), false, hi ntsEnabled, sources);
3387 }
3388 }
3389 return new List<Source>.from(sources);
3390 }
3391 AnalysisContentStatistics get statistics {
3392 AnalysisContentStatisticsImpl statistics = new AnalysisContentStatisticsImpl ();
3393 {
3394 for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
3395 SourceEntry entry = mapEntry.getValue();
3396 if (entry is DartEntry) {
3397 Source source = mapEntry.getKey();
3398 DartEntry dartEntry = entry as DartEntry;
3399 SourceKind kind = dartEntry.getValue(DartEntry.SOURCE_KIND);
3400 statistics.putCacheItem(dartEntry, DartEntry.PARSE_ERRORS);
3401 statistics.putCacheItem(dartEntry, DartEntry.PARSED_UNIT);
3402 statistics.putCacheItem(dartEntry, DartEntry.SOURCE_KIND);
3403 statistics.putCacheItem(dartEntry, DartEntry.LINE_INFO);
3404 if (identical(kind, SourceKind.LIBRARY)) {
3405 statistics.putCacheItem(dartEntry, DartEntry.ELEMENT);
3406 statistics.putCacheItem(dartEntry, DartEntry.EXPORTED_LIBRARIES);
3407 statistics.putCacheItem(dartEntry, DartEntry.IMPORTED_LIBRARIES);
3408 statistics.putCacheItem(dartEntry, DartEntry.INCLUDED_PARTS);
3409 statistics.putCacheItem(dartEntry, DartEntry.IS_CLIENT);
3410 statistics.putCacheItem(dartEntry, DartEntry.IS_LAUNCHABLE);
3411 }
3412 List<Source> librarySources = getLibrariesContaining(source);
3413 for (Source librarySource in librarySources) {
3414 statistics.putCacheItem2(dartEntry, librarySource, DartEntry.HINTS);
3415 statistics.putCacheItem2(dartEntry, librarySource, DartEntry.RESOLUT ION_ERRORS);
3416 statistics.putCacheItem2(dartEntry, librarySource, DartEntry.RESOLVE D_UNIT);
3417 statistics.putCacheItem2(dartEntry, librarySource, DartEntry.VERIFIC ATION_ERRORS);
3418 }
3419 }
3420 }
3421 }
3422 return statistics;
3423 }
3424 TimestampedData<CompilationUnit> internalResolveCompilationUnit(Source unitSou rce, LibraryElement libraryElement) {
3425 DartEntry dartEntry = getReadableDartEntry(unitSource);
3426 if (dartEntry == null) {
3427 throw new AnalysisException.con1("internalResolveCompilationUnit invoked f or non-Dart file: ${unitSource.fullName}");
3428 }
3429 Source librarySource = libraryElement.source;
3430 dartEntry = cacheDartResolutionData(unitSource, librarySource, dartEntry, Da rtEntry.RESOLVED_UNIT);
3431 return new TimestampedData<CompilationUnit>(dartEntry.modificationTime, dart Entry.getValue2(DartEntry.RESOLVED_UNIT, librarySource));
3432 }
3433 bool isClientLibrary(Source librarySource) {
3434 SourceEntry sourceEntry = getReadableSourceEntry(librarySource);
3435 if (sourceEntry is DartEntry) {
3436 DartEntry dartEntry = sourceEntry as DartEntry;
3437 return dartEntry.getValue(DartEntry.IS_CLIENT) && dartEntry.getValue(DartE ntry.IS_LAUNCHABLE);
3438 }
3439 return false;
3440 }
3441 bool isServerLibrary(Source librarySource) {
3442 SourceEntry sourceEntry = getReadableSourceEntry(librarySource);
3443 if (sourceEntry is DartEntry) {
3444 DartEntry dartEntry = sourceEntry as DartEntry;
3445 return !dartEntry.getValue(DartEntry.IS_CLIENT) && dartEntry.getValue(Dart Entry.IS_LAUNCHABLE);
3446 }
3447 return false;
3448 }
3449 void mergeContext(AnalysisContext context) {
3450 if (context is InstrumentedAnalysisContextImpl) {
3451 context = ((context as InstrumentedAnalysisContextImpl)).basis;
3452 }
3453 if (context is! AnalysisContextImpl) {
3454 return;
3455 }
3456 {
3457 for (MapEntry<Source, SourceEntry> entry in ((context as AnalysisContextIm pl))._cache.entrySet()) {
3458 Source newSource = entry.getKey();
3459 SourceEntry existingEntry = getReadableSourceEntry(newSource);
3460 if (existingEntry == null) {
3461 _cache.put(newSource, entry.getValue().writableCopy);
3462 } else {
3463 }
3464 }
3465 }
3466 }
3467 CompilationUnit parseCompilationUnit(Source source) => getDartParseData2(sourc e, DartEntry.PARSED_UNIT, null);
3468 HtmlUnit parseHtmlUnit(Source source) => getHtmlParseData(source, HtmlEntry.PA RSED_UNIT, null);
3469 AnalysisResult performAnalysisTask() {
3470 int getStart = JavaSystem.currentTimeMillis();
3471 AnalysisTask task = nextTaskAnalysisTask;
3472 int getEnd = JavaSystem.currentTimeMillis();
3473 if (task == null) {
3474 return new AnalysisResult(getChangeNotices(true), getEnd - getStart, null, -1);
3475 }
3476 int performStart = JavaSystem.currentTimeMillis();
3477 try {
3478 task.perform(_resultRecorder);
3479 } on AnalysisException catch (exception) {
3480 if (exception.cause is! JavaIOException) {
3481 AnalysisEngine.instance.logger.logError2("Internal error while performin g the task: ${task}", exception);
3482 }
3483 }
3484 int performEnd = JavaSystem.currentTimeMillis();
3485 return new AnalysisResult(getChangeNotices(false), getEnd - getStart, task.r untimeType.toString(), performEnd - performStart);
3486 }
3487 void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
3488 {
3489 Source htmlSource = _sourceFactory.forUri(DartSdk.DART_HTML);
3490 for (MapEntry<Source, LibraryElement> entry in getMapEntrySet(elementMap)) {
3491 Source librarySource = entry.getKey();
3492 LibraryElement library = entry.getValue();
3493 DartEntry dartEntry = getReadableDartEntry(librarySource);
3494 if (dartEntry != null) {
3495 DartEntryImpl dartCopy = dartEntry.writableCopy;
3496 recordElementData(dartCopy, library, htmlSource);
3497 _cache.put(librarySource, dartCopy);
3498 }
3499 }
3500 }
3501 }
3502 CompilationUnit resolveCompilationUnit(Source unitSource, LibraryElement libra ry) {
3503 if (library == null) {
3504 return null;
3505 }
3506 return resolveCompilationUnit2(unitSource, library.source);
3507 }
3508 CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySourc e) => getDartResolutionData2(unitSource, librarySource, DartEntry.RESOLVED_UNIT, null);
3509 HtmlUnit resolveHtmlUnit(Source htmlSource) => parseHtmlUnit(htmlSource);
3510 void set analysisOptions(AnalysisOptions options) {
3511 {
3512 bool needsRecompute = this._options.dart2jsHint != options.dart2jsHint || (this._options.hint && !options.hint);
3513 int cacheSize = options.cacheSize;
3514 if (this._options.cacheSize != cacheSize) {
3515 this._options.cacheSize = cacheSize;
3516 _cache.maxCacheSize = cacheSize;
3517 int maxPriorityOrderSize = cacheSize - _PRIORITY_ORDER_SIZE_DELTA;
3518 if (_priorityOrder.length > maxPriorityOrderSize) {
3519 List<Source> newPriorityOrder = new List<Source>(maxPriorityOrderSize) ;
3520 JavaSystem.arraycopy(_priorityOrder, 0, newPriorityOrder, 0, maxPriori tyOrderSize);
3521 _priorityOrder = newPriorityOrder;
3522 }
3523 }
3524 this._options.dart2jsHint = options.dart2jsHint;
3525 this._options.hint = options.hint;
3526 this._options.strictMode = options.strictMode;
3527 if (needsRecompute) {
3528 invalidateAllResolutionInformation();
3529 }
3530 }
3531 }
3532 void set analysisPriorityOrder(List<Source> sources) {
3533 {
3534 if (sources == null || sources.isEmpty) {
3535 _priorityOrder = Source.EMPTY_ARRAY;
3536 } else {
3537 while (sources.remove(null)) {
3538 }
3539 if (sources.isEmpty) {
3540 _priorityOrder = Source.EMPTY_ARRAY;
3541 }
3542 int count = Math.min(sources.length, _options.cacheSize - _PRIORITY_ORDE R_SIZE_DELTA);
3543 _priorityOrder = new List<Source>(count);
3544 for (int i = 0; i < count; i++) {
3545 _priorityOrder[i] = sources[i];
3546 }
3547 }
3548 }
3549 }
3550 void setChangedContents(Source source, String contents, int offset, int oldLen gth, int newLength) {
3551 {
3552 String originalContents = _sourceFactory.setContents(source, contents);
3553 if (originalContents == null) {
3554 if (contents != null) {
3555 _incrementalAnalysisCache = IncrementalAnalysisCache.update(_increment alAnalysisCache, source, originalContents, contents, offset, oldLength, newLengt h, getReadableSourceEntry(source));
3556 sourceChanged(source);
3557 }
3558 } else if (originalContents != contents) {
3559 _incrementalAnalysisCache = IncrementalAnalysisCache.update(_incremental AnalysisCache, source, originalContents, contents, offset, oldLength, newLength, getReadableSourceEntry(source));
3560 sourceChanged(source);
3561 } else if (contents == null) {
3562 _incrementalAnalysisCache = IncrementalAnalysisCache.clear(_incrementalA nalysisCache, source);
3563 }
3564 }
3565 }
3566 void setContents(Source source, String contents) {
3567 {
3568 String originalContents = _sourceFactory.setContents(source, contents);
3569 if (originalContents == null) {
3570 if (contents != null) {
3571 sourceChanged(source);
3572 }
3573 } else if (originalContents != contents) {
3574 sourceChanged(source);
3575 }
3576 _incrementalAnalysisCache = IncrementalAnalysisCache.clear(_incrementalAna lysisCache, source);
3577 }
3578 }
3579 void set sourceFactory(SourceFactory factory) {
3580 {
3581 if (identical(_sourceFactory, factory)) {
3582 return;
3583 } else if (factory.context != null) {
3584 throw new IllegalStateException("Source factories cannot be shared betwe en contexts");
3585 }
3586 if (_sourceFactory != null) {
3587 _sourceFactory.context = null;
3588 }
3589 factory.context = this;
3590 _sourceFactory = factory;
3591 invalidateAllResolutionInformation();
3592 }
3593 }
3594 Iterable<Source> sourcesToResolve(List<Source> changedSources) {
3595 List<Source> librarySources = new List<Source>();
3596 for (Source source in changedSources) {
3597 if (identical(computeKindOf(source), SourceKind.LIBRARY)) {
3598 librarySources.add(source);
3599 }
3600 }
3601 return librarySources;
3602 }
3603
3604 /**
3605 * Add all of the sources contained in the given source container to the given list of sources.
3606 *
3607 * Note: This method must only be invoked while we are synchronized on [cacheL ock].
3608 *
3609 * @param sources the list to which sources are to be added
3610 * @param container the source container containing the sources to be added to the list
3611 */
3612 void addSourcesInContainer(List<Source> sources, SourceContainer container) {
3613 for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
3614 Source source = entry.getKey();
3615 if (container.contains(source)) {
3616 sources.add(source);
3617 }
3618 }
3619 }
3620
3621 /**
3622 * Return `true` if the modification times of the sources used by the given li brary resolver
3623 * to resolve one or more libraries are consistent with the modification times in the cache.
3624 *
3625 * @param resolver the library resolver used to resolve one or more libraries
3626 * @return `true` if we should record the results of the resolution
3627 * @throws AnalysisException if any of the modification times could not be det ermined (this should
3628 * not happen)
3629 */
3630 bool allModificationTimesMatch(Set<Library> resolvedLibraries) {
3631 bool allTimesMatch = true;
3632 for (Library library in resolvedLibraries) {
3633 for (Source source in library.compilationUnitSources) {
3634 DartEntry dartEntry = getReadableDartEntry(source);
3635 if (dartEntry == null) {
3636 throw new AnalysisException.con1("Internal error: attempting to reolve non-Dart file as a Dart file: ${source.fullName}");
3637 }
3638 int sourceTime = source.modificationStamp;
3639 int resultTime = library.getModificationTime(source);
3640 if (sourceTime != resultTime) {
3641 sourceChanged(source);
3642 allTimesMatch = false;
3643 }
3644 }
3645 }
3646 return allTimesMatch;
3647 }
3648
3649 /**
3650 * Given a source for a Dart file and the library that contains it, return a c ache entry in which
3651 * the data represented by the given descriptor is available. This method assu mes that the data
3652 * can be produced by generating hints for the library if the data is not alre ady cached.
3653 *
3654 * @param unitSource the source representing the Dart file
3655 * @param librarySource the source representing the library containing the Dar t file
3656 * @param dartEntry the cache entry associated with the Dart file
3657 * @param descriptor the descriptor representing the data to be returned
3658 * @return a cache entry containing the required data
3659 * @throws AnalysisException if data could not be returned because the source could not be parsed
3660 */
3661 DartEntry cacheDartHintData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
3662 CacheState state = dartEntry.getState2(descriptor, librarySource);
3663 while (state != CacheState.ERROR && state != CacheState.VALID) {
3664 dartEntry = new GenerateDartHintsTask(this, getLibraryElement(librarySourc e)).perform(_resultRecorder) as DartEntry;
3665 state = dartEntry.getState2(descriptor, librarySource);
3666 }
3667 return dartEntry;
3668 }
3669
3670 /**
3671 * Given a source for a Dart file, return a cache entry in which the data repr esented by the given
3672 * descriptor is available. This method assumes that the data can be produced by parsing the
3673 * source if it is not already cached.
3674 *
3675 * @param source the source representing the Dart file
3676 * @param dartEntry the cache entry associated with the Dart file
3677 * @param descriptor the descriptor representing the data to be returned
3678 * @return a cache entry containing the required data
3679 * @throws AnalysisException if data could not be returned because the source could not be
3680 * resolved
3681 */
3682 DartEntry cacheDartParseData(Source source, DartEntry dartEntry, DataDescripto r descriptor) {
3683 if (identical(descriptor, DartEntry.PARSED_UNIT)) {
3684 CompilationUnit unit = dartEntry.anyParsedCompilationUnit;
3685 if (unit != null) {
3686 return dartEntry;
3687 }
3688 }
3689 CacheState state = dartEntry.getState(descriptor);
3690 while (state != CacheState.ERROR && state != CacheState.VALID) {
3691 dartEntry = new ParseDartTask(this, source).perform(_resultRecorder) as Da rtEntry;
3692 state = dartEntry.getState(descriptor);
3693 }
3694 return dartEntry;
3695 }
3696
3697 /**
3698 * Given a source for a Dart file and the library that contains it, return a c ache entry in which
3699 * the data represented by the given descriptor is available. This method assu mes that the data
3700 * can be produced by resolving the source in the context of the library if it is not already
3701 * cached.
3702 *
3703 * @param unitSource the source representing the Dart file
3704 * @param librarySource the source representing the library containing the Dar t file
3705 * @param dartEntry the cache entry associated with the Dart file
3706 * @param descriptor the descriptor representing the data to be returned
3707 * @return a cache entry containing the required data
3708 * @throws AnalysisException if data could not be returned because the source could not be parsed
3709 */
3710 DartEntry cacheDartResolutionData(Source unitSource, Source librarySource, Dar tEntry dartEntry, DataDescriptor descriptor) {
3711 CacheState state = (identical(descriptor, DartEntry.ELEMENT)) ? dartEntry.ge tState(descriptor) : dartEntry.getState2(descriptor, librarySource);
3712 while (state != CacheState.ERROR && state != CacheState.VALID) {
3713 dartEntry = new ResolveDartLibraryTask(this, unitSource, librarySource).pe rform(_resultRecorder) as DartEntry;
3714 state = (identical(descriptor, DartEntry.ELEMENT)) ? dartEntry.getState(de scriptor) : dartEntry.getState2(descriptor, librarySource);
3715 }
3716 return dartEntry;
3717 }
3718
3719 /**
3720 * Given a source for a Dart file and the library that contains it, return a c ache entry in which
3721 * the data represented by the given descriptor is available. This method assu mes that the data
3722 * can be produced by verifying the source in the given library if the data is not already cached.
3723 *
3724 * @param unitSource the source representing the Dart file
3725 * @param librarySource the source representing the library containing the Dar t file
3726 * @param dartEntry the cache entry associated with the Dart file
3727 * @param descriptor the descriptor representing the data to be returned
3728 * @return a cache entry containing the required data
3729 * @throws AnalysisException if data could not be returned because the source could not be parsed
3730 */
3731 DartEntry cacheDartVerificationData(Source unitSource, Source librarySource, D artEntry dartEntry, DataDescriptor descriptor) {
3732 CacheState state = dartEntry.getState2(descriptor, librarySource);
3733 while (state != CacheState.ERROR && state != CacheState.VALID) {
3734 dartEntry = new GenerateDartErrorsTask(this, unitSource, getLibraryElement (librarySource)).perform(_resultRecorder) as DartEntry;
3735 state = dartEntry.getState2(descriptor, librarySource);
3736 }
3737 return dartEntry;
3738 }
3739
3740 /**
3741 * Given a source for an HTML file, return a cache entry in which all of the d ata represented by
3742 * the given descriptors is available. This method assumes that the data can b e produced by
3743 * parsing the source if it is not already cached.
3744 *
3745 * @param source the source representing the HTML file
3746 * @param htmlEntry the cache entry associated with the HTML file
3747 * @param descriptor the descriptor representing the data to be returned
3748 * @return a cache entry containing the required data
3749 * @throws AnalysisException if data could not be returned because the source could not be
3750 * resolved
3751 */
3752 HtmlEntry cacheHtmlParseData(Source source, HtmlEntry htmlEntry, DataDescripto r descriptor) {
3753 CacheState state = htmlEntry.getState(descriptor);
3754 while (state != CacheState.ERROR && state != CacheState.VALID) {
3755 htmlEntry = new ParseHtmlTask(this, source).perform(_resultRecorder) as Ht mlEntry;
3756 state = htmlEntry.getState(descriptor);
3757 }
3758 return htmlEntry;
3759 }
3760
3761 /**
3762 * Given a source for an HTML file, return a cache entry in which the the data represented by the
3763 * given descriptor is available. This method assumes that the data can be pro duced by resolving
3764 * the source if it is not already cached.
3765 *
3766 * @param source the source representing the HTML file
3767 * @param dartEntry the cache entry associated with the HTML file
3768 * @param descriptor the descriptor representing the data to be returned
3769 * @return a cache entry containing the required data
3770 * @throws AnalysisException if data could not be returned because the source could not be
3771 * resolved
3772 */
3773 HtmlEntry cacheHtmlResolutionData(Source source, HtmlEntry htmlEntry, DataDesc riptor descriptor) {
3774 CacheState state = htmlEntry.getState(descriptor);
3775 while (state != CacheState.ERROR && state != CacheState.VALID) {
3776 htmlEntry = new ResolveHtmlTask(this, source).perform(_resultRecorder) as HtmlEntry;
3777 state = htmlEntry.getState(descriptor);
3778 }
3779 return htmlEntry;
3780 }
3781
3782 /**
3783 * Given the encoded form of a source, use the source factory to reconstitute the original source.
3784 *
3785 * @param encoding the encoded form of a source
3786 * @return the source represented by the encoding
3787 */
3788 Source computeSourceFromEncoding(String encoding) {
3789 {
3790 return _sourceFactory.fromEncoding(encoding);
3791 }
3792 }
3793
3794 /**
3795 * Return `true` if the given array of sources contains the given source.
3796 *
3797 * @param sources the sources being searched
3798 * @param targetSource the source being searched for
3799 * @return `true` if the given source is in the array
3800 */
3801 bool contains(List<Source> sources, Source targetSource) {
3802 for (Source source in sources) {
3803 if (source == targetSource) {
3804 return true;
3805 }
3806 }
3807 return false;
3808 }
3809
3810 /**
3811 * Return `true` if the given array of sources contains any of the given targe t sources.
3812 *
3813 * @param sources the sources being searched
3814 * @param targetSources the sources being searched for
3815 * @return `true` if any of the given target sources are in the array
3816 */
3817 bool containsAny(List<Source> sources, List<Source> targetSources) {
3818 for (Source targetSource in targetSources) {
3819 if (contains(sources, targetSource)) {
3820 return true;
3821 }
3822 }
3823 return false;
3824 }
3825
3826 /**
3827 * Create a source information object suitable for the given source. Return th e source information
3828 * object that was created, or `null` if the source should not be tracked by t his context.
3829 *
3830 * @param source the source for which an information object is being created
3831 * @return the source information object that was created
3832 */
3833 SourceEntry createSourceEntry(Source source) {
3834 String name = source.shortName;
3835 if (AnalysisEngine.isHtmlFileName(name)) {
3836 HtmlEntryImpl htmlEntry = new HtmlEntryImpl();
3837 htmlEntry.modificationTime = source.modificationStamp;
3838 _cache.put(source, htmlEntry);
3839 return htmlEntry;
3840 } else {
3841 DartEntryImpl dartEntry = new DartEntryImpl();
3842 dartEntry.modificationTime = source.modificationStamp;
3843 _cache.put(source, dartEntry);
3844 return dartEntry;
3845 }
3846 }
3847
3848 /**
3849 * Return an array containing all of the change notices that are waiting to be returned. If there
3850 * are no notices, then return either `null` or an empty array, depending on t he value of
3851 * the argument.
3852 *
3853 * @param nullIfEmpty `true` if `null` should be returned when there are no no tices
3854 * @return the change notices that are waiting to be returned
3855 */
3856 List<ChangeNotice> getChangeNotices(bool nullIfEmpty) {
3857 {
3858 if (_pendingNotices.isEmpty) {
3859 if (nullIfEmpty) {
3860 return null;
3861 }
3862 return ChangeNoticeImpl.EMPTY_ARRAY;
3863 }
3864 List<ChangeNotice> notices = new List.from(_pendingNotices.values);
3865 _pendingNotices.clear();
3866 return notices;
3867 }
3868 }
3869
3870 /**
3871 * Given a source for a Dart file and the library that contains it, return the data represented by
3872 * the given descriptor that is associated with that source. This method assum es that the data can
3873 * be produced by generating hints for the library if it is not already cached .
3874 *
3875 * @param unitSource the source representing the Dart file
3876 * @param librarySource the source representing the library containing the Dar t file
3877 * @param dartEntry the entry representing the Dart file
3878 * @param descriptor the descriptor representing the data to be returned
3879 * @return the requested data about the given source
3880 * @throws AnalysisException if data could not be returned because the source could not be
3881 * resolved
3882 */
3883 Object getDartHintData(Source unitSource, Source librarySource, DartEntry dart Entry, DataDescriptor descriptor) {
3884 dartEntry = cacheDartHintData(unitSource, librarySource, dartEntry, descript or);
3885 if (identical(descriptor, DartEntry.ELEMENT)) {
3886 return dartEntry.getValue(descriptor);
3887 }
3888 return dartEntry.getValue2(descriptor, librarySource);
3889 }
3890
3891 /**
3892 * Given a source for a Dart file, return the data represented by the given de scriptor that is
3893 * associated with that source. This method assumes that the data can be produ ced by parsing the
3894 * source if it is not already cached.
3895 *
3896 * @param source the source representing the Dart file
3897 * @param dartEntry the cache entry associated with the Dart file
3898 * @param descriptor the descriptor representing the data to be returned
3899 * @return the requested data about the given source
3900 * @throws AnalysisException if data could not be returned because the source could not be parsed
3901 */
3902 Object getDartParseData(Source source, DartEntry dartEntry, DataDescriptor des criptor) {
3903 dartEntry = cacheDartParseData(source, dartEntry, descriptor);
3904 if (identical(descriptor, DartEntry.PARSED_UNIT)) {
3905 return dartEntry.anyParsedCompilationUnit as Object;
3906 }
3907 return dartEntry.getValue(descriptor);
3908 }
3909
3910 /**
3911 * Given a source for a Dart file, return the data represented by the given de scriptor that is
3912 * associated with that source, or the given default value if the source is no t a Dart file. This
3913 * method assumes that the data can be produced by parsing the source if it is not already cached.
3914 *
3915 * @param source the source representing the Dart file
3916 * @param descriptor the descriptor representing the data to be returned
3917 * @param defaultValue the value to be returned if the source is not a Dart fi le
3918 * @return the requested data about the given source
3919 * @throws AnalysisException if data could not be returned because the source could not be parsed
3920 */
3921 Object getDartParseData2(Source source, DataDescriptor descriptor, Object defa ultValue) {
3922 DartEntry dartEntry = getReadableDartEntry(source);
3923 if (dartEntry == null) {
3924 return defaultValue;
3925 }
3926 return getDartParseData(source, dartEntry, descriptor);
3927 }
3928
3929 /**
3930 * Given a source for a Dart file and the library that contains it, return the data represented by
3931 * the given descriptor that is associated with that source. This method assum es that the data can
3932 * be produced by resolving the source in the context of the library if it is not already cached.
3933 *
3934 * @param unitSource the source representing the Dart file
3935 * @param librarySource the source representing the library containing the Dar t file
3936 * @param dartEntry the entry representing the Dart file
3937 * @param descriptor the descriptor representing the data to be returned
3938 * @return the requested data about the given source
3939 * @throws AnalysisException if data could not be returned because the source could not be
3940 * resolved
3941 */
3942 Object getDartResolutionData(Source unitSource, Source librarySource, DartEntr y dartEntry, DataDescriptor descriptor) {
3943 dartEntry = cacheDartResolutionData(unitSource, librarySource, dartEntry, de scriptor);
3944 if (identical(descriptor, DartEntry.ELEMENT)) {
3945 return dartEntry.getValue(descriptor);
3946 }
3947 return dartEntry.getValue2(descriptor, librarySource);
3948 }
3949
3950 /**
3951 * Given a source for a Dart file and the library that contains it, return the data represented by
3952 * the given descriptor that is associated with that source, or the given defa ult value if the
3953 * source is not a Dart file. This method assumes that the data can be produce d by resolving the
3954 * source in the context of the library if it is not already cached.
3955 *
3956 * @param unitSource the source representing the Dart file
3957 * @param librarySource the source representing the library containing the Dar t file
3958 * @param descriptor the descriptor representing the data to be returned
3959 * @param defaultValue the value to be returned if the source is not a Dart fi le
3960 * @return the requested data about the given source
3961 * @throws AnalysisException if data could not be returned because the source could not be
3962 * resolved
3963 */
3964 Object getDartResolutionData2(Source unitSource, Source librarySource, DataDes criptor descriptor, Object defaultValue) {
3965 DartEntry dartEntry = getReadableDartEntry(unitSource);
3966 if (dartEntry == null) {
3967 return defaultValue;
3968 }
3969 return getDartResolutionData(unitSource, librarySource, dartEntry, descripto r);
3970 }
3971
3972 /**
3973 * Given a source for a Dart file and the library that contains it, return the data represented by
3974 * the given descriptor that is associated with that source. This method assum es that the data can
3975 * be produced by verifying the source within the given library if it is not a lready cached.
3976 *
3977 * @param unitSource the source representing the Dart file
3978 * @param librarySource the source representing the library containing the Dar t file
3979 * @param dartEntry the entry representing the Dart file
3980 * @param descriptor the descriptor representing the data to be returned
3981 * @return the requested data about the given source
3982 * @throws AnalysisException if data could not be returned because the source could not be
3983 * resolved
3984 */
3985 Object getDartVerificationData(Source unitSource, Source librarySource, DartEn try dartEntry, DataDescriptor descriptor) {
3986 dartEntry = cacheDartVerificationData(unitSource, librarySource, dartEntry, descriptor);
3987 return dartEntry.getValue2(descriptor, librarySource);
3988 }
3989
3990 /**
3991 * Given a source for an HTML file, return the data represented by the given d escriptor that is
3992 * associated with that source, or the given default value if the source is no t an HTML file. This
3993 * method assumes that the data can be produced by parsing the source if it is not already cached.
3994 *
3995 * @param source the source representing the Dart file
3996 * @param descriptor the descriptor representing the data to be returned
3997 * @param defaultValue the value to be returned if the source is not an HTML f ile
3998 * @return the requested data about the given source
3999 * @throws AnalysisException if data could not be returned because the source could not be parsed
4000 */
4001 Object getHtmlParseData(Source source, DataDescriptor descriptor, Object defau ltValue) {
4002 HtmlEntry htmlEntry = getReadableHtmlEntry(source);
4003 if (htmlEntry == null) {
4004 return defaultValue;
4005 }
4006 htmlEntry = cacheHtmlParseData(source, htmlEntry, descriptor);
4007 return htmlEntry.getValue(descriptor);
4008 }
4009
4010 /**
4011 * Given a source for an HTML file, return the data represented by the given d escriptor that is
4012 * associated with that source, or the given default value if the source is no t an HTML file. This
4013 * method assumes that the data can be produced by resolving the source if it is not already
4014 * cached.
4015 *
4016 * @param source the source representing the HTML file
4017 * @param descriptor the descriptor representing the data to be returned
4018 * @param defaultValue the value to be returned if the source is not an HTML f ile
4019 * @return the requested data about the given source
4020 * @throws AnalysisException if data could not be returned because the source could not be
4021 * resolved
4022 */
4023 Object getHtmlResolutionData(Source source, DataDescriptor descriptor, Object defaultValue) {
4024 HtmlEntry htmlEntry = getReadableHtmlEntry(source);
4025 if (htmlEntry == null) {
4026 return defaultValue;
4027 }
4028 return getHtmlResolutionData2(source, htmlEntry, descriptor);
4029 }
4030
4031 /**
4032 * Given a source for an HTML file, return the data represented by the given d escriptor that is
4033 * associated with that source. This method assumes that the data can be produ ced by resolving the
4034 * source if it is not already cached.
4035 *
4036 * @param source the source representing the HTML file
4037 * @param htmlEntry the entry representing the HTML file
4038 * @param descriptor the descriptor representing the data to be returned
4039 * @return the requested data about the given source
4040 * @throws AnalysisException if data could not be returned because the source could not be
4041 * resolved
4042 */
4043 Object getHtmlResolutionData2(Source source, HtmlEntry htmlEntry, DataDescript or descriptor) {
4044 htmlEntry = cacheHtmlResolutionData(source, htmlEntry, descriptor);
4045 return htmlEntry.getValue(descriptor);
4046 }
4047
4048 /**
4049 * Look through the cache for a task that needs to be performed. Return the ta sk that was found,
4050 * or `null` if there is no more work to be done.
4051 *
4052 * @return the next task that needs to be performed
4053 */
4054 AnalysisTask get nextTaskAnalysisTask {
4055 {
4056 bool hintsEnabled = _options.hint;
4057 for (Source source in _priorityOrder) {
4058 AnalysisTask task = getNextTaskAnalysisTask2(source, _cache.get(source), true, hintsEnabled);
4059 if (task != null) {
4060 return task;
4061 }
4062 }
4063 for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
4064 AnalysisTask task = getNextTaskAnalysisTask2(entry.getKey(), entry.getVa lue(), false, hintsEnabled);
4065 if (task != null) {
4066 return task;
4067 }
4068 }
4069 return null;
4070 }
4071 }
4072
4073 /**
4074 * Look at the given source to see whether a task needs to be performed relate d to it. Return the
4075 * task that should be performed, or `null` if there is no more work to be don e for the
4076 * source.
4077 *
4078 * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
4079 *
4080 * @param source the source to be checked
4081 * @param sourceEntry the cache entry associated with the source
4082 * @param isPriority `true` if the source is a priority source
4083 * @param hintsEnabled `true` if hints are currently enabled
4084 * @return the next task that needs to be performed for the given source
4085 */
4086 AnalysisTask getNextTaskAnalysisTask2(Source source, SourceEntry sourceEntry, bool isPriority, bool hintsEnabled) {
4087 if (sourceEntry is DartEntry) {
4088 DartEntry dartEntry = sourceEntry as DartEntry;
4089 CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
4090 if (identical(parseErrorsState, CacheState.INVALID) || (isPriority && iden tical(parseErrorsState, CacheState.FLUSHED))) {
4091 DartEntryImpl dartCopy = dartEntry.writableCopy;
4092 dartCopy.setState(DartEntry.PARSE_ERRORS, CacheState.IN_PROCESS);
4093 _cache.put(source, dartCopy);
4094 return new ParseDartTask(this, source);
4095 }
4096 if (isPriority && parseErrorsState != CacheState.ERROR) {
4097 CompilationUnit parseUnit = dartEntry.anyParsedCompilationUnit;
4098 if (parseUnit == null) {
4099 DartEntryImpl dartCopy = dartEntry.writableCopy;
4100 dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.IN_PROCESS);
4101 _cache.put(source, dartCopy);
4102 return new ParseDartTask(this, source);
4103 }
4104 }
4105 for (Source librarySource in getLibrariesContaining(source)) {
4106 SourceEntry libraryEntry = _cache.get(librarySource);
4107 if (libraryEntry is DartEntry) {
4108 CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
4109 if (identical(elementState, CacheState.INVALID) || (isPriority && iden tical(elementState, CacheState.FLUSHED))) {
4110 DartEntryImpl libraryCopy = ((libraryEntry as DartEntry)).writableCo py;
4111 libraryCopy.setState(DartEntry.ELEMENT, CacheState.IN_PROCESS);
4112 _cache.put(librarySource, libraryCopy);
4113 return new ResolveDartLibraryTask(this, source, librarySource);
4114 }
4115 CacheState resolvedUnitState = dartEntry.getState2(DartEntry.RESOLVED_ UNIT, librarySource);
4116 if (identical(resolvedUnitState, CacheState.INVALID) || (isPriority && identical(resolvedUnitState, CacheState.FLUSHED))) {
4117 DartEntryImpl dartCopy = dartEntry.writableCopy;
4118 dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheStat e.IN_PROCESS);
4119 _cache.put(source, dartCopy);
4120 return new ResolveDartLibraryTask(this, source, librarySource);
4121 }
4122 CacheState verificationErrorsState = dartEntry.getState2(DartEntry.VER IFICATION_ERRORS, librarySource);
4123 if (identical(verificationErrorsState, CacheState.INVALID) || (isPrior ity && identical(verificationErrorsState, CacheState.FLUSHED))) {
4124 LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEM ENT);
4125 if (libraryElement != null) {
4126 DartEntryImpl dartCopy = dartEntry.writableCopy;
4127 dartCopy.setState2(DartEntry.VERIFICATION_ERRORS, librarySource, C acheState.IN_PROCESS);
4128 _cache.put(source, dartCopy);
4129 return new GenerateDartErrorsTask(this, source, libraryElement);
4130 }
4131 }
4132 if (hintsEnabled) {
4133 CacheState hintsState = dartEntry.getState2(DartEntry.HINTS, library Source);
4134 if (identical(hintsState, CacheState.INVALID) || (isPriority && iden tical(hintsState, CacheState.FLUSHED))) {
4135 LibraryElement libraryElement = libraryEntry.getValue(DartEntry.EL EMENT);
4136 if (libraryElement != null) {
4137 DartEntryImpl dartCopy = dartEntry.writableCopy;
4138 dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.IN _PROCESS);
4139 _cache.put(source, dartCopy);
4140 return new GenerateDartHintsTask(this, libraryElement);
4141 }
4142 }
4143 }
4144 }
4145 }
4146 } else if (sourceEntry is HtmlEntry) {
4147 HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
4148 CacheState parsedUnitState = htmlEntry.getState(HtmlEntry.PARSED_UNIT);
4149 if (identical(parsedUnitState, CacheState.INVALID) || (isPriority && ident ical(parsedUnitState, CacheState.FLUSHED))) {
4150 HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
4151 htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.IN_PROCESS);
4152 _cache.put(source, htmlCopy);
4153 return new ParseHtmlTask(this, source);
4154 }
4155 CacheState elementState = htmlEntry.getState(HtmlEntry.ELEMENT);
4156 if (identical(elementState, CacheState.INVALID) || (isPriority && identica l(elementState, CacheState.FLUSHED))) {
4157 HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
4158 htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.IN_PROCESS);
4159 _cache.put(source, htmlCopy);
4160 return new ResolveHtmlTask(this, source);
4161 }
4162 }
4163 return null;
4164 }
4165
4166 /**
4167 * Return a change notice for the given source, creating one if one does not a lready exist.
4168 *
4169 * @param source the source for which changes are being reported
4170 * @return a change notice for the given source
4171 */
4172 ChangeNoticeImpl getNotice(Source source) {
4173 ChangeNoticeImpl notice = _pendingNotices[source];
4174 if (notice == null) {
4175 notice = new ChangeNoticeImpl(source);
4176 _pendingNotices[source] = notice;
4177 }
4178 return notice;
4179 }
4180
4181 /**
4182 * Return the cache entry associated with the given source, or `null` if the s ource is not a
4183 * Dart file.
4184 *
4185 * @param source the source for which a cache entry is being sought
4186 * @return the source cache entry associated with the given source
4187 */
4188 DartEntry getReadableDartEntry(Source source) {
4189 {
4190 SourceEntry sourceEntry = _cache.get(source);
4191 if (sourceEntry == null) {
4192 sourceEntry = createSourceEntry(source);
4193 }
4194 if (sourceEntry is DartEntry) {
4195 _cache.accessed(source);
4196 return sourceEntry as DartEntry;
4197 }
4198 return null;
4199 }
4200 }
4201
4202 /**
4203 * Return the cache entry associated with the given source, or `null` if the s ource is not
4204 * an HTML file.
4205 *
4206 * @param source the source for which a cache entry is being sought
4207 * @return the source cache entry associated with the given source
4208 */
4209 HtmlEntry getReadableHtmlEntry(Source source) {
4210 {
4211 SourceEntry sourceEntry = _cache.get(source);
4212 if (sourceEntry == null) {
4213 sourceEntry = createSourceEntry(source);
4214 }
4215 if (sourceEntry is HtmlEntry) {
4216 _cache.accessed(source);
4217 return sourceEntry as HtmlEntry;
4218 }
4219 return null;
4220 }
4221 }
4222
4223 /**
4224 * Return the cache entry associated with the given source, or `null` if there is no entry
4225 * associated with the source.
4226 *
4227 * @param source the source for which a cache entry is being sought
4228 * @return the source cache entry associated with the given source
4229 */
4230 SourceEntry getReadableSourceEntry(Source source) {
4231 {
4232 SourceEntry sourceEntry = _cache.get(source);
4233 if (sourceEntry == null) {
4234 sourceEntry = createSourceEntry(source);
4235 }
4236 if (sourceEntry != null) {
4237 _cache.accessed(source);
4238 }
4239 return sourceEntry;
4240 }
4241 }
4242
4243 /**
4244 * Return an array containing all of the sources known to this context that ha ve the given kind.
4245 *
4246 * @param kind the kind of sources to be returned
4247 * @return all of the sources known to this context that have the given kind
4248 */
4249 List<Source> getSources(SourceKind kind) {
4250 List<Source> sources = new List<Source>();
4251 {
4252 for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
4253 if (identical(entry.getValue().kind, kind)) {
4254 sources.add(entry.getKey());
4255 }
4256 }
4257 }
4258 return new List.from(sources);
4259 }
4260
4261 /**
4262 * Look at the given source to see whether a task needs to be performed relate d to it. If so, add
4263 * the source to the set of sources that need to be processed. This method dup licates, and must
4264 * therefore be kept in sync with,
4265 * [getNextTaskAnalysisTask]. This method is
4266 * intended to be used for testing purposes only.
4267 *
4268 * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
4269 *
4270 * @param source the source to be checked
4271 * @param sourceEntry the cache entry associated with the source
4272 * @param isPriority `true` if the source is a priority source
4273 * @param hintsEnabled `true` if hints are currently enabled
4274 * @param sources the set to which sources should be added
4275 */
4276 void getSourcesNeedingProcessing2(Source source, SourceEntry sourceEntry, bool isPriority, bool hintsEnabled, Set<Source> sources) {
4277 if (sourceEntry is DartEntry) {
4278 DartEntry dartEntry = sourceEntry as DartEntry;
4279 CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
4280 if (identical(parseErrorsState, CacheState.INVALID) || (isPriority && iden tical(parseErrorsState, CacheState.FLUSHED))) {
4281 javaSetAdd(sources, source);
4282 return;
4283 }
4284 if (isPriority) {
4285 CompilationUnit parseUnit = dartEntry.anyParsedCompilationUnit;
4286 if (parseUnit == null) {
4287 javaSetAdd(sources, source);
4288 return;
4289 }
4290 }
4291 for (Source librarySource in getLibrariesContaining(source)) {
4292 SourceEntry libraryEntry = _cache.get(librarySource);
4293 if (libraryEntry is DartEntry) {
4294 CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
4295 if (identical(elementState, CacheState.INVALID) || (isPriority && iden tical(elementState, CacheState.FLUSHED))) {
4296 javaSetAdd(sources, source);
4297 return;
4298 }
4299 CacheState resolvedUnitState = dartEntry.getState2(DartEntry.RESOLVED_ UNIT, librarySource);
4300 if (identical(resolvedUnitState, CacheState.INVALID) || (isPriority && identical(resolvedUnitState, CacheState.FLUSHED))) {
4301 LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEM ENT);
4302 if (libraryElement != null) {
4303 javaSetAdd(sources, source);
4304 return;
4305 }
4306 }
4307 CacheState verificationErrorsState = dartEntry.getState2(DartEntry.VER IFICATION_ERRORS, librarySource);
4308 if (identical(verificationErrorsState, CacheState.INVALID) || (isPrior ity && identical(verificationErrorsState, CacheState.FLUSHED))) {
4309 LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEM ENT);
4310 if (libraryElement != null) {
4311 javaSetAdd(sources, source);
4312 return;
4313 }
4314 }
4315 if (hintsEnabled) {
4316 CacheState hintsState = dartEntry.getState2(DartEntry.HINTS, library Source);
4317 if (identical(hintsState, CacheState.INVALID) || (isPriority && iden tical(hintsState, CacheState.FLUSHED))) {
4318 LibraryElement libraryElement = libraryEntry.getValue(DartEntry.EL EMENT);
4319 if (libraryElement != null) {
4320 javaSetAdd(sources, source);
4321 return;
4322 }
4323 }
4324 }
4325 }
4326 }
4327 } else if (sourceEntry is HtmlEntry) {
4328 HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
4329 CacheState parsedUnitState = htmlEntry.getState(HtmlEntry.PARSED_UNIT);
4330 if (identical(parsedUnitState, CacheState.INVALID) || (isPriority && ident ical(parsedUnitState, CacheState.FLUSHED))) {
4331 javaSetAdd(sources, source);
4332 return;
4333 }
4334 CacheState elementState = htmlEntry.getState(HtmlEntry.ELEMENT);
4335 if (identical(elementState, CacheState.INVALID) || (isPriority && identica l(elementState, CacheState.FLUSHED))) {
4336 javaSetAdd(sources, source);
4337 return;
4338 }
4339 }
4340 }
4341
4342 /**
4343 * Invalidate all of the resolution results computed by this context.
4344 *
4345 * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
4346 */
4347 void invalidateAllResolutionInformation() {
4348 for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
4349 SourceEntry sourceEntry = mapEntry.getValue();
4350 if (sourceEntry is HtmlEntry) {
4351 HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
4352 htmlCopy.invalidateAllResolutionInformation();
4353 mapEntry.setValue(htmlCopy);
4354 } else if (sourceEntry is DartEntry) {
4355 DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
4356 dartCopy.invalidateAllResolutionInformation();
4357 mapEntry.setValue(dartCopy);
4358 }
4359 }
4360 }
4361
4362 /**
4363 * In response to a change to at least one of the compilation units in the giv en library,
4364 * invalidate any results that are dependent on the result of resolving that l ibrary.
4365 *
4366 * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
4367 *
4368 * @param librarySource the source of the library being invalidated
4369 */
4370 void invalidateLibraryResolution(Source librarySource) {
4371 DartEntry libraryEntry = getReadableDartEntry(librarySource);
4372 if (libraryEntry != null) {
4373 List<Source> includedParts = libraryEntry.getValue(DartEntry.INCLUDED_PART S);
4374 DartEntryImpl libraryCopy = libraryEntry.writableCopy;
4375 libraryCopy.invalidateAllResolutionInformation();
4376 libraryCopy.setState(DartEntry.INCLUDED_PARTS, CacheState.INVALID);
4377 _cache.put(librarySource, libraryCopy);
4378 for (Source partSource in includedParts) {
4379 SourceEntry partEntry = _cache.get(partSource);
4380 if (partEntry is DartEntry) {
4381 DartEntryImpl partCopy = ((partEntry as DartEntry)).writableCopy;
4382 partCopy.invalidateAllResolutionInformation();
4383 _cache.put(partSource, partCopy);
4384 }
4385 }
4386 }
4387 }
4388
4389 /**
4390 * Return `true` if this library is, or depends on, dart:html.
4391 *
4392 * @param library the library being tested
4393 * @param visitedLibraries a collection of the libraries that have been visite d, used to prevent
4394 * infinite recursion
4395 * @return `true` if this library is, or depends on, dart:html
4396 */
4397 bool isClient(LibraryElement library, Source htmlSource, Set<LibraryElement> v isitedLibraries) {
4398 if (visitedLibraries.contains(library)) {
4399 return false;
4400 }
4401 if (library.source == htmlSource) {
4402 return true;
4403 }
4404 javaSetAdd(visitedLibraries, library);
4405 for (LibraryElement imported in library.importedLibraries) {
4406 if (isClient(imported, htmlSource, visitedLibraries)) {
4407 return true;
4408 }
4409 }
4410 for (LibraryElement exported in library.exportedLibraries) {
4411 if (isClient(exported, htmlSource, visitedLibraries)) {
4412 return true;
4413 }
4414 }
4415 return false;
4416 }
4417
4418 /**
4419 * Given a cache entry and a library element, record the library element and o ther information
4420 * gleaned from the element in the cache entry.
4421 *
4422 * @param dartCopy the cache entry in which data is to be recorded
4423 * @param library the library element used to record information
4424 * @param htmlSource the source for the HTML library
4425 */
4426 void recordElementData(DartEntryImpl dartCopy, LibraryElement library, Source htmlSource) {
4427 dartCopy.setValue(DartEntry.ELEMENT, library);
4428 dartCopy.setValue(DartEntry.IS_LAUNCHABLE, library.entryPoint != null);
4429 dartCopy.setValue(DartEntry.IS_CLIENT, isClient(library, htmlSource, new Set <LibraryElement>()));
4430 List<Source> unitSources = new List<Source>();
4431 unitSources.add(library.definingCompilationUnit.source);
4432 for (CompilationUnitElement part in library.parts) {
4433 Source partSource = part.source;
4434 unitSources.add(partSource);
4435 }
4436 dartCopy.setValue(DartEntry.INCLUDED_PARTS, new List.from(unitSources));
4437 }
4438
4439 /**
4440 * Record the results produced by performing a [GenerateDartErrorsTask]. If th e results were
4441 * computed from data that is now out-of-date, then the results will not be re corded.
4442 *
4443 * @param task the task that was performed
4444 * @return an entry containing the computed results
4445 * @throws AnalysisException if the results could not be recorded
4446 */
4447 DartEntry recordGenerateDartErrorsTask(GenerateDartErrorsTask task) {
4448 Source source = task.source;
4449 Source librarySource = task.libraryElement.source;
4450 AnalysisException thrownException = task.exception;
4451 DartEntry dartEntry = null;
4452 {
4453 SourceEntry sourceEntry = _cache.get(source);
4454 if (sourceEntry is! DartEntry) {
4455 throw new AnalysisException.con1("Internal error: attempting to verify n on-Dart file as a Dart file: ${source.fullName}");
4456 }
4457 dartEntry = sourceEntry as DartEntry;
4458 _cache.accessed(source);
4459 int sourceTime = source.modificationStamp;
4460 int resultTime = task.modificationTime;
4461 if (sourceTime == resultTime) {
4462 if (dartEntry.modificationTime != sourceTime) {
4463 sourceChanged(source);
4464 dartEntry = getReadableDartEntry(source);
4465 if (dartEntry == null) {
4466 throw new AnalysisException.con1("A Dart file became a non-Dart file : ${source.fullName}");
4467 }
4468 }
4469 DartEntryImpl dartCopy = dartEntry.writableCopy;
4470 if (thrownException == null) {
4471 dartCopy.setValue2(DartEntry.VERIFICATION_ERRORS, librarySource, task. errors);
4472 ChangeNoticeImpl notice = getNotice(source);
4473 notice.setErrors(dartCopy.allErrors, dartCopy.getValue(SourceEntry.LIN E_INFO));
4474 } else {
4475 dartCopy.setState2(DartEntry.VERIFICATION_ERRORS, librarySource, Cache State.ERROR);
4476 }
4477 dartCopy.exception = thrownException;
4478 _cache.put(source, dartCopy);
4479 dartEntry = dartCopy;
4480 } else {
4481 DartEntryImpl dartCopy = dartEntry.writableCopy;
4482 if (thrownException == null || resultTime >= 0) {
4483 dartCopy.setState2(DartEntry.VERIFICATION_ERRORS, librarySource, Cache State.INVALID);
4484 } else {
4485 dartCopy.setState2(DartEntry.VERIFICATION_ERRORS, librarySource, Cache State.ERROR);
4486 }
4487 dartCopy.exception = thrownException;
4488 _cache.put(source, dartCopy);
4489 dartEntry = dartCopy;
4490 }
4491 }
4492 if (thrownException != null) {
4493 throw thrownException;
4494 }
4495 return dartEntry;
4496 }
4497
4498 /**
4499 * Record the results produced by performing a [GenerateDartHintsTask]. If the results were
4500 * computed from data that is now out-of-date, then the results will not be re corded.
4501 *
4502 * @param task the task that was performed
4503 * @return an entry containing the computed results
4504 * @throws AnalysisException if the results could not be recorded
4505 */
4506 DartEntry recordGenerateDartHintsTask(GenerateDartHintsTask task) {
4507 Source librarySource = task.libraryElement.source;
4508 AnalysisException thrownException = task.exception;
4509 DartEntry libraryEntry = null;
4510 Map<Source, TimestampedData<List<AnalysisError>>> hintMap = task.hintMap;
4511 if (hintMap == null) {
4512 {
4513 SourceEntry sourceEntry = _cache.get(librarySource);
4514 if (sourceEntry is! DartEntry) {
4515 throw new AnalysisException.con1("Internal error: attempting to genera te hints for non-Dart file as a Dart file: ${librarySource.fullName}");
4516 }
4517 if (thrownException == null) {
4518 thrownException = new AnalysisException.con1("GenerateDartHintsTask re turned a null hint map without throwing an exception: ${librarySource.fullName}" );
4519 }
4520 DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
4521 dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.ERROR);
4522 dartCopy.exception = thrownException;
4523 _cache.put(librarySource, dartCopy);
4524 }
4525 throw thrownException;
4526 }
4527 for (MapEntry<Source, TimestampedData<List<AnalysisError>>> entry in getMapE ntrySet(hintMap)) {
4528 Source unitSource = entry.getKey();
4529 TimestampedData<List<AnalysisError>> results = entry.getValue();
4530 {
4531 SourceEntry sourceEntry = _cache.get(unitSource);
4532 if (sourceEntry is! DartEntry) {
4533 throw new AnalysisException.con1("Internal error: attempting to parse non-Dart file as a Dart file: ${unitSource.fullName}");
4534 }
4535 DartEntry dartEntry = sourceEntry as DartEntry;
4536 if (unitSource == librarySource) {
4537 libraryEntry = dartEntry;
4538 }
4539 _cache.accessed(unitSource);
4540 int sourceTime = unitSource.modificationStamp;
4541 int resultTime = results.modificationTime;
4542 if (sourceTime == resultTime) {
4543 if (dartEntry.modificationTime != sourceTime) {
4544 sourceChanged(unitSource);
4545 dartEntry = getReadableDartEntry(unitSource);
4546 if (dartEntry == null) {
4547 throw new AnalysisException.con1("A Dart file became a non-Dart fi le: ${unitSource.fullName}");
4548 }
4549 }
4550 DartEntryImpl dartCopy = dartEntry.writableCopy;
4551 if (thrownException == null) {
4552 dartCopy.setValue2(DartEntry.HINTS, librarySource, results.data);
4553 ChangeNoticeImpl notice = getNotice(unitSource);
4554 notice.setErrors(dartCopy.allErrors, dartCopy.getValue(SourceEntry.L INE_INFO));
4555 } else {
4556 dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.ERROR) ;
4557 }
4558 dartCopy.exception = thrownException;
4559 _cache.put(unitSource, dartCopy);
4560 dartEntry = dartCopy;
4561 } else {
4562 if (identical(dartEntry.getState2(DartEntry.HINTS, librarySource), Cac heState.IN_PROCESS)) {
4563 DartEntryImpl dartCopy = dartEntry.writableCopy;
4564 if (thrownException == null || resultTime >= 0) {
4565 dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.INVA LID);
4566 } else {
4567 dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.ERRO R);
4568 }
4569 dartCopy.exception = thrownException;
4570 _cache.put(unitSource, dartCopy);
4571 dartEntry = dartCopy;
4572 }
4573 }
4574 }
4575 }
4576 if (thrownException != null) {
4577 throw thrownException;
4578 }
4579 return libraryEntry;
4580 }
4581
4582 /**
4583 * Record the results produced by performing a [ParseDartTask]. If the results were computed
4584 * from data that is now out-of-date, then the results will not be recorded.
4585 *
4586 * @param task the task that was performed
4587 * @return an entry containing the computed results
4588 * @throws AnalysisException if the results could not be recorded
4589 */
4590 DartEntry recordParseDartTaskResults(ParseDartTask task) {
4591 Source source = task.source;
4592 AnalysisException thrownException = task.exception;
4593 DartEntry dartEntry = null;
4594 {
4595 SourceEntry sourceEntry = _cache.get(source);
4596 if (sourceEntry is! DartEntry) {
4597 throw new AnalysisException.con1("Internal error: attempting to parse no n-Dart file as a Dart file: ${source.fullName}");
4598 }
4599 dartEntry = sourceEntry as DartEntry;
4600 _cache.accessed(source);
4601 int sourceTime = source.modificationStamp;
4602 int resultTime = task.modificationTime;
4603 if (sourceTime == resultTime) {
4604 if (dartEntry.modificationTime != sourceTime) {
4605 sourceChanged(source);
4606 dartEntry = getReadableDartEntry(source);
4607 if (dartEntry == null) {
4608 throw new AnalysisException.con1("A Dart file became a non-Dart file : ${source.fullName}");
4609 }
4610 }
4611 DartEntryImpl dartCopy = dartEntry.writableCopy;
4612 if (thrownException == null) {
4613 LineInfo lineInfo = task.lineInfo;
4614 dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
4615 if (task.hasPartOfDirective() && !task.hasLibraryDirective()) {
4616 dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.PART);
4617 } else {
4618 dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
4619 }
4620 dartCopy.setValue(DartEntry.PARSED_UNIT, task.compilationUnit);
4621 dartCopy.setValue(DartEntry.PARSE_ERRORS, task.errors);
4622 dartCopy.setValue(DartEntry.EXPORTED_LIBRARIES, task.exportedSources);
4623 dartCopy.setValue(DartEntry.IMPORTED_LIBRARIES, task.importedSources);
4624 dartCopy.setValue(DartEntry.INCLUDED_PARTS, task.includedSources);
4625 ChangeNoticeImpl notice = getNotice(source);
4626 notice.setErrors(dartEntry.allErrors, lineInfo);
4627 } else {
4628 dartCopy.recordParseError();
4629 }
4630 dartCopy.exception = thrownException;
4631 _cache.put(source, dartCopy);
4632 dartEntry = dartCopy;
4633 } else {
4634 DartEntryImpl dartCopy = dartEntry.writableCopy;
4635 if (thrownException == null || resultTime >= 0) {
4636 dartCopy.recordParseNotInProcess();
4637 } else {
4638 dartCopy.recordParseError();
4639 }
4640 dartCopy.exception = thrownException;
4641 _cache.put(source, dartCopy);
4642 dartEntry = dartCopy;
4643 }
4644 }
4645 if (thrownException != null) {
4646 throw thrownException;
4647 }
4648 return dartEntry;
4649 }
4650
4651 /**
4652 * Record the results produced by performing a [ParseHtmlTask]. If the results were computed
4653 * from data that is now out-of-date, then the results will not be recorded.
4654 *
4655 * @param task the task that was performed
4656 * @return an entry containing the computed results
4657 * @throws AnalysisException if the results could not be recorded
4658 */
4659 HtmlEntry recordParseHtmlTaskResults(ParseHtmlTask task) {
4660 Source source = task.source;
4661 AnalysisException thrownException = task.exception;
4662 HtmlEntry htmlEntry = null;
4663 {
4664 SourceEntry sourceEntry = _cache.get(source);
4665 if (sourceEntry is! HtmlEntry) {
4666 throw new AnalysisException.con1("Internal error: attempting to parse no n-HTML file as a HTML file: ${source.fullName}");
4667 }
4668 htmlEntry = sourceEntry as HtmlEntry;
4669 _cache.accessed(source);
4670 int sourceTime = source.modificationStamp;
4671 int resultTime = task.modificationTime;
4672 if (sourceTime == resultTime) {
4673 if (htmlEntry.modificationTime != sourceTime) {
4674 sourceChanged(source);
4675 htmlEntry = getReadableHtmlEntry(source);
4676 if (htmlEntry == null) {
4677 throw new AnalysisException.con1("An HTML file became a non-HTML fil e: ${source.fullName}");
4678 }
4679 }
4680 HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
4681 if (thrownException == null) {
4682 LineInfo lineInfo = task.lineInfo;
4683 HtmlUnit unit = task.htmlUnit;
4684 htmlCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
4685 htmlCopy.setValue(HtmlEntry.PARSED_UNIT, unit);
4686 htmlCopy.setValue(HtmlEntry.REFERENCED_LIBRARIES, task.referencedLibra ries);
4687 ChangeNoticeImpl notice = getNotice(source);
4688 notice.setErrors(htmlEntry.allErrors, lineInfo);
4689 } else {
4690 htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.ERROR);
4691 htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.ERROR);
4692 htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.ERROR);
4693 }
4694 htmlCopy.exception = thrownException;
4695 _cache.put(source, htmlCopy);
4696 htmlEntry = htmlCopy;
4697 } else {
4698 HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
4699 if (thrownException == null || resultTime >= 0) {
4700 if (identical(htmlCopy.getState(SourceEntry.LINE_INFO), CacheState.IN_ PROCESS)) {
4701 htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.INVALID);
4702 }
4703 if (identical(htmlCopy.getState(HtmlEntry.PARSED_UNIT), CacheState.IN_ PROCESS)) {
4704 htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.INVALID);
4705 }
4706 if (identical(htmlCopy.getState(HtmlEntry.REFERENCED_LIBRARIES), Cache State.IN_PROCESS)) {
4707 htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.INVALID );
4708 }
4709 } else {
4710 htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.ERROR);
4711 htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.ERROR);
4712 htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.ERROR);
4713 }
4714 htmlCopy.exception = thrownException;
4715 _cache.put(source, htmlCopy);
4716 htmlEntry = htmlCopy;
4717 }
4718 }
4719 if (thrownException != null) {
4720 throw thrownException;
4721 }
4722 return htmlEntry;
4723 }
4724
4725 /**
4726 * Record the results produced by performing a [ResolveDartLibraryTask]. If th e results were
4727 * computed from data that is now out-of-date, then the results will not be re corded.
4728 *
4729 * @param task the task that was performed
4730 * @return an entry containing the computed results
4731 * @throws AnalysisException if the results could not be recorded
4732 */
4733 DartEntry recordResolveDartLibraryTaskResults(ResolveDartLibraryTask task) {
4734 LibraryResolver resolver = task.libraryResolver;
4735 AnalysisException thrownException = task.exception;
4736 DartEntry unitEntry = null;
4737 Source unitSource = task.unitSource;
4738 if (resolver != null) {
4739 Set<Library> resolvedLibraries = resolver.resolvedLibraries;
4740 if (resolvedLibraries == null) {
4741 unitEntry = getReadableDartEntry(unitSource);
4742 if (unitEntry == null) {
4743 throw new AnalysisException.con1("A Dart file became a non-Dart file: ${unitSource.fullName}");
4744 }
4745 DartEntryImpl dartCopy = unitEntry.writableCopy;
4746 dartCopy.recordResolutionError();
4747 dartCopy.exception = thrownException;
4748 _cache.put(unitSource, dartCopy);
4749 if (thrownException != null) {
4750 throw thrownException;
4751 }
4752 return dartCopy;
4753 }
4754 {
4755 if (allModificationTimesMatch(resolvedLibraries)) {
4756 Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
4757 RecordingErrorListener errorListener = resolver.errorListener;
4758 for (Library library in resolvedLibraries) {
4759 Source librarySource = library.librarySource;
4760 for (Source source in library.compilationUnitSources) {
4761 CompilationUnit unit = library.getAST(source);
4762 List<AnalysisError> errors = errorListener.getErrors2(source);
4763 LineInfo lineInfo = getLineInfo(source);
4764 DartEntry dartEntry = _cache.get(source) as DartEntry;
4765 int sourceTime = source.modificationStamp;
4766 if (dartEntry.modificationTime != sourceTime) {
4767 sourceChanged(source);
4768 dartEntry = getReadableDartEntry(source);
4769 if (dartEntry == null) {
4770 throw new AnalysisException.con1("A Dart file became a non-Dar t file: ${source.fullName}");
4771 }
4772 }
4773 DartEntryImpl dartCopy = dartEntry.writableCopy;
4774 if (thrownException == null) {
4775 dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
4776 dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
4777 dartCopy.setValue2(DartEntry.RESOLVED_UNIT, librarySource, unit) ;
4778 dartCopy.setValue2(DartEntry.RESOLUTION_ERRORS, librarySource, e rrors);
4779 if (identical(source, librarySource)) {
4780 recordElementData(dartCopy, library.libraryElement, htmlSource );
4781 }
4782 } else {
4783 dartCopy.recordResolutionError();
4784 }
4785 dartCopy.exception = thrownException;
4786 _cache.put(source, dartCopy);
4787 if (source == unitSource) {
4788 unitEntry = dartCopy;
4789 }
4790 ChangeNoticeImpl notice = getNotice(source);
4791 notice.compilationUnit = unit;
4792 notice.setErrors(dartCopy.allErrors, lineInfo);
4793 }
4794 }
4795 } else {
4796 for (Library library in resolvedLibraries) {
4797 for (Source source in library.compilationUnitSources) {
4798 DartEntry dartEntry = getReadableDartEntry(source);
4799 if (dartEntry != null) {
4800 int resultTime = library.getModificationTime(source);
4801 DartEntryImpl dartCopy = dartEntry.writableCopy;
4802 if (thrownException == null || resultTime >= 0) {
4803 dartCopy.recordResolutionNotInProcess();
4804 } else {
4805 dartCopy.recordResolutionError();
4806 }
4807 dartCopy.exception = thrownException;
4808 _cache.put(source, dartCopy);
4809 if (source == unitSource) {
4810 unitEntry = dartCopy;
4811 }
4812 }
4813 }
4814 }
4815 }
4816 }
4817 }
4818 if (thrownException != null) {
4819 throw thrownException;
4820 }
4821 if (unitEntry == null) {
4822 unitEntry = getReadableDartEntry(unitSource);
4823 if (unitEntry == null) {
4824 throw new AnalysisException.con1("A Dart file became a non-Dart file: ${ unitSource.fullName}");
4825 }
4826 }
4827 return unitEntry;
4828 }
4829
4830 /**
4831 * Record the results produced by performing a [ResolveDartUnitTask]. If the r esults were
4832 * computed from data that is now out-of-date, then the results will not be re corded.
4833 *
4834 * @param task the task that was performed
4835 * @return an entry containing the computed results
4836 * @throws AnalysisException if the results could not be recorded
4837 */
4838 SourceEntry recordResolveDartUnitTaskResults(ResolveDartUnitTask task) {
4839 Source unitSource = task.source;
4840 Source librarySource = task.librarySource;
4841 AnalysisException thrownException = task.exception;
4842 DartEntry dartEntry = null;
4843 {
4844 SourceEntry sourceEntry = _cache.get(unitSource);
4845 if (sourceEntry is! DartEntry) {
4846 throw new AnalysisException.con1("Internal error: attempting to reolve n on-Dart file as a Dart file: ${unitSource.fullName}");
4847 }
4848 dartEntry = sourceEntry as DartEntry;
4849 _cache.accessed(unitSource);
4850 int sourceTime = unitSource.modificationStamp;
4851 int resultTime = task.modificationTime;
4852 if (sourceTime == resultTime) {
4853 if (dartEntry.modificationTime != sourceTime) {
4854 sourceChanged(unitSource);
4855 dartEntry = getReadableDartEntry(unitSource);
4856 if (dartEntry == null) {
4857 throw new AnalysisException.con1("A Dart file became a non-Dart file : ${unitSource.fullName}");
4858 }
4859 }
4860 DartEntryImpl dartCopy = dartEntry.writableCopy;
4861 if (thrownException == null) {
4862 dartCopy.setValue2(DartEntry.RESOLVED_UNIT, librarySource, task.resolv edUnit);
4863 } else {
4864 dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState. ERROR);
4865 }
4866 dartCopy.exception = thrownException;
4867 _cache.put(unitSource, dartCopy);
4868 dartEntry = dartCopy;
4869 } else {
4870 DartEntryImpl dartCopy = dartEntry.writableCopy;
4871 if (thrownException == null || resultTime >= 0) {
4872 if (identical(dartCopy.getState(DartEntry.RESOLVED_UNIT), CacheState.I N_PROCESS)) {
4873 dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheStat e.INVALID);
4874 }
4875 } else {
4876 dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState. ERROR);
4877 }
4878 dartCopy.exception = thrownException;
4879 _cache.put(unitSource, dartCopy);
4880 dartEntry = dartCopy;
4881 }
4882 }
4883 if (thrownException != null) {
4884 throw thrownException;
4885 }
4886 return dartEntry;
4887 }
4888
4889 /**
4890 * Record the results produced by performing a [ResolveHtmlTask]. If the resul ts were
4891 * computed from data that is now out-of-date, then the results will not be re corded.
4892 *
4893 * @param task the task that was performed
4894 * @return an entry containing the computed results
4895 * @throws AnalysisException if the results could not be recorded
4896 */
4897 SourceEntry recordResolveHtmlTaskResults(ResolveHtmlTask task) {
4898 Source source = task.source;
4899 AnalysisException thrownException = task.exception;
4900 HtmlEntry htmlEntry = null;
4901 {
4902 SourceEntry sourceEntry = _cache.get(source);
4903 if (sourceEntry is! HtmlEntry) {
4904 throw new AnalysisException.con1("Internal error: attempting to reolve n on-HTML file as an HTML file: ${source.fullName}");
4905 }
4906 htmlEntry = sourceEntry as HtmlEntry;
4907 _cache.accessed(source);
4908 int sourceTime = source.modificationStamp;
4909 int resultTime = task.modificationTime;
4910 if (sourceTime == resultTime) {
4911 if (htmlEntry.modificationTime != sourceTime) {
4912 sourceChanged(source);
4913 htmlEntry = getReadableHtmlEntry(source);
4914 if (htmlEntry == null) {
4915 throw new AnalysisException.con1("An HTML file became a non-HTML fil e: ${source.fullName}");
4916 }
4917 }
4918 HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
4919 if (thrownException == null) {
4920 htmlCopy.setValue(HtmlEntry.ELEMENT, task.element);
4921 htmlCopy.setValue(HtmlEntry.RESOLUTION_ERRORS, task.resolutionErrors);
4922 ChangeNoticeImpl notice = getNotice(source);
4923 notice.setErrors(htmlCopy.allErrors, htmlCopy.getValue(SourceEntry.LIN E_INFO));
4924 } else {
4925 htmlCopy.recordResolutionError();
4926 }
4927 htmlCopy.exception = thrownException;
4928 _cache.put(source, htmlCopy);
4929 htmlEntry = htmlCopy;
4930 } else {
4931 HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
4932 if (thrownException == null || resultTime >= 0) {
4933 if (identical(htmlCopy.getState(HtmlEntry.ELEMENT), CacheState.IN_PROC ESS)) {
4934 htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.INVALID);
4935 }
4936 if (identical(htmlCopy.getState(HtmlEntry.RESOLUTION_ERRORS), CacheSta te.IN_PROCESS)) {
4937 htmlCopy.setState(HtmlEntry.RESOLUTION_ERRORS, CacheState.INVALID);
4938 }
4939 } else {
4940 htmlCopy.recordResolutionError();
4941 }
4942 htmlCopy.exception = thrownException;
4943 _cache.put(source, htmlCopy);
4944 htmlEntry = htmlCopy;
4945 }
4946 }
4947 if (thrownException != null) {
4948 throw thrownException;
4949 }
4950 return htmlEntry;
4951 }
4952
4953 /**
4954 * Create an entry for the newly added source. Return `true` if the new source is a Dart
4955 * file.
4956 *
4957 * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
4958 *
4959 * @param source the source that has been added
4960 * @return `true` if the new source is a Dart file
4961 */
4962 bool sourceAvailable(Source source) {
4963 SourceEntry sourceEntry = _cache.get(source);
4964 if (sourceEntry == null) {
4965 sourceEntry = createSourceEntry(source);
4966 } else {
4967 SourceEntryImpl sourceCopy = sourceEntry.writableCopy;
4968 sourceCopy.modificationTime = source.modificationStamp;
4969 _cache.put(source, sourceCopy);
4970 }
4971 return sourceEntry is DartEntry;
4972 }
4973
4974 /**
4975 * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
4976 *
4977 * @param source the source that has been changed
4978 */
4979 void sourceChanged(Source source) {
4980 SourceEntry sourceEntry = _cache.get(source);
4981 if (sourceEntry is HtmlEntry) {
4982 HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
4983 htmlCopy.modificationTime = source.modificationStamp;
4984 htmlCopy.invalidateAllInformation();
4985 _cache.put(source, htmlCopy);
4986 } else if (sourceEntry is DartEntry) {
4987 List<Source> containingLibraries = getLibrariesContaining(source);
4988 Set<Source> librariesToInvalidate = new Set<Source>();
4989 for (Source containingLibrary in containingLibraries) {
4990 javaSetAdd(librariesToInvalidate, containingLibrary);
4991 for (Source dependentLibrary in getLibrariesDependingOn(containingLibrar y)) {
4992 javaSetAdd(librariesToInvalidate, dependentLibrary);
4993 }
4994 }
4995 for (Source library in librariesToInvalidate) {
4996 invalidateLibraryResolution(library);
4997 }
4998 DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
4999 dartCopy.modificationTime = source.modificationStamp;
5000 dartCopy.invalidateAllInformation();
5001 _cache.put(source, dartCopy);
5002 }
5003 }
5004
5005 /**
5006 * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
5007 *
5008 * @param source the source that has been deleted
5009 */
5010 void sourceRemoved(Source source) {
5011 SourceEntry sourceEntry = _cache.get(source);
5012 if (sourceEntry is DartEntry) {
5013 Set<Source> libraries = new Set<Source>();
5014 for (Source librarySource in getLibrariesContaining(source)) {
5015 javaSetAdd(libraries, librarySource);
5016 for (Source dependentLibrary in getLibrariesDependingOn(librarySource)) {
5017 javaSetAdd(libraries, dependentLibrary);
5018 }
5019 }
5020 for (Source librarySource in libraries) {
5021 invalidateLibraryResolution(librarySource);
5022 }
5023 }
5024 _cache.remove(source);
5025 }
5026 }
5027 /**
5028 * Instances of the class `AnalysisTaskResultRecorder` are used by an analysis c ontext to
5029 * record the results of a task.
5030 */
5031 class AnalysisContextImpl_AnalysisTaskResultRecorder implements AnalysisTaskVisi tor<SourceEntry> {
5032 final AnalysisContextImpl AnalysisContextImpl_this;
5033 AnalysisContextImpl_AnalysisTaskResultRecorder(this.AnalysisContextImpl_this);
5034 SourceEntry visitGenerateDartErrorsTask(GenerateDartErrorsTask task) => Analys isContextImpl_this.recordGenerateDartErrorsTask(task);
5035 SourceEntry visitGenerateDartHintsTask(GenerateDartHintsTask task) => Analysis ContextImpl_this.recordGenerateDartHintsTask(task);
5036 DartEntry visitParseDartTask(ParseDartTask task) => AnalysisContextImpl_this.r ecordParseDartTaskResults(task);
5037 HtmlEntry visitParseHtmlTask(ParseHtmlTask task) => AnalysisContextImpl_this.r ecordParseHtmlTaskResults(task);
5038 DartEntry visitResolveDartLibraryTask(ResolveDartLibraryTask task) => Analysis ContextImpl_this.recordResolveDartLibraryTaskResults(task);
5039 SourceEntry visitResolveDartUnitTask(ResolveDartUnitTask task) => AnalysisCont extImpl_this.recordResolveDartUnitTaskResults(task);
5040 SourceEntry visitResolveHtmlTask(ResolveHtmlTask task) => AnalysisContextImpl_ this.recordResolveHtmlTaskResults(task);
5041 }
5042 class AnalysisContextImpl_ContextRetentionPolicy implements CacheRetentionPolicy {
5043 final AnalysisContextImpl AnalysisContextImpl_this;
5044 AnalysisContextImpl_ContextRetentionPolicy(this.AnalysisContextImpl_this);
5045 RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) {
5046 for (Source prioritySource in AnalysisContextImpl_this._priorityOrder) {
5047 if (source == prioritySource) {
5048 return RetentionPriority.HIGH;
5049 }
5050 }
5051 if (sourceEntry is DartEntry) {
5052 DartEntry dartEntry = sourceEntry as DartEntry;
5053 if (astIsNeeded(dartEntry)) {
5054 return RetentionPriority.MEDIUM;
5055 }
5056 }
5057 return RetentionPriority.LOW;
5058 }
5059 bool astIsNeeded(DartEntry dartEntry) => dartEntry.hasInvalidData(DartEntry.HI NTS) || dartEntry.hasInvalidData(DartEntry.VERIFICATION_ERRORS) || dartEntry.has InvalidData(DartEntry.RESOLUTION_ERRORS);
5060 }
5061 /**
5062 * Instances of the class `AnalysisErrorInfoImpl` represent the analysis errors and line info
5063 * associated with a source.
5064 */
5065 class AnalysisErrorInfoImpl implements AnalysisErrorInfo {
5066
5067 /**
5068 * The analysis errors associated with a source, or `null` if there are no err ors.
5069 */
5070 List<AnalysisError> _errors;
5071
5072 /**
5073 * The line information associated with the errors, or `null` if there are no errors.
5074 */
5075 LineInfo _lineInfo;
5076
5077 /**
5078 * Initialize an newly created error info with the errors and line information
5079 *
5080 * @param errors the errors as a result of analysis
5081 * @param lineinfo the line info for the errors
5082 */
5083 AnalysisErrorInfoImpl(List<AnalysisError> errors, LineInfo lineInfo) {
5084 this._errors = errors;
5085 this._lineInfo = lineInfo;
5086 }
5087
5088 /**
5089 * Return the errors of analysis, or `null` if there were no errors.
5090 *
5091 * @return the errors as a result of the analysis
5092 */
5093 List<AnalysisError> get errors => _errors;
5094
5095 /**
5096 * Return the line information associated with the errors, or `null` if there were no
5097 * errors.
5098 *
5099 * @return the line information associated with the errors
5100 */
5101 LineInfo get lineInfo => _lineInfo;
5102 }
5103 /**
5104 * Instances of the class `AnalysisOptions` represent a set of analysis options used to
5105 * control the behavior of an analysis context.
5106 */
5107 class AnalysisOptionsImpl implements AnalysisOptions {
5108
5109 /**
5110 * The maximum number of sources for which data should be kept in the cache.
5111 */
5112 static int DEFAULT_CACHE_SIZE = 64;
5113
5114 /**
5115 * The maximum number of sources for which AST structures should be kept in th e cache.
5116 */
5117 int _cacheSize = DEFAULT_CACHE_SIZE;
5118
5119 /**
5120 * A flag indicating whether analysis is to generate dart2js related hint resu lts.
5121 */
5122 bool _dart2jsHint = true;
5123
5124 /**
5125 * A flag indicating whether analysis is to generate hint results (e.g. type i nference based
5126 * information and pub best practices).
5127 */
5128 bool _hint = true;
5129
5130 /**
5131 * A flag indicating whether analysis is to use strict mode. In strict mode, e rror reporting is
5132 * based exclusively on the static type information.
5133 */
5134 bool _strictMode = true;
5135
5136 /**
5137 * Initialize a newly created set of analysis options to have their default va lues.
5138 */
5139 AnalysisOptionsImpl();
5140
5141 /**
5142 * Initialize a newly created set of analysis options to have the same values as those in the
5143 * given set of analysis options.
5144 *
5145 * @param options the analysis options whose values are being copied
5146 */
5147 AnalysisOptionsImpl.con1(AnalysisOptions options) {
5148 _cacheSize = options.cacheSize;
5149 _dart2jsHint = options.dart2jsHint;
5150 _hint = options.hint;
5151 _strictMode = options.strictMode;
5152 }
5153 int get cacheSize => _cacheSize;
5154 bool get dart2jsHint => _dart2jsHint;
5155 bool get hint => _hint;
5156
5157 /**
5158 * Return `true` if analysis is to use strict mode. In strict mode, error repo rting is based
5159 * exclusively on the static type information.
5160 *
5161 * @return `true` if analysis is to use strict mode
5162 */
5163 bool get strictMode => _strictMode;
5164
5165 /**
5166 * Set the maximum number of sources for which AST structures should be kept i n the cache to the
5167 * given size.
5168 *
5169 * @param cacheSize the maximum number of sources for which AST structures sho uld be kept in the
5170 * cache
5171 */
5172 void set cacheSize(int cacheSize) {
5173 this._cacheSize = cacheSize;
5174 }
5175
5176 /**
5177 * Set whether analysis is to generate dart2js related hint results.
5178 *
5179 * @param hint `true` if analysis is to generate dart2js related hint results
5180 */
5181 void set dart2jsHint(bool dart2jsHints) {
5182 this._dart2jsHint = dart2jsHints;
5183 }
5184
5185 /**
5186 * Set whether analysis is to generate hint results (e.g. type inference based information and pub
5187 * best practices).
5188 *
5189 * @param hint `true` if analysis is to generate hint results
5190 */
5191 void set hint(bool hint) {
5192 this._hint = hint;
5193 }
5194
5195 /**
5196 * Set whether analysis is to use strict mode to the given value. In strict mo de, error reporting
5197 * is based exclusively on the static type information.
5198 *
5199 * @param isStrict `true` if analysis is to use strict mode
5200 */
5201 void set strictMode(bool isStrict) {
5202 _strictMode = isStrict;
5203 }
5204 }
5205 /**
5206 * Instances of the class `ChangeNoticeImpl` represent a change to the analysis results
5207 * associated with a given source.
5208 *
5209 * @coverage dart.engine
5210 */
5211 class ChangeNoticeImpl implements ChangeNotice {
5212
5213 /**
5214 * The source for which the result is being reported.
5215 */
5216 Source _source;
5217
5218 /**
5219 * The fully resolved AST that changed as a result of the analysis, or `null` if the AST was
5220 * not changed.
5221 */
5222 CompilationUnit _compilationUnit;
5223
5224 /**
5225 * The errors that changed as a result of the analysis, or `null` if errors we re not
5226 * changed.
5227 */
5228 List<AnalysisError> _errors;
5229
5230 /**
5231 * The line information associated with the source, or `null` if errors were n ot changed.
5232 */
5233 LineInfo _lineInfo;
5234
5235 /**
5236 * An empty array of change notices.
5237 */
5238 static List<ChangeNoticeImpl> EMPTY_ARRAY = new List<ChangeNoticeImpl>(0);
5239
5240 /**
5241 * Initialize a newly created notice associated with the given source.
5242 *
5243 * @param source the source for which the change is being reported
5244 */
5245 ChangeNoticeImpl(Source source) {
5246 this._source = source;
5247 }
5248
5249 /**
5250 * Return the fully resolved AST that changed as a result of the analysis, or `null` if the
5251 * AST was not changed.
5252 *
5253 * @return the fully resolved AST that changed as a result of the analysis
5254 */
5255 CompilationUnit get compilationUnit => _compilationUnit;
5256
5257 /**
5258 * Return the errors that changed as a result of the analysis, or `null` if er rors were not
5259 * changed.
5260 *
5261 * @return the errors that changed as a result of the analysis
5262 */
5263 List<AnalysisError> get errors => _errors;
5264
5265 /**
5266 * Return the line information associated with the source, or `null` if errors were not
5267 * changed.
5268 *
5269 * @return the line information associated with the source
5270 */
5271 LineInfo get lineInfo => _lineInfo;
5272
5273 /**
5274 * Return the source for which the result is being reported.
5275 *
5276 * @return the source for which the result is being reported
5277 */
5278 Source get source => _source;
5279
5280 /**
5281 * Set the fully resolved AST that changed as a result of the analysis to the given AST.
5282 *
5283 * @param compilationUnit the fully resolved AST that changed as a result of t he analysis
5284 */
5285 void set compilationUnit(CompilationUnit compilationUnit) {
5286 this._compilationUnit = compilationUnit;
5287 }
5288
5289 /**
5290 * Set the errors that changed as a result of the analysis to the given errors and set the line
5291 * information to the given line information.
5292 *
5293 * @param errors the errors that changed as a result of the analysis
5294 * @param lineInfo the line information associated with the source
5295 */
5296 void setErrors(List<AnalysisError> errors, LineInfo lineInfo) {
5297 this._errors = errors;
5298 this._lineInfo = lineInfo;
5299 if (lineInfo == null) {
5300 AnalysisEngine.instance.logger.logError2("No line info: ${_source}", new J avaException());
5301 }
5302 }
5303 String toString() => "Changes for ${_source.fullName}";
5304 }
5305 /**
5306 * Instances of the class `DelegatingAnalysisContextImpl` extend [AnalysisContex tImpl
5307 ] to delegate sources to the appropriate analysis context. For instance, if the
5308 * source is in a system library then the analysis context from the [DartSdk] is used.
5309 *
5310 * @coverage dart.engine
5311 */
5312 class DelegatingAnalysisContextImpl extends AnalysisContextImpl {
5313
5314 /**
5315 * This references the [InternalAnalysisContext] held onto by the [DartSdk] wh ich is
5316 * used (instead of this [AnalysisContext]) for SDK sources. This field is set when
5317 * #setSourceFactory(SourceFactory) is called, and references the analysis con text in the
5318 * [DartUriResolver] in the [SourceFactory], this analysis context assumes tha t there
5319 * will be such a resolver.
5320 */
5321 InternalAnalysisContext _sdkAnalysisContext;
5322 void addSourceInfo(Source source, SourceEntry info) {
5323 if (source.isInSystemLibrary) {
5324 _sdkAnalysisContext.addSourceInfo(source, info);
5325 } else {
5326 super.addSourceInfo(source, info);
5327 }
5328 }
5329 List<AnalysisError> computeErrors(Source source) {
5330 if (source.isInSystemLibrary) {
5331 return _sdkAnalysisContext.computeErrors(source);
5332 } else {
5333 return super.computeErrors(source);
5334 }
5335 }
5336 List<Source> computeExportedLibraries(Source source) {
5337 if (source.isInSystemLibrary) {
5338 return _sdkAnalysisContext.computeExportedLibraries(source);
5339 } else {
5340 return super.computeExportedLibraries(source);
5341 }
5342 }
5343 HtmlElement computeHtmlElement(Source source) {
5344 if (source.isInSystemLibrary) {
5345 return _sdkAnalysisContext.computeHtmlElement(source);
5346 } else {
5347 return super.computeHtmlElement(source);
5348 }
5349 }
5350 List<Source> computeImportedLibraries(Source source) {
5351 if (source.isInSystemLibrary) {
5352 return _sdkAnalysisContext.computeImportedLibraries(source);
5353 } else {
5354 return super.computeImportedLibraries(source);
5355 }
5356 }
5357 SourceKind computeKindOf(Source source) {
5358 if (source.isInSystemLibrary) {
5359 return _sdkAnalysisContext.computeKindOf(source);
5360 } else {
5361 return super.computeKindOf(source);
5362 }
5363 }
5364 LibraryElement computeLibraryElement(Source source) {
5365 if (source.isInSystemLibrary) {
5366 return _sdkAnalysisContext.computeLibraryElement(source);
5367 } else {
5368 return super.computeLibraryElement(source);
5369 }
5370 }
5371 LineInfo computeLineInfo(Source source) {
5372 if (source.isInSystemLibrary) {
5373 return _sdkAnalysisContext.computeLineInfo(source);
5374 } else {
5375 return super.computeLineInfo(source);
5376 }
5377 }
5378 ResolvableCompilationUnit computeResolvableCompilationUnit(Source source) {
5379 if (source.isInSystemLibrary) {
5380 return _sdkAnalysisContext.computeResolvableCompilationUnit(source);
5381 } else {
5382 return super.computeResolvableCompilationUnit(source);
5383 }
5384 }
5385 AnalysisErrorInfo getErrors(Source source) {
5386 if (source.isInSystemLibrary) {
5387 return _sdkAnalysisContext.getErrors(source);
5388 } else {
5389 return super.getErrors(source);
5390 }
5391 }
5392 HtmlElement getHtmlElement(Source source) {
5393 if (source.isInSystemLibrary) {
5394 return _sdkAnalysisContext.getHtmlElement(source);
5395 } else {
5396 return super.getHtmlElement(source);
5397 }
5398 }
5399 List<Source> getHtmlFilesReferencing(Source source) {
5400 if (source.isInSystemLibrary) {
5401 return _sdkAnalysisContext.getHtmlFilesReferencing(source);
5402 } else {
5403 return super.getHtmlFilesReferencing(source);
5404 }
5405 }
5406 SourceKind getKindOf(Source source) {
5407 if (source.isInSystemLibrary) {
5408 return _sdkAnalysisContext.getKindOf(source);
5409 } else {
5410 return super.getKindOf(source);
5411 }
5412 }
5413 List<Source> getLibrariesContaining(Source source) {
5414 if (source.isInSystemLibrary) {
5415 return _sdkAnalysisContext.getLibrariesContaining(source);
5416 } else {
5417 return super.getLibrariesContaining(source);
5418 }
5419 }
5420 List<Source> getLibrariesDependingOn(Source librarySource) {
5421 if (librarySource.isInSystemLibrary) {
5422 return _sdkAnalysisContext.getLibrariesDependingOn(librarySource);
5423 } else {
5424 return super.getLibrariesDependingOn(librarySource);
5425 }
5426 }
5427 LibraryElement getLibraryElement(Source source) {
5428 if (source.isInSystemLibrary) {
5429 return _sdkAnalysisContext.getLibraryElement(source);
5430 } else {
5431 return super.getLibraryElement(source);
5432 }
5433 }
5434 List<Source> get librarySources => ArrayUtils.addAll(super.librarySources, _sd kAnalysisContext.librarySources);
5435 LineInfo getLineInfo(Source source) {
5436 if (source.isInSystemLibrary) {
5437 return _sdkAnalysisContext.getLineInfo(source);
5438 } else {
5439 return super.getLineInfo(source);
5440 }
5441 }
5442 Namespace getPublicNamespace(LibraryElement library) {
5443 Source source = library.source;
5444 if (source.isInSystemLibrary) {
5445 return _sdkAnalysisContext.getPublicNamespace(library);
5446 } else {
5447 return super.getPublicNamespace(library);
5448 }
5449 }
5450 Namespace getPublicNamespace2(Source source) {
5451 if (source.isInSystemLibrary) {
5452 return _sdkAnalysisContext.getPublicNamespace2(source);
5453 } else {
5454 return super.getPublicNamespace2(source);
5455 }
5456 }
5457 CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement l ibrary) {
5458 if (unitSource.isInSystemLibrary) {
5459 return _sdkAnalysisContext.getResolvedCompilationUnit(unitSource, library) ;
5460 } else {
5461 return super.getResolvedCompilationUnit(unitSource, library);
5462 }
5463 }
5464 CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source libraryS ource) {
5465 if (unitSource.isInSystemLibrary) {
5466 return _sdkAnalysisContext.getResolvedCompilationUnit2(unitSource, library Source);
5467 } else {
5468 return super.getResolvedCompilationUnit2(unitSource, librarySource);
5469 }
5470 }
5471 bool isClientLibrary(Source librarySource) {
5472 if (librarySource.isInSystemLibrary) {
5473 return _sdkAnalysisContext.isClientLibrary(librarySource);
5474 } else {
5475 return super.isClientLibrary(librarySource);
5476 }
5477 }
5478 bool isServerLibrary(Source librarySource) {
5479 if (librarySource.isInSystemLibrary) {
5480 return _sdkAnalysisContext.isServerLibrary(librarySource);
5481 } else {
5482 return super.isServerLibrary(librarySource);
5483 }
5484 }
5485 CompilationUnit parseCompilationUnit(Source source) {
5486 if (source.isInSystemLibrary) {
5487 return _sdkAnalysisContext.parseCompilationUnit(source);
5488 } else {
5489 return super.parseCompilationUnit(source);
5490 }
5491 }
5492 HtmlUnit parseHtmlUnit(Source source) {
5493 if (source.isInSystemLibrary) {
5494 return _sdkAnalysisContext.parseHtmlUnit(source);
5495 } else {
5496 return super.parseHtmlUnit(source);
5497 }
5498 }
5499 void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
5500 if (elementMap.isEmpty) {
5501 return;
5502 }
5503 Source source = new JavaIterator(elementMap.keys.toSet()).next();
5504 if (source.isInSystemLibrary) {
5505 _sdkAnalysisContext.recordLibraryElements(elementMap);
5506 } else {
5507 super.recordLibraryElements(elementMap);
5508 }
5509 }
5510 CompilationUnit resolveCompilationUnit(Source source, LibraryElement library) {
5511 if (source.isInSystemLibrary) {
5512 return _sdkAnalysisContext.resolveCompilationUnit(source, library);
5513 } else {
5514 return super.resolveCompilationUnit(source, library);
5515 }
5516 }
5517 CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySourc e) {
5518 if (unitSource.isInSystemLibrary) {
5519 return _sdkAnalysisContext.resolveCompilationUnit2(unitSource, librarySour ce);
5520 } else {
5521 return super.resolveCompilationUnit2(unitSource, librarySource);
5522 }
5523 }
5524 HtmlUnit resolveHtmlUnit(Source unitSource) {
5525 if (unitSource.isInSystemLibrary) {
5526 return _sdkAnalysisContext.resolveHtmlUnit(unitSource);
5527 } else {
5528 return super.resolveHtmlUnit(unitSource);
5529 }
5530 }
5531 void setChangedContents(Source source, String contents, int offset, int oldLen gth, int newLength) {
5532 if (source.isInSystemLibrary) {
5533 _sdkAnalysisContext.setChangedContents(source, contents, offset, oldLength , newLength);
5534 } else {
5535 super.setChangedContents(source, contents, offset, oldLength, newLength);
5536 }
5537 }
5538 void setContents(Source source, String contents) {
5539 if (source.isInSystemLibrary) {
5540 _sdkAnalysisContext.setContents(source, contents);
5541 } else {
5542 super.setContents(source, contents);
5543 }
5544 }
5545 void set sourceFactory(SourceFactory factory) {
5546 super.sourceFactory = factory;
5547 DartSdk sdk = factory.dartSdk;
5548 if (sdk != null) {
5549 _sdkAnalysisContext = sdk.context as InternalAnalysisContext;
5550 if (_sdkAnalysisContext is DelegatingAnalysisContextImpl) {
5551 _sdkAnalysisContext = null;
5552 throw new IllegalStateException("The context provided by an SDK cannot i tself be a delegating analysis context");
5553 }
5554 } else {
5555 throw new IllegalStateException("SourceFactorys provided to DelegatingAnal ysisContextImpls must have a DartSdk associated with the provided SourceFactory. ");
5556 }
5557 }
5558 }
5559 /**
5560 * Instances of the class `IncrementalAnalysisCache` hold information used to pe rform
5561 * incremental analysis.
5562 *
5563 * @see AnalysisContextImpl#setChangedContents(Source, String, int, int, int)
5564 */
5565 class IncrementalAnalysisCache {
5566
5567 /**
5568 * Determine if the cache should be cleared.
5569 *
5570 * @param cache the prior cache or `null` if none
5571 * @param source the source being updated (not `null`)
5572 * @return the cache used for incremental analysis or `null` if incremental an alysis cannot
5573 * be performed
5574 */
5575 static IncrementalAnalysisCache clear(IncrementalAnalysisCache cache, Source s ource) {
5576 if (cache == null || cache.source == source) {
5577 return null;
5578 }
5579 return cache;
5580 }
5581
5582 /**
5583 * Determine if incremental analysis can be performed from the given informati on.
5584 *
5585 * @param cache the prior cache or `null` if none
5586 * @param source the source being updated (not `null`)
5587 * @param oldContents the original source contents prior to this update (not ` null`)
5588 * @param newContents the new contents after this incremental change (not `nul l`)
5589 * @param offset the offset at which the change occurred
5590 * @param oldLength the length of the text being replaced
5591 * @param newLength the length of the replacement text
5592 * @param sourceEntry the cached entry for the given source or `null` if none
5593 * @return the cache used for incremental analysis or `null` if incremental an alysis cannot
5594 * be performed
5595 */
5596 static IncrementalAnalysisCache update(IncrementalAnalysisCache cache, Source source, String oldContents, String newContents, int offset, int oldLength, int n ewLength, SourceEntry sourceEntry) {
5597 if (cache == null || cache.source != source) {
5598 if (sourceEntry is! DartEntryImpl) {
5599 return null;
5600 }
5601 DartEntryImpl dartEntry = sourceEntry as DartEntryImpl;
5602 List<Source> librarySources = dartEntry.librariesContaining;
5603 if (librarySources.length != 1) {
5604 return null;
5605 }
5606 Source librarySource = librarySources[0];
5607 if (librarySource == null) {
5608 return null;
5609 }
5610 CompilationUnit unit = dartEntry.getValue2(DartEntry.RESOLVED_UNIT, librar ySource);
5611 if (unit == null) {
5612 return null;
5613 }
5614 if (oldContents == null) {
5615 if (oldLength != 0) {
5616 return null;
5617 }
5618 oldContents = "${newContents.substring(0, offset)}${newContents.substrin g(offset + newLength)}";
5619 }
5620 return new IncrementalAnalysisCache(librarySource, source, unit, oldConten ts, newContents, offset, oldLength, newLength);
5621 }
5622 if (cache.offset > offset || offset > cache.offset + cache.newLength) {
5623 return null;
5624 }
5625 cache.newContents = newContents;
5626 cache.newLength += newLength - oldLength;
5627 return cache;
5628 }
5629 Source librarySource;
5630 Source source;
5631 String oldContents;
5632 CompilationUnit resolvedUnit;
5633 String newContents;
5634 int offset = 0;
5635 int oldLength = 0;
5636 int newLength = 0;
5637 IncrementalAnalysisCache(Source librarySource, Source source, CompilationUnit resolvedUnit, String oldContents, String newContents, int offset, int oldLength, int newLength) {
5638 this.librarySource = librarySource;
5639 this.source = source;
5640 this.resolvedUnit = resolvedUnit;
5641 this.oldContents = oldContents;
5642 this.newContents = newContents;
5643 this.offset = offset;
5644 this.oldLength = oldLength;
5645 this.newLength = newLength;
5646 }
5647 }
5648 /**
5649 * Instances of the class `InstrumentedAnalysisContextImpl` implement an
5650 * [AnalysisContext] by recording instrumentation data and delegating to
5651 * another analysis context to do the non-instrumentation work.
5652 *
5653 * @coverage dart.engine
5654 */
5655 class InstrumentedAnalysisContextImpl implements InternalAnalysisContext {
5656
5657 /**
5658 * Record an exception that was thrown during analysis.
5659 *
5660 * @param instrumentation the instrumentation builder being used to record the exception
5661 * @param exception the exception being reported
5662 */
5663 static void recordAnalysisException(InstrumentationBuilder instrumentation, An alysisException exception) {
5664 instrumentation.record(exception);
5665 }
5666
5667 /**
5668 * The unique identifier used to identify this analysis context in the instrum entation data.
5669 */
5670 String _contextId = UUID.randomUUID().toString();
5671
5672 /**
5673 * The analysis context to which all of the non-instrumentation work is delega ted.
5674 */
5675 InternalAnalysisContext basis;
5676
5677 /**
5678 * Create a new [InstrumentedAnalysisContextImpl] which wraps a new
5679 * [AnalysisContextImpl] as the basis context.
5680 */
5681 InstrumentedAnalysisContextImpl() : this.con1(new DelegatingAnalysisContextImp l());
5682
5683 /**
5684 * Create a new [InstrumentedAnalysisContextImpl] with a specified basis conte xt, aka the
5685 * context to wrap and instrument.
5686 *
5687 * @param context some [InstrumentedAnalysisContext] to wrap and instrument
5688 */
5689 InstrumentedAnalysisContextImpl.con1(InternalAnalysisContext context) {
5690 basis = context;
5691 }
5692 void addSourceInfo(Source source, SourceEntry info) {
5693 basis.addSourceInfo(source, info);
5694 }
5695 void applyChanges(ChangeSet changeSet) {
5696 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- applyChanges");
5697 try {
5698 instrumentation.metric3("contextId", _contextId);
5699 basis.applyChanges(changeSet);
5700 } finally {
5701 instrumentation.log();
5702 }
5703 }
5704 String computeDocumentationComment(Element element) {
5705 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- computeDocumentationComment");
5706 try {
5707 instrumentation.metric3("contextId", _contextId);
5708 return basis.computeDocumentationComment(element);
5709 } finally {
5710 instrumentation.log();
5711 }
5712 }
5713 List<AnalysisError> computeErrors(Source source) {
5714 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- computeErrors");
5715 try {
5716 instrumentation.metric3("contextId", _contextId);
5717 List<AnalysisError> errors = basis.computeErrors(source);
5718 instrumentation.metric2("Errors-count", errors.length);
5719 return errors;
5720 } finally {
5721 instrumentation.log();
5722 }
5723 }
5724 List<Source> computeExportedLibraries(Source source) {
5725 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- computeExportedLibraries");
5726 try {
5727 instrumentation.metric3("contextId", _contextId);
5728 return basis.computeExportedLibraries(source);
5729 } finally {
5730 instrumentation.log();
5731 }
5732 }
5733 HtmlElement computeHtmlElement(Source source) {
5734 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- computeHtmlElement");
5735 try {
5736 instrumentation.metric3("contextId", _contextId);
5737 return basis.computeHtmlElement(source);
5738 } on AnalysisException catch (e) {
5739 recordAnalysisException(instrumentation, e);
5740 throw e;
5741 } finally {
5742 instrumentation.log();
5743 }
5744 }
5745 List<Source> computeImportedLibraries(Source source) {
5746 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- computeImportedLibraries");
5747 try {
5748 instrumentation.metric3("contextId", _contextId);
5749 return basis.computeImportedLibraries(source);
5750 } finally {
5751 instrumentation.log();
5752 }
5753 }
5754 SourceKind computeKindOf(Source source) {
5755 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- computeKindOf");
5756 try {
5757 instrumentation.metric3("contextId", _contextId);
5758 return basis.computeKindOf(source);
5759 } finally {
5760 instrumentation.log();
5761 }
5762 }
5763 LibraryElement computeLibraryElement(Source source) {
5764 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- computeLibraryElement");
5765 try {
5766 instrumentation.metric3("contextId", _contextId);
5767 return basis.computeLibraryElement(source);
5768 } on AnalysisException catch (e) {
5769 recordAnalysisException(instrumentation, e);
5770 throw e;
5771 } finally {
5772 instrumentation.log();
5773 }
5774 }
5775 LineInfo computeLineInfo(Source source) {
5776 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- computeLineInfo");
5777 try {
5778 instrumentation.metric3("contextId", _contextId);
5779 return basis.computeLineInfo(source);
5780 } on AnalysisException catch (e) {
5781 recordAnalysisException(instrumentation, e);
5782 throw e;
5783 } finally {
5784 instrumentation.log();
5785 }
5786 }
5787 ResolvableCompilationUnit computeResolvableCompilationUnit(Source source) => b asis.computeResolvableCompilationUnit(source);
5788 ResolvableHtmlUnit computeResolvableHtmlUnit(Source source) => basis.computeRe solvableHtmlUnit(source);
5789 AnalysisContext extractContext(SourceContainer container) {
5790 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- extractContext");
5791 try {
5792 instrumentation.metric3("contextId", _contextId);
5793 InstrumentedAnalysisContextImpl newContext = new InstrumentedAnalysisConte xtImpl();
5794 basis.extractContextInto(container, newContext.basis);
5795 return newContext;
5796 } finally {
5797 instrumentation.log();
5798 }
5799 }
5800 InternalAnalysisContext extractContextInto(SourceContainer container, Internal AnalysisContext newContext) => basis.extractContextInto(container, newContext);
5801 AnalysisOptions get analysisOptions {
5802 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getAnalysisOptions");
5803 try {
5804 instrumentation.metric3("contextId", _contextId);
5805 return basis.analysisOptions;
5806 } finally {
5807 instrumentation.log();
5808 }
5809 }
5810 Element getElement(ElementLocation location) {
5811 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getElement");
5812 try {
5813 instrumentation.metric3("contextId", _contextId);
5814 return basis.getElement(location);
5815 } finally {
5816 instrumentation.log();
5817 }
5818 }
5819 AnalysisErrorInfo getErrors(Source source) {
5820 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getErrors");
5821 try {
5822 instrumentation.metric3("contextId", _contextId);
5823 AnalysisErrorInfo ret = basis.getErrors(source);
5824 if (ret != null) {
5825 instrumentation.metric2("Errors-count", ret.errors.length);
5826 }
5827 return ret;
5828 } finally {
5829 instrumentation.log();
5830 }
5831 }
5832 HtmlElement getHtmlElement(Source source) {
5833 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getHtmlElement");
5834 try {
5835 instrumentation.metric3("contextId", _contextId);
5836 return basis.getHtmlElement(source);
5837 } finally {
5838 instrumentation.log();
5839 }
5840 }
5841 List<Source> getHtmlFilesReferencing(Source source) {
5842 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getHtmlFilesReferencing");
5843 try {
5844 instrumentation.metric3("contextId", _contextId);
5845 List<Source> ret = basis.getHtmlFilesReferencing(source);
5846 if (ret != null) {
5847 instrumentation.metric2("Source-count", ret.length);
5848 }
5849 return ret;
5850 } finally {
5851 instrumentation.log();
5852 }
5853 }
5854 List<Source> get htmlSources {
5855 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getHtmlSources");
5856 try {
5857 instrumentation.metric3("contextId", _contextId);
5858 List<Source> ret = basis.htmlSources;
5859 if (ret != null) {
5860 instrumentation.metric2("Source-count", ret.length);
5861 }
5862 return ret;
5863 } finally {
5864 instrumentation.log();
5865 }
5866 }
5867 SourceKind getKindOf(Source source) {
5868 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getKindOf");
5869 try {
5870 instrumentation.metric3("contextId", _contextId);
5871 return basis.getKindOf(source);
5872 } finally {
5873 instrumentation.log();
5874 }
5875 }
5876 List<Source> get launchableClientLibrarySources {
5877 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getLaunchableClientLibrarySources");
5878 try {
5879 instrumentation.metric3("contextId", _contextId);
5880 List<Source> ret = basis.launchableClientLibrarySources;
5881 if (ret != null) {
5882 instrumentation.metric2("Source-count", ret.length);
5883 }
5884 return ret;
5885 } finally {
5886 instrumentation.log();
5887 }
5888 }
5889 List<Source> get launchableServerLibrarySources {
5890 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getLaunchableServerLibrarySources");
5891 try {
5892 instrumentation.metric3("contextId", _contextId);
5893 List<Source> ret = basis.launchableServerLibrarySources;
5894 if (ret != null) {
5895 instrumentation.metric2("Source-count", ret.length);
5896 }
5897 return ret;
5898 } finally {
5899 instrumentation.log();
5900 }
5901 }
5902 List<Source> getLibrariesContaining(Source source) {
5903 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getLibrariesContaining");
5904 try {
5905 instrumentation.metric3("contextId", _contextId);
5906 List<Source> ret = basis.getLibrariesContaining(source);
5907 if (ret != null) {
5908 instrumentation.metric2("Source-count", ret.length);
5909 }
5910 return ret;
5911 } finally {
5912 instrumentation.log2(2);
5913 }
5914 }
5915 List<Source> getLibrariesDependingOn(Source librarySource) {
5916 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getLibrariesDependingOn");
5917 try {
5918 instrumentation.metric3("contextId", _contextId);
5919 List<Source> ret = basis.getLibrariesDependingOn(librarySource);
5920 if (ret != null) {
5921 instrumentation.metric2("Source-count", ret.length);
5922 }
5923 return ret;
5924 } finally {
5925 instrumentation.log();
5926 }
5927 }
5928 LibraryElement getLibraryElement(Source source) {
5929 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getLibraryElement");
5930 try {
5931 instrumentation.metric3("contextId", _contextId);
5932 return basis.getLibraryElement(source);
5933 } finally {
5934 instrumentation.log();
5935 }
5936 }
5937 List<Source> get librarySources {
5938 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getLibrarySources");
5939 try {
5940 instrumentation.metric3("contextId", _contextId);
5941 List<Source> ret = basis.librarySources;
5942 if (ret != null) {
5943 instrumentation.metric2("Source-count", ret.length);
5944 }
5945 return ret;
5946 } finally {
5947 instrumentation.log();
5948 }
5949 }
5950 LineInfo getLineInfo(Source source) {
5951 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getLineInfo");
5952 try {
5953 instrumentation.metric3("contextId", _contextId);
5954 return basis.getLineInfo(source);
5955 } finally {
5956 instrumentation.log();
5957 }
5958 }
5959 Namespace getPublicNamespace(LibraryElement library) => basis.getPublicNamespa ce(library);
5960 Namespace getPublicNamespace2(Source source) => basis.getPublicNamespace2(sour ce);
5961 List<Source> get refactoringUnsafeSources => basis.refactoringUnsafeSources;
5962 CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement l ibrary) {
5963 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getResolvedCompilationUnit");
5964 try {
5965 instrumentation.metric3("contextId", _contextId);
5966 return basis.getResolvedCompilationUnit(unitSource, library);
5967 } finally {
5968 instrumentation.log();
5969 }
5970 }
5971 CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source libraryS ource) {
5972 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getResolvedCompilationUnit");
5973 try {
5974 instrumentation.metric3("contextId", _contextId);
5975 return basis.getResolvedCompilationUnit2(unitSource, librarySource);
5976 } finally {
5977 instrumentation.log2(2);
5978 }
5979 }
5980 SourceFactory get sourceFactory {
5981 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- getSourceFactory");
5982 try {
5983 instrumentation.metric3("contextId", _contextId);
5984 return basis.sourceFactory;
5985 } finally {
5986 instrumentation.log2(2);
5987 }
5988 }
5989 AnalysisContentStatistics get statistics => basis.statistics;
5990 TimestampedData<CompilationUnit> internalResolveCompilationUnit(Source unitSou rce, LibraryElement libraryElement) => basis.internalResolveCompilationUnit(unit Source, libraryElement);
5991 bool isClientLibrary(Source librarySource) {
5992 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- isClientLibrary");
5993 try {
5994 instrumentation.metric3("contextId", _contextId);
5995 return basis.isClientLibrary(librarySource);
5996 } finally {
5997 instrumentation.log();
5998 }
5999 }
6000 bool isServerLibrary(Source librarySource) {
6001 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- isServerLibrary");
6002 try {
6003 instrumentation.metric3("contextId", _contextId);
6004 return basis.isServerLibrary(librarySource);
6005 } finally {
6006 instrumentation.log();
6007 }
6008 }
6009 void mergeContext(AnalysisContext context) {
6010 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- mergeContext");
6011 try {
6012 instrumentation.metric3("contextId", _contextId);
6013 if (context is InstrumentedAnalysisContextImpl) {
6014 context = ((context as InstrumentedAnalysisContextImpl)).basis;
6015 }
6016 basis.mergeContext(context);
6017 } finally {
6018 instrumentation.log();
6019 }
6020 }
6021 CompilationUnit parseCompilationUnit(Source source) {
6022 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- parseCompilationUnit");
6023 try {
6024 instrumentation.metric3("contextId", _contextId);
6025 return basis.parseCompilationUnit(source);
6026 } on AnalysisException catch (e) {
6027 recordAnalysisException(instrumentation, e);
6028 throw e;
6029 } finally {
6030 instrumentation.log();
6031 }
6032 }
6033 HtmlUnit parseHtmlUnit(Source source) {
6034 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- parseHtmlUnit");
6035 try {
6036 instrumentation.metric3("contextId", _contextId);
6037 return basis.parseHtmlUnit(source);
6038 } on AnalysisException catch (e) {
6039 recordAnalysisException(instrumentation, e);
6040 throw e;
6041 } finally {
6042 instrumentation.log();
6043 }
6044 }
6045 AnalysisResult performAnalysisTask() {
6046 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- performAnalysisTask");
6047 try {
6048 instrumentation.metric3("contextId", _contextId);
6049 AnalysisResult result = basis.performAnalysisTask();
6050 if (result.changeNotices != null) {
6051 instrumentation.metric2("ChangeNotice-count", result.changeNotices.lengt h);
6052 }
6053 return result;
6054 } finally {
6055 instrumentation.log2(2);
6056 }
6057 }
6058 void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
6059 basis.recordLibraryElements(elementMap);
6060 }
6061 CompilationUnit resolveCompilationUnit(Source unitSource, LibraryElement libra ry) {
6062 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- resolveCompilationUnit");
6063 try {
6064 instrumentation.metric3("contextId", _contextId);
6065 return basis.resolveCompilationUnit(unitSource, library);
6066 } on AnalysisException catch (e) {
6067 recordAnalysisException(instrumentation, e);
6068 throw e;
6069 } finally {
6070 instrumentation.log();
6071 }
6072 }
6073 CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySourc e) {
6074 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- resolveCompilationUnit");
6075 try {
6076 instrumentation.metric3("contextId", _contextId);
6077 return basis.resolveCompilationUnit2(unitSource, librarySource);
6078 } on AnalysisException catch (e) {
6079 recordAnalysisException(instrumentation, e);
6080 throw e;
6081 } finally {
6082 instrumentation.log();
6083 }
6084 }
6085 HtmlUnit resolveHtmlUnit(Source htmlSource) {
6086 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- resolveHtmlUnit");
6087 try {
6088 instrumentation.metric3("contextId", _contextId);
6089 return basis.resolveHtmlUnit(htmlSource);
6090 } on AnalysisException catch (e) {
6091 recordAnalysisException(instrumentation, e);
6092 throw e;
6093 } finally {
6094 instrumentation.log();
6095 }
6096 }
6097 void set analysisOptions(AnalysisOptions options) {
6098 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- setAnalysisOptions");
6099 try {
6100 instrumentation.metric3("contextId", _contextId);
6101 basis.analysisOptions = options;
6102 } finally {
6103 instrumentation.log();
6104 }
6105 }
6106 void set analysisPriorityOrder(List<Source> sources) {
6107 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- setAnalysisPriorityOrder");
6108 try {
6109 instrumentation.metric3("contextId", _contextId);
6110 basis.analysisPriorityOrder = sources;
6111 } finally {
6112 instrumentation.log();
6113 }
6114 }
6115 void setChangedContents(Source source, String contents, int offset, int oldLen gth, int newLength) {
6116 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- setChangedContents");
6117 try {
6118 instrumentation.metric3("contextId", _contextId);
6119 basis.setChangedContents(source, contents, offset, oldLength, newLength);
6120 } finally {
6121 instrumentation.log();
6122 }
6123 }
6124 void setContents(Source source, String contents) {
6125 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- setContents");
6126 try {
6127 instrumentation.metric3("contextId", _contextId);
6128 basis.setContents(source, contents);
6129 } finally {
6130 instrumentation.log();
6131 }
6132 }
6133 void set sourceFactory(SourceFactory factory) {
6134 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- setSourceFactory");
6135 try {
6136 instrumentation.metric3("contextId", _contextId);
6137 basis.sourceFactory = factory;
6138 } finally {
6139 instrumentation.log();
6140 }
6141 }
6142 Iterable<Source> sourcesToResolve(List<Source> changedSources) {
6143 InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis- sourcesToResolve");
6144 try {
6145 instrumentation.metric3("contextId", _contextId);
6146 return basis.sourcesToResolve(changedSources);
6147 } finally {
6148 instrumentation.log();
6149 }
6150 }
6151 }
6152 /**
6153 * The interface `InternalAnalysisContext` defines additional behavior for an an alysis context
6154 * that is required by internal users of the context.
6155 */
6156 abstract class InternalAnalysisContext implements AnalysisContext {
6157
6158 /**
6159 * Add the given source with the given information to this context.
6160 *
6161 * @param source the source to be added
6162 * @param info the information about the source
6163 */
6164 void addSourceInfo(Source source, SourceEntry info);
6165
6166 /**
6167 * Return an array containing the sources of the libraries that are exported b y the library with
6168 * the given source. The array will be empty if the given source is invalid, i f the given source
6169 * does not represent a library, or if the library does not export any other l ibraries.
6170 *
6171 * @param source the source representing the library whose exports are to be r eturned
6172 * @return the sources of the libraries that are exported by the given library
6173 * @throws AnalysisException if the exported libraries could not be computed
6174 */
6175 List<Source> computeExportedLibraries(Source source);
6176
6177 /**
6178 * Return an array containing the sources of the libraries that are imported b y the library with
6179 * the given source. The array will be empty if the given source is invalid, i f the given source
6180 * does not represent a library, or if the library does not import any other l ibraries.
6181 *
6182 * @param source the source representing the library whose imports are to be r eturned
6183 * @return the sources of the libraries that are imported by the given library
6184 * @throws AnalysisException if the imported libraries could not be computed
6185 */
6186 List<Source> computeImportedLibraries(Source source);
6187
6188 /**
6189 * Return an AST structure corresponding to the given source, but ensure that the structure has
6190 * not already been resolved and will not be resolved by any other threads or in any other
6191 * library.
6192 *
6193 * @param source the compilation unit for which an AST structure should be ret urned
6194 * @return the AST structure representing the content of the source
6195 * @throws AnalysisException if the analysis could not be performed
6196 */
6197 ResolvableCompilationUnit computeResolvableCompilationUnit(Source source);
6198
6199 /**
6200 * Return an AST structure corresponding to the given source, but ensure that the structure has
6201 * not already been resolved and will not be resolved by any other threads.
6202 *
6203 * @param source the compilation unit for which an AST structure should be ret urned
6204 * @return the AST structure representing the content of the source
6205 * @throws AnalysisException if the analysis could not be performed
6206 */
6207 ResolvableHtmlUnit computeResolvableHtmlUnit(Source source);
6208
6209 /**
6210 * Initialize the specified context by removing the specified sources from the receiver and adding
6211 * them to the specified context.
6212 *
6213 * @param container the container containing sources that should be removed fr om this context and
6214 * added to the returned context
6215 * @param newContext the context to be initialized
6216 * @return the analysis context that was initialized
6217 */
6218 InternalAnalysisContext extractContextInto(SourceContainer container, Internal AnalysisContext newContext);
6219
6220 /**
6221 * Return a namespace containing mappings for all of the public names defined by the given
6222 * library.
6223 *
6224 * @param library the library whose public namespace is to be returned
6225 * @return the public namespace of the given library
6226 */
6227 Namespace getPublicNamespace(LibraryElement library);
6228
6229 /**
6230 * Return a namespace containing mappings for all of the public names defined by the library
6231 * defined by the given source.
6232 *
6233 * @param source the source defining the library whose public namespace is to be returned
6234 * @return the public namespace corresponding to the library defined by the gi ven source
6235 * @throws AnalysisException if the public namespace could not be computed
6236 */
6237 Namespace getPublicNamespace2(Source source);
6238
6239 /**
6240 * Returns a statistics about this context.
6241 */
6242 AnalysisContentStatistics get statistics;
6243
6244 /**
6245 * Return a time-stamped fully-resolved compilation unit for the given source in the given
6246 * library.
6247 *
6248 * @param unitSource the source of the compilation unit for which a resolved A ST structure is to
6249 * be returned
6250 * @param libraryElement the element representing the library in which the com pilation unit is to
6251 * be resolved
6252 * @return a time-stamped fully-resolved compilation unit for the source
6253 * @throws AnalysisException if the resolved compilation unit could not be com puted
6254 */
6255 TimestampedData<CompilationUnit> internalResolveCompilationUnit(Source unitSou rce, LibraryElement libraryElement);
6256
6257 /**
6258 * Given a table mapping the source for the libraries represented by the corre sponding elements to
6259 * the elements representing the libraries, record those mappings.
6260 *
6261 * @param elementMap a table mapping the source for the libraries represented by the elements to
6262 * the elements representing the libraries
6263 */
6264 void recordLibraryElements(Map<Source, LibraryElement> elementMap);
6265 }
6266 /**
6267 * Container with global [AnalysisContext] performance statistics.
6268 */
6269 class PerformanceStatistics {
6270
6271 /**
6272 * The [TimeCounter] for time spent in scanning.
6273 */
6274 static TimeCounter scan = new TimeCounter();
6275
6276 /**
6277 * The [TimeCounter] for time spent in parsing.
6278 */
6279 static TimeCounter parse = new TimeCounter();
6280
6281 /**
6282 * The [TimeCounter] for time spent in resolving.
6283 */
6284 static TimeCounter resolve = new TimeCounter();
6285
6286 /**
6287 * The [TimeCounter] for time spent in error verifier.
6288 */
6289 static TimeCounter errors = new TimeCounter();
6290
6291 /**
6292 * The [TimeCounter] for time spent in hints generator.
6293 */
6294 static TimeCounter hints = new TimeCounter();
6295 }
6296 /**
6297 * Instances of the class `RecordingErrorListener` implement an error listener t hat will
6298 * record the errors that are reported to it in a way that is appropriate for ca ching those errors
6299 * within an analysis context.
6300 *
6301 * @coverage dart.engine
6302 */
6303 class RecordingErrorListener implements AnalysisErrorListener {
6304
6305 /**
6306 * A HashMap of lists containing the errors that were collected, keyed by each [Source].
6307 */
6308 Map<Source, Set<AnalysisError>> _errors = new Map<Source, Set<AnalysisError>>( );
6309
6310 /**
6311 * Add all of the errors recorded by the given listener to this listener.
6312 *
6313 * @param listener the listener that has recorded the errors to be added
6314 */
6315 void addAll(RecordingErrorListener listener) {
6316 for (AnalysisError error in listener.errors) {
6317 onError(error);
6318 }
6319 }
6320
6321 /**
6322 * Answer the errors collected by the listener.
6323 *
6324 * @return an array of errors (not `null`, contains no `null`s)
6325 */
6326 List<AnalysisError> get errors {
6327 Iterable<MapEntry<Source, Set<AnalysisError>>> entrySet = getMapEntrySet(_er rors);
6328 int numEntries = entrySet.length;
6329 if (numEntries == 0) {
6330 return AnalysisError.NO_ERRORS;
6331 }
6332 List<AnalysisError> resultList = new List<AnalysisError>();
6333 for (MapEntry<Source, Set<AnalysisError>> entry in entrySet) {
6334 resultList.addAll(entry.getValue());
6335 }
6336 return new List.from(resultList);
6337 }
6338
6339 /**
6340 * Answer the errors collected by the listener for some passed [Source].
6341 *
6342 * @param source some [Source] for which the caller wants the set of [Analysis Error]s
6343 * collected by this listener
6344 * @return the errors collected by the listener for the passed [Source]
6345 */
6346 List<AnalysisError> getErrors2(Source source) {
6347 Set<AnalysisError> errorsForSource = _errors[source];
6348 if (errorsForSource == null) {
6349 return AnalysisError.NO_ERRORS;
6350 } else {
6351 return new List.from(errorsForSource);
6352 }
6353 }
6354 void onError(AnalysisError error) {
6355 Source source = error.source;
6356 Set<AnalysisError> errorsForSource = _errors[source];
6357 if (_errors[source] == null) {
6358 errorsForSource = new Set<AnalysisError>();
6359 _errors[source] = errorsForSource;
6360 }
6361 javaSetAdd(errorsForSource, error);
6362 }
6363 }
6364 /**
6365 * Instances of the class `ResolutionEraser` remove any resolution information f rom an AST
6366 * structure when used to visit that structure.
6367 */
6368 class ResolutionEraser extends GeneralizingASTVisitor<Object> {
6369 Object visitAssignmentExpression(AssignmentExpression node) {
6370 node.staticElement = null;
6371 node.propagatedElement = null;
6372 return super.visitAssignmentExpression(node);
6373 }
6374 Object visitBinaryExpression(BinaryExpression node) {
6375 node.staticElement = null;
6376 node.propagatedElement = null;
6377 return super.visitBinaryExpression(node);
6378 }
6379 Object visitCompilationUnit(CompilationUnit node) {
6380 node.element = null;
6381 return super.visitCompilationUnit(node);
6382 }
6383 Object visitConstructorDeclaration(ConstructorDeclaration node) {
6384 node.element = null;
6385 return super.visitConstructorDeclaration(node);
6386 }
6387 Object visitConstructorName(ConstructorName node) {
6388 node.staticElement = null;
6389 return super.visitConstructorName(node);
6390 }
6391 Object visitDirective(Directive node) {
6392 node.element = null;
6393 return super.visitDirective(node);
6394 }
6395 Object visitExpression(Expression node) {
6396 node.staticType = null;
6397 node.propagatedType = null;
6398 return super.visitExpression(node);
6399 }
6400 Object visitFunctionExpression(FunctionExpression node) {
6401 node.element = null;
6402 return super.visitFunctionExpression(node);
6403 }
6404 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
6405 node.staticElement = null;
6406 node.propagatedElement = null;
6407 return super.visitFunctionExpressionInvocation(node);
6408 }
6409 Object visitIndexExpression(IndexExpression node) {
6410 node.staticElement = null;
6411 node.propagatedElement = null;
6412 return super.visitIndexExpression(node);
6413 }
6414 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
6415 node.staticElement = null;
6416 return super.visitInstanceCreationExpression(node);
6417 }
6418 Object visitPostfixExpression(PostfixExpression node) {
6419 node.staticElement = null;
6420 node.propagatedElement = null;
6421 return super.visitPostfixExpression(node);
6422 }
6423 Object visitPrefixExpression(PrefixExpression node) {
6424 node.staticElement = null;
6425 node.propagatedElement = null;
6426 return super.visitPrefixExpression(node);
6427 }
6428 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
6429 node.staticElement = null;
6430 return super.visitRedirectingConstructorInvocation(node);
6431 }
6432 Object visitSimpleIdentifier(SimpleIdentifier node) {
6433 node.staticElement = null;
6434 node.propagatedElement = null;
6435 return super.visitSimpleIdentifier(node);
6436 }
6437 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
6438 node.staticElement = null;
6439 return super.visitSuperConstructorInvocation(node);
6440 }
6441 }
6442 /**
6443 * Instances of the class `ResolvableCompilationUnit` represent a compilation un it that is not
6444 * referenced by any other objects and for which we have modification stamp info rmation. It is used
6445 * by the [LibraryResolver] to resolve a library.
6446 */
6447 class ResolvableCompilationUnit extends TimestampedData<CompilationUnit> {
6448
6449 /**
6450 * Initialize a newly created holder to hold the given values.
6451 *
6452 * @param modificationTime the modification time of the source from which the AST was created
6453 * @param unit the AST that was created from the source
6454 */
6455 ResolvableCompilationUnit(int modificationTime, CompilationUnit unit) : super( modificationTime, unit);
6456
6457 /**
6458 * Return the AST that was created from the source.
6459 *
6460 * @return the AST that was created from the source
6461 */
6462 CompilationUnit get compilationUnit => data;
6463 }
6464 /**
6465 * Instances of the class `ResolvableHtmlUnit` represent an HTML unit that is no t referenced
6466 * by any other objects and for which we have modification stamp information. It is used by the
6467 * [ResolveHtmlTask] to resolve an HTML source.
6468 */
6469 class ResolvableHtmlUnit extends TimestampedData<HtmlUnit> {
6470
6471 /**
6472 * Initialize a newly created holder to hold the given values.
6473 *
6474 * @param modificationTime the modification time of the source from which the AST was created
6475 * @param unit the AST that was created from the source
6476 */
6477 ResolvableHtmlUnit(int modificationTime, HtmlUnit unit) : super(modificationTi me, unit);
6478
6479 /**
6480 * Return the AST that was created from the source.
6481 *
6482 * @return the AST that was created from the source
6483 */
6484 HtmlUnit get compilationUnit => data;
6485 }
6486 /**
6487 * Instances of the class `TimestampedData` represent analysis data for which we have a
6488 * modification time.
6489 */
6490 class TimestampedData<E> {
6491
6492 /**
6493 * The modification time of the source from which the data was created.
6494 */
6495 int modificationTime = 0;
6496
6497 /**
6498 * The data that was created from the source.
6499 */
6500 E data;
6501
6502 /**
6503 * Initialize a newly created holder to hold the given values.
6504 *
6505 * @param modificationTime the modification time of the source from which the data was created
6506 * @param unit the data that was created from the source
6507 */
6508 TimestampedData(int modificationTime, E data) {
6509 this.modificationTime = modificationTime;
6510 this.data = data;
6511 }
6512 }
6513 /**
6514 * The abstract class `AnalysisTask` defines the behavior of objects used to per form an
6515 * analysis task.
6516 */
6517 abstract class AnalysisTask {
6518
6519 /**
6520 * The context in which the task is to be performed.
6521 */
6522 InternalAnalysisContext context;
6523
6524 /**
6525 * The exception that was thrown while performing this task, or `null` if the task completed
6526 * successfully.
6527 */
6528 AnalysisException exception;
6529
6530 /**
6531 * Initialize a newly created task to perform analysis within the given contex t.
6532 *
6533 * @param context the context in which the task is to be performed
6534 */
6535 AnalysisTask(InternalAnalysisContext context) {
6536 this.context = context;
6537 }
6538
6539 /**
6540 * Use the given visitor to visit this task.
6541 *
6542 * @param visitor the visitor that should be used to visit this task
6543 * @return the value returned by the visitor
6544 * @throws AnalysisException if the visitor throws the exception
6545 */
6546 accept(AnalysisTaskVisitor visitor);
6547
6548 /**
6549 * Perform this analysis task and use the given visitor to visit this task aft er it has completed.
6550 *
6551 * @param visitor the visitor used to visit this task after it has completed
6552 * @return the value returned by the visitor
6553 * @throws AnalysisException if the visitor throws the exception
6554 */
6555 Object perform(AnalysisTaskVisitor visitor) {
6556 try {
6557 safelyPerform();
6558 } on AnalysisException catch (exception) {
6559 this.exception = exception;
6560 AnalysisEngine.instance.logger.logInformation2("Task failed: ${taskDescrip tion}", exception);
6561 }
6562 return accept(visitor);
6563 }
6564 String toString() => taskDescription;
6565
6566 /**
6567 * Return a textual description of this task.
6568 *
6569 * @return a textual description of this task
6570 */
6571 String get taskDescription;
6572
6573 /**
6574 * Perform this analysis task, protected by an exception handler.
6575 *
6576 * @throws AnalysisException if an exception occurs while performing the task
6577 */
6578 void internalPerform();
6579
6580 /**
6581 * Perform this analysis task, ensuring that all exceptions are wrapped in an
6582 * [AnalysisException].
6583 *
6584 * @throws AnalysisException if any exception occurs while performing the task
6585 */
6586 void safelyPerform() {
6587 try {
6588 internalPerform();
6589 } on AnalysisException catch (exception) {
6590 throw exception;
6591 } on JavaException catch (exception) {
6592 throw new AnalysisException.con3(exception);
6593 }
6594 }
6595 }
6596 /**
6597 * The interface `AnalysisTaskVisitor` defines the behavior of objects that can visit tasks.
6598 * While tasks are not structured in any interesting way, this class provides th e ability to
6599 * dispatch to an appropriate method.
6600 */
6601 abstract class AnalysisTaskVisitor<E> {
6602
6603 /**
6604 * Visit a [GenerateDartErrorsTask].
6605 *
6606 * @param task the task to be visited
6607 * @return the result of visiting the task
6608 * @throws AnalysisException if the visitor throws an exception for some reaso n
6609 */
6610 E visitGenerateDartErrorsTask(GenerateDartErrorsTask task);
6611
6612 /**
6613 * Visit a [GenerateDartHintsTask].
6614 *
6615 * @param task the task to be visited
6616 * @return the result of visiting the task
6617 * @throws AnalysisException if the visitor throws an exception for some reaso n
6618 */
6619 E visitGenerateDartHintsTask(GenerateDartHintsTask task);
6620
6621 /**
6622 * Visit a [ParseDartTask].
6623 *
6624 * @param task the task to be visited
6625 * @return the result of visiting the task
6626 * @throws AnalysisException if the visitor throws an exception for some reaso n
6627 */
6628 E visitParseDartTask(ParseDartTask task);
6629
6630 /**
6631 * Visit a [ParseHtmlTask].
6632 *
6633 * @param task the task to be visited
6634 * @return the result of visiting the task
6635 * @throws AnalysisException if the visitor throws an exception for some reaso n
6636 */
6637 E visitParseHtmlTask(ParseHtmlTask task);
6638
6639 /**
6640 * Visit a [ResolveDartLibraryTask].
6641 *
6642 * @param task the task to be visited
6643 * @return the result of visiting the task
6644 * @throws AnalysisException if the visitor throws an exception for some reaso n
6645 */
6646 E visitResolveDartLibraryTask(ResolveDartLibraryTask task);
6647
6648 /**
6649 * Visit a [ResolveDartUnitTask].
6650 *
6651 * @param task the task to be visited
6652 * @return the result of visiting the task
6653 * @throws AnalysisException if the visitor throws an exception for some reaso n
6654 */
6655 E visitResolveDartUnitTask(ResolveDartUnitTask task);
6656
6657 /**
6658 * Visit a [ResolveHtmlTask].
6659 *
6660 * @param task the task to be visited
6661 * @return the result of visiting the task
6662 * @throws AnalysisException if the visitor throws an exception for some reaso n
6663 */
6664 E visitResolveHtmlTask(ResolveHtmlTask task);
6665 }
6666 /**
6667 * Instances of the class `GenerateDartErrorsTask` generate errors and warnings for a single
6668 * Dart source.
6669 */
6670 class GenerateDartErrorsTask extends AnalysisTask {
6671
6672 /**
6673 * The source for which errors and warnings are to be produced.
6674 */
6675 Source source;
6676
6677 /**
6678 * The element model for the library containing the source.
6679 */
6680 LibraryElement libraryElement;
6681
6682 /**
6683 * The time at which the contents of the source were last modified.
6684 */
6685 int modificationTime = -1;
6686
6687 /**
6688 * The errors that were generated for the source.
6689 */
6690 List<AnalysisError> errors;
6691
6692 /**
6693 * Initialize a newly created task to perform analysis within the given contex t.
6694 *
6695 * @param context the context in which the task is to be performed
6696 * @param source the source for which errors and warnings are to be produced
6697 * @param libraryElement the element model for the library containing the sour ce
6698 */
6699 GenerateDartErrorsTask(InternalAnalysisContext context, Source source, Library Element libraryElement) : super(context) {
6700 this.source = source;
6701 this.libraryElement = libraryElement;
6702 }
6703 accept(AnalysisTaskVisitor visitor) => visitor.visitGenerateDartErrorsTask(thi s);
6704 String get taskDescription => "generate errors and warnings for ${source.fullN ame}";
6705 void internalPerform() {
6706 InternalAnalysisContext context = this.context;
6707 TimestampedData<CompilationUnit> data = context.internalResolveCompilationUn it(source, libraryElement);
6708 TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.errors.sta rt();
6709 try {
6710 modificationTime = data.modificationTime;
6711 CompilationUnit unit = data.data;
6712 RecordingErrorListener errorListener = new RecordingErrorListener();
6713 ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
6714 Source coreSource = context.sourceFactory.forUri(DartSdk.DART_CORE);
6715 LibraryElement coreLibrary = context.getLibraryElement(coreSource);
6716 TypeProvider typeProvider = new TypeProviderImpl(coreLibrary);
6717 ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, ty peProvider);
6718 unit.accept(constantVerifier);
6719 ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, libraryElem ent, typeProvider, new InheritanceManager(libraryElement));
6720 unit.accept(errorVerifier);
6721 errors = errorListener.getErrors2(source);
6722 } finally {
6723 timeCounter.stop();
6724 }
6725 }
6726 }
6727 /**
6728 * Instances of the class `GenerateDartHintsTask` generate hints for a single Da rt library.
6729 */
6730 class GenerateDartHintsTask extends AnalysisTask {
6731
6732 /**
6733 * The element model for the library being analyzed.
6734 */
6735 LibraryElement libraryElement;
6736
6737 /**
6738 * A table mapping the sources that were analyzed to the hints that were gener ated for the
6739 * sources.
6740 */
6741 Map<Source, TimestampedData<List<AnalysisError>>> hintMap;
6742
6743 /**
6744 * Initialize a newly created task to perform analysis within the given contex t.
6745 *
6746 * @param context the context in which the task is to be performed
6747 * @param libraryElement the element model for the library being analyzed
6748 */
6749 GenerateDartHintsTask(InternalAnalysisContext context, LibraryElement libraryE lement) : super(context) {
6750 this.libraryElement = libraryElement;
6751 }
6752 accept(AnalysisTaskVisitor visitor) => visitor.visitGenerateDartHintsTask(this );
6753 String get taskDescription {
6754 Source librarySource = libraryElement.source;
6755 if (librarySource == null) {
6756 return "generate Dart hints for library without source";
6757 }
6758 return "generate Dart hints for ${librarySource.fullName}";
6759 }
6760 void internalPerform() {
6761 RecordingErrorListener errorListener = new RecordingErrorListener();
6762 List<CompilationUnitElement> parts = libraryElement.parts;
6763 int partCount = parts.length;
6764 List<CompilationUnit> compilationUnits = new List<CompilationUnit>(partCount + 1);
6765 Map<Source, TimestampedData<CompilationUnit>> timestampMap = new Map<Source, TimestampedData<CompilationUnit>>();
6766 Source unitSource = libraryElement.definingCompilationUnit.source;
6767 TimestampedData<CompilationUnit> resolvedUnit = getCompilationUnit(unitSourc e);
6768 timestampMap[unitSource] = resolvedUnit;
6769 CompilationUnit unit = resolvedUnit.data;
6770 if (unit == null) {
6771 throw new AnalysisException.con1("Internal error: GenerateDartHintsTask fa iled to access resolved compilation unit for ${unitSource.fullName}");
6772 }
6773 compilationUnits[0] = unit;
6774 for (int i = 0; i < partCount; i++) {
6775 unitSource = parts[i].source;
6776 resolvedUnit = getCompilationUnit(unitSource);
6777 timestampMap[unitSource] = resolvedUnit;
6778 unit = resolvedUnit.data;
6779 if (unit == null) {
6780 throw new AnalysisException.con1("Internal error: GenerateDartHintsTask failed to access resolved compilation unit for ${unitSource.fullName}");
6781 }
6782 compilationUnits[i + 1] = unit;
6783 }
6784 HintGenerator hintGenerator = new HintGenerator(compilationUnits, context, e rrorListener);
6785 hintGenerator.generateForLibrary();
6786 hintMap = new Map<Source, TimestampedData<List<AnalysisError>>>();
6787 for (MapEntry<Source, TimestampedData<CompilationUnit>> entry in getMapEntry Set(timestampMap)) {
6788 Source source = entry.getKey();
6789 TimestampedData<CompilationUnit> unitData = entry.getValue();
6790 List<AnalysisError> errors = errorListener.getErrors2(source);
6791 hintMap[source] = new TimestampedData<List<AnalysisError>>(unitData.modifi cationTime, errors);
6792 }
6793 }
6794
6795 /**
6796 * Return the resolved compilation unit associated with the given source.
6797 *
6798 * @param unitSource the source for the compilation unit whose resolved AST is to be returned
6799 * @return the resolved compilation unit associated with the given source
6800 * @throws AnalysisException if the resolved compilation unit could not be com puted
6801 */
6802 TimestampedData<CompilationUnit> getCompilationUnit(Source unitSource) => cont ext.internalResolveCompilationUnit(unitSource, libraryElement);
6803 }
6804 /**
6805 * Instances of the class `ParseDartTask` parse a specific source as a Dart file .
6806 */
6807 class ParseDartTask extends AnalysisTask {
6808
6809 /**
6810 * The source to be parsed.
6811 */
6812 Source source;
6813
6814 /**
6815 * The time at which the contents of the source were last modified.
6816 */
6817 int modificationTime = -1;
6818
6819 /**
6820 * The line information that was produced.
6821 */
6822 LineInfo lineInfo;
6823
6824 /**
6825 * The compilation unit that was produced by parsing the source.
6826 */
6827 CompilationUnit compilationUnit;
6828
6829 /**
6830 * The errors that were produced by scanning and parsing the source.
6831 */
6832 List<AnalysisError> errors = AnalysisError.NO_ERRORS;
6833
6834 /**
6835 * A flag indicating whether the source contains a 'part of' directive.
6836 */
6837 bool _hasPartOfDirective2 = false;
6838
6839 /**
6840 * A flag indicating whether the source contains a 'library' directive.
6841 */
6842 bool _hasLibraryDirective2 = false;
6843
6844 /**
6845 * A set containing the sources referenced by 'export' directives.
6846 */
6847 Set<Source> _exportedSources = new Set<Source>();
6848
6849 /**
6850 * A set containing the sources referenced by 'import' directives.
6851 */
6852 Set<Source> _importedSources = new Set<Source>();
6853
6854 /**
6855 * A set containing the sources referenced by 'part' directives.
6856 */
6857 Set<Source> _includedSources = new Set<Source>();
6858
6859 /**
6860 * Initialize a newly created task to perform analysis within the given contex t.
6861 *
6862 * @param context the context in which the task is to be performed
6863 * @param source the source to be parsed
6864 */
6865 ParseDartTask(InternalAnalysisContext context, Source source) : super(context) {
6866 this.source = source;
6867 }
6868 accept(AnalysisTaskVisitor visitor) => visitor.visitParseDartTask(this);
6869
6870 /**
6871 * Return an array containing the sources referenced by 'export' directives, o r an empty array if
6872 * the task has not yet been performed or if an exception occurred.
6873 *
6874 * @return an array containing the sources referenced by 'export' directives
6875 */
6876 List<Source> get exportedSources => toArray(_exportedSources);
6877
6878 /**
6879 * Return an array containing the sources referenced by 'import' directives, o r an empty array if
6880 * the task has not yet been performed or if an exception occurred.
6881 *
6882 * @return an array containing the sources referenced by 'import' directives
6883 */
6884 List<Source> get importedSources => toArray(_importedSources);
6885
6886 /**
6887 * Return an array containing the sources referenced by 'part' directives, or an empty array if
6888 * the task has not yet been performed or if an exception occurred.
6889 *
6890 * @return an array containing the sources referenced by 'part' directives
6891 */
6892 List<Source> get includedSources => toArray(_includedSources);
6893
6894 /**
6895 * Return `true` if the source contains a 'library' directive, or `false` if t he task
6896 * has not yet been performed or if an exception occurred.
6897 *
6898 * @return `true` if the source contains a 'library' directive
6899 */
6900 bool hasLibraryDirective() => _hasLibraryDirective2;
6901
6902 /**
6903 * Return `true` if the source contains a 'part of' directive, or `false` if t he task
6904 * has not yet been performed or if an exception occurred.
6905 *
6906 * @return `true` if the source contains a 'part of' directive
6907 */
6908 bool hasPartOfDirective() => _hasPartOfDirective2;
6909 String get taskDescription {
6910 if (source == null) {
6911 return "parse as dart null source";
6912 }
6913 return "parse as dart ${source.fullName}";
6914 }
6915 void internalPerform() {
6916 RecordingErrorListener errorListener = new RecordingErrorListener();
6917 List<Token> token = [null];
6918 TimeCounter_TimeCounterHandle timeCounterScan = PerformanceStatistics.scan.s tart();
6919 try {
6920 Source_ContentReceiver receiver = new Source_ContentReceiver_11(this, erro rListener, token);
6921 try {
6922 source.getContents(receiver);
6923 } on JavaException catch (exception) {
6924 modificationTime = source.modificationStamp;
6925 throw new AnalysisException.con3(exception);
6926 }
6927 } finally {
6928 timeCounterScan.stop();
6929 }
6930 TimeCounter_TimeCounterHandle timeCounterParse = PerformanceStatistics.parse .start();
6931 try {
6932 Parser parser = new Parser(source, errorListener);
6933 compilationUnit = parser.parseCompilationUnit(token[0]);
6934 errors = errorListener.getErrors2(source);
6935 for (Directive directive in compilationUnit.directives) {
6936 if (directive is ExportDirective) {
6937 Source exportSource = resolveSource(source, directive as ExportDirecti ve);
6938 if (exportSource != null) {
6939 javaSetAdd(_exportedSources, exportSource);
6940 }
6941 } else if (directive is ImportDirective) {
6942 Source importSource = resolveSource(source, directive as ImportDirecti ve);
6943 if (importSource != null) {
6944 javaSetAdd(_importedSources, importSource);
6945 }
6946 } else if (directive is LibraryDirective) {
6947 _hasLibraryDirective2 = true;
6948 } else if (directive is PartDirective) {
6949 Source partSource = resolveSource(source, directive as PartDirective);
6950 if (partSource != null) {
6951 javaSetAdd(_includedSources, partSource);
6952 }
6953 } else if (directive is PartOfDirective) {
6954 _hasPartOfDirective2 = true;
6955 }
6956 }
6957 compilationUnit.lineInfo = lineInfo;
6958 } finally {
6959 timeCounterParse.stop();
6960 }
6961 }
6962
6963 /**
6964 * Return the result of resolving the URI of the given URI-based directive aga inst the URI of the
6965 * given library, or `null` if the URI is not valid.
6966 *
6967 * @param librarySource the source representing the library containing the dir ective
6968 * @param directive the directive which URI should be resolved
6969 * @return the result of resolving the URI against the URI of the library
6970 */
6971 Source resolveSource(Source librarySource, UriBasedDirective directive) {
6972 StringLiteral uriLiteral = directive.uri;
6973 if (uriLiteral is StringInterpolation) {
6974 return null;
6975 }
6976 String uriContent = uriLiteral.stringValue.trim();
6977 if (uriContent == null) {
6978 return null;
6979 }
6980 uriContent = Uri.encodeFull(uriContent);
6981 try {
6982 parseUriWithException(uriContent);
6983 return context.sourceFactory.resolveUri(librarySource, uriContent);
6984 } on URISyntaxException catch (exception) {
6985 return null;
6986 }
6987 }
6988
6989 /**
6990 * Efficiently convert the given set of sources to an array.
6991 *
6992 * @param sources the set to be converted
6993 * @return an array containing all of the sources in the given set
6994 */
6995 List<Source> toArray(Set<Source> sources) {
6996 int size = sources.length;
6997 if (size == 0) {
6998 return Source.EMPTY_ARRAY;
6999 }
7000 return new List.from(sources);
7001 }
7002 }
7003 class Source_ContentReceiver_11 implements Source_ContentReceiver {
7004 final ParseDartTask ParseDartTask_this;
7005 RecordingErrorListener errorListener;
7006 List<Token> token;
7007 Source_ContentReceiver_11(this.ParseDartTask_this, this.errorListener, this.to ken);
7008 void accept(CharBuffer contents, int modificationTime) {
7009 ParseDartTask_this.modificationTime = modificationTime;
7010 Scanner scanner = new Scanner(ParseDartTask_this.source, new CharSequenceRea der(contents), errorListener);
7011 token[0] = scanner.tokenize();
7012 ParseDartTask_this.lineInfo = new LineInfo(scanner.lineStarts);
7013 }
7014 void accept2(String contents, int modificationTime) {
7015 ParseDartTask_this.modificationTime = modificationTime;
7016 Scanner scanner = new Scanner(ParseDartTask_this.source, new CharSequenceRea der(new CharSequence(contents)), errorListener);
7017 token[0] = scanner.tokenize();
7018 ParseDartTask_this.lineInfo = new LineInfo(scanner.lineStarts);
7019 }
7020 }
7021 /**
7022 * Instances of the class `ParseHtmlTask` parse a specific source as an HTML fil e.
7023 */
7024 class ParseHtmlTask extends AnalysisTask {
7025
7026 /**
7027 * The source to be parsed.
7028 */
7029 Source source;
7030
7031 /**
7032 * The time at which the contents of the source were last modified.
7033 */
7034 int modificationTime = -1;
7035
7036 /**
7037 * The line information that was produced.
7038 */
7039 LineInfo lineInfo;
7040
7041 /**
7042 * The HTML unit that was produced by parsing the source.
7043 */
7044 HtmlUnit htmlUnit;
7045
7046 /**
7047 * An array containing the sources of the libraries that are referenced within the HTML.
7048 */
7049 List<Source> referencedLibraries = Source.EMPTY_ARRAY;
7050
7051 /**
7052 * The name of the 'src' attribute in a HTML tag.
7053 */
7054 static String _ATTRIBUTE_SRC = "src";
7055
7056 /**
7057 * The name of the 'type' attribute in a HTML tag.
7058 */
7059 static String _ATTRIBUTE_TYPE = "type";
7060
7061 /**
7062 * The name of the 'script' tag in an HTML file.
7063 */
7064 static String _TAG_SCRIPT = "script";
7065
7066 /**
7067 * The value of the 'type' attribute of a 'script' tag that indicates that the script is written
7068 * in Dart.
7069 */
7070 static String _TYPE_DART = "application/dart";
7071
7072 /**
7073 * Initialize a newly created task to perform analysis within the given contex t.
7074 *
7075 * @param context the context in which the task is to be performed
7076 * @param source the source to be parsed
7077 */
7078 ParseHtmlTask(InternalAnalysisContext context, Source source) : super(context) {
7079 this.source = source;
7080 }
7081 accept(AnalysisTaskVisitor visitor) => visitor.visitParseHtmlTask(this);
7082 String get taskDescription {
7083 if (source == null) {
7084 return "parse as html null source";
7085 }
7086 return "parse as html ${source.fullName}";
7087 }
7088 void internalPerform() {
7089 HtmlScanner scanner = new HtmlScanner(source);
7090 try {
7091 source.getContents(scanner);
7092 } on JavaException catch (exception) {
7093 throw new AnalysisException.con3(exception);
7094 }
7095 HtmlScanResult scannerResult = scanner.result;
7096 modificationTime = scannerResult.modificationTime;
7097 lineInfo = new LineInfo(scannerResult.lineStarts);
7098 HtmlParseResult result = new HtmlParser(source).parse(scannerResult);
7099 htmlUnit = result.htmlUnit;
7100 referencedLibraries = librarySources;
7101 }
7102
7103 /**
7104 * Return the sources of libraries that are referenced in the specified HTML f ile.
7105 *
7106 * @return the sources of libraries that are referenced in the HTML file
7107 */
7108 List<Source> get librarySources {
7109 List<Source> libraries = new List<Source>();
7110 htmlUnit.accept(new RecursiveXmlVisitor_12(this, libraries));
7111 if (libraries.isEmpty) {
7112 return Source.EMPTY_ARRAY;
7113 }
7114 return new List.from(libraries);
7115 }
7116 }
7117 class RecursiveXmlVisitor_12 extends RecursiveXmlVisitor<Object> {
7118 final ParseHtmlTask ParseHtmlTask_this;
7119 List<Source> libraries;
7120 RecursiveXmlVisitor_12(this.ParseHtmlTask_this, this.libraries) : super();
7121 Object visitXmlTagNode(XmlTagNode node) {
7122 if (javaStringEqualsIgnoreCase(node.tag.lexeme, ParseHtmlTask._TAG_SCRIPT)) {
7123 bool isDartScript = false;
7124 XmlAttributeNode scriptAttribute = null;
7125 for (XmlAttributeNode attribute in node.attributes) {
7126 if (javaStringEqualsIgnoreCase(attribute.name.lexeme, ParseHtmlTask._ATT RIBUTE_SRC)) {
7127 scriptAttribute = attribute;
7128 } else if (javaStringEqualsIgnoreCase(attribute.name.lexeme, ParseHtmlTa sk._ATTRIBUTE_TYPE)) {
7129 if (javaStringEqualsIgnoreCase(attribute.text, ParseHtmlTask._TYPE_DAR T)) {
7130 isDartScript = true;
7131 }
7132 }
7133 }
7134 if (isDartScript && scriptAttribute != null) {
7135 try {
7136 Uri uri = new Uri(path: scriptAttribute.text);
7137 String fileName = uri.path;
7138 Source librarySource = ParseHtmlTask_this.context.sourceFactory.resolv eUri(ParseHtmlTask_this.source, fileName);
7139 if (librarySource != null && librarySource.exists()) {
7140 libraries.add(librarySource);
7141 }
7142 } on URISyntaxException catch (e) {
7143 }
7144 }
7145 }
7146 return super.visitXmlTagNode(node);
7147 }
7148 }
7149 /**
7150 * Instances of the class `ResolveDartLibraryTask` parse a specific Dart library .
7151 */
7152 class ResolveDartLibraryTask extends AnalysisTask {
7153
7154 /**
7155 * The source representing the file whose compilation unit is to be returned.
7156 */
7157 Source unitSource;
7158
7159 /**
7160 * The source representing the library to be resolved.
7161 */
7162 Source librarySource;
7163
7164 /**
7165 * The library resolver holding information about the libraries that were reso lved.
7166 */
7167 LibraryResolver libraryResolver;
7168
7169 /**
7170 * Initialize a newly created task to perform analysis within the given contex t.
7171 *
7172 * @param context the context in which the task is to be performed
7173 * @param unitSource the source representing the file whose compilation unit i s to be returned
7174 * @param librarySource the source representing the library to be resolved
7175 */
7176 ResolveDartLibraryTask(InternalAnalysisContext context, Source unitSource, Sou rce librarySource) : super(context) {
7177 this.unitSource = unitSource;
7178 this.librarySource = librarySource;
7179 }
7180 accept(AnalysisTaskVisitor visitor) => visitor.visitResolveDartLibraryTask(thi s);
7181 String get taskDescription {
7182 if (librarySource == null) {
7183 return "resolve library null source";
7184 }
7185 return "resolve library ${librarySource.fullName}";
7186 }
7187 void internalPerform() {
7188 libraryResolver = new LibraryResolver(context);
7189 libraryResolver.resolveLibrary(librarySource, true);
7190 }
7191 }
7192 /**
7193 * Instances of the class `ResolveDartUnitTask` resolve a single Dart file based on a existing
7194 * element model.
7195 */
7196 class ResolveDartUnitTask extends AnalysisTask {
7197
7198 /**
7199 * The source that is to be resolved.
7200 */
7201 Source source;
7202
7203 /**
7204 * The element model for the library containing the source.
7205 */
7206 LibraryElement _libraryElement;
7207
7208 /**
7209 * The time at which the contents of the source were last modified.
7210 */
7211 int modificationTime = -1;
7212
7213 /**
7214 * The compilation unit that was resolved by this task.
7215 */
7216 CompilationUnit resolvedUnit;
7217
7218 /**
7219 * Initialize a newly created task to perform analysis within the given contex t.
7220 *
7221 * @param context the context in which the task is to be performed
7222 * @param source the source to be parsed
7223 * @param libraryElement the element model for the library containing the sour ce
7224 */
7225 ResolveDartUnitTask(InternalAnalysisContext context, Source source, LibraryEle ment libraryElement) : super(context) {
7226 this.source = source;
7227 this._libraryElement = libraryElement;
7228 }
7229 accept(AnalysisTaskVisitor visitor) => visitor.visitResolveDartUnitTask(this);
7230
7231 /**
7232 * Return the source for the library containing the source that is to be resol ved.
7233 *
7234 * @return the source for the library containing the source that is to be reso lved
7235 */
7236 Source get librarySource => _libraryElement.source;
7237 String get taskDescription {
7238 Source librarySource = _libraryElement.source;
7239 if (librarySource == null) {
7240 return "resolve unit null source";
7241 }
7242 return "resolve unit ${librarySource.fullName}";
7243 }
7244 void internalPerform() {
7245 Source coreLibrarySource = _libraryElement.context.sourceFactory.forUri(Dart Sdk.DART_CORE);
7246 LibraryElement coreElement = context.computeLibraryElement(coreLibrarySource );
7247 TypeProvider typeProvider = new TypeProviderImpl(coreElement);
7248 ResolvableCompilationUnit resolvableUnit = context.computeResolvableCompilat ionUnit(source);
7249 modificationTime = resolvableUnit.modificationTime;
7250 CompilationUnit unit = resolvableUnit.compilationUnit;
7251 if (unit == null) {
7252 throw new AnalysisException.con1("Internal error: computeResolvableCompila tionUnit returned a value without a parsed Dart unit");
7253 }
7254 new DeclarationResolver().resolve(unit, find(_libraryElement, source));
7255 RecordingErrorListener errorListener = new RecordingErrorListener();
7256 TypeResolverVisitor typeResolverVisitor = new TypeResolverVisitor.con2(_libr aryElement, source, typeProvider, errorListener);
7257 unit.accept(typeResolverVisitor);
7258 InheritanceManager inheritanceManager = new InheritanceManager(_libraryEleme nt);
7259 ResolverVisitor resolverVisitor = new ResolverVisitor.con2(_libraryElement, source, typeProvider, inheritanceManager, errorListener);
7260 unit.accept(resolverVisitor);
7261 for (ProxyConditionalAnalysisError conditionalCode in resolverVisitor.proxyC onditionalAnalysisErrors) {
7262 if (conditionalCode.shouldIncludeErrorCode()) {
7263 resolverVisitor.reportError(conditionalCode.analysisError);
7264 }
7265 }
7266 TimeCounter_TimeCounterHandle counterHandleErrors = PerformanceStatistics.er rors.start();
7267 try {
7268 ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
7269 ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, _libraryEle ment, typeProvider, inheritanceManager);
7270 unit.accept(errorVerifier);
7271 ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, ty peProvider);
7272 unit.accept(constantVerifier);
7273 } finally {
7274 counterHandleErrors.stop();
7275 }
7276 resolvedUnit = unit;
7277 }
7278
7279 /**
7280 * Search the compilation units that are part of the given library and return the element
7281 * representing the compilation unit with the given source. Return `null` if t here is no
7282 * such compilation unit.
7283 *
7284 * @param libraryElement the element representing the library being searched t hrough
7285 * @param unitSource the source for the compilation unit whose element is to b e returned
7286 * @return the element representing the compilation unit
7287 */
7288 CompilationUnitElement find(LibraryElement libraryElement, Source unitSource) {
7289 CompilationUnitElement element = libraryElement.definingCompilationUnit;
7290 if (element.source == unitSource) {
7291 return element;
7292 }
7293 for (CompilationUnitElement partElement in libraryElement.parts) {
7294 if (partElement.source == unitSource) {
7295 return partElement;
7296 }
7297 }
7298 return null;
7299 }
7300 }
7301 /**
7302 * Instances of the class `ResolveHtmlTask` resolve a specific source as an HTML file.
7303 */
7304 class ResolveHtmlTask extends AnalysisTask {
7305
7306 /**
7307 * The source to be resolved.
7308 */
7309 Source source;
7310
7311 /**
7312 * The time at which the contents of the source were last modified.
7313 */
7314 int modificationTime = -1;
7315
7316 /**
7317 * The element produced by resolving the source.
7318 */
7319 HtmlElement element = null;
7320
7321 /**
7322 * The resolution errors that were discovered while resolving the source.
7323 */
7324 List<AnalysisError> resolutionErrors = AnalysisError.NO_ERRORS;
7325
7326 /**
7327 * Initialize a newly created task to perform analysis within the given contex t.
7328 *
7329 * @param context the context in which the task is to be performed
7330 * @param source the source to be resolved
7331 */
7332 ResolveHtmlTask(InternalAnalysisContext context, Source source) : super(contex t) {
7333 this.source = source;
7334 }
7335 accept(AnalysisTaskVisitor visitor) => visitor.visitResolveHtmlTask(this);
7336 String get taskDescription {
7337 if (source == null) {
7338 return "resolve as html null source";
7339 }
7340 return "resolve as html ${source.fullName}";
7341 }
7342 void internalPerform() {
7343 ResolvableHtmlUnit resolvableHtmlUnit = context.computeResolvableHtmlUnit(so urce);
7344 HtmlUnit unit = resolvableHtmlUnit.compilationUnit;
7345 if (unit == null) {
7346 throw new AnalysisException.con1("Internal error: computeResolvableHtmlUni t returned a value without a parsed HTML unit");
7347 }
7348 modificationTime = resolvableHtmlUnit.modificationTime;
7349 HtmlUnitBuilder builder = new HtmlUnitBuilder(context);
7350 element = builder.buildHtmlElement2(source, modificationTime, unit);
7351 resolutionErrors = builder.errorListener.getErrors2(source);
7352 }
7353 }
7354 /**
7355 * The interface `Logger` defines the behavior of objects that can be used to re ceive
7356 * information about errors within the analysis engine. Implementations usually write this
7357 * information to a file, but can also record the information for later use (suc h as during testing)
7358 * or even ignore the information.
7359 *
7360 * @coverage dart.engine.utilities
7361 */
7362 abstract class Logger {
7363 static final Logger NULL = new Logger_NullLogger();
7364
7365 /**
7366 * Log the given message as an error.
7367 *
7368 * @param message an explanation of why the error occurred or what it means
7369 */
7370 void logError(String message);
7371
7372 /**
7373 * Log the given exception as one representing an error.
7374 *
7375 * @param message an explanation of why the error occurred or what it means
7376 * @param exception the exception being logged
7377 */
7378 void logError2(String message, Exception exception);
7379
7380 /**
7381 * Log the given exception as one representing an error.
7382 *
7383 * @param exception the exception being logged
7384 */
7385 void logError3(Exception exception);
7386
7387 /**
7388 * Log the given informational message.
7389 *
7390 * @param message an explanation of why the error occurred or what it means
7391 * @param exception the exception being logged
7392 */
7393 void logInformation(String message);
7394
7395 /**
7396 * Log the given exception as one representing an informational message.
7397 *
7398 * @param message an explanation of why the error occurred or what it means
7399 * @param exception the exception being logged
7400 */
7401 void logInformation2(String message, Exception exception);
7402 }
7403 /**
7404 * Implementation of [Logger] that does nothing.
7405 */
7406 class Logger_NullLogger implements Logger {
7407 void logError(String message) {
7408 }
7409 void logError2(String message, Exception exception) {
7410 }
7411 void logError3(Exception exception) {
7412 }
7413 void logInformation(String message) {
7414 }
7415 void logInformation2(String message, Exception exception) {
7416 }
7417 }
OLDNEW
« no previous file with comments | « pkg/analyzer_experimental/lib/src/generated/element.dart ('k') | pkg/analyzer_experimental/lib/src/generated/error.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698