| // This code was auto-generated, is not intended to be edited, and is subject to |
| // significant change. Please see the README file for more information. |
| |
| library engine; |
| |
| import 'dart:collection' show HasNextIterator; |
| import 'dart:uri' show Uri; |
| import 'java_core.dart'; |
| import 'java_engine.dart'; |
| import 'instrumentation.dart'; |
| import 'error.dart'; |
| import 'source.dart'; |
| import 'scanner.dart' show Token, CharBufferScanner, StringScanner; |
| import 'ast.dart'; |
| import 'parser.dart' show Parser; |
| import 'sdk.dart' show DartSdk; |
| import 'element.dart'; |
| import 'resolver.dart'; |
| import 'html.dart' show XmlTagNode, XmlAttributeNode, RecursiveXmlVisitor, HtmlScanner, HtmlScanResult, HtmlParser, HtmlParseResult, HtmlUnit; |
| |
| /** |
| * The unique instance of the class {@code AnalysisEngine} serves as the entry point for the |
| * functionality provided by the analysis engine. |
| * @coverage dart.engine |
| */ |
| class AnalysisEngine { |
| /** |
| * The suffix used for Dart source files. |
| */ |
| static String SUFFIX_DART = "dart"; |
| /** |
| * The short suffix used for HTML files. |
| */ |
| static String SUFFIX_HTM = "htm"; |
| /** |
| * The long suffix used for HTML files. |
| */ |
| static String SUFFIX_HTML = "html"; |
| /** |
| * The unique instance of this class. |
| */ |
| static AnalysisEngine _UniqueInstance = new AnalysisEngine(); |
| /** |
| * Return the unique instance of this class. |
| * @return the unique instance of this class |
| */ |
| static AnalysisEngine get instance => _UniqueInstance; |
| /** |
| * Return {@code true} if the given file name is assumed to contain Dart source code. |
| * @param fileName the name of the file being tested |
| * @return {@code true} if the given file name is assumed to contain Dart source code |
| */ |
| static bool isDartFileName(String fileName) { |
| if (fileName == null) { |
| return false; |
| } |
| return javaStringEqualsIgnoreCase(FileNameUtilities.getExtension(fileName), SUFFIX_DART); |
| } |
| /** |
| * Return {@code true} if the given file name is assumed to contain HTML. |
| * @param fileName the name of the file being tested |
| * @return {@code true} if the given file name is assumed to contain HTML |
| */ |
| static bool isHtmlFileName(String fileName) { |
| if (fileName == null) { |
| return false; |
| } |
| String extension = FileNameUtilities.getExtension(fileName); |
| return javaStringEqualsIgnoreCase(extension, SUFFIX_HTML) || javaStringEqualsIgnoreCase(extension, SUFFIX_HTM); |
| } |
| /** |
| * The logger that should receive information about errors within the analysis engine. |
| */ |
| Logger _logger = Logger.NULL; |
| /** |
| * Prevent the creation of instances of this class. |
| */ |
| AnalysisEngine() : super() { |
| } |
| /** |
| * Create a new context in which analysis can be performed. |
| * @return the analysis context that was created |
| */ |
| AnalysisContext createAnalysisContext() { |
| if (Instrumentation.isNullLogger()) { |
| return new DelegatingAnalysisContextImpl(); |
| } else { |
| return new InstrumentedAnalysisContextImpl.con1(new DelegatingAnalysisContextImpl()); |
| } |
| } |
| /** |
| * Return the logger that should receive information about errors within the analysis engine. |
| * @return the logger that should receive information about errors within the analysis engine |
| */ |
| Logger get logger => _logger; |
| /** |
| * Set the logger that should receive information about errors within the analysis engine to the |
| * given logger. |
| * @param logger the logger that should receive information about errors within the analysis |
| * engine |
| */ |
| void set logger(Logger logger2) { |
| this._logger = logger2 == null ? Logger.NULL : logger2; |
| } |
| } |
| /** |
| * The interface {@code AnalysisContext} defines the behavior of objects that represent a context in |
| * which a single analysis can be performed and incrementally maintained. The context includes such |
| * information as the version of the SDK being analyzed against as well as the package-root used to |
| * resolve 'package:' URI's. (Both of which are known indirectly through the {@link SourceFactorysource factory}.) |
| * <p> |
| * An analysis context also represents the state of the analysis, which includes knowing which |
| * sources have been included in the analysis (either directly or indirectly) and the results of the |
| * analysis. Sources must be added and removed from the context using the method{@link #applyChanges(ChangeSet)}, which is also used to notify the context when sources have been |
| * modified and, consequently, previously known results might have been invalidated. |
| * <p> |
| * There are two ways to access the results of the analysis. The most common is to use one of the |
| * 'get' methods to access the results. The 'get' methods have the advantage that they will always |
| * return quickly, but have the disadvantage that if the results are not currently available they |
| * will return either nothing or in some cases an incomplete result. The second way to access |
| * results is by using one of the 'compute' methods. The 'compute' methods will always attempt to |
| * compute the requested results but might block the caller for a significant period of time. |
| * <p> |
| * When results have been invalidated, have never been computed (as is the case for newly added |
| * sources), or have been removed from the cache, they are <b>not</b> automatically recreated. They |
| * will only be recreated if one of the 'compute' methods is invoked. |
| * <p> |
| * However, this is not always acceptable. Some clients need to keep the analysis results |
| * up-to-date. For such clients there is a mechanism that allows them to incrementally perform |
| * needed analysis and get notified of the consequent changes to the analysis results. This |
| * mechanism is realized by the method {@link #performAnalysisTask()}. |
| * <p> |
| * Analysis engine allows for having more than one context. This can be used, for example, to |
| * perform one analysis based on the state of files on disk and a separate analysis based on the |
| * state of those files in open editors. It can also be used to perform an analysis based on a |
| * proposed future state, such as the state after a refactoring. |
| */ |
| abstract class AnalysisContext { |
| /** |
| * Apply the changes specified by the given change set to this context. Any analysis results that |
| * have been invalidated by these changes will be removed. |
| * @param changeSet a description of the changes that are to be applied |
| */ |
| void applyChanges(ChangeSet changeSet); |
| /** |
| * Return an array containing all of the errors associated with the given source. If the errors |
| * are not already known then the source will be analyzed in order to determine the errors |
| * associated with it. |
| * @param source the source whose errors are to be returned |
| * @return all of the errors associated with the given source |
| * @throws AnalysisException if the errors could not be determined because the analysis could not |
| * be performed |
| * @see #getErrors(Source) |
| */ |
| List<AnalysisError> computeErrors(Source source); |
| /** |
| * Return the element model corresponding to the HTML file defined by the given source. If the |
| * element model does not yet exist it will be created. The process of creating an element model |
| * for an HTML file can long-running, depending on the size of the file and the number of |
| * libraries that are defined in it (via script tags) that also need to have a model built for |
| * them. |
| * @param source the source defining the HTML file whose element model is to be returned |
| * @return the element model corresponding to the HTML file defined by the given source |
| * @throws AnalysisException if the element model could not be determined because the analysis |
| * could not be performed |
| * @see #getHtmlElement(Source) |
| */ |
| HtmlElement computeHtmlElement(Source source); |
| /** |
| * Return the kind of the given source, computing it's kind if it is not already known. Return{@link SourceKind#UNKNOWN} if the source is not contained in this context. |
| * @param source the source whose kind is to be returned |
| * @return the kind of the given source |
| * @see #getKindOf(Source) |
| */ |
| SourceKind computeKindOf(Source source); |
| /** |
| * Return the element model corresponding to the library defined by the given source. If the |
| * element model does not yet exist it will be created. The process of creating an element model |
| * for a library can long-running, depending on the size of the library and the number of |
| * libraries that are imported into it that also need to have a model built for them. |
| * @param source the source defining the library whose element model is to be returned |
| * @return the element model corresponding to the library defined by the given source |
| * @throws AnalysisException if the element model could not be determined because the analysis |
| * could not be performed |
| * @see #getLibraryElement(Source) |
| */ |
| LibraryElement computeLibraryElement(Source source); |
| /** |
| * Return the line information for the given source, or {@code null} if the source is not of a |
| * recognized kind (neither a Dart nor HTML file). If the line information was not previously |
| * known it will be created. The line information is used to map offsets from the beginning of the |
| * source to line and column pairs. |
| * @param source the source whose line information is to be returned |
| * @return the line information for the given source |
| * @throws AnalysisException if the line information could not be determined because the analysis |
| * could not be performed |
| * @see #getLineInfo(Source) |
| */ |
| LineInfo computeLineInfo(Source source); |
| /** |
| * Create a new context in which analysis can be performed. Any sources in the specified container |
| * will be removed from this context and added to the newly created context. |
| * @param container the container containing sources that should be removed from this context and |
| * added to the returned context |
| * @return the analysis context that was created |
| */ |
| AnalysisContext extractContext(SourceContainer container); |
| /** |
| * Return the element referenced by the given location, or {@code null} if the element is not |
| * immediately available or if there is no element with the given location. The latter condition |
| * can occur, for example, if the location describes an element from a different context or if the |
| * element has been removed from this context as a result of some change since it was originally |
| * obtained. |
| * @param location the reference describing the element to be returned |
| * @return the element referenced by the given location |
| */ |
| Element getElement(ElementLocation location); |
| /** |
| * Return an analysis error info containing the array of all of the errors and the line info |
| * associated with the given source. The array of errors will be empty if the source is not known |
| * to this context or if there are no errors in the source. The errors contained in the array can |
| * be incomplete. |
| * @param source the source whose errors are to be returned |
| * @return all of the errors associated with the given source and the line info |
| * @see #computeErrors(Source) |
| */ |
| AnalysisErrorInfo getErrors(Source source); |
| /** |
| * Return the element model corresponding to the HTML file defined by the given source, or{@code null} if the source does not represent an HTML file, the element representing the file |
| * has not yet been created, or the analysis of the HTML file failed for some reason. |
| * @param source the source defining the HTML file whose element model is to be returned |
| * @return the element model corresponding to the HTML file defined by the given source |
| * @see #computeHtmlElement(Source) |
| */ |
| HtmlElement getHtmlElement(Source source); |
| /** |
| * Return the sources for the HTML files that reference the given compilation unit. If the source |
| * does not represent a Dart source or is not known to this context, the returned array will be |
| * empty. The contents of the array can be incomplete. |
| * @param source the source referenced by the returned HTML files |
| * @return the sources for the HTML files that reference the given compilation unit |
| */ |
| List<Source> getHtmlFilesReferencing(Source source); |
| /** |
| * Return an array containing all of the sources known to this context that represent HTML files. |
| * The contents of the array can be incomplete. |
| * @return the sources known to this context that represent HTML files |
| */ |
| List<Source> get htmlSources; |
| /** |
| * Return the kind of the given source, or {@code null} if the kind is not known to this context. |
| * @param source the source whose kind is to be returned |
| * @return the kind of the given source |
| * @see #computeKindOf(Source) |
| */ |
| SourceKind getKindOf(Source source); |
| /** |
| * Return an array containing all of the sources known to this context that represent the defining |
| * compilation unit of a library that can be run within a browser. The sources that are returned |
| * represent libraries that have a 'main' method and are either referenced by an HTML file or |
| * import, directly or indirectly, a client-only library. The contents of the array can be |
| * incomplete. |
| * @return the sources known to this context that represent the defining compilation unit of a |
| * library that can be run within a browser |
| */ |
| List<Source> get launchableClientLibrarySources; |
| /** |
| * Return an array containing all of the sources known to this context that represent the defining |
| * compilation unit of a library that can be run outside of a browser. The contents of the array |
| * can be incomplete. |
| * @return the sources known to this context that represent the defining compilation unit of a |
| * library that can be run outside of a browser |
| */ |
| List<Source> get launchableServerLibrarySources; |
| /** |
| * Return the sources for the defining compilation units of any libraries of which the given |
| * source is a part. The array will normally contain a single library because most Dart sources |
| * are only included in a single library, but it is possible to have a part that is contained in |
| * multiple identically named libraries. If the source represents the defining compilation unit of |
| * a library, then the returned array will contain the given source as its only element. If the |
| * source does not represent a Dart source or is not known to this context, the returned array |
| * will be empty. The contents of the array can be incomplete. |
| * @param source the source contained in the returned libraries |
| * @return the sources for the libraries containing the given source |
| */ |
| List<Source> getLibrariesContaining(Source source); |
| /** |
| * Return the element model corresponding to the library defined by the given source, or{@code null} if the element model does not currently exist or if the library cannot be analyzed |
| * for some reason. |
| * @param source the source defining the library whose element model is to be returned |
| * @return the element model corresponding to the library defined by the given source |
| */ |
| LibraryElement getLibraryElement(Source source); |
| /** |
| * Return an array containing all of the sources known to this context that represent the defining |
| * compilation unit of a library. The contents of the array can be incomplete. |
| * @return the sources known to this context that represent the defining compilation unit of a |
| * library |
| */ |
| List<Source> get librarySources; |
| /** |
| * Return the line information for the given source, or {@code null} if the line information is |
| * not known. The line information is used to map offsets from the beginning of the source to line |
| * and column pairs. |
| * @param source the source whose line information is to be returned |
| * @return the line information for the given source |
| * @see #computeLineInfo(Source) |
| */ |
| LineInfo getLineInfo(Source source); |
| /** |
| * Return a fully resolved AST for a single compilation unit within the given library, or{@code null} if the resolved AST is not already computed. |
| * @param unitSource the source of the compilation unit |
| * @param library the library containing the compilation unit |
| * @return a fully resolved AST for the compilation unit |
| * @see #resolveCompilationUnit(Source,LibraryElement) |
| */ |
| CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library); |
| /** |
| * Return a fully resolved AST for a single compilation unit within the given library, or{@code null} if the resolved AST is not already computed. |
| * @param unitSource the source of the compilation unit |
| * @param librarySource the source of the defining compilation unit of the library containing the |
| * compilation unit |
| * @return a fully resolved AST for the compilation unit |
| * @see #resolveCompilationUnit(Source,Source) |
| */ |
| CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source librarySource); |
| /** |
| * Return the source factory used to create the sources that can be analyzed in this context. |
| * @return the source factory used to create the sources that can be analyzed in this context |
| */ |
| SourceFactory get sourceFactory; |
| /** |
| * Return {@code true} if the given source is known to be the defining compilation unit of a |
| * library that can be run on a client (references 'dart:html', either directly or indirectly). |
| * <p> |
| * <b>Note:</b> In addition to the expected case of returning {@code false} if the source is known |
| * to be a library that cannot be run on a client, this method will also return {@code false} if |
| * the source is not known to be a library or if we do not know whether it can be run on a client. |
| * @param librarySource the source being tested |
| * @return {@code true} if the given source is known to be a library that can be run on a client |
| */ |
| bool isClientLibrary(Source librarySource); |
| /** |
| * Return {@code true} if the given source is known to be the defining compilation unit of a |
| * library that can be run on the server (does not reference 'dart:html', either directly or |
| * indirectly). |
| * <p> |
| * <b>Note:</b> In addition to the expected case of returning {@code false} if the source is known |
| * to be a library that cannot be run on the server, this method will also return {@code false} if |
| * the source is not known to be a library or if we do not know whether it can be run on the |
| * server. |
| * @param librarySource the source being tested |
| * @return {@code true} if the given source is known to be a library that can be run on the server |
| */ |
| bool isServerLibrary(Source librarySource); |
| /** |
| * Add the sources contained in the specified context to this context's collection of sources. |
| * This method is called when an existing context's pubspec has been removed, and the contained |
| * sources should be reanalyzed as part of this context. |
| * @param context the context being merged |
| */ |
| void mergeContext(AnalysisContext context); |
| /** |
| * Parse a single source to produce an AST structure. The resulting AST structure may or may not |
| * be resolved, and may have a slightly different structure depending upon whether it is resolved. |
| * @param source the source to be parsed |
| * @return the AST structure representing the content of the source |
| * @throws AnalysisException if the analysis could not be performed |
| */ |
| CompilationUnit parseCompilationUnit(Source source); |
| /** |
| * Parse a single HTML source to produce an AST structure. The resulting HTML AST structure may or |
| * may not be resolved, and may have a slightly different structure depending upon whether it is |
| * resolved. |
| * @param source the HTML source to be parsed |
| * @return the parse result (not {@code null}) |
| * @throws AnalysisException if the analysis could not be performed |
| */ |
| HtmlUnit parseHtmlUnit(Source source); |
| /** |
| * Perform the next unit of work required to keep the analysis results up-to-date and return |
| * information about the consequent changes to the analysis results. If there were no results the |
| * returned array will be empty. If there are no more units of work required, then this method |
| * returns {@code null}. This method can be long running. |
| * @return an array containing notices of changes to the analysis results |
| */ |
| List<ChangeNotice> performAnalysisTask(); |
| /** |
| * Parse and resolve a single source within the given context to produce a fully resolved AST. |
| * @param unitSource the source to be parsed and resolved |
| * @param library the library containing the source to be resolved |
| * @return the result of resolving the AST structure representing the content of the source in the |
| * context of the given library |
| * @throws AnalysisException if the analysis could not be performed |
| * @see #getResolvedCompilationUnit(Source,LibraryElement) |
| */ |
| CompilationUnit resolveCompilationUnit(Source unitSource, LibraryElement library); |
| /** |
| * Parse and resolve a single source within the given context to produce a fully resolved AST. |
| * @param unitSource the source to be parsed and resolved |
| * @param librarySource the source of the defining compilation unit of the library containing the |
| * source to be resolved |
| * @return the result of resolving the AST structure representing the content of the source in the |
| * context of the given library |
| * @throws AnalysisException if the analysis could not be performed |
| * @see #getResolvedCompilationUnit(Source,Source) |
| */ |
| CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource); |
| /** |
| * Parse and resolve a single source within the given context to produce a fully resolved AST. |
| * @param htmlSource the source to be parsed and resolved |
| * @return the result of resolving the AST structure representing the content of the source |
| * @throws AnalysisException if the analysis could not be performed |
| */ |
| HtmlUnit resolveHtmlUnit(Source htmlSource); |
| /** |
| * Set the contents of the given source to the given contents and mark the source as having |
| * changed. This has the effect of overriding the default contents of the source. If the contents |
| * are {@code null} the override is removed so that the default contents will be returned. |
| * @param source the source whose contents are being overridden |
| * @param contents the new contents of the source |
| */ |
| void setContents(Source source, String contents); |
| /** |
| * Set the source factory used to create the sources that can be analyzed in this context to the |
| * given source factory. Clients can safely assume that all analysis results have been |
| * invalidated. |
| * @param factory the source factory used to create the sources that can be analyzed in this |
| * context |
| */ |
| void set sourceFactory(SourceFactory factory); |
| /** |
| * Given a collection of sources with content that has changed, return an {@link Iterable}identifying the sources that need to be resolved. |
| * @param changedSources an array of sources (not {@code null}, contains no {@code null}s) |
| * @return An iterable returning the sources to be resolved |
| */ |
| Iterable<Source> sourcesToResolve(List<Source> changedSources); |
| } |
| /** |
| * The interface {@code AnalysisErrorInfo} contains the analysis errors and line information for the |
| * errors. |
| */ |
| abstract class AnalysisErrorInfo { |
| /** |
| * Return the errors that as a result of the analysis, or {@code null} if there were no errors. |
| * @return the errors as a result of the analysis |
| */ |
| List<AnalysisError> get errors; |
| /** |
| * Return the line information associated with the errors, or {@code null} if there were no |
| * errors. |
| * @return the line information associated with the errors |
| */ |
| LineInfo get lineInfo; |
| } |
| /** |
| * Instances of the class {@code AnalysisException} represent an exception that occurred during the |
| * analysis of one or more sources. |
| * @coverage dart.engine |
| */ |
| class AnalysisException extends JavaException { |
| /** |
| * Initialize a newly created exception. |
| */ |
| AnalysisException() : super() { |
| _jtd_constructor_125_impl(); |
| } |
| _jtd_constructor_125_impl() { |
| } |
| /** |
| * Initialize a newly created exception to have the given message. |
| * @param message the message associated with the exception |
| */ |
| AnalysisException.con1(String message) : super(message) { |
| _jtd_constructor_126_impl(message); |
| } |
| _jtd_constructor_126_impl(String message) { |
| } |
| /** |
| * Initialize a newly created exception to have the given message and cause. |
| * @param message the message associated with the exception |
| * @param cause the underlying exception that caused this exception |
| */ |
| AnalysisException.con2(String message, Exception cause) : super(message, cause) { |
| _jtd_constructor_127_impl(message, cause); |
| } |
| _jtd_constructor_127_impl(String message, Exception cause) { |
| } |
| /** |
| * Initialize a newly created exception to have the given cause. |
| * @param cause the underlying exception that caused this exception |
| */ |
| AnalysisException.con3(Exception cause) : super.withCause(cause) { |
| _jtd_constructor_128_impl(cause); |
| } |
| _jtd_constructor_128_impl(Exception cause) { |
| } |
| } |
| /** |
| * The interface {@code ChangeNotice} defines the behavior of objects that represent a change to the |
| * analysis results associated with a given source. |
| * @coverage dart.engine |
| */ |
| abstract class ChangeNotice implements AnalysisErrorInfo { |
| /** |
| * Return the fully resolved AST that changed as a result of the analysis, or {@code null} if the |
| * AST was not changed. |
| * @return the fully resolved AST that changed as a result of the analysis |
| */ |
| CompilationUnit get compilationUnit; |
| /** |
| * Return the source for which the result is being reported. |
| * @return the source for which the result is being reported |
| */ |
| Source get source; |
| } |
| /** |
| * Instances of the class {@code ChangeSet} indicate what sources have been added, changed, or |
| * removed. |
| * @coverage dart.engine |
| */ |
| class ChangeSet { |
| /** |
| * A list containing the sources that have been added. |
| */ |
| List<Source> _added2 = new List<Source>(); |
| /** |
| * A list containing the sources that have been changed. |
| */ |
| List<Source> _changed2 = new List<Source>(); |
| /** |
| * A list containing the sources that have been removed. |
| */ |
| List<Source> _removed2 = new List<Source>(); |
| /** |
| * A list containing the source containers specifying additional sources that have been removed. |
| */ |
| List<SourceContainer> _removedContainers = new List<SourceContainer>(); |
| /** |
| * Initialize a newly created change set to be empty. |
| */ |
| ChangeSet() : super() { |
| } |
| /** |
| * Record that the specified source has been added and that it's content is the default contents |
| * of the source. |
| * @param source the source that was added |
| */ |
| void added(Source source) { |
| _added2.add(source); |
| } |
| /** |
| * Record that the specified source has been changed and that it's content is the default contents |
| * of the source. |
| * @param source the source that was changed |
| */ |
| void changed(Source source) { |
| _changed2.add(source); |
| } |
| /** |
| * Return a collection of the sources that have been added. |
| * @return a collection of the sources that have been added |
| */ |
| List<Source> get added3 => _added2; |
| /** |
| * Return a collection of sources that have been changed. |
| * @return a collection of sources that have been changed |
| */ |
| List<Source> get changed3 => _changed2; |
| /** |
| * Return a list containing the sources that were removed. |
| * @return a list containing the sources that were removed |
| */ |
| List<Source> get removed => _removed2; |
| /** |
| * Return a list containing the source containers that were removed. |
| * @return a list containing the source containers that were removed |
| */ |
| List<SourceContainer> get removedContainers => _removedContainers; |
| /** |
| * Return {@code true} if this change set does not contain any changes. |
| * @return {@code true} if this change set does not contain any changes |
| */ |
| bool isEmpty() => _added2.isEmpty && _changed2.isEmpty && _removed2.isEmpty && _removedContainers.isEmpty; |
| /** |
| * Record that the specified source has been removed. |
| * @param source the source that was removed |
| */ |
| void removed3(Source source) { |
| if (source != null) { |
| _removed2.add(source); |
| } |
| } |
| /** |
| * Record that the specified source container has been removed. |
| * @param container the source container that was removed |
| */ |
| void removedContainer(SourceContainer container) { |
| if (container != null) { |
| _removedContainers.add(container); |
| } |
| } |
| } |
| /** |
| * Instances of the class {@code AnalysisContextImpl} implement an {@link AnalysisContext analysis |
| * context}. |
| * @coverage dart.engine |
| */ |
| class AnalysisContextImpl implements InternalAnalysisContext { |
| /** |
| * The source factory used to create the sources that can be analyzed in this context. |
| */ |
| SourceFactory _sourceFactory; |
| /** |
| * A table mapping the sources known to the context to the information known about the source. |
| */ |
| Map<Source, SourceInfo> _sourceMap = new Map<Source, SourceInfo>(); |
| /** |
| * A table mapping sources to the change notices that are waiting to be returned related to that |
| * source. |
| */ |
| Map<Source, ChangeNoticeImpl> _pendingNotices = new Map<Source, ChangeNoticeImpl>(); |
| /** |
| * A list containing the most recently accessed sources with the most recently used at the end of |
| * the list. When more sources are added than the maximum allowed then the least recently used |
| * source will be removed and will have it's cached AST structure flushed. |
| */ |
| List<Source> _recentlyUsed = new List<Source>(); |
| /** |
| * The object used to synchronize access to all of the caches. |
| */ |
| Object _cacheLock = new Object(); |
| /** |
| * The maximum number of sources for which data should be kept in the cache. |
| */ |
| static int _MAX_CACHE_SIZE = 64; |
| /** |
| * The name of the 'src' attribute in a HTML tag. |
| */ |
| static String _ATTRIBUTE_SRC = "src"; |
| /** |
| * The name of the 'script' tag in an HTML file. |
| */ |
| static String _TAG_SCRIPT = "script"; |
| /** |
| * The number of times that the flushing of information from the cache has been disabled without |
| * being re-enabled. |
| */ |
| int _cacheRemovalCount = 0; |
| /** |
| * Initialize a newly created analysis context. |
| */ |
| AnalysisContextImpl() : super() { |
| } |
| void addSourceInfo(Source source, SourceInfo info) { |
| _sourceMap[source] = info; |
| } |
| void applyChanges(ChangeSet changeSet) { |
| if (changeSet.isEmpty()) { |
| return; |
| } |
| { |
| List<Source> removedSources = new List<Source>.from(changeSet.removed); |
| for (SourceContainer container in changeSet.removedContainers) { |
| addSourcesInContainer(removedSources, container); |
| } |
| for (Source source in changeSet.added3) { |
| sourceAvailable(source); |
| } |
| for (Source source in changeSet.changed3) { |
| sourceChanged(source); |
| } |
| for (Source source in removedSources) { |
| sourceRemoved(source); |
| } |
| } |
| } |
| List<AnalysisError> computeErrors(Source source) { |
| { |
| CompilationUnitInfo info = getCompilationUnitInfo(source); |
| if (info == null) { |
| return AnalysisError.NO_ERRORS; |
| } |
| if (info.hasInvalidParseErrors()) { |
| parseCompilationUnit(source); |
| } |
| if (info.hasInvalidResolutionErrors()) { |
| } |
| return info.allErrors; |
| } |
| } |
| HtmlElement computeHtmlElement(Source source) { |
| if (!AnalysisEngine.isHtmlFileName(source.shortName)) { |
| return null; |
| } |
| { |
| HtmlUnitInfo htmlUnitInfo = getHtmlUnitInfo(source); |
| if (htmlUnitInfo == null) { |
| return null; |
| } |
| HtmlElement element2 = htmlUnitInfo.element; |
| if (element2 == null) { |
| HtmlUnit unit = htmlUnitInfo.resolvedUnit; |
| if (unit == null) { |
| unit = htmlUnitInfo.parsedUnit; |
| if (unit == null) { |
| unit = parseHtmlUnit(source); |
| } |
| } |
| HtmlUnitBuilder builder = new HtmlUnitBuilder(this); |
| element2 = builder.buildHtmlElement2(source, unit); |
| htmlUnitInfo.resolvedUnit = unit; |
| htmlUnitInfo.element = element2; |
| } |
| return element2; |
| } |
| } |
| SourceKind computeKindOf(Source source) { |
| { |
| SourceInfo sourceInfo = getSourceInfo(source); |
| if (sourceInfo == null) { |
| return SourceKind.UNKNOWN; |
| } else if (identical(sourceInfo, DartInfo.pendingInstance)) { |
| sourceInfo = internalComputeKindOf(source); |
| } |
| return sourceInfo.kind; |
| } |
| } |
| LibraryElement computeLibraryElement(Source source) { |
| if (!AnalysisEngine.isDartFileName(source.shortName)) { |
| return null; |
| } |
| { |
| LibraryInfo libraryInfo = getLibraryInfo(source); |
| if (libraryInfo == null) { |
| return null; |
| } |
| LibraryElement element2 = libraryInfo.element; |
| if (element2 == null) { |
| if (computeKindOf(source) != SourceKind.LIBRARY) { |
| return null; |
| } |
| LibraryResolver resolver = new LibraryResolver.con1(this); |
| try { |
| element2 = resolver.resolveLibrary(source, true); |
| if (element2 != null) { |
| libraryInfo.element = element2; |
| } |
| } on AnalysisException catch (exception) { |
| AnalysisEngine.instance.logger.logError2("Could not resolve the library ${source.fullName}", exception); |
| } |
| } |
| return element2; |
| } |
| } |
| LineInfo computeLineInfo(Source source) { |
| { |
| SourceInfo sourceInfo = getSourceInfo(source); |
| if (sourceInfo == null) { |
| return null; |
| } |
| LineInfo lineInfo2 = sourceInfo.lineInfo; |
| if (lineInfo2 == null) { |
| if (identical(sourceInfo, DartInfo.pendingInstance)) { |
| sourceInfo = internalComputeKindOf(source); |
| } |
| if (sourceInfo is HtmlUnitInfo) { |
| parseHtmlUnit(source); |
| lineInfo2 = sourceInfo.lineInfo; |
| } else if (sourceInfo is CompilationUnitInfo) { |
| parseCompilationUnit(source); |
| lineInfo2 = sourceInfo.lineInfo; |
| } |
| } |
| return lineInfo2; |
| } |
| } |
| CompilationUnit computeResolvableCompilationUnit(Source source) { |
| { |
| CompilationUnitInfo compilationUnitInfo = getCompilationUnitInfo(source); |
| if (compilationUnitInfo == null) { |
| return null; |
| } |
| CompilationUnit unit = compilationUnitInfo.parsedCompilationUnit; |
| if (unit == null) { |
| unit = compilationUnitInfo.resolvedCompilationUnit; |
| } |
| if (unit != null) { |
| return unit.accept(new ASTCloner()) as CompilationUnit; |
| } |
| unit = internalParseCompilationUnit(compilationUnitInfo, source); |
| compilationUnitInfo.clearParsedUnit(); |
| return unit; |
| } |
| } |
| AnalysisContext extractContext(SourceContainer container) => extractContextInto(container, (AnalysisEngine.instance.createAnalysisContext() as AnalysisContextImpl)); |
| InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext) { |
| List<Source> sourcesToRemove = new List<Source>(); |
| { |
| for (MapEntry<Source, SourceInfo> entry in getMapEntrySet(_sourceMap)) { |
| Source source = entry.getKey(); |
| if (container.contains(source)) { |
| sourcesToRemove.add(source); |
| newContext.addSourceInfo(source, entry.getValue().copy()); |
| } |
| } |
| } |
| return newContext; |
| } |
| Element getElement(ElementLocation location) { |
| List<String> components2 = ((location as ElementLocationImpl)).components; |
| ElementImpl element; |
| { |
| Source librarySource = _sourceFactory.fromEncoding(components2[0]); |
| try { |
| element = computeLibraryElement(librarySource) as ElementImpl; |
| } on AnalysisException catch (exception) { |
| return null; |
| } |
| } |
| for (int i = 1; i < components2.length; i++) { |
| if (element == null) { |
| return null; |
| } |
| element = element.getChild(components2[i]); |
| } |
| return element; |
| } |
| AnalysisErrorInfo getErrors(Source source) { |
| { |
| SourceInfo info = getSourceInfo(source); |
| if (info is CompilationUnitInfo) { |
| CompilationUnitInfo compilationUnitInfo = info as CompilationUnitInfo; |
| return new AnalysisErrorInfoImpl(compilationUnitInfo.allErrors, compilationUnitInfo.lineInfo); |
| } |
| return new AnalysisErrorInfoImpl(AnalysisError.NO_ERRORS, info.lineInfo); |
| } |
| } |
| HtmlElement getHtmlElement(Source source) { |
| { |
| SourceInfo info = getSourceInfo(source); |
| if (info is HtmlUnitInfo) { |
| return ((info as HtmlUnitInfo)).element; |
| } |
| return null; |
| } |
| } |
| List<Source> getHtmlFilesReferencing(Source source) { |
| { |
| List<Source> htmlSources = new List<Source>(); |
| while (true) { |
| if (getKindOf(source) == SourceKind.LIBRARY) { |
| } else if (getKindOf(source) == SourceKind.PART) { |
| List<Source> librarySources = getLibrariesContaining(source); |
| for (MapEntry<Source, SourceInfo> entry in getMapEntrySet(_sourceMap)) { |
| if (identical(entry.getValue().kind, SourceKind.HTML)) { |
| if (containsAny(((entry.getValue() as HtmlUnitInfo)).librarySources, librarySources)) { |
| htmlSources.add(entry.getKey()); |
| } |
| } |
| } |
| } |
| break; |
| } |
| if (htmlSources.isEmpty) { |
| return Source.EMPTY_ARRAY; |
| } |
| return new List.from(htmlSources); |
| } |
| } |
| List<Source> get htmlSources => getSources(SourceKind.HTML); |
| SourceKind getKindOf(Source source) { |
| { |
| SourceInfo sourceInfo = getSourceInfo(source); |
| if (sourceInfo == null) { |
| return SourceKind.UNKNOWN; |
| } |
| return sourceInfo.kind; |
| } |
| } |
| List<Source> get launchableClientLibrarySources { |
| List<Source> sources = new List<Source>(); |
| { |
| for (MapEntry<Source, SourceInfo> entry in getMapEntrySet(_sourceMap)) { |
| Source source = entry.getKey(); |
| SourceInfo info = entry.getValue(); |
| if (identical(info.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary()) { |
| sources.add(source); |
| } |
| } |
| } |
| return new List.from(sources); |
| } |
| List<Source> get launchableServerLibrarySources { |
| List<Source> sources = new List<Source>(); |
| { |
| for (MapEntry<Source, SourceInfo> entry in getMapEntrySet(_sourceMap)) { |
| Source source = entry.getKey(); |
| SourceInfo info = entry.getValue(); |
| if (identical(info.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary()) { |
| sources.add(source); |
| } |
| } |
| } |
| return new List.from(sources); |
| } |
| List<Source> getLibrariesContaining(Source source) { |
| { |
| List<Source> librarySources = new List<Source>(); |
| for (MapEntry<Source, SourceInfo> entry in getMapEntrySet(_sourceMap)) { |
| if (identical(entry.getValue().kind, SourceKind.LIBRARY)) { |
| if (contains(((entry.getValue() as LibraryInfo)).unitSources, source)) { |
| librarySources.add(entry.getKey()); |
| } |
| } |
| } |
| if (librarySources.isEmpty) { |
| return Source.EMPTY_ARRAY; |
| } |
| return new List.from(librarySources); |
| } |
| } |
| LibraryElement getLibraryElement(Source source) { |
| { |
| SourceInfo info = getSourceInfo(source); |
| if (info is LibraryInfo) { |
| return ((info as LibraryInfo)).element; |
| } |
| return null; |
| } |
| } |
| List<Source> get librarySources => getSources(SourceKind.LIBRARY); |
| LineInfo getLineInfo(Source source) { |
| { |
| SourceInfo info = getSourceInfo(source); |
| if (info != null) { |
| return info.lineInfo; |
| } |
| return null; |
| } |
| } |
| Namespace getPublicNamespace(LibraryElement library) { |
| Source source2 = library.definingCompilationUnit.source; |
| { |
| LibraryInfo libraryInfo = getLibraryInfo(source2); |
| if (libraryInfo == null) { |
| return null; |
| } |
| Namespace namespace = libraryInfo.publicNamespace; |
| if (namespace == null) { |
| NamespaceBuilder builder = new NamespaceBuilder(); |
| namespace = builder.createPublicNamespace(library); |
| libraryInfo.publicNamespace = namespace; |
| } |
| return namespace; |
| } |
| } |
| Namespace getPublicNamespace2(Source source) { |
| { |
| LibraryInfo libraryInfo = getLibraryInfo(source); |
| if (libraryInfo == null) { |
| return null; |
| } |
| Namespace namespace = libraryInfo.publicNamespace; |
| if (namespace == null) { |
| LibraryElement library = computeLibraryElement(source); |
| if (library == null) { |
| return null; |
| } |
| NamespaceBuilder builder = new NamespaceBuilder(); |
| namespace = builder.createPublicNamespace(library); |
| libraryInfo.publicNamespace = namespace; |
| } |
| return namespace; |
| } |
| } |
| CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library) { |
| if (library == null) { |
| return null; |
| } |
| return getResolvedCompilationUnit2(unitSource, library.source); |
| } |
| CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source librarySource) { |
| { |
| accessed(unitSource); |
| CompilationUnitInfo compilationUnitInfo = getCompilationUnitInfo(unitSource); |
| if (compilationUnitInfo == null) { |
| return null; |
| } |
| return compilationUnitInfo.resolvedCompilationUnit; |
| } |
| } |
| SourceFactory get sourceFactory => _sourceFactory; |
| bool isClientLibrary(Source librarySource) { |
| SourceInfo sourceInfo = getSourceInfo(librarySource); |
| if (sourceInfo is LibraryInfo) { |
| LibraryInfo libraryInfo = sourceInfo as LibraryInfo; |
| if (libraryInfo.hasInvalidLaunchable() || libraryInfo.hasInvalidClientServer()) { |
| return false; |
| } |
| return libraryInfo.isLaunchable() && libraryInfo.isClient(); |
| } |
| return false; |
| } |
| bool isServerLibrary(Source librarySource) { |
| SourceInfo sourceInfo = getSourceInfo(librarySource); |
| if (sourceInfo is LibraryInfo) { |
| LibraryInfo libraryInfo = sourceInfo as LibraryInfo; |
| if (libraryInfo.hasInvalidLaunchable() || libraryInfo.hasInvalidClientServer()) { |
| return false; |
| } |
| return libraryInfo.isLaunchable() && libraryInfo.isServer(); |
| } |
| return false; |
| } |
| void mergeContext(AnalysisContext context) { |
| { |
| for (MapEntry<Source, SourceInfo> entry in getMapEntrySet(((context as AnalysisContextImpl))._sourceMap)) { |
| Source newSource = entry.getKey(); |
| SourceInfo existingInfo = getSourceInfo(newSource); |
| if (existingInfo == null) { |
| _sourceMap[newSource] = entry.getValue().copy(); |
| } else { |
| } |
| } |
| } |
| } |
| CompilationUnit parseCompilationUnit(Source source) { |
| { |
| accessed(source); |
| CompilationUnitInfo compilationUnitInfo = getCompilationUnitInfo(source); |
| if (compilationUnitInfo == null) { |
| return null; |
| } |
| CompilationUnit unit = compilationUnitInfo.resolvedCompilationUnit; |
| if (unit == null) { |
| unit = compilationUnitInfo.parsedCompilationUnit; |
| if (unit == null) { |
| unit = internalParseCompilationUnit(compilationUnitInfo, source); |
| } |
| } |
| return unit; |
| } |
| } |
| HtmlUnit parseHtmlUnit(Source source) { |
| { |
| accessed(source); |
| HtmlUnitInfo htmlUnitInfo = getHtmlUnitInfo(source); |
| if (htmlUnitInfo == null) { |
| return null; |
| } |
| HtmlUnit unit = htmlUnitInfo.resolvedUnit; |
| if (unit == null) { |
| unit = htmlUnitInfo.parsedUnit; |
| if (unit == null) { |
| HtmlParseResult result = new HtmlParser(source).parse(scanHtml(source)); |
| unit = result.htmlUnit; |
| htmlUnitInfo.lineInfo = new LineInfo(result.lineStarts); |
| htmlUnitInfo.parsedUnit = unit; |
| htmlUnitInfo.librarySources = getLibrarySources2(source, unit); |
| } |
| } |
| return unit; |
| } |
| } |
| List<ChangeNotice> performAnalysisTask() { |
| { |
| if (!performSingleAnalysisTask() && _pendingNotices.isEmpty) { |
| return null; |
| } |
| if (_pendingNotices.isEmpty) { |
| return ChangeNoticeImpl.EMPTY_ARRAY; |
| } |
| List<ChangeNotice> notices = new List.from(_pendingNotices.values); |
| _pendingNotices.clear(); |
| return notices; |
| } |
| } |
| void recordLibraryElements(Map<Source, LibraryElement> elementMap) { |
| Source htmlSource = _sourceFactory.forUri("dart:html"); |
| { |
| for (MapEntry<Source, LibraryElement> entry in getMapEntrySet(elementMap)) { |
| Source librarySource = entry.getKey(); |
| LibraryElement library = entry.getValue(); |
| LibraryInfo libraryInfo = getLibraryInfo(librarySource); |
| if (libraryInfo != null) { |
| libraryInfo.element = library; |
| libraryInfo.launchable = library.entryPoint != null; |
| libraryInfo.client = isClient(library, htmlSource, new Set<LibraryElement>()); |
| List<Source> unitSources = new List<Source>(); |
| unitSources.add(librarySource); |
| for (CompilationUnitElement part in library.parts) { |
| Source partSource = part.source; |
| unitSources.add(partSource); |
| } |
| libraryInfo.unitSources = new List.from(unitSources); |
| } |
| } |
| } |
| } |
| void recordResolutionErrors(Source source, List<AnalysisError> errors, LineInfo lineInfo2) { |
| { |
| CompilationUnitInfo compilationUnitInfo = getCompilationUnitInfo(source); |
| if (compilationUnitInfo != null) { |
| compilationUnitInfo.lineInfo = lineInfo2; |
| compilationUnitInfo.resolutionErrors = errors; |
| } |
| getNotice(source).setErrors(compilationUnitInfo.allErrors, lineInfo2); |
| } |
| } |
| void recordResolvedCompilationUnit(Source source, CompilationUnit unit) { |
| { |
| CompilationUnitInfo compilationUnitInfo = getCompilationUnitInfo(source); |
| if (compilationUnitInfo != null) { |
| compilationUnitInfo.resolvedCompilationUnit = unit; |
| compilationUnitInfo.clearParsedUnit(); |
| getNotice(source).compilationUnit = unit; |
| } |
| } |
| } |
| CompilationUnit resolveCompilationUnit(Source source2, LibraryElement library) { |
| if (library == null) { |
| return null; |
| } |
| return resolveCompilationUnit2(source2, library.source); |
| } |
| CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) { |
| { |
| accessed(unitSource); |
| CompilationUnitInfo compilationUnitInfo = getCompilationUnitInfo(unitSource); |
| if (compilationUnitInfo == null) { |
| return null; |
| } |
| CompilationUnit unit = compilationUnitInfo.resolvedCompilationUnit; |
| if (unit == null) { |
| disableCacheRemoval(); |
| try { |
| LibraryElement libraryElement = computeLibraryElement(librarySource); |
| unit = compilationUnitInfo.resolvedCompilationUnit; |
| if (unit == null && libraryElement != null) { |
| Source coreLibrarySource = libraryElement.context.sourceFactory.forUri(DartSdk.DART_CORE); |
| LibraryElement coreElement = computeLibraryElement(coreLibrarySource); |
| TypeProvider typeProvider = new TypeProviderImpl(coreElement); |
| CompilationUnit unitAST = computeResolvableCompilationUnit(unitSource); |
| new DeclarationResolver().resolve(unitAST, find(libraryElement, unitSource)); |
| RecordingErrorListener errorListener = new RecordingErrorListener(); |
| TypeResolverVisitor typeResolverVisitor = new TypeResolverVisitor.con2(libraryElement, unitSource, typeProvider, errorListener); |
| unitAST.accept(typeResolverVisitor); |
| ResolverVisitor resolverVisitor = new ResolverVisitor.con2(libraryElement, unitSource, typeProvider, errorListener); |
| unitAST.accept(resolverVisitor); |
| ErrorReporter errorReporter = new ErrorReporter(errorListener, unitSource); |
| ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, libraryElement, typeProvider); |
| unitAST.accept(errorVerifier); |
| ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter); |
| unitAST.accept(constantVerifier); |
| unitAST.resolutionErrors = errorListener.errors; |
| compilationUnitInfo.resolvedCompilationUnit = unitAST; |
| unit = unitAST; |
| } |
| } finally { |
| enableCacheRemoval(); |
| } |
| } |
| return unit; |
| } |
| } |
| HtmlUnit resolveHtmlUnit(Source unitSource) { |
| { |
| accessed(unitSource); |
| HtmlUnitInfo htmlUnitInfo = getHtmlUnitInfo(unitSource); |
| if (htmlUnitInfo == null) { |
| return null; |
| } |
| HtmlUnit unit = htmlUnitInfo.resolvedUnit; |
| if (unit == null) { |
| disableCacheRemoval(); |
| try { |
| computeHtmlElement(unitSource); |
| unit = htmlUnitInfo.resolvedUnit; |
| if (unit == null) { |
| unit = parseHtmlUnit(unitSource); |
| } |
| } finally { |
| enableCacheRemoval(); |
| } |
| } |
| return unit; |
| } |
| } |
| void setContents(Source source, String contents) { |
| { |
| _sourceFactory.setContents(source, contents); |
| sourceChanged(source); |
| } |
| } |
| void set sourceFactory(SourceFactory factory) { |
| if (identical(_sourceFactory, factory)) { |
| return; |
| } else if (factory.context != null) { |
| throw new IllegalStateException("Source factories cannot be shared between contexts"); |
| } |
| { |
| if (_sourceFactory != null) { |
| _sourceFactory.context = null; |
| } |
| factory.context = this; |
| _sourceFactory = factory; |
| for (SourceInfo sourceInfo in _sourceMap.values) { |
| if (sourceInfo is HtmlUnitInfo) { |
| ((sourceInfo as HtmlUnitInfo)).invalidateResolvedUnit(); |
| } else if (sourceInfo is CompilationUnitInfo) { |
| CompilationUnitInfo compilationUnitInfo = sourceInfo as CompilationUnitInfo; |
| compilationUnitInfo.invalidateResolvedUnit(); |
| compilationUnitInfo.invalidateResolutionErrors(); |
| if (sourceInfo is LibraryInfo) { |
| LibraryInfo libraryInfo = sourceInfo as LibraryInfo; |
| libraryInfo.invalidateElement(); |
| libraryInfo.invalidatePublicNamespace(); |
| libraryInfo.invalidateLaunchable(); |
| libraryInfo.invalidateClientServer(); |
| } |
| } |
| } |
| } |
| } |
| Iterable<Source> sourcesToResolve(List<Source> changedSources) { |
| List<Source> librarySources = new List<Source>(); |
| for (Source source in changedSources) { |
| if (identical(computeKindOf(source), SourceKind.LIBRARY)) { |
| librarySources.add(source); |
| } |
| } |
| return librarySources; |
| } |
| /** |
| * Record that the given source was just accessed for some unspecified purpose. |
| * <p> |
| * Note: This method must only be invoked while we are synchronized on {@link #cacheLock}. |
| * @param source the source that was accessed |
| */ |
| void accessed(Source source) { |
| if (_recentlyUsed.contains(source)) { |
| _recentlyUsed.remove(source); |
| _recentlyUsed.add(source); |
| return; |
| } |
| if (_cacheRemovalCount == 0 && _recentlyUsed.length >= _MAX_CACHE_SIZE) { |
| Source removedSource = _recentlyUsed.removeAt(0); |
| SourceInfo sourceInfo = _sourceMap[removedSource]; |
| if (sourceInfo is HtmlUnitInfo) { |
| ((sourceInfo as HtmlUnitInfo)).clearParsedUnit(); |
| ((sourceInfo as HtmlUnitInfo)).clearResolvedUnit(); |
| } else if (sourceInfo is CompilationUnitInfo) { |
| ((sourceInfo as CompilationUnitInfo)).clearParsedUnit(); |
| ((sourceInfo as CompilationUnitInfo)).clearResolvedUnit(); |
| } |
| } |
| _recentlyUsed.add(source); |
| } |
| /** |
| * Add all of the sources contained in the given source container to the given list of sources. |
| * <p> |
| * Note: This method must only be invoked while we are synchronized on {@link #cacheLock}. |
| * @param sources the list to which sources are to be added |
| * @param container the source container containing the sources to be added to the list |
| */ |
| void addSourcesInContainer(List<Source> sources, SourceContainer container) { |
| for (Source source in _sourceMap.keys.toSet()) { |
| if (container.contains(source)) { |
| sources.add(source); |
| } |
| } |
| } |
| /** |
| * Return {@code true} if the given array of sources contains the given source. |
| * @param sources the sources being searched |
| * @param targetSource the source being searched for |
| * @return {@code true} if the given source is in the array |
| */ |
| bool contains(List<Source> sources, Source targetSource) { |
| for (Source source in sources) { |
| if (source == targetSource) { |
| return true; |
| } |
| } |
| return false; |
| } |
| /** |
| * Return {@code true} if the given array of sources contains any of the given target sources. |
| * @param sources the sources being searched |
| * @param targetSources the sources being searched for |
| * @return {@code true} if any of the given target sources are in the array |
| */ |
| bool containsAny(List<Source> sources, List<Source> targetSources) { |
| for (Source targetSource in targetSources) { |
| if (contains(sources, targetSource)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| /** |
| * Create a source information object suitable for the given source. Return the source information |
| * object that was created, or {@code null} if the source should not be tracked by this context. |
| * @param source the source for which an information object is being created |
| * @return the source information object that was created |
| */ |
| SourceInfo createSourceInfo(Source source) { |
| String name = source.shortName; |
| if (AnalysisEngine.isHtmlFileName(name)) { |
| HtmlUnitInfo info = new HtmlUnitInfo(); |
| _sourceMap[source] = info; |
| return info; |
| } else if (AnalysisEngine.isDartFileName(name)) { |
| DartInfo info = DartInfo.pendingInstance; |
| _sourceMap[source] = info; |
| return info; |
| } |
| return null; |
| } |
| /** |
| * Disable flushing information from the cache until {@link #enableCacheRemoval()} has been |
| * called. |
| */ |
| void disableCacheRemoval() { |
| _cacheRemovalCount++; |
| } |
| /** |
| * Re-enable flushing information from the cache. |
| */ |
| void enableCacheRemoval() { |
| if (_cacheRemovalCount > 0) { |
| _cacheRemovalCount--; |
| } |
| if (_cacheRemovalCount == 0) { |
| while (_recentlyUsed.length >= _MAX_CACHE_SIZE) { |
| Source removedSource = _recentlyUsed.removeAt(0); |
| SourceInfo sourceInfo = _sourceMap[removedSource]; |
| if (sourceInfo is HtmlUnitInfo) { |
| ((sourceInfo as HtmlUnitInfo)).clearParsedUnit(); |
| ((sourceInfo as HtmlUnitInfo)).clearResolvedUnit(); |
| } else if (sourceInfo is CompilationUnitInfo) { |
| ((sourceInfo as CompilationUnitInfo)).clearParsedUnit(); |
| ((sourceInfo as CompilationUnitInfo)).clearResolvedUnit(); |
| } |
| } |
| } |
| } |
| /** |
| * Search the compilation units that are part of the given library and return the element |
| * representing the compilation unit with the given source. Return {@code null} if there is no |
| * such compilation unit. |
| * @param libraryElement the element representing the library being searched through |
| * @param unitSource the source for the compilation unit whose element is to be returned |
| * @return the element representing the compilation unit |
| */ |
| CompilationUnitElement find(LibraryElement libraryElement, Source unitSource) { |
| CompilationUnitElement element = libraryElement.definingCompilationUnit; |
| if (element.source == unitSource) { |
| return element; |
| } |
| for (CompilationUnitElement partElement in libraryElement.parts) { |
| if (partElement.source == unitSource) { |
| return partElement; |
| } |
| } |
| return null; |
| } |
| /** |
| * Return the compilation unit information associated with the given source, or {@code null} if |
| * the source is not known to this context. This method should be used to access the compilation |
| * unit information rather than accessing the compilation unit map directly because sources in the |
| * SDK are implicitly part of every analysis context and are therefore only added to the map when |
| * first accessed. |
| * <p> |
| * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}. |
| * @param source the source for which information is being sought |
| * @return the compilation unit information associated with the given source |
| */ |
| CompilationUnitInfo getCompilationUnitInfo(Source source) { |
| SourceInfo sourceInfo = getSourceInfo(source); |
| if (sourceInfo == null) { |
| sourceInfo = new CompilationUnitInfo(); |
| _sourceMap[source] = sourceInfo; |
| return sourceInfo as CompilationUnitInfo; |
| } else if (sourceInfo is CompilationUnitInfo) { |
| return sourceInfo as CompilationUnitInfo; |
| } else if (identical(sourceInfo, DartInfo.pendingInstance)) { |
| sourceInfo = internalComputeKindOf(source); |
| if (sourceInfo is CompilationUnitInfo) { |
| return sourceInfo as CompilationUnitInfo; |
| } |
| } |
| return null; |
| } |
| /** |
| * Return the HTML unit information associated with the given source, or {@code null} if the |
| * source is not known to this context. This method should be used to access the HTML unit |
| * information rather than accessing the HTML unit map directly because sources in the SDK are |
| * implicitly part of every analysis context and are therefore only added to the map when first |
| * accessed. |
| * <p> |
| * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}. |
| * @param source the source for which information is being sought |
| * @return the HTML unit information associated with the given source |
| */ |
| HtmlUnitInfo getHtmlUnitInfo(Source source) { |
| SourceInfo sourceInfo = getSourceInfo(source); |
| if (sourceInfo == null) { |
| sourceInfo = new HtmlUnitInfo(); |
| _sourceMap[source] = sourceInfo; |
| return sourceInfo as HtmlUnitInfo; |
| } else if (sourceInfo is HtmlUnitInfo) { |
| return sourceInfo as HtmlUnitInfo; |
| } |
| return null; |
| } |
| /** |
| * Return the library information associated with the given source, or {@code null} if the source |
| * is not known to this context. This method should be used to access the library information |
| * rather than accessing the library map directly because sources in the SDK are implicitly part |
| * of every analysis context and are therefore only added to the map when first accessed. |
| * <p> |
| * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}. |
| * @param source the source for which information is being sought |
| * @return the library information associated with the given source |
| */ |
| LibraryInfo getLibraryInfo(Source source) { |
| SourceInfo sourceInfo = getSourceInfo(source); |
| if (sourceInfo == null) { |
| sourceInfo = new LibraryInfo(); |
| _sourceMap[source] = sourceInfo; |
| return sourceInfo as LibraryInfo; |
| } else if (sourceInfo is LibraryInfo) { |
| return sourceInfo as LibraryInfo; |
| } else if (identical(sourceInfo, DartInfo.pendingInstance)) { |
| sourceInfo = internalComputeKindOf(source); |
| if (sourceInfo is LibraryInfo) { |
| return sourceInfo as LibraryInfo; |
| } |
| } |
| return null; |
| } |
| /** |
| * Return the sources of libraries that are referenced in the specified HTML file. |
| * @param htmlSource the source of the HTML file being analyzed |
| * @param htmlUnit the AST for the HTML file being analyzed |
| * @return the sources of libraries that are referenced in the HTML file |
| */ |
| List<Source> getLibrarySources2(Source htmlSource, HtmlUnit htmlUnit) { |
| List<Source> libraries = new List<Source>(); |
| htmlUnit.accept(new RecursiveXmlVisitor_6(this, htmlSource, libraries)); |
| if (libraries.isEmpty) { |
| return Source.EMPTY_ARRAY; |
| } |
| return new List.from(libraries); |
| } |
| /** |
| * Return a change notice for the given source, creating one if one does not already exist. |
| * @param source the source for which changes are being reported |
| * @return a change notice for the given source |
| */ |
| ChangeNoticeImpl getNotice(Source source) { |
| ChangeNoticeImpl notice = _pendingNotices[source]; |
| if (notice == null) { |
| notice = new ChangeNoticeImpl(source); |
| _pendingNotices[source] = notice; |
| } |
| return notice; |
| } |
| /** |
| * Return the source information associated with the given source, or {@code null} if the source |
| * is not known to this context. This method should be used to access the source information |
| * rather than accessing the source map directly because sources in the SDK are implicitly part of |
| * every analysis context and are therefore only added to the map when first accessed. |
| * <p> |
| * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}. |
| * @param source the source for which information is being sought |
| * @return the source information associated with the given source |
| */ |
| SourceInfo getSourceInfo(Source source) { |
| SourceInfo sourceInfo = _sourceMap[source]; |
| if (sourceInfo == null) { |
| sourceInfo = createSourceInfo(source); |
| } |
| return sourceInfo; |
| } |
| /** |
| * Return an array containing all of the sources known to this context that have the given kind. |
| * @param kind the kind of sources to be returned |
| * @return all of the sources known to this context that have the given kind |
| */ |
| List<Source> getSources(SourceKind kind2) { |
| List<Source> sources = new List<Source>(); |
| { |
| for (MapEntry<Source, SourceInfo> entry in getMapEntrySet(_sourceMap)) { |
| if (identical(entry.getValue().kind, kind2)) { |
| sources.add(entry.getKey()); |
| } |
| } |
| } |
| return new List.from(sources); |
| } |
| /** |
| * Return {@code true} if the given compilation unit has a part-of directive but no library |
| * directive. |
| * @param unit the compilation unit being tested |
| * @return {@code true} if the compilation unit has a part-of directive |
| */ |
| bool hasPartOfDirective(CompilationUnit unit) { |
| bool hasPartOf = false; |
| for (Directive directive in unit.directives) { |
| if (directive is PartOfDirective) { |
| hasPartOf = true; |
| } else if (directive is LibraryDirective) { |
| return false; |
| } |
| } |
| return hasPartOf; |
| } |
| /** |
| * Compute the kind of the given source. This method should only be invoked when the kind is not |
| * already known. In such a case the source is currently being represented by a {@link DartInfo}. |
| * After this method has run the source will be represented by a new information object that is |
| * appropriate to the computed kind of the source. |
| * @param source the source for which a kind is to be computed |
| * @return the new source info that was created to represent the source |
| */ |
| SourceInfo internalComputeKindOf(Source source) { |
| try { |
| accessed(source); |
| RecordingErrorListener errorListener = new RecordingErrorListener(); |
| AnalysisContextImpl_ScanResult scanResult = internalScan(source, errorListener); |
| Parser parser = new Parser(source, errorListener); |
| CompilationUnit unit = parser.parseCompilationUnit(scanResult._token); |
| LineInfo lineInfo = new LineInfo(scanResult._lineStarts); |
| List<AnalysisError> errors = errorListener.getErrors2(source); |
| unit.parsingErrors = errors; |
| unit.lineInfo = lineInfo; |
| CompilationUnitInfo sourceInfo; |
| if (hasPartOfDirective(unit)) { |
| sourceInfo = new CompilationUnitInfo(); |
| } else { |
| sourceInfo = new LibraryInfo(); |
| } |
| sourceInfo.lineInfo = lineInfo; |
| sourceInfo.parsedCompilationUnit = unit; |
| sourceInfo.parseErrors = errors; |
| _sourceMap[source] = sourceInfo; |
| return sourceInfo; |
| } on AnalysisException catch (exception) { |
| DartInfo sourceInfo = DartInfo.errorInstance; |
| _sourceMap[source] = sourceInfo; |
| return sourceInfo; |
| } |
| } |
| CompilationUnit internalParseCompilationUnit(CompilationUnitInfo compilationUnitInfo, Source source) { |
| accessed(source); |
| RecordingErrorListener errorListener = new RecordingErrorListener(); |
| AnalysisContextImpl_ScanResult scanResult = internalScan(source, errorListener); |
| Parser parser = new Parser(source, errorListener); |
| CompilationUnit unit = parser.parseCompilationUnit(scanResult._token); |
| LineInfo lineInfo = new LineInfo(scanResult._lineStarts); |
| List<AnalysisError> errors = errorListener.getErrors2(source); |
| unit.parsingErrors = errors; |
| unit.lineInfo = lineInfo; |
| compilationUnitInfo.lineInfo = lineInfo; |
| compilationUnitInfo.parsedCompilationUnit = unit; |
| compilationUnitInfo.parseErrors = errors; |
| return unit; |
| } |
| AnalysisContextImpl_ScanResult internalScan(Source source, AnalysisErrorListener errorListener) { |
| AnalysisContextImpl_ScanResult result = new AnalysisContextImpl_ScanResult(); |
| Source_ContentReceiver receiver = new Source_ContentReceiver_7(source, errorListener, result); |
| try { |
| source.getContents(receiver); |
| } catch (exception) { |
| throw new AnalysisException.con3(exception); |
| } |
| return result; |
| } |
| /** |
| * In response to a change to at least one of the compilation units in the given library, |
| * invalidate any results that are dependent on the result of resolving that library. |
| * @param librarySource the source of the library being invalidated |
| * @param libraryInfo the information for the library being invalidated |
| */ |
| void invalidateLibraryResolution(Source librarySource, LibraryInfo libraryInfo) { |
| if (libraryInfo != null) { |
| libraryInfo.invalidateElement(); |
| libraryInfo.invalidateLaunchable(); |
| libraryInfo.invalidatePublicNamespace(); |
| libraryInfo.invalidateResolutionErrors(); |
| libraryInfo.invalidateResolvedUnit(); |
| for (Source unitSource in libraryInfo.unitSources) { |
| CompilationUnitInfo partInfo = getCompilationUnitInfo(unitSource); |
| partInfo.invalidateResolutionErrors(); |
| partInfo.invalidateResolvedUnit(); |
| } |
| libraryInfo.invalidateUnitSources(); |
| } |
| } |
| /** |
| * Return {@code true} if this library is, or depends on, dart:html. |
| * @param library the library being tested |
| * @param visitedLibraries a collection of the libraries that have been visited, used to prevent |
| * infinite recursion |
| * @return {@code true} if this library is, or depends on, dart:html |
| */ |
| bool isClient(LibraryElement library, Source htmlSource, Set<LibraryElement> visitedLibraries) { |
| if (visitedLibraries.contains(library)) { |
| return false; |
| } |
| if (library.source == htmlSource) { |
| return true; |
| } |
| javaSetAdd(visitedLibraries, library); |
| for (LibraryElement imported in library.importedLibraries) { |
| if (isClient(imported, htmlSource, visitedLibraries)) { |
| return true; |
| } |
| } |
| for (LibraryElement exported in library.exportedLibraries) { |
| if (isClient(exported, htmlSource, visitedLibraries)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| /** |
| * Perform a single analysis task. |
| * <p> |
| * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}. |
| * @return {@code true} if work was done, implying that there might be more work to be done |
| */ |
| bool performSingleAnalysisTask() { |
| for (MapEntry<Source, SourceInfo> entry in getMapEntrySet(_sourceMap)) { |
| SourceInfo sourceInfo = entry.getValue(); |
| if (identical(sourceInfo, DartInfo.pendingInstance)) { |
| internalComputeKindOf(entry.getKey()); |
| return true; |
| } |
| } |
| for (MapEntry<Source, SourceInfo> entry in getMapEntrySet(_sourceMap)) { |
| SourceInfo sourceInfo = entry.getValue(); |
| if (sourceInfo is CompilationUnitInfo) { |
| CompilationUnitInfo unitInfo = sourceInfo as CompilationUnitInfo; |
| if (unitInfo.hasInvalidParsedUnit()) { |
| try { |
| parseCompilationUnit(entry.getKey()); |
| } on AnalysisException catch (exception) { |
| unitInfo.parsedCompilationUnit = null; |
| AnalysisEngine.instance.logger.logError2("Could not parse ${entry.getKey().fullName}", exception); |
| } |
| return true; |
| } |
| } else if (sourceInfo is HtmlUnitInfo) { |
| HtmlUnitInfo unitInfo = sourceInfo as HtmlUnitInfo; |
| if (unitInfo.hasInvalidParsedUnit()) { |
| try { |
| parseHtmlUnit(entry.getKey()); |
| } on AnalysisException catch (exception) { |
| unitInfo.parsedUnit = null; |
| AnalysisEngine.instance.logger.logError2("Could not parse ${entry.getKey().fullName}", exception); |
| } |
| return true; |
| } |
| } |
| } |
| for (MapEntry<Source, SourceInfo> entry in getMapEntrySet(_sourceMap)) { |
| SourceInfo sourceInfo = entry.getValue(); |
| if (sourceInfo is LibraryInfo) { |
| LibraryInfo libraryInfo = sourceInfo as LibraryInfo; |
| if (libraryInfo.hasInvalidElement()) { |
| try { |
| computeLibraryElement(entry.getKey()); |
| } on AnalysisException catch (exception) { |
| libraryInfo.element = null; |
| AnalysisEngine.instance.logger.logError2("Could not resolve ${entry.getKey().fullName}", exception); |
| } |
| return true; |
| } |
| } else if (sourceInfo is HtmlUnitInfo) { |
| HtmlUnitInfo unitInfo = sourceInfo as HtmlUnitInfo; |
| if (unitInfo.hasInvalidResolvedUnit()) { |
| try { |
| resolveHtmlUnit(entry.getKey()); |
| } on AnalysisException catch (exception) { |
| unitInfo.resolvedUnit = null; |
| AnalysisEngine.instance.logger.logError2("Could not resolve ${entry.getKey().fullName}", exception); |
| } |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| HtmlScanResult scanHtml(Source source) { |
| HtmlScanner scanner = new HtmlScanner(source); |
| try { |
| source.getContents(scanner); |
| } catch (exception) { |
| throw new AnalysisException.con3(exception); |
| } |
| return scanner.result; |
| } |
| /** |
| * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}. |
| * @param source the source that has been added |
| */ |
| void sourceAvailable(Source source) { |
| SourceInfo existingInfo = _sourceMap[source]; |
| if (existingInfo == null) { |
| createSourceInfo(source); |
| } |
| } |
| /** |
| * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}. |
| * @param source the source that has been changed |
| */ |
| void sourceChanged(Source source) { |
| SourceInfo sourceInfo = _sourceMap[source]; |
| if (sourceInfo is HtmlUnitInfo) { |
| HtmlUnitInfo htmlUnitInfo = sourceInfo as HtmlUnitInfo; |
| htmlUnitInfo.invalidateElement(); |
| htmlUnitInfo.invalidateLineInfo(); |
| htmlUnitInfo.invalidateParsedUnit(); |
| htmlUnitInfo.invalidateResolvedUnit(); |
| } else if (sourceInfo is LibraryInfo) { |
| LibraryInfo libraryInfo = sourceInfo as LibraryInfo; |
| invalidateLibraryResolution(source, libraryInfo); |
| _sourceMap[source] = DartInfo.pendingInstance; |
| } else if (sourceInfo is CompilationUnitInfo) { |
| for (Source librarySource in getLibrariesContaining(source)) { |
| LibraryInfo libraryInfo = getLibraryInfo(librarySource); |
| invalidateLibraryResolution(librarySource, libraryInfo); |
| } |
| _sourceMap[source] = DartInfo.pendingInstance; |
| } |
| } |
| /** |
| * <b>Note:</b> This method must only be invoked while we are synchronized on {@link #cacheLock}. |
| * @param source the source that has been deleted |
| */ |
| void sourceRemoved(Source source) { |
| CompilationUnitInfo compilationUnitInfo = getCompilationUnitInfo(source); |
| if (compilationUnitInfo != null) { |
| for (Source librarySource in getLibrariesContaining(source)) { |
| LibraryInfo libraryInfo = getLibraryInfo(librarySource); |
| invalidateLibraryResolution(librarySource, libraryInfo); |
| } |
| } |
| _sourceMap.remove(source); |
| } |
| } |
| /** |
| * Instances of the class {@code ScanResult} represent the results of scanning a source. |
| */ |
| class AnalysisContextImpl_ScanResult { |
| /** |
| * The time at which the contents of the source were last set. |
| */ |
| int _modificationTime = 0; |
| /** |
| * The first token in the token stream. |
| */ |
| Token _token; |
| /** |
| * The line start information that was produced. |
| */ |
| List<int> _lineStarts; |
| /** |
| * Initialize a newly created result object to be empty. |
| */ |
| AnalysisContextImpl_ScanResult() : super() { |
| } |
| } |
| class RecursiveXmlVisitor_6 extends RecursiveXmlVisitor<Object> { |
| final AnalysisContextImpl AnalysisContextImpl_this; |
| Source htmlSource; |
| List<Source> libraries; |
| RecursiveXmlVisitor_6(this.AnalysisContextImpl_this, this.htmlSource, this.libraries) : super(); |
| Object visitXmlTagNode(XmlTagNode node) { |
| if (javaStringEqualsIgnoreCase(node.tag.lexeme, AnalysisContextImpl._TAG_SCRIPT)) { |
| for (XmlAttributeNode attribute in node.attributes) { |
| if (javaStringEqualsIgnoreCase(attribute.name.lexeme, AnalysisContextImpl._ATTRIBUTE_SRC)) { |
| try { |
| Uri uri = new Uri.fromComponents(path: attribute.text); |
| String fileName = uri.path; |
| if (AnalysisEngine.isDartFileName(fileName)) { |
| Source librarySource = AnalysisContextImpl_this._sourceFactory.resolveUri(htmlSource, fileName); |
| if (librarySource.exists()) { |
| libraries.add(librarySource); |
| } |
| } |
| } catch (exception) { |
| AnalysisEngine.instance.logger.logError2("Invalid URL ('${attribute.text}') in script tag in '${htmlSource.fullName}'", exception); |
| } |
| } |
| } |
| } |
| return super.visitXmlTagNode(node); |
| } |
| } |
| class Source_ContentReceiver_7 implements Source_ContentReceiver { |
| Source source; |
| AnalysisErrorListener errorListener; |
| AnalysisContextImpl_ScanResult result; |
| Source_ContentReceiver_7(this.source, this.errorListener, this.result); |
| void accept(CharBuffer contents, int modificationTime2) { |
| CharBufferScanner scanner = new CharBufferScanner(source, contents, errorListener); |
| result._modificationTime = modificationTime2; |
| result._token = scanner.tokenize(); |
| result._lineStarts = scanner.lineStarts; |
| } |
| void accept2(String contents, int modificationTime2) { |
| StringScanner scanner = new StringScanner(source, contents, errorListener); |
| result._modificationTime = modificationTime2; |
| result._token = scanner.tokenize(); |
| result._lineStarts = scanner.lineStarts; |
| } |
| } |
| /** |
| * Instances of the class {@code AnalysisErrorInfoImpl} represent the analysis errors and line info |
| * associated with a source. |
| */ |
| class AnalysisErrorInfoImpl implements AnalysisErrorInfo { |
| /** |
| * The analysis errors associated with a source, or {@code null} if there are no errors. |
| */ |
| List<AnalysisError> _errors; |
| /** |
| * The line information associated with the errors, or {@code null} if there are no errors. |
| */ |
| LineInfo _lineInfo; |
| /** |
| * Initialize an newly created error info with the errors and line information |
| * @param errors the errors as a result of analysis |
| * @param lineinfo the line info for the errors |
| */ |
| AnalysisErrorInfoImpl(List<AnalysisError> errors, LineInfo lineInfo) { |
| this._errors = errors; |
| this._lineInfo = lineInfo; |
| } |
| /** |
| * Return the errors of analysis, or {@code null} if there were no errors. |
| * @return the errors as a result of the analysis |
| */ |
| List<AnalysisError> get errors => _errors; |
| /** |
| * Return the line information associated with the errors, or {@code null} if there were no |
| * errors. |
| * @return the line information associated with the errors |
| */ |
| LineInfo get lineInfo => _lineInfo; |
| } |
| /** |
| * The enumeration {@code CacheState} defines the possible states of cached data. |
| */ |
| class CacheState implements Comparable<CacheState> { |
| /** |
| * A state representing the fact that the data was up-to-date but flushed from the cache in order |
| * to control memory usage. |
| */ |
| static final CacheState FLUSHED = new CacheState('FLUSHED', 0); |
| /** |
| * A state representing the fact that the data was removed from the cache because it was invalid |
| * and needs to be recomputed. |
| */ |
| static final CacheState INVALID = new CacheState('INVALID', 1); |
| /** |
| * A state representing the fact that the data is in the cache and valid. |
| */ |
| static final CacheState VALID = new CacheState('VALID', 2); |
| static final List<CacheState> values = [FLUSHED, INVALID, VALID]; |
| final String __name; |
| final int __ordinal; |
| int get ordinal => __ordinal; |
| CacheState(this.__name, this.__ordinal) { |
| } |
| int compareTo(CacheState other) => __ordinal - other.__ordinal; |
| String toString() => __name; |
| } |
| /** |
| * Instances of the class {@code ChangeNoticeImpl} represent a change to the analysis results |
| * associated with a given source. |
| * @coverage dart.engine |
| */ |
| class ChangeNoticeImpl implements ChangeNotice { |
| /** |
| * The source for which the result is being reported. |
| */ |
| Source _source; |
| /** |
| * The fully resolved AST that changed as a result of the analysis, or {@code null} if the AST was |
| * not changed. |
| */ |
| CompilationUnit _compilationUnit; |
| /** |
| * The errors that changed as a result of the analysis, or {@code null} if errors were not |
| * changed. |
| */ |
| List<AnalysisError> _errors; |
| /** |
| * The line information associated with the source, or {@code null} if errors were not changed. |
| */ |
| LineInfo _lineInfo; |
| /** |
| * An empty array of change notices. |
| */ |
| static List<ChangeNoticeImpl> EMPTY_ARRAY = new List<ChangeNoticeImpl>(0); |
| /** |
| * Initialize a newly created notice associated with the given source. |
| * @param source the source for which the change is being reported |
| */ |
| ChangeNoticeImpl(Source source) { |
| this._source = source; |
| } |
| /** |
| * Return the fully resolved AST that changed as a result of the analysis, or {@code null} if the |
| * AST was not changed. |
| * @return the fully resolved AST that changed as a result of the analysis |
| */ |
| CompilationUnit get compilationUnit => _compilationUnit; |
| /** |
| * Return the errors that changed as a result of the analysis, or {@code null} if errors were not |
| * changed. |
| * @return the errors that changed as a result of the analysis |
| */ |
| List<AnalysisError> get errors => _errors; |
| /** |
| * Return the line information associated with the source, or {@code null} if errors were not |
| * changed. |
| * @return the line information associated with the source |
| */ |
| LineInfo get lineInfo => _lineInfo; |
| /** |
| * Return the source for which the result is being reported. |
| * @return the source for which the result is being reported |
| */ |
| Source get source => _source; |
| /** |
| * Set the fully resolved AST that changed as a result of the analysis to the given AST. |
| * @param compilationUnit the fully resolved AST that changed as a result of the analysis |
| */ |
| void set compilationUnit(CompilationUnit compilationUnit2) { |
| this._compilationUnit = compilationUnit2; |
| } |
| /** |
| * Set the errors that changed as a result of the analysis to the given errors and set the line |
| * information to the given line information. |
| * @param errors the errors that changed as a result of the analysis |
| * @param lineInfo the line information associated with the source |
| */ |
| void setErrors(List<AnalysisError> errors2, LineInfo lineInfo2) { |
| this._errors = errors2; |
| this._lineInfo = lineInfo2; |
| } |
| } |
| /** |
| * Instances of the class {@code CompilationUnitInfo} maintain the information cached by an analysis |
| * context about an individual compilation unit. |
| * @coverage dart.engine |
| */ |
| class CompilationUnitInfo extends SourceInfo { |
| /** |
| * The state of the cached parsed compilation unit. |
| */ |
| CacheState _parsedUnitState = CacheState.INVALID; |
| /** |
| * The parsed compilation unit, or {@code null} if the parsed compilation unit is not currently |
| * cached. |
| */ |
| CompilationUnit _parsedUnit; |
| /** |
| * The state of the cached resolved compilation unit. |
| */ |
| CacheState _resolvedUnitState = CacheState.INVALID; |
| /** |
| * The resolved compilation unit, or {@code null} if the resolved compilation unit is not |
| * currently cached. |
| */ |
| CompilationUnit _resolvedUnit; |
| /** |
| * The state of the cached parse errors. |
| */ |
| CacheState _parseErrorsState = CacheState.INVALID; |
| /** |
| * The errors produced while scanning and parsing the compilation unit, or {@code null} if the |
| * errors are not currently cached. |
| */ |
| List<AnalysisError> _parseErrors; |
| /** |
| * The state of the cached resolution errors. |
| */ |
| CacheState _resolutionErrorsState = CacheState.INVALID; |
| /** |
| * The errors produced while resolving the compilation unit, or {@code null} if the errors are not |
| * currently cached. |
| */ |
| List<AnalysisError> _resolutionErrors; |
| /** |
| * Initialize a newly created information holder to be empty. |
| */ |
| CompilationUnitInfo() : super() { |
| } |
| /** |
| * Remove the parsed compilation unit from the cache. |
| */ |
| void clearParsedUnit() { |
| _parsedUnit = null; |
| _parsedUnitState = CacheState.FLUSHED; |
| } |
| /** |
| * Remove the parse errors from the cache. |
| */ |
| void clearParseErrors() { |
| _parseErrors = null; |
| _parseErrorsState = CacheState.FLUSHED; |
| } |
| /** |
| * Remove the resolution errors from the cache. |
| */ |
| void clearResolutionErrors() { |
| _resolutionErrors = null; |
| _resolutionErrorsState = CacheState.FLUSHED; |
| } |
| /** |
| * Remove the resolved compilation unit from the cache. |
| */ |
| void clearResolvedUnit() { |
| _resolvedUnit = null; |
| _resolvedUnitState = CacheState.FLUSHED; |
| } |
| CompilationUnitInfo copy() { |
| CompilationUnitInfo copy = new CompilationUnitInfo(); |
| copy.copyFrom(this); |
| return copy; |
| } |
| /** |
| * Return all of the errors associated with the compilation unit. |
| * @return all of the errors associated with the compilation unit |
| */ |
| List<AnalysisError> get allErrors { |
| if (_parseErrors == null) { |
| if (_resolutionErrors == null) { |
| return null; |
| } |
| return _resolutionErrors; |
| } else if (_resolutionErrors == null) { |
| return _parseErrors; |
| } |
| int parseCount = _parseErrors.length; |
| int resolutionCount = _resolutionErrors.length; |
| List<AnalysisError> errors = new List<AnalysisError>(parseCount + resolutionCount); |
| JavaSystem.arraycopy(_parseErrors, 0, errors, 0, parseCount); |
| JavaSystem.arraycopy(_resolutionErrors, 0, errors, parseCount, resolutionCount); |
| return errors; |
| } |
| SourceKind get kind => SourceKind.PART; |
| /** |
| * Return the parsed compilation unit, or {@code null} if the parsed compilation unit is not |
| * currently cached. |
| * @return the parsed compilation unit |
| */ |
| CompilationUnit get parsedCompilationUnit => _parsedUnit; |
| /** |
| * Return the errors produced while scanning and parsing the compilation unit, or {@code null} if |
| * the errors are not currently cached. |
| * @return the errors produced while scanning and parsing the compilation unit |
| */ |
| List<AnalysisError> get parseErrors => _parseErrors; |
| /** |
| * Return the errors produced while resolving the compilation unit, or {@code null} if the errors |
| * are not currently cached. |
| * @return the errors produced while resolving the compilation unit |
| */ |
| List<AnalysisError> get resolutionErrors => _resolutionErrors; |
| /** |
| * Return the resolved compilation unit, or {@code null} if the resolved compilation unit is not |
| * currently cached. |
| * @return the resolved compilation unit |
| */ |
| CompilationUnit get resolvedCompilationUnit => _resolvedUnit; |
| /** |
| * Return {@code true} if the parsed compilation unit needs to be recomputed. |
| * @return {@code true} if the parsed compilation unit needs to be recomputed |
| */ |
| bool hasInvalidParsedUnit() => identical(_parsedUnitState, CacheState.INVALID); |
| /** |
| * Return {@code true} if the parse errors needs to be recomputed. |
| * @return {@code true} if the parse errors needs to be recomputed |
| */ |
| bool hasInvalidParseErrors() => identical(_parseErrorsState, CacheState.INVALID); |
| /** |
| * Return {@code true} if the resolution errors needs to be recomputed. |
| * @return {@code true} if the resolution errors needs to be recomputed |
| */ |
| bool hasInvalidResolutionErrors() => identical(_resolutionErrorsState, CacheState.INVALID); |
| /** |
| * Return {@code true} if the resolved compilation unit needs to be recomputed. |
| * @return {@code true} if the resolved compilation unit needs to be recomputed |
| */ |
| bool hasInvalidResolvedUnit() => identical(_resolvedUnitState, CacheState.INVALID); |
| /** |
| * Mark the parsed compilation unit as needing to be recomputed. |
| */ |
| void invalidateParsedUnit() { |
| _parsedUnitState = CacheState.INVALID; |
| _parsedUnit = null; |
| } |
| /** |
| * Mark the parse errors as needing to be recomputed. |
| */ |
| void invalidateParseErrors() { |
| _parseErrorsState = CacheState.INVALID; |
| _parseErrors = null; |
| } |
| /** |
| * Mark the resolution errors as needing to be recomputed. |
| */ |
| void invalidateResolutionErrors() { |
| _resolutionErrorsState = CacheState.INVALID; |
| _resolutionErrors = null; |
| } |
| /** |
| * Mark the resolved compilation unit as needing to be recomputed. |
| */ |
| void invalidateResolvedUnit() { |
| _resolvedUnitState = CacheState.INVALID; |
| _resolvedUnit = null; |
| } |
| /** |
| * Set the parsed compilation unit to the given compilation unit. |
| * <p> |
| * <b>Note:</b> Do not use this method to clear or invalidate the parsed compilation unit. Use |
| * either {@link #clear} or {@link #invalidate}. |
| * @param unit the parsed compilation unit |
| */ |
| void set parsedCompilationUnit(CompilationUnit unit) { |
| _parsedUnit = unit; |
| _parsedUnitState = CacheState.VALID; |
| } |
| /** |
| * Set the errors produced while scanning and parsing the compilation unit to the given errors. |
| * <p> |
| * <b>Note:</b> Do not use this method to clear or invalidate the parse errors. Use either{@link #clear} or {@link #invalidate}. |
| * @param errors the errors produced while scanning and parsing the compilation unit |
| */ |
| void set parseErrors(List<AnalysisError> errors) { |
| _parseErrors = errors; |
| _parseErrorsState = CacheState.VALID; |
| } |
| /** |
| * Set the errors produced while resolving the compilation unit to the given errors. |
| * <p> |
| * <b>Note:</b> Do not use this method to clear or invalidate the resolution errors. Use either{@link #clear} or {@link #invalidate}. |
| * @param errors the errors produced while resolving the compilation unit |
| */ |
| void set resolutionErrors(List<AnalysisError> errors) { |
| _resolutionErrors = errors; |
| _resolutionErrorsState = CacheState.VALID; |
| } |
| /** |
| * Set the resolved compilation unit to the given compilation unit. |
| * <p> |
| * <b>Note:</b> Do not use this method to clear or invalidate the resolved compilation unit. Use |
| * either {@link #clear} or {@link #invalidate}. |
| * @param unit the resolved compilation unit |
| */ |
| void set resolvedCompilationUnit(CompilationUnit unit) { |
| _resolvedUnit = unit; |
| _resolvedUnitState = CacheState.VALID; |
| } |
| void copyFrom(SourceInfo info) { |
| super.copyFrom(info); |
| } |
| } |
| /** |
| * Instances of the class {@code DartInfo} acts as a placeholder for Dart compilation units that |
| * have not yet had their kind computed. |
| * @coverage dart.engine |
| */ |
| class DartInfo extends SourceInfo { |
| /** |
| * The instance of this class used to represent a compilation unit for which an attempt was made |
| * to compute the kind but the kind could not be computed. |
| */ |
| static DartInfo _ErrorInstance = new DartInfo(); |
| /** |
| * The instance of this class used to represent a compilation unit for which no attempt has been |
| * made to compute the kind. |
| */ |
| static DartInfo _PendingInstance = new DartInfo(); |
| /** |
| * Return an instance of this class representing a compilation unit for which an attempt was made |
| * to compute the kind but the kind could not be computed. |
| * @return an instance of this class used to indicate that the computation of the kind resulted in |
| * an error and there is no point trying again |
| */ |
| static DartInfo get errorInstance => _ErrorInstance; |
| /** |
| * Return an instance of this class representing a compilation unit for which no attempt has been |
| * made to compute the kind. |
| * @return an instance of this class used to indicate that the computation of the kind is pending |
| */ |
| static DartInfo get pendingInstance => _PendingInstance; |
| /** |
| * Prevent the creation of instances of this class. |
| */ |
| DartInfo() : super() { |
| } |
| DartInfo copy() => this; |
| SourceKind get kind => SourceKind.UNKNOWN; |
| } |
| /** |
| * Instances of the class {@code DelegatingAnalysisContextImpl} extend {@link AnalysisContextImplanalysis context} to delegate sources to the appropriate analysis context. For instance, if the |
| * source is in a system library then the analysis context from the {@link DartSdk} is used. |
| * @coverage dart.engine |
| */ |
| class DelegatingAnalysisContextImpl extends AnalysisContextImpl { |
| /** |
| * This references the {@link InternalAnalysisContext} held onto by the {@link DartSdk} which is |
| * used (instead of this {@link AnalysisContext}) for SDK sources. This field is set when |
| * #setSourceFactory(SourceFactory) is called, and references the analysis context in the{@link DartUriResolver} in the {@link SourceFactory}, this analysis context assumes that there |
| * will be such a resolver. |
| */ |
| InternalAnalysisContext _sdkAnalysisContext; |
| /** |
| * Initialize a newly created delegating analysis context. |
| */ |
| DelegatingAnalysisContextImpl() : super() { |
| } |
| void addSourceInfo(Source source, SourceInfo info) { |
| if (source.isInSystemLibrary()) { |
| _sdkAnalysisContext.addSourceInfo(source, info); |
| } else { |
| super.addSourceInfo(source, info); |
| } |
| } |
| List<AnalysisError> computeErrors(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.computeErrors(source); |
| } else { |
| return super.computeErrors(source); |
| } |
| } |
| HtmlElement computeHtmlElement(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.computeHtmlElement(source); |
| } else { |
| return super.computeHtmlElement(source); |
| } |
| } |
| SourceKind computeKindOf(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.computeKindOf(source); |
| } else { |
| return super.computeKindOf(source); |
| } |
| } |
| LibraryElement computeLibraryElement(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.computeLibraryElement(source); |
| } else { |
| return super.computeLibraryElement(source); |
| } |
| } |
| LineInfo computeLineInfo(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.computeLineInfo(source); |
| } else { |
| return super.computeLineInfo(source); |
| } |
| } |
| CompilationUnit computeResolvableCompilationUnit(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.computeResolvableCompilationUnit(source); |
| } else { |
| return super.computeResolvableCompilationUnit(source); |
| } |
| } |
| AnalysisErrorInfo getErrors(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.getErrors(source); |
| } else { |
| return super.getErrors(source); |
| } |
| } |
| HtmlElement getHtmlElement(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.getHtmlElement(source); |
| } else { |
| return super.getHtmlElement(source); |
| } |
| } |
| List<Source> getHtmlFilesReferencing(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.getHtmlFilesReferencing(source); |
| } else { |
| return super.getHtmlFilesReferencing(source); |
| } |
| } |
| SourceKind getKindOf(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.getKindOf(source); |
| } else { |
| return super.getKindOf(source); |
| } |
| } |
| List<Source> getLibrariesContaining(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.getLibrariesContaining(source); |
| } else { |
| return super.getLibrariesContaining(source); |
| } |
| } |
| LibraryElement getLibraryElement(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.getLibraryElement(source); |
| } else { |
| return super.getLibraryElement(source); |
| } |
| } |
| List<Source> get librarySources => ArrayUtils.addAll(super.librarySources, _sdkAnalysisContext.librarySources); |
| LineInfo getLineInfo(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.getLineInfo(source); |
| } else { |
| return super.getLineInfo(source); |
| } |
| } |
| Namespace getPublicNamespace(LibraryElement library) { |
| Source source2 = library.source; |
| if (source2.isInSystemLibrary()) { |
| return _sdkAnalysisContext.getPublicNamespace(library); |
| } else { |
| return super.getPublicNamespace(library); |
| } |
| } |
| Namespace getPublicNamespace2(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.getPublicNamespace2(source); |
| } else { |
| return super.getPublicNamespace2(source); |
| } |
| } |
| CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library) { |
| if (unitSource.isInSystemLibrary()) { |
| return _sdkAnalysisContext.getResolvedCompilationUnit(unitSource, library); |
| } else { |
| return super.getResolvedCompilationUnit(unitSource, library); |
| } |
| } |
| CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source librarySource) { |
| if (unitSource.isInSystemLibrary()) { |
| return _sdkAnalysisContext.getResolvedCompilationUnit2(unitSource, librarySource); |
| } else { |
| return super.getResolvedCompilationUnit2(unitSource, librarySource); |
| } |
| } |
| bool isClientLibrary(Source librarySource) { |
| if (librarySource.isInSystemLibrary()) { |
| return _sdkAnalysisContext.isClientLibrary(librarySource); |
| } else { |
| return super.isClientLibrary(librarySource); |
| } |
| } |
| bool isServerLibrary(Source librarySource) { |
| if (librarySource.isInSystemLibrary()) { |
| return _sdkAnalysisContext.isServerLibrary(librarySource); |
| } else { |
| return super.isServerLibrary(librarySource); |
| } |
| } |
| CompilationUnit parseCompilationUnit(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.parseCompilationUnit(source); |
| } else { |
| return super.parseCompilationUnit(source); |
| } |
| } |
| HtmlUnit parseHtmlUnit(Source source) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.parseHtmlUnit(source); |
| } else { |
| return super.parseHtmlUnit(source); |
| } |
| } |
| void recordLibraryElements(Map<Source, LibraryElement> elementMap) { |
| if (elementMap.isEmpty) { |
| return; |
| } |
| Source source = new JavaIterator(elementMap.keys.toSet()).next(); |
| if (source.isInSystemLibrary()) { |
| _sdkAnalysisContext.recordLibraryElements(elementMap); |
| } else { |
| super.recordLibraryElements(elementMap); |
| } |
| } |
| void recordResolutionErrors(Source source, List<AnalysisError> errors, LineInfo lineInfo) { |
| if (source.isInSystemLibrary()) { |
| _sdkAnalysisContext.recordResolutionErrors(source, errors, lineInfo); |
| } else { |
| super.recordResolutionErrors(source, errors, lineInfo); |
| } |
| } |
| void recordResolvedCompilationUnit(Source source, CompilationUnit unit) { |
| if (source.isInSystemLibrary()) { |
| _sdkAnalysisContext.recordResolvedCompilationUnit(source, unit); |
| } else { |
| super.recordResolvedCompilationUnit(source, unit); |
| } |
| } |
| CompilationUnit resolveCompilationUnit(Source source, LibraryElement library) { |
| if (source.isInSystemLibrary()) { |
| return _sdkAnalysisContext.resolveCompilationUnit(source, library); |
| } else { |
| return super.resolveCompilationUnit(source, library); |
| } |
| } |
| CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) { |
| if (unitSource.isInSystemLibrary()) { |
| return _sdkAnalysisContext.resolveCompilationUnit2(unitSource, librarySource); |
| } else { |
| return super.resolveCompilationUnit2(unitSource, librarySource); |
| } |
| } |
| HtmlUnit resolveHtmlUnit(Source unitSource) { |
| if (unitSource.isInSystemLibrary()) { |
| return _sdkAnalysisContext.resolveHtmlUnit(unitSource); |
| } else { |
| return super.resolveHtmlUnit(unitSource); |
| } |
| } |
| void setContents(Source source, String contents) { |
| if (source.isInSystemLibrary()) { |
| _sdkAnalysisContext.setContents(source, contents); |
| } else { |
| super.setContents(source, contents); |
| } |
| } |
| void set sourceFactory(SourceFactory factory) { |
| super.sourceFactory = factory; |
| DartSdk sdk = factory.dartSdk; |
| if (sdk != null) { |
| _sdkAnalysisContext = sdk.context as InternalAnalysisContext; |
| } else { |
| throw new IllegalStateException("SourceFactorys provided to DelegatingAnalysisContextImpls must have a DartSdk associated with the provided SourceFactory."); |
| } |
| } |
| } |
| /** |
| * Instances of the class {@code HtmlUnitInfo} maintain the information cached by an analysis |
| * context about an individual HTML file. |
| * @coverage dart.engine |
| */ |
| class HtmlUnitInfo extends SourceInfo { |
| /** |
| * The state of the cached parsed (but not resolved) HTML unit. |
| */ |
| CacheState _parsedUnitState = CacheState.INVALID; |
| /** |
| * The parsed HTML unit, or {@code null} if the parsed HTML unit is not currently cached. |
| */ |
| HtmlUnit _parsedUnit; |
| /** |
| * The state of the cached parsed and resolved HTML unit. |
| */ |
| CacheState _resolvedUnitState = CacheState.INVALID; |
| /** |
| * The resolved HTML unit, or {@code null} if the resolved HTML unit is not currently cached. |
| */ |
| HtmlUnit _resolvedUnit; |
| /** |
| * The state of the cached HTML element. |
| */ |
| CacheState _elementState = CacheState.INVALID; |
| /** |
| * The element representing the HTML file, or {@code null} if the element is not currently cached. |
| */ |
| HtmlElement _element; |
| /** |
| * The state of the cached library sources. |
| */ |
| CacheState _librarySourcesState = CacheState.INVALID; |
| /** |
| * The sources of libraries referenced by this HTML file. |
| */ |
| List<Source> _librarySources = Source.EMPTY_ARRAY; |
| /** |
| * Initialize a newly created information holder to be empty. |
| */ |
| HtmlUnitInfo() : super() { |
| } |
| /** |
| * Remove the parsed HTML unit from the cache. |
| */ |
| void clearParsedUnit() { |
| _parsedUnit = null; |
| _parsedUnitState = CacheState.FLUSHED; |
| } |
| /** |
| * Remove the resolved HTML unit from the cache. |
| */ |
| void clearResolvedUnit() { |
| _resolvedUnit = null; |
| _resolvedUnitState = CacheState.FLUSHED; |
| } |
| HtmlUnitInfo copy() { |
| HtmlUnitInfo copy = new HtmlUnitInfo(); |
| copy.copyFrom(this); |
| return copy; |
| } |
| /** |
| * Return the element representing the HTML file, or {@code null} if the element is not currently |
| * cached. |
| * @return the element representing the HTML file |
| */ |
| HtmlElement get element => _element; |
| SourceKind get kind => SourceKind.HTML; |
| /** |
| * Return the sources of libraries referenced by this HTML file. |
| * @return the sources of libraries referenced by this HTML file |
| */ |
| List<Source> get librarySources => _librarySources; |
| /** |
| * Return the parsed HTML unit, or {@code null} if the parsed HTML unit is not currently cached. |
| * @return the parsed HTML unit |
| */ |
| HtmlUnit get parsedUnit => _parsedUnit; |
| /** |
| * Return the resolved HTML unit, or {@code null} if the resolved HTML unit is not currently |
| * cached. |
| * @return the resolved HTML unit |
| */ |
| HtmlUnit get resolvedUnit => _resolvedUnit; |
| /** |
| * Return {@code true} if the HTML element needs to be recomputed. |
| * @return {@code true} if the HTML element needs to be recomputed |
| */ |
| bool hasInvalidElement() => identical(_elementState, CacheState.INVALID); |
| /** |
| * Return {@code true} if the parsed HTML unit needs to be recomputed. |
| * @return {@code true} if the parsed HTML unit needs to be recomputed |
| */ |
| bool hasInvalidParsedUnit() => identical(_parsedUnitState, CacheState.INVALID); |
| /** |
| * Return {@code true} if the resolved HTML unit needs to be recomputed. |
| * @return {@code true} if the resolved HTML unit needs to be recomputed |
| */ |
| bool hasInvalidResolvedUnit() => identical(_resolvedUnitState, CacheState.INVALID); |
| /** |
| * Mark the HTML element as needing to be recomputed. |
| */ |
| void invalidateElement() { |
| _elementState = CacheState.INVALID; |
| _element = null; |
| } |
| /** |
| * Mark the library sources as needing to be recomputed. |
| */ |
| void invalidateLibrarySources() { |
| _librarySourcesState = CacheState.INVALID; |
| _librarySources = Source.EMPTY_ARRAY; |
| } |
| /** |
| * Mark the parsed HTML unit as needing to be recomputed. |
| */ |
| void invalidateParsedUnit() { |
| _parsedUnitState = CacheState.INVALID; |
| _parsedUnit = null; |
| } |
| /** |
| * Mark the resolved HTML unit as needing to be recomputed. |
| */ |
| void invalidateResolvedUnit() { |
| invalidateElement(); |
| _resolvedUnitState = CacheState.INVALID; |
| _resolvedUnit = null; |
| } |
| /** |
| * Set the element representing the HTML file to the given element. |
| * <p> |
| * <b>Note:</b> Do not use this method to clear or invalidate the element. Use either{@link #clearElement()} or {@link #invalidateElement()}. |
| * @param element the element representing the HTML file |
| */ |
| void set element(HtmlElement element2) { |
| this._element = element2; |
| _elementState = CacheState.VALID; |
| } |
| /** |
| * Set the sources of libraries referenced by this HTML file to the given sources. |
| * @param sources the sources of libraries referenced by this HTML file |
| */ |
| void set librarySources(List<Source> sources) { |
| _librarySources = sources; |
| _librarySourcesState = CacheState.VALID; |
| } |
| /** |
| * Set the parsed HTML unit to the given HTML unit. |
| * <p> |
| * <b>Note:</b> Do not use this method to clear or invalidate the HTML unit. Use either{@link #clearParsedUnit()} or {@link #invalidateParsedUnit()}. |
| * @param unit the result of parsing the source as an HTML unit |
| */ |
| void set parsedUnit(HtmlUnit unit) { |
| _parsedUnit = unit; |
| _parsedUnitState = CacheState.VALID; |
| } |
| /** |
| * Set the resolved HTML unit to the given HTML unit. |
| * <p> |
| * <b>Note:</b> Do not use this method to clear or invalidate the HTML unit. Use either{@link #clearResolvedUnit()} or {@link #invalidateResolvedUnit()}. |
| * @param unit the result of resolving the source as an HTML unit |
| */ |
| void set resolvedUnit(HtmlUnit unit) { |
| _resolvedUnit = unit; |
| _resolvedUnitState = CacheState.VALID; |
| } |
| void copyFrom(SourceInfo info) { |
| super.copyFrom(info); |
| } |
| } |
| /** |
| * Instances of the class {@code InstrumentedAnalysisContextImpl} implement an{@link AnalysisContext analysis context} by recording instrumentation data and delegating to |
| * another analysis context to do the non-instrumentation work. |
| * @coverage dart.engine |
| */ |
| class InstrumentedAnalysisContextImpl implements InternalAnalysisContext { |
| /** |
| * Record an exception that was thrown during analysis. |
| * @param instrumentation the instrumentation builder being used to record the exception |
| * @param exception the exception being reported |
| */ |
| static void recordAnalysisException(InstrumentationBuilder instrumentation, AnalysisException exception) { |
| instrumentation.record(exception); |
| } |
| /** |
| * The unique identifier used to identify this analysis context in the instrumentation data. |
| */ |
| String _contextId = UUID.randomUUID().toString(); |
| /** |
| * The analysis context to which all of the non-instrumentation work is delegated. |
| */ |
| InternalAnalysisContext _basis; |
| /** |
| * Create a new {@link InstrumentedAnalysisContextImpl} which wraps a new{@link AnalysisContextImpl} as the basis context. |
| */ |
| InstrumentedAnalysisContextImpl() { |
| _jtd_constructor_175_impl(); |
| } |
| _jtd_constructor_175_impl() { |
| _jtd_constructor_176_impl(new AnalysisContextImpl()); |
| } |
| /** |
| * Create a new {@link InstrumentedAnalysisContextImpl} with a specified basis context, aka the |
| * context to wrap and instrument. |
| * @param context some {@link InstrumentedAnalysisContext} to wrap and instrument |
| */ |
| InstrumentedAnalysisContextImpl.con1(InternalAnalysisContext context) { |
| _jtd_constructor_176_impl(context); |
| } |
| _jtd_constructor_176_impl(InternalAnalysisContext context) { |
| _basis = context; |
| } |
| void addSourceInfo(Source source, SourceInfo info) { |
| _basis.addSourceInfo(source, info); |
| } |
| void applyChanges(ChangeSet changeSet) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-applyChanges"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| _basis.applyChanges(changeSet); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| List<AnalysisError> computeErrors(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeErrors"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| List<AnalysisError> errors = _basis.computeErrors(source); |
| instrumentation.metric2("Errors-count", errors.length); |
| return errors; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| HtmlElement computeHtmlElement(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeHtmlElement"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.computeHtmlElement(source); |
| } on AnalysisException catch (e) { |
| recordAnalysisException(instrumentation, e); |
| throw e; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| SourceKind computeKindOf(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeKindOf"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.computeKindOf(source); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| LibraryElement computeLibraryElement(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeLibraryElement"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.computeLibraryElement(source); |
| } on AnalysisException catch (e) { |
| recordAnalysisException(instrumentation, e); |
| throw e; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| LineInfo computeLineInfo(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeLineInfo"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.computeLineInfo(source); |
| } on AnalysisException catch (e) { |
| recordAnalysisException(instrumentation, e); |
| throw e; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| CompilationUnit computeResolvableCompilationUnit(Source source) => _basis.computeResolvableCompilationUnit(source); |
| AnalysisContext extractContext(SourceContainer container) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-extractContext"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| InstrumentedAnalysisContextImpl newContext = new InstrumentedAnalysisContextImpl(); |
| _basis.extractContextInto(container, newContext._basis); |
| return newContext; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext) => _basis.extractContextInto(container, newContext); |
| /** |
| * @return the underlying {@link AnalysisContext}. |
| */ |
| AnalysisContext get basis => _basis; |
| Element getElement(ElementLocation location) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getElement"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.getElement(location); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| AnalysisErrorInfo getErrors(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getErrors"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| AnalysisErrorInfo ret = _basis.getErrors(source); |
| if (ret != null) { |
| instrumentation.metric2("Errors-count", ret.errors.length); |
| } |
| return ret; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| HtmlElement getHtmlElement(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getHtmlElement"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.getHtmlElement(source); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| List<Source> getHtmlFilesReferencing(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getHtmlFilesReferencing"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| List<Source> ret = _basis.getHtmlFilesReferencing(source); |
| if (ret != null) { |
| instrumentation.metric2("Source-count", ret.length); |
| } |
| return ret; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| List<Source> get htmlSources { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getHtmlSources"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| List<Source> ret = _basis.htmlSources; |
| if (ret != null) { |
| instrumentation.metric2("Source-count", ret.length); |
| } |
| return ret; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| SourceKind getKindOf(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getKindOf"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.getKindOf(source); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| List<Source> get launchableClientLibrarySources { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getLaunchableClientLibrarySources"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| List<Source> ret = _basis.launchableClientLibrarySources; |
| if (ret != null) { |
| instrumentation.metric2("Source-count", ret.length); |
| } |
| return ret; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| List<Source> get launchableServerLibrarySources { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getLaunchableServerLibrarySources"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| List<Source> ret = _basis.launchableServerLibrarySources; |
| if (ret != null) { |
| instrumentation.metric2("Source-count", ret.length); |
| } |
| return ret; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| List<Source> getLibrariesContaining(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getLibrariesContaining"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| List<Source> ret = _basis.getLibrariesContaining(source); |
| if (ret != null) { |
| instrumentation.metric2("Source-count", ret.length); |
| } |
| return ret; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| LibraryElement getLibraryElement(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getLibraryElement"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.getLibraryElement(source); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| List<Source> get librarySources { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getLibrarySources"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| List<Source> ret = _basis.librarySources; |
| if (ret != null) { |
| instrumentation.metric2("Source-count", ret.length); |
| } |
| return ret; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| LineInfo getLineInfo(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getLineInfo"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.getLineInfo(source); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| Namespace getPublicNamespace(LibraryElement library) => _basis.getPublicNamespace(library); |
| Namespace getPublicNamespace2(Source source) => _basis.getPublicNamespace2(source); |
| CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getResolvedCompilationUnit"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.getResolvedCompilationUnit(unitSource, library); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source librarySource) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getResolvedCompilationUnit"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.getResolvedCompilationUnit2(unitSource, librarySource); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| SourceFactory get sourceFactory { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getSourceFactory"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.sourceFactory; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| bool isClientLibrary(Source librarySource) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-isClientLibrary"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.isClientLibrary(librarySource); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| bool isServerLibrary(Source librarySource) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-isServerLibrary"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.isServerLibrary(librarySource); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| void mergeContext(AnalysisContext context) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-mergeContext"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| if (context is InstrumentedAnalysisContextImpl) { |
| context = ((context as InstrumentedAnalysisContextImpl))._basis; |
| } |
| _basis.mergeContext(context); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| CompilationUnit parseCompilationUnit(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-parseCompilationUnit"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.parseCompilationUnit(source); |
| } on AnalysisException catch (e) { |
| recordAnalysisException(instrumentation, e); |
| throw e; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| HtmlUnit parseHtmlUnit(Source source) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-parseHtmlUnit"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.parseHtmlUnit(source); |
| } on AnalysisException catch (e) { |
| recordAnalysisException(instrumentation, e); |
| throw e; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| List<ChangeNotice> performAnalysisTask() { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-performAnalysisTask"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| List<ChangeNotice> ret = _basis.performAnalysisTask(); |
| if (ret != null) { |
| instrumentation.metric2("ChangeNotice-count", ret.length); |
| } |
| return ret; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| void recordLibraryElements(Map<Source, LibraryElement> elementMap) { |
| _basis.recordLibraryElements(elementMap); |
| } |
| void recordResolutionErrors(Source source, List<AnalysisError> errors, LineInfo lineInfo) { |
| _basis.recordResolutionErrors(source, errors, lineInfo); |
| } |
| void recordResolvedCompilationUnit(Source source, CompilationUnit unit) { |
| _basis.recordResolvedCompilationUnit(source, unit); |
| } |
| CompilationUnit resolveCompilationUnit(Source unitSource, LibraryElement library) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-resolveCompilationUnit"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.resolveCompilationUnit(unitSource, library); |
| } on AnalysisException catch (e) { |
| recordAnalysisException(instrumentation, e); |
| throw e; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-resolveCompilationUnit"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.resolveCompilationUnit2(unitSource, librarySource); |
| } on AnalysisException catch (e) { |
| recordAnalysisException(instrumentation, e); |
| throw e; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| HtmlUnit resolveHtmlUnit(Source htmlSource) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-resolveHtmlUnit"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.resolveHtmlUnit(htmlSource); |
| } on AnalysisException catch (e) { |
| recordAnalysisException(instrumentation, e); |
| throw e; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| void setContents(Source source, String contents) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-setContents"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| _basis.setContents(source, contents); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| void set sourceFactory(SourceFactory factory) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-setSourceFactory"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| _basis.sourceFactory = factory; |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| Iterable<Source> sourcesToResolve(List<Source> changedSources) { |
| InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-sourcesToResolve"); |
| try { |
| instrumentation.metric3("contextId", _contextId); |
| return _basis.sourcesToResolve(changedSources); |
| } finally { |
| instrumentation.log(); |
| } |
| } |
| } |
| /** |
| * The interface {@code InternalAnalysisContext} defines additional behavior for an analysis context |
| * that is required by internal users of the context. |
| */ |
| abstract class InternalAnalysisContext implements AnalysisContext { |
| /** |
| * Add the given source with the given information to this context. |
| * @param source the source to be added |
| * @param info the information about the source |
| */ |
| void addSourceInfo(Source source, SourceInfo info); |
| /** |
| * Return an AST structure corresponding to the given source, but ensure that the structure has |
| * not already been resolved and will not be resolved by any other threads or in any other |
| * library. |
| * @param source the compilation unit for which an AST structure should be returned |
| * @return the AST structure representing the content of the source |
| * @throws AnalysisException if the analysis could not be performed |
| */ |
| CompilationUnit computeResolvableCompilationUnit(Source source); |
| /** |
| * Initialize the specified context by removing the specified sources from the receiver and adding |
| * them to the specified context. |
| * @param container the container containing sources that should be removed from this context and |
| * added to the returned context |
| * @param newContext the context to be initialized |
| * @return the analysis context that was initialized |
| */ |
| InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext); |
| /** |
| * Return a namespace containing mappings for all of the public names defined by the given |
| * library. |
| * @param library the library whose public namespace is to be returned |
| * @return the public namespace of the given library |
| */ |
| Namespace getPublicNamespace(LibraryElement library); |
| /** |
| * Return a namespace containing mappings for all of the public names defined by the library |
| * defined by the given source. |
| * @param source the source defining the library whose public namespace is to be returned |
| * @return the public namespace corresponding to the library defined by the given source |
| * @throws AnalysisException if the public namespace could not be computed |
| */ |
| Namespace getPublicNamespace2(Source source); |
| /** |
| * Given a table mapping the source for the libraries represented by the corresponding elements to |
| * the elements representing the libraries, record those mappings. |
| * @param elementMap a table mapping the source for the libraries represented by the elements to |
| * the elements representing the libraries |
| */ |
| void recordLibraryElements(Map<Source, LibraryElement> elementMap); |
| /** |
| * Give the resolution errors and line info associated with the given source, add the information |
| * to the cache. |
| * @param source the source with which the information is associated |
| * @param errors the resolution errors associated with the source |
| * @param lineInfo the line information associated with the source |
| */ |
| void recordResolutionErrors(Source source, List<AnalysisError> errors, LineInfo lineInfo); |
| /** |
| * Give the resolved compilation unit associated with the given source, add the unit to the cache. |
| * @param source the source with which the unit is associated |
| * @param unit the compilation unit associated with the source |
| */ |
| void recordResolvedCompilationUnit(Source source, CompilationUnit unit); |
| } |
| /** |
| * Instances of the class {@code LibraryInfo} maintain the information cached by an analysis context |
| * about an individual library. |
| * @coverage dart.engine |
| */ |
| class LibraryInfo extends CompilationUnitInfo { |
| /** |
| * Mask indicating that this library is launchable: that the file has a main method. |
| */ |
| static int _LAUNCHABLE = 1 << 1; |
| /** |
| * Mask indicating that the library is client code: that the library depends on the html library. |
| * If the library is not "client code", then it is referenced as "server code". |
| */ |
| static int _CLIENT_CODE = 1 << 2; |
| /** |
| * The state of the cached library element. |
| */ |
| CacheState _elementState = CacheState.INVALID; |
| /** |
| * The element representing the library, or {@code null} if the element is not currently cached. |
| */ |
| LibraryElement _element; |
| /** |
| * The state of the cached unit sources. |
| */ |
| CacheState _unitSourcesState = CacheState.INVALID; |
| /** |
| * The sources of the compilation units that compose the library, including both the defining |
| * compilation unit and any parts. |
| */ |
| List<Source> _unitSources = Source.EMPTY_ARRAY; |
| /** |
| * The state of the cached public namespace. |
| */ |
| CacheState _publicNamespaceState = CacheState.INVALID; |
| /** |
| * The public namespace of the library, or {@code null} if the namespace is not currently cached. |
| */ |
| Namespace _publicNamespace; |
| /** |
| * The state of the cached client/ server flag. |
| */ |
| CacheState _clientServerState = CacheState.INVALID; |
| /** |
| * The state of the cached launchable flag. |
| */ |
| CacheState _launchableState = CacheState.INVALID; |
| /** |
| * An integer holding bit masks such as {@link #LAUNCHABLE} and {@link #CLIENT_CODE}. |
| */ |
| int _bitmask = 0; |
| /** |
| * Initialize a newly created information holder to be empty. |
| */ |
| LibraryInfo() : super() { |
| } |
| /** |
| * Remove the library element from the cache. |
| */ |
| void clearElement() { |
| _element = null; |
| _elementState = CacheState.FLUSHED; |
| } |
| /** |
| * Remove the public namespace from the cache. |
| */ |
| void clearPublicNamespace() { |
| _publicNamespace = null; |
| _publicNamespaceState = CacheState.FLUSHED; |
| } |
| LibraryInfo copy() { |
| LibraryInfo copy = new LibraryInfo(); |
| copy.copyFrom(this); |
| return copy; |
| } |
| /** |
| * Return the element representing the library, or {@code null} if the element is not currently |
| * cached. |
| * @return the element representing the library |
| */ |
| LibraryElement get element => _element; |
| SourceKind get kind => SourceKind.LIBRARY; |
| /** |
| * Return the public namespace of the library, or {@code null} if the namespace is not currently |
| * cached. |
| * @return the public namespace of the library |
| */ |
| Namespace get publicNamespace => _publicNamespace; |
| /** |
| * Return the sources of the compilation units that compose the library, including both the |
| * defining compilation unit and any parts. |
| * @return the sources of the compilation units that compose the library |
| */ |
| List<Source> get unitSources => _unitSources; |
| /** |
| * Return {@code true} if the client/ server flag needs to be recomputed. |
| * @return {@code true} if the client/ server flag needs to be recomputed |
| */ |
| bool hasInvalidClientServer() => identical(_clientServerState, CacheState.INVALID); |
| /** |
| * Return {@code true} if the library element needs to be recomputed. |
| * @return {@code true} if the library element needs to be recomputed |
| */ |
| bool hasInvalidElement() => identical(_elementState, CacheState.INVALID); |
| /** |
| * Return {@code true} if the launchable flag needs to be recomputed. |
| * @return {@code true} if the launchable flag needs to be recomputed |
| */ |
| bool hasInvalidLaunchable() => identical(_launchableState, CacheState.INVALID); |
| /** |
| * Return {@code true} if the public namespace needs to be recomputed. |
| * @return {@code true} if the public namespace needs to be recomputed |
| */ |
| bool hasInvalidPublicNamespace() => identical(_publicNamespaceState, CacheState.INVALID); |
| /** |
| * Mark the client/ server flag as needing to be recomputed. |
| */ |
| void invalidateClientServer() { |
| _clientServerState = CacheState.INVALID; |
| _bitmask &= ~_CLIENT_CODE; |
| } |
| /** |
| * Mark the library element as needing to be recomputed. |
| */ |
| void invalidateElement() { |
| _elementState = CacheState.INVALID; |
| _element = null; |
| } |
| /** |
| * Mark the launchable flag as needing to be recomputed. |
| */ |
| void invalidateLaunchable() { |
| _launchableState = CacheState.INVALID; |
| _bitmask &= ~_LAUNCHABLE; |
| } |
| /** |
| * Mark the public namespace as needing to be recomputed. |
| */ |
| void invalidatePublicNamespace() { |
| _publicNamespaceState = CacheState.INVALID; |
| _publicNamespace = null; |
| } |
| /** |
| * Mark the compilation unit sources as needing to be recomputed. |
| */ |
| void invalidateUnitSources() { |
| _unitSourcesState = CacheState.INVALID; |
| _unitSources = Source.EMPTY_ARRAY; |
| } |
| /** |
| * Return {@code true} if this library is client based code: the library depends on the html |
| * library. |
| * @return {@code true} if this library is client based code: the library depends on the html |
| * library |
| */ |
| bool isClient() => (_bitmask & _CLIENT_CODE) != 0; |
| /** |
| * Return {@code true} if this library is launchable: the file includes a main method. |
| * @return {@code true} if this library is launchable: the file includes a main method |
| */ |
| bool isLaunchable() => (_bitmask & _LAUNCHABLE) != 0; |
| /** |
| * Return {@code true} if this library is server based code: the library does not depends on the |
| * html library. |
| * @return {@code true} if this library is server based code: the library does not depends on the |
| * html library |
| */ |
| bool isServer() => (_bitmask & _CLIENT_CODE) == 0; |
| /** |
| * Sets the value of the client/ server flag. |
| * <p> |
| * <b>Note:</b> Do not use this method to invalidate the flag, use{@link #invalidateClientServer()}. |
| * @param isClient the new value of the client flag |
| */ |
| void set client(bool isClient) { |
| if (isClient) { |
| _bitmask |= _CLIENT_CODE; |
| } else { |
| _bitmask &= ~_CLIENT_CODE; |
| } |
| _clientServerState = CacheState.VALID; |
| } |
| /** |
| * Set the element representing the library to the given element. |
| * <p> |
| * <b>Note:</b> Do not use this method to clear or invalidate the element. Use either{@link #clearElement()} or {@link #invalidateElement()}. |
| * @param element the element representing the library |
| */ |
| void set element(LibraryElement element2) { |
| this._element = element2; |
| _elementState = CacheState.VALID; |
| } |
| /** |
| * Sets the value of the launchable flag. |
| * <p> |
| * <b>Note:</b> Do not use this method to invalidate the flag, use {@link #invalidateLaunchable()}. |
| * @param isClient the new value of the client flag |
| */ |
| void set launchable(bool launchable2) { |
| if (launchable2) { |
| _bitmask |= _LAUNCHABLE; |
| } else { |
| _bitmask &= ~_LAUNCHABLE; |
| } |
| _launchableState = CacheState.VALID; |
| } |
| /** |
| * Set the public namespace of the library to the given namespace. |
| * <p> |
| * <b>Note:</b> Do not use this method to clear or invalidate the element. Use either{@link #clearPublicNamespace()} or {@link #invalidatePublicNamespace()}. |
| * @param namespace the public namespace of the library |
| */ |
| void set publicNamespace(Namespace namespace) { |
| _publicNamespace = namespace; |
| _publicNamespaceState = CacheState.VALID; |
| } |
| /** |
| * Set the sources of the compilation units that compose the library to the given sources. |
| * @param sources the sources of the compilation units that compose the library |
| */ |
| void set unitSources(List<Source> sources) { |
| _unitSourcesState = CacheState.VALID; |
| _unitSources = sources; |
| } |
| void copyFrom(SourceInfo info) { |
| super.copyFrom(info); |
| } |
| } |
| /** |
| * Instances of the class {@code RecordingErrorListener} implement an error listener that will |
| * record the errors that are reported to it in a way that is appropriate for caching those errors |
| * within an analysis context. |
| * @coverage dart.engine |
| */ |
| class RecordingErrorListener implements AnalysisErrorListener { |
| /** |
| * A HashMap of lists containing the errors that were collected, keyed by each {@link Source}. |
| */ |
| Map<Source, List<AnalysisError>> _errors = new Map<Source, List<AnalysisError>>(); |
| /** |
| * Answer the errors collected by the listener. |
| * @return an array of errors (not {@code null}, contains no {@code null}s) |
| */ |
| List<AnalysisError> get errors { |
| Set<MapEntry<Source, List<AnalysisError>>> entrySet2 = getMapEntrySet(_errors); |
| if (entrySet2.length == 0) { |
| return AnalysisError.NO_ERRORS; |
| } |
| List<AnalysisError> resultList = new List<AnalysisError>(); |
| for (MapEntry<Source, List<AnalysisError>> entry in entrySet2) { |
| resultList.addAll(entry.getValue()); |
| } |
| return new List.from(resultList); |
| } |
| /** |
| * Answer the errors collected by the listener for some passed {@link Source}. |
| * @param source some {@link Source} for which the caller wants the set of {@link AnalysisError}s |
| * collected by this listener |
| * @return the errors collected by the listener for the passed {@link Source} |
| */ |
| List<AnalysisError> getErrors2(Source source) { |
| List<AnalysisError> errorsForSource = _errors[source]; |
| if (errorsForSource == null) { |
| return AnalysisError.NO_ERRORS; |
| } else { |
| return new List.from(errorsForSource); |
| } |
| } |
| void onError(AnalysisError event) { |
| Source source2 = event.source; |
| List<AnalysisError> errorsForSource = _errors[source2]; |
| if (_errors[source2] == null) { |
| errorsForSource = new List<AnalysisError>(); |
| _errors[source2] = errorsForSource; |
| } |
| errorsForSource.add(event); |
| } |
| } |
| /** |
| * Instances of the class {@code ResolutionEraser} remove any resolution information from an AST |
| * structure when used to visit that structure. |
| */ |
| class ResolutionEraser extends GeneralizingASTVisitor<Object> { |
| Object visitAssignmentExpression(AssignmentExpression node) { |
| node.element = null; |
| return super.visitAssignmentExpression(node); |
| } |
| Object visitBinaryExpression(BinaryExpression node) { |
| node.element = null; |
| return super.visitBinaryExpression(node); |
| } |
| Object visitCompilationUnit(CompilationUnit node) { |
| node.element = null; |
| return super.visitCompilationUnit(node); |
| } |
| Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| node.element = null; |
| return super.visitConstructorDeclaration(node); |
| } |
| Object visitConstructorName(ConstructorName node) { |
| node.element = null; |
| return super.visitConstructorName(node); |
| } |
| Object visitDirective(Directive node) { |
| node.element = null; |
| return super.visitDirective(node); |
| } |
| Object visitExpression(Expression node) { |
| node.staticType = null; |
| node.propagatedType = null; |
| return super.visitExpression(node); |
| } |
| Object visitFunctionExpression(FunctionExpression node) { |
| node.element = null; |
| return super.visitFunctionExpression(node); |
| } |
| Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| node.element = null; |
| return super.visitFunctionExpressionInvocation(node); |
| } |
| Object visitIndexExpression(IndexExpression node) { |
| node.element = null; |
| return super.visitIndexExpression(node); |
| } |
| Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
| node.element = null; |
| return super.visitInstanceCreationExpression(node); |
| } |
| Object visitPostfixExpression(PostfixExpression node) { |
| node.element = null; |
| return super.visitPostfixExpression(node); |
| } |
| Object visitPrefixExpression(PrefixExpression node) { |
| node.element = null; |
| return super.visitPrefixExpression(node); |
| } |
| Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) { |
| node.element = null; |
| return super.visitRedirectingConstructorInvocation(node); |
| } |
| Object visitSimpleIdentifier(SimpleIdentifier node) { |
| node.element = null; |
| return super.visitSimpleIdentifier(node); |
| } |
| Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| node.element = null; |
| return super.visitSuperConstructorInvocation(node); |
| } |
| } |
| /** |
| * Instances of the class {@code SourceInfo} maintain the information cached by an analysis context |
| * about an individual source. |
| * @coverage dart.engine |
| */ |
| abstract class SourceInfo { |
| /** |
| * The state of the cached line information. |
| */ |
| CacheState _lineInfoState = CacheState.INVALID; |
| /** |
| * The line information computed for the source, or {@code null} if the line information is not |
| * currently cached. |
| */ |
| LineInfo _lineInfo; |
| /** |
| * Initialize a newly created information holder to be empty. |
| */ |
| SourceInfo() : super() { |
| } |
| /** |
| * Remove the line information from the cache. |
| */ |
| void clearLineInfo() { |
| _lineInfo = null; |
| _lineInfoState = CacheState.FLUSHED; |
| } |
| /** |
| * Return a copy of this information holder. |
| * @return a copy of this information holder |
| */ |
| SourceInfo copy(); |
| /** |
| * Return the kind of the source, or {@code null} if the kind is not currently cached. |
| * @return the kind of the source |
| */ |
| SourceKind get kind; |
| /** |
| * Return the line information computed for the source, or {@code null} if the line information is |
| * not currently cached. |
| * @return the line information computed for the source |
| */ |
| LineInfo get lineInfo => _lineInfo; |
| /** |
| * Return {@code true} if the line information needs to be recomputed. |
| * @return {@code true} if the line information needs to be recomputed |
| */ |
| bool hasInvalidLineInfo() => identical(_lineInfoState, CacheState.INVALID); |
| /** |
| * Mark the line information as needing to be recomputed. |
| */ |
| void invalidateLineInfo() { |
| _lineInfoState = CacheState.INVALID; |
| _lineInfo = null; |
| } |
| /** |
| * Set the line information for the source to the given line information. |
| * <p> |
| * <b>Note:</b> Do not use this method to clear or invalidate the element. Use either{@link #clearLineInfo()} or {@link #invalidateLineInfo()}. |
| * @param info the line information for the source |
| */ |
| void set lineInfo(LineInfo info) { |
| _lineInfo = info; |
| _lineInfoState = CacheState.VALID; |
| } |
| /** |
| * Copy the information from the given information holder. |
| * @param info the information holder from which information will be copied |
| */ |
| void copyFrom(SourceInfo info) { |
| _lineInfoState = info._lineInfoState; |
| _lineInfo = info._lineInfo; |
| } |
| } |
| /** |
| * The interface {@code Logger} defines the behavior of objects that can be used to receive |
| * information about errors within the analysis engine. Implementations usually write this |
| * information to a file, but can also record the information for later use (such as during testing) |
| * or even ignore the information. |
| * @coverage dart.engine.utilities |
| */ |
| abstract class Logger { |
| static Logger NULL = new Logger_NullLogger(); |
| /** |
| * Log the given message as an error. |
| * @param message an explanation of why the error occurred or what it means |
| */ |
| void logError(String message); |
| /** |
| * Log the given exception as one representing an error. |
| * @param message an explanation of why the error occurred or what it means |
| * @param exception the exception being logged |
| */ |
| void logError2(String message, Exception exception); |
| /** |
| * Log the given exception as one representing an error. |
| * @param exception the exception being logged |
| */ |
| void logError3(Exception exception); |
| /** |
| * Log the given informational message. |
| * @param message an explanation of why the error occurred or what it means |
| * @param exception the exception being logged |
| */ |
| void logInformation(String message); |
| /** |
| * Log the given exception as one representing an informational message. |
| * @param message an explanation of why the error occurred or what it means |
| * @param exception the exception being logged |
| */ |
| void logInformation2(String message, Exception exception); |
| } |
| /** |
| * Implementation of {@link Logger} that does nothing. |
| */ |
| class Logger_NullLogger implements Logger { |
| void logError(String message) { |
| } |
| void logError2(String message, Exception exception) { |
| } |
| void logError3(Exception exception) { |
| } |
| void logInformation(String message) { |
| } |
| void logInformation2(String message, Exception exception) { |
| } |
| } |