| OLD | NEW |
| (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 } | |
| OLD | NEW |