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

Unified Diff: pkg/analyzer_experimental/lib/src/generated/engine.dart

Issue 23461019: New analyzer_experimental snapshot. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer_experimental/lib/src/generated/engine.dart
diff --git a/pkg/analyzer_experimental/lib/src/generated/engine.dart b/pkg/analyzer_experimental/lib/src/generated/engine.dart
index 909e4f7b03aac67c00b1051740ca73590d472436..4c6d3d79909db707046566e0d3ecb381cbe6cc97 100644
--- a/pkg/analyzer_experimental/lib/src/generated/engine.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/engine.dart
@@ -82,16 +82,26 @@ class AnalysisEngine {
Logger _logger = Logger.NULL;
/**
+ * A flag indicating whether the new analysis context should be created.
+ */
+ bool _useExperimentalContext = false;
+
+ /**
* Create a new context in which analysis can be performed.
*
* @return the analysis context that was created
*/
AnalysisContext createAnalysisContext() {
if (Instrumentation.isNullLogger) {
+ if (_useExperimentalContext) {
+ return new DelegatingAnalysisContextImpl2();
+ }
return new DelegatingAnalysisContextImpl();
- } else {
- return new InstrumentedAnalysisContextImpl.con1(new DelegatingAnalysisContextImpl());
}
+ if (_useExperimentalContext) {
+ return new InstrumentedAnalysisContextImpl.con1(new DelegatingAnalysisContextImpl2());
+ }
+ return new InstrumentedAnalysisContextImpl.con1(new DelegatingAnalysisContextImpl());
}
/**
@@ -102,6 +112,13 @@ class AnalysisEngine {
Logger get logger => _logger;
/**
+ * Return `true` if the new analysis context should be created.
+ *
+ * @return `true` if the new analysis context should be created
+ */
+ bool get useExperimentalContext => _useExperimentalContext;
+
+ /**
* Set the logger that should receive information about errors within the analysis engine to the
* given logger.
*
@@ -111,6 +128,15 @@ class AnalysisEngine {
void set logger(Logger logger2) {
this._logger = logger2 == null ? Logger.NULL : logger2;
}
+
+ /**
+ * Set whether the new analysis context should be created to the given flag.
+ *
+ * @param use `true` if the new analysis context should be created
+ */
+ void set useExperimentalContext(bool use) {
+ _useExperimentalContext = use;
+ }
}
/**
* Container with statistics about the [AnalysisContext].
@@ -523,6 +549,8 @@ abstract class AnalysisContext {
/**
* Parse and resolve a single source within the given context to produce a fully resolved AST.
+ * Return the resolved AST structure, or `null` if the source could not be either parsed or
+ * resolved.
*
* @param unitSource the source to be parsed and resolved
* @param librarySource the source of the defining compilation unit of the library containing the
@@ -917,6 +945,15 @@ class AnalysisCache {
}
/**
+ * Remove all information related to the given source from this cache.
+ *
+ * @param source the source to be removed
+ */
+ void remove(Source source) {
+ _sourceMap.remove(source);
+ }
+
+ /**
* Set the sources for which data should not be flushed to the given array.
*
* @param sources the sources for which data should not be flushed
@@ -1501,6 +1538,34 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
}
/**
+ * Record that an in-process parse has stopped without recording results because the results were
+ * invalidated before they could be recorded.
+ */
+ void recordParseNotInProcess() {
+ if (identical(getState(SourceEntry.LINE_INFO), CacheState.IN_PROCESS)) {
+ setState(SourceEntry.LINE_INFO, CacheState.INVALID);
+ }
+ if (identical(_sourceKindState, CacheState.IN_PROCESS)) {
+ _sourceKindState = CacheState.INVALID;
+ }
+ if (identical(_parseErrorsState, CacheState.IN_PROCESS)) {
+ _parseErrorsState = CacheState.INVALID;
+ }
+ if (identical(_parsedUnitState, CacheState.IN_PROCESS)) {
+ _parsedUnitState = CacheState.INVALID;
+ }
+ if (identical(_exportedLibrariesState, CacheState.IN_PROCESS)) {
+ _exportedLibrariesState = CacheState.INVALID;
+ }
+ if (identical(_importedLibrariesState, CacheState.IN_PROCESS)) {
+ _importedLibrariesState = CacheState.INVALID;
+ }
+ if (identical(_includedPartsState, CacheState.IN_PROCESS)) {
+ _includedPartsState = CacheState.INVALID;
+ }
+ }
+
+ /**
* Record that an error occurred while attempting to scan or parse the entry represented by this
* entry. This will set the state of all resolution-based information as being in error, but will
* not change the state of any parse results.
@@ -1517,6 +1582,26 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
}
/**
+ * Record that an in-process parse has stopped without recording results because the results were
+ * invalidated before they could be recorded.
+ */
+ void recordResolutionNotInProcess() {
+ if (identical(_elementState, CacheState.IN_PROCESS)) {
+ _elementState = CacheState.INVALID;
+ }
+ if (identical(_clientServerState, CacheState.IN_PROCESS)) {
+ _clientServerState = CacheState.INVALID;
+ }
+ if (identical(_launchableState, CacheState.IN_PROCESS)) {
+ _launchableState = CacheState.INVALID;
+ }
+ if (identical(_publicNamespaceState, CacheState.IN_PROCESS)) {
+ _publicNamespaceState = CacheState.INVALID;
+ }
+ _resolutionState.recordResolutionNotInProcess();
+ }
+
+ /**
* Remove any resolution information associated with this compilation unit being part of the given
* library, presumably because it is no longer part of the library.
*
@@ -1910,6 +1995,25 @@ class DartEntryImpl_ResolutionState {
}
/**
+ * Record that an in-process parse has stopped without recording results because the results
+ * were invalidated before they could be recorded.
+ */
+ void recordResolutionNotInProcess() {
+ if (identical(_resolvedUnitState, CacheState.IN_PROCESS)) {
+ _resolvedUnitState = CacheState.INVALID;
+ }
+ if (identical(_resolutionErrorsState, CacheState.IN_PROCESS)) {
+ _resolutionErrorsState = CacheState.INVALID;
+ }
+ if (identical(_hintsState, CacheState.IN_PROCESS)) {
+ _hintsState = CacheState.INVALID;
+ }
+ if (_nextState != null) {
+ _nextState.recordResolutionNotInProcess();
+ }
+ }
+
+ /**
* Write a textual representation of this state to the given builder. The result will only be
* used for debugging purposes.
*
@@ -2099,7 +2203,19 @@ class HtmlEntryImpl extends SourceEntryImpl implements HtmlEntry {
}
/**
- * Invalidate all of the resolution information associated with the compilation unit.
+ * Invalidate all of the information associated with the HTML file.
+ */
+ void invalidateAllInformation() {
+ setState(SourceEntry.LINE_INFO, CacheState.INVALID);
+ _parsedUnit = null;
+ _parsedUnitState = CacheState.INVALID;
+ _referencedLibraries = Source.EMPTY_ARRAY;
+ _referencedLibrariesState = CacheState.INVALID;
+ invalidateAllResolutionInformation();
+ }
+
+ /**
+ * Invalidate all of the resolution information associated with the HTML file.
*/
void invalidateAllResolutionInformation() {
_element = null;
@@ -2109,6 +2225,15 @@ class HtmlEntryImpl extends SourceEntryImpl implements HtmlEntry {
_hints = AnalysisError.NO_ERRORS;
_hintsState = CacheState.INVALID;
}
+
+ /**
+ * Record that an error was encountered while attempting to resolve the source associated with
+ * this entry.
+ */
+ void recordResolutionError() {
+ setState(HtmlEntry.ELEMENT, CacheState.ERROR);
+ setState(HtmlEntry.RESOLUTION_ERRORS, CacheState.ERROR);
+ }
void setState(DataDescriptor descriptor, CacheState state) {
if (identical(descriptor, HtmlEntry.ELEMENT)) {
_element = updatedValue(state, _element, null);
@@ -2368,7 +2493,13 @@ class AnalysisContentStatisticsImpl implements AnalysisContentStatistics {
Iterable<AnalysisContentStatistics_CacheRow> items = _dataMap.values;
return new List.from(items);
}
- void putCacheItem(DataDescriptor rowDesc, CacheState state) {
+ void putCacheItem(DartEntry dartEntry, DataDescriptor descriptor) {
+ putCacheItem3(descriptor, dartEntry.getState(descriptor));
+ }
+ void putCacheItem2(DartEntry dartEntry, Source librarySource, DataDescriptor descriptor) {
+ putCacheItem3(descriptor, dartEntry.getState2(descriptor, librarySource));
+ }
+ void putCacheItem3(DataDescriptor rowDesc, CacheState state) {
String rowName = rowDesc.toString();
AnalysisContentStatisticsImpl_CacheRowImpl row = _dataMap[rowName] as AnalysisContentStatisticsImpl_CacheRowImpl;
if (row == null) {
@@ -2426,7 +2557,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* object.
*/
static void putStatCacheItem(AnalysisContentStatisticsImpl statistics, DartEntry dartEntry, Source librarySource, DataDescriptor key) {
- statistics.putCacheItem(key, dartEntry.getState2(key, librarySource));
+ statistics.putCacheItem3(key, dartEntry.getState2(key, librarySource));
}
/**
@@ -2434,7 +2565,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* statistics object.
*/
static void putStatCacheItem2(AnalysisContentStatisticsImpl statistics, SourceEntry entry, DataDescriptor key) {
- statistics.putCacheItem(key, entry.getState(key));
+ statistics.putCacheItem3(key, entry.getState(key));
}
/**
@@ -2515,6 +2646,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* in Dart.
*/
static String _TYPE_DART = "application/dart";
+
+ /**
+ * Initialize a newly created analysis context.
+ */
+ AnalysisContextImpl() : super() {
+ if (AnalysisEngine.instance.useExperimentalContext) {
+ throw new RuntimeException("Should not be creating an instance of AnalysisContextImpl");
+ }
+ }
void addSourceInfo(Source source, SourceEntry info) {
_sourceMap[source] = info;
}
@@ -2686,6 +2826,18 @@ class AnalysisContextImpl implements InternalAnalysisContext {
internalParseDart(source);
}
}
+ ResolvableHtmlUnit computeResolvableHtmlUnit(Source source) {
+ HtmlEntry htmlEntry = getReadableHtmlEntry(source);
+ if (htmlEntry == null) {
+ throw new AnalysisException.con1("computeResolvableHtmlUnit invoked for non-HTML file: ${source.fullName}");
+ }
+ htmlEntry = internalCacheHtmlParseData(source, htmlEntry, [HtmlEntry.PARSED_UNIT]);
+ HtmlUnit unit = htmlEntry.getValue(HtmlEntry.PARSED_UNIT);
+ if (unit == null) {
+ throw new AnalysisException.con1("Internal error: computeResolvableHtmlUnit could not parse ${source.fullName}");
+ }
+ return new ResolvableHtmlUnit(htmlEntry.modificationTime, unit);
+ }
AnalysisContext extractContext(SourceContainer container) => extractContextInto(container, AnalysisEngine.instance.createAnalysisContext() as InternalAnalysisContext);
InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext) {
List<Source> sourcesToRemove = new List<Source>();
@@ -4826,1278 +4978,4129 @@ class Source_ContentReceiver_7 implements Source_ContentReceiver {
}
}
/**
- * Instances of the class `AnalysisErrorInfoImpl` represent the analysis errors and line info
- * associated with a source.
+ * Instances of the class `AnalysisContextImpl` implement an [AnalysisContext].
+ *
+ * @coverage dart.engine
*/
-class AnalysisErrorInfoImpl implements AnalysisErrorInfo {
+class AnalysisContextImpl2 implements InternalAnalysisContext {
/**
- * The analysis errors associated with a source, or `null` if there are no errors.
+ * The set of analysis options controlling the behavior of this context.
*/
- List<AnalysisError> _errors;
+ AnalysisOptions _options = new AnalysisOptionsImpl();
/**
- * The line information associated with the errors, or `null` if there are no errors.
+ * The source factory used to create the sources that can be analyzed in this context.
*/
- LineInfo _lineInfo;
+ SourceFactory _sourceFactory;
/**
- * 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
+ * A table mapping the sources known to the context to the information known about the source.
*/
- AnalysisErrorInfoImpl(List<AnalysisError> errors, LineInfo lineInfo) {
- this._errors = errors;
- this._lineInfo = lineInfo;
- }
+ AnalysisCache _cache = new AnalysisCache(_MAX_CACHE_SIZE);
/**
- * Return the errors of analysis, or `null` if there were no errors.
- *
- * @return the errors as a result of the analysis
+ * A table mapping sources to the change notices that are waiting to be returned related to that
+ * source.
*/
- List<AnalysisError> get errors => _errors;
+ Map<Source, ChangeNoticeImpl> _pendingNotices = new Map<Source, ChangeNoticeImpl>();
/**
- * Return the line information associated with the errors, or `null` if there were no
- * errors.
+ * The object used to synchronize access to all of the caches. The rules related to the use of
+ * this lock object are
+ *
+ * * no analysis work is done while holding the lock, and
+ * * no analysis results can be recorded unless we have obtained the lock and validated that the
+ * results are for the same version (modification time) of the source as our current cache
+ * content.
*
- * @return the line information associated with the errors
*/
- LineInfo get lineInfo => _lineInfo;
-}
-/**
- * Instances of the class `AnalysisOptions` represent a set of analysis options used to
- * control the behavior of an analysis context.
- */
-class AnalysisOptionsImpl implements AnalysisOptions {
+ Object _cacheLock = new Object();
/**
- * A flag indicating whether analysis is to use strict mode. In strict mode, error reporting is
- * based exclusively on the static type information.
+ * The object used to record the results of performing an analysis task.
*/
- bool _strictMode = true;
+ AnalysisContextImpl2_AnalysisTaskResultRecorder _resultRecorder;
/**
- * A flag indicating whether analysis is to generate hint results (e.g. type inference based
- * information and pub best practices).
+ * The maximum number of sources for which data should be kept in the cache.
*/
- bool _hint = true;
- bool get hint => _hint;
+ static int _MAX_CACHE_SIZE = 64;
/**
- * Return `true` if analysis is to use strict mode. In strict mode, error reporting is based
- * exclusively on the static type information.
+ * The maximum number of sources that can be on the priority list. This <b>must</b> be less than
+ * the [MAX_CACHE_SIZE] in order to prevent an infinite loop in performAnalysisTask().
*
- * @return `true` if analysis is to use strict mode
+ * @see #setAnalysisPriorityOrder(List)
*/
- bool get strictMode => _strictMode;
+ static int _MAX_PRIORITY_LIST_SIZE = _MAX_CACHE_SIZE - 4;
/**
- * Set whether analysis is to generate hint results (e.g. type inference based information and pub
- * best practices).
- *
- * @param hint `true` if analysis is to generate hint results
+ * Initialize a newly created analysis context.
*/
- void set hint(bool hint2) {
- this._hint = hint2;
+ AnalysisContextImpl2() : super() {
+ _resultRecorder = new AnalysisContextImpl2_AnalysisTaskResultRecorder(this);
}
-
- /**
- * Set whether analysis is to use strict mode to the given value. In strict mode, error reporting
- * is based exclusively on the static type information.
- *
- * @param isStrict `true` if analysis is to use strict mode
- */
- void set strictMode(bool isStrict) {
- _strictMode = isStrict;
+ void addSourceInfo(Source source, SourceEntry info) {
+ _cache.put(source, info);
}
-}
-/**
- * The enumeration `CacheState` defines the possible states of cached data.
- */
-class CacheState extends Enum<CacheState> {
-
- /**
- * The data is not in the cache and the last time an attempt was made to compute the data an
- * exception occurred, making it pointless to attempt.
- *
- * Valid Transitions:
- *
- * * [INVALID] if a source was modified that might cause the data to be computable
- *
- */
- static final CacheState ERROR = new CacheState('ERROR', 0);
-
- /**
- * The data is not in the cache because it was flushed from the cache in order to control memory
- * usage. If the data is recomputed, results do not need to be reported.
- *
- * Valid Transitions:
- *
- * * [IN_PROCESS] if the data is being recomputed
- * * [INVALID] if a source was modified that causes the data to need to be recomputed
- *
- */
- static final CacheState FLUSHED = new CacheState('FLUSHED', 1);
-
- /**
- * The data might or might not be in the cache but is in the process of being recomputed.
- *
- * Valid Transitions:
- *
- * * [ERROR] if an exception occurred while trying to compute the data
- * * [VALID] if the data was successfully computed and stored in the cache
- *
- */
- static final CacheState IN_PROCESS = new CacheState('IN_PROCESS', 2);
-
- /**
- * The data is not in the cache and needs to be recomputed so that results can be reported.
- *
- * Valid Transitions:
- *
- * * [IN_PROCESS] if an attempt is being made to recompute the data
- *
- */
- static final CacheState INVALID = new CacheState('INVALID', 3);
-
- /**
- * The data is in the cache and up-to-date.
- *
- * Valid Transitions:
- *
- * * [FLUSHED] if the data is removed in order to manage memory usage
- * * [INVALID] if a source was modified in such a way as to invalidate the previous data
- *
- */
- static final CacheState VALID = new CacheState('VALID', 4);
- static final List<CacheState> values = [ERROR, FLUSHED, IN_PROCESS, INVALID, VALID];
- CacheState(String name, int ordinal) : super(name, ordinal);
-}
-/**
- * Instances of the class `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 `null` if the AST was
- * not changed.
- */
- CompilationUnit _compilationUnit;
-
- /**
- * The errors that changed as a result of the analysis, or `null` if errors were not
- * changed.
- */
- List<AnalysisError> _errors;
-
- /**
- * The line information associated with the source, or `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 `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 `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 `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 `DelegatingAnalysisContextImpl` extend [AnalysisContextImpl
- ] to delegate sources to the appropriate analysis context. For instance, if the
- * source is in a system library then the analysis context from the [DartSdk] is used.
- *
- * @coverage dart.engine
- */
-class DelegatingAnalysisContextImpl extends AnalysisContextImpl {
-
- /**
- * This references the [InternalAnalysisContext] held onto by the [DartSdk] which is
- * used (instead of this [AnalysisContext]) for SDK sources. This field is set when
- * #setSourceFactory(SourceFactory) is called, and references the analysis context in the
- * [DartUriResolver] in the [SourceFactory], this analysis context assumes that there
- * will be such a resolver.
- */
- InternalAnalysisContext _sdkAnalysisContext;
- void addSourceInfo(Source source, SourceEntry info) {
- if (source.isInSystemLibrary) {
- _sdkAnalysisContext.addSourceInfo(source, info);
- } else {
- super.addSourceInfo(source, info);
+ void applyChanges(ChangeSet changeSet) {
+ if (changeSet.isEmpty) {
+ return;
}
- }
- List<AnalysisError> computeErrors(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeErrors(source);
- } else {
- return super.computeErrors(source);
+ {
+ List<Source> removedSources = new List<Source>.from(changeSet.removed);
+ for (SourceContainer container in changeSet.removedContainers) {
+ addSourcesInContainer(removedSources, container);
+ }
+ bool addedDartSource = false;
+ for (Source source in changeSet.added3) {
+ if (sourceAvailable(source)) {
+ addedDartSource = true;
+ }
+ }
+ for (Source source in changeSet.changed3) {
+ sourceChanged(source);
+ }
+ for (Source source in removedSources) {
+ sourceRemoved(source);
+ }
+ if (addedDartSource) {
+ for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
+ if (!mapEntry.getKey().isInSystemLibrary && mapEntry.getValue() is DartEntry) {
+ DartEntryImpl dartCopy = ((mapEntry.getValue() as DartEntry)).writableCopy;
+ dartCopy.invalidateAllResolutionInformation();
+ mapEntry.setValue(dartCopy);
+ }
+ }
+ }
}
}
- List<Source> computeExportedLibraries(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeExportedLibraries(source);
- } else {
- return super.computeExportedLibraries(source);
+ String computeDocumentationComment(Element element) {
+ if (element == null) {
+ return null;
}
- }
- HtmlElement computeHtmlElement(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeHtmlElement(source);
- } else {
- return super.computeHtmlElement(source);
+ Source source = element.source;
+ if (source == null) {
+ return null;
}
- }
- List<Source> computeImportedLibraries(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeImportedLibraries(source);
- } else {
- return super.computeImportedLibraries(source);
+ CompilationUnit unit = parseCompilationUnit(source);
+ if (unit == null) {
+ return null;
+ }
+ NodeLocator locator = new NodeLocator.con1(element.nameOffset);
+ ASTNode nameNode = locator.searchWithin(unit);
+ while (nameNode != null) {
+ if (nameNode is AnnotatedNode) {
+ Comment comment = ((nameNode as AnnotatedNode)).documentationComment;
+ if (comment == null) {
+ return null;
+ }
+ JavaStringBuilder builder = new JavaStringBuilder();
+ List<Token> tokens = comment.tokens;
+ for (int i = 0; i < tokens.length; i++) {
+ if (i > 0) {
+ builder.append('\n');
+ }
+ builder.append(tokens[i].lexeme);
+ }
+ return builder.toString();
+ }
+ nameNode = nameNode.parent;
}
+ return null;
}
- SourceKind computeKindOf(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeKindOf(source);
- } else {
- return super.computeKindOf(source);
+ List<AnalysisError> computeErrors(Source source) {
+ SourceEntry sourceEntry = getReadableSourceEntry(source);
+ if (sourceEntry is DartEntry) {
+ List<AnalysisError> errors = new List<AnalysisError>();
+ DartEntry dartEntry = sourceEntry as DartEntry;
+ ListUtilities.addAll(errors, getDartParseData(source, dartEntry, DartEntry.PARSE_ERRORS));
+ dartEntry = getReadableDartEntry(source);
+ if (identical(dartEntry.getValue(DartEntry.SOURCE_KIND), SourceKind.LIBRARY)) {
+ ListUtilities.addAll(errors, getDartResolutionData(source, source, dartEntry, DartEntry.RESOLUTION_ERRORS));
+ } else {
+ List<Source> libraries = getLibrariesContaining(source);
+ for (Source librarySource in libraries) {
+ ListUtilities.addAll(errors, getDartResolutionData(source, librarySource, dartEntry, DartEntry.RESOLUTION_ERRORS));
+ }
+ }
+ if (errors.isEmpty) {
+ return AnalysisError.NO_ERRORS;
+ }
+ return new List.from(errors);
+ } else if (sourceEntry is HtmlEntry) {
+ HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
+ return getHtmlResolutionData2(source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS);
}
+ return AnalysisError.NO_ERRORS;
}
- LibraryElement computeLibraryElement(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeLibraryElement(source);
- } else {
- return super.computeLibraryElement(source);
+ List<Source> computeExportedLibraries(Source source) => getDartParseData2(source, DartEntry.EXPORTED_LIBRARIES, Source.EMPTY_ARRAY);
+ HtmlElement computeHtmlElement(Source source) => getHtmlResolutionData(source, HtmlEntry.ELEMENT, null);
+ List<Source> computeImportedLibraries(Source source) => getDartParseData2(source, DartEntry.IMPORTED_LIBRARIES, Source.EMPTY_ARRAY);
+ SourceKind computeKindOf(Source source) {
+ SourceEntry sourceEntry = getReadableSourceEntry(source);
+ if (sourceEntry == null) {
+ return SourceKind.UNKNOWN;
+ } else if (sourceEntry is DartEntry) {
+ try {
+ return getDartParseData(source, sourceEntry as DartEntry, DartEntry.SOURCE_KIND);
+ } on AnalysisException catch (exception) {
+ return SourceKind.UNKNOWN;
+ }
}
+ return sourceEntry.kind;
}
+ LibraryElement computeLibraryElement(Source source) => getDartResolutionData2(source, source, DartEntry.ELEMENT, null);
LineInfo computeLineInfo(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeLineInfo(source);
- } else {
- return super.computeLineInfo(source);
+ SourceEntry sourceEntry = getReadableSourceEntry(source);
+ if (sourceEntry is HtmlEntry) {
+ return getHtmlParseData(source, SourceEntry.LINE_INFO, null);
+ } else if (sourceEntry is DartEntry) {
+ return getDartParseData2(source, SourceEntry.LINE_INFO, null);
}
+ return null;
}
ResolvableCompilationUnit computeResolvableCompilationUnit(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeResolvableCompilationUnit(source);
- } else {
- return super.computeResolvableCompilationUnit(source);
+ while (true) {
+ {
+ DartEntry dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("computeResolvableCompilationUnit for non-Dart: ${source.fullName}");
+ }
+ if (identical(dartEntry.getState(DartEntry.PARSED_UNIT), CacheState.ERROR)) {
+ throw new AnalysisException.con1("Internal error: computeResolvableCompilationUnit could not parse ${source.fullName}");
+ }
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ CompilationUnit unit = dartCopy.resolvableCompilationUnit;
+ if (unit != null) {
+ _cache.put(source, dartCopy);
+ return new ResolvableCompilationUnit(dartCopy.modificationTime, unit);
+ }
+ }
+ cacheDartParseData(source, getReadableDartEntry(source), DartEntry.PARSED_UNIT);
}
}
- AnalysisErrorInfo getErrors(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getErrors(source);
- } else {
- return super.getErrors(source);
+ ResolvableHtmlUnit computeResolvableHtmlUnit(Source source) {
+ HtmlEntry htmlEntry = getReadableHtmlEntry(source);
+ if (htmlEntry == null) {
+ throw new AnalysisException.con1("computeResolvableHtmlUnit invoked for non-HTML file: ${source.fullName}");
}
- }
- HtmlElement getHtmlElement(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getHtmlElement(source);
- } else {
- return super.getHtmlElement(source);
+ htmlEntry = cacheHtmlParseData(source, htmlEntry, HtmlEntry.PARSED_UNIT);
+ HtmlUnit unit = htmlEntry.getValue(HtmlEntry.PARSED_UNIT);
+ if (unit == null) {
+ throw new AnalysisException.con1("Internal error: computeResolvableHtmlUnit could not parse ${source.fullName}");
}
+ return new ResolvableHtmlUnit(htmlEntry.modificationTime, unit);
}
- List<Source> getHtmlFilesReferencing(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getHtmlFilesReferencing(source);
- } else {
- return super.getHtmlFilesReferencing(source);
+ AnalysisContext extractContext(SourceContainer container) => extractContextInto(container, AnalysisEngine.instance.createAnalysisContext() as InternalAnalysisContext);
+ InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext) {
+ List<Source> sourcesToRemove = new List<Source>();
+ {
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
+ Source source = entry.getKey();
+ if (container.contains(source)) {
+ sourcesToRemove.add(source);
+ newContext.addSourceInfo(source, entry.getValue().writableCopy);
+ }
+ }
}
+ return newContext;
}
- SourceKind getKindOf(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getKindOf(source);
- } else {
- return super.getKindOf(source);
+ AnalysisOptions get analysisOptions => _options;
+ Element getElement(ElementLocation location) {
+ try {
+ List<String> components = ((location as ElementLocationImpl)).components;
+ Source librarySource = computeSourceFromEncoding(components[0]);
+ ElementImpl element = computeLibraryElement(librarySource) as ElementImpl;
+ for (int i = 1; i < components.length; i++) {
+ if (element == null) {
+ return null;
+ }
+ element = element.getChild(components[i]);
+ }
+ return element;
+ } on AnalysisException catch (exception) {
+ return null;
}
}
- List<Source> getLibrariesContaining(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getLibrariesContaining(source);
- } else {
- return super.getLibrariesContaining(source);
+ AnalysisErrorInfo getErrors(Source source) {
+ SourceEntry sourceEntry = getReadableSourceEntry(source);
+ if (sourceEntry is DartEntry) {
+ DartEntry dartEntry = sourceEntry as DartEntry;
+ return new AnalysisErrorInfoImpl(dartEntry.allErrors, dartEntry.getValue(SourceEntry.LINE_INFO));
+ } else if (sourceEntry is HtmlEntry) {
+ HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
+ return new AnalysisErrorInfoImpl(htmlEntry.allErrors, htmlEntry.getValue(SourceEntry.LINE_INFO));
}
+ return new AnalysisErrorInfoImpl(AnalysisError.NO_ERRORS, null);
}
- List<Source> getLibrariesDependingOn(Source librarySource) {
- if (librarySource.isInSystemLibrary) {
- return _sdkAnalysisContext.getLibrariesDependingOn(librarySource);
- } else {
- return super.getLibrariesDependingOn(librarySource);
+ HtmlElement getHtmlElement(Source source) {
+ SourceEntry sourceEntry = getReadableSourceEntry(source);
+ if (sourceEntry is HtmlEntry) {
+ return ((sourceEntry as HtmlEntry)).getValue(HtmlEntry.ELEMENT);
}
+ return null;
}
- LibraryElement getLibraryElement(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getLibraryElement(source);
- } else {
- return super.getLibraryElement(source);
+ List<Source> getHtmlFilesReferencing(Source source) {
+ SourceKind sourceKind = getKindOf(source);
+ if (sourceKind == null) {
+ return Source.EMPTY_ARRAY;
}
- }
- 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);
+ {
+ List<Source> htmlSources = new List<Source>();
+ while (true) {
+ if (sourceKind == SourceKind.LIBRARY) {
+ } else if (sourceKind == SourceKind.PART) {
+ List<Source> librarySources = getLibrariesContaining(source);
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
+ SourceEntry sourceEntry = entry.getValue();
+ if (identical(sourceEntry.kind, SourceKind.HTML)) {
+ List<Source> referencedLibraries = ((sourceEntry as HtmlEntry)).getValue(HtmlEntry.REFERENCED_LIBRARIES);
+ if (containsAny(referencedLibraries, librarySources)) {
+ htmlSources.add(entry.getKey());
+ }
+ }
+ }
+ }
+ break;
+ }
+ if (htmlSources.isEmpty) {
+ return Source.EMPTY_ARRAY;
+ }
+ return new List.from(htmlSources);
}
}
- Namespace getPublicNamespace(LibraryElement library) {
- Source source = library.source;
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getPublicNamespace(library);
- } else {
- return super.getPublicNamespace(library);
+ List<Source> get htmlSources => getSources(SourceKind.HTML);
+ SourceKind getKindOf(Source source) {
+ SourceEntry sourceEntry = getReadableSourceEntry(source);
+ if (sourceEntry == null) {
+ return SourceKind.UNKNOWN;
}
+ return sourceEntry.kind;
}
- Namespace getPublicNamespace2(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getPublicNamespace2(source);
- } else {
- return super.getPublicNamespace2(source);
+ List<Source> get launchableClientLibrarySources {
+ List<Source> sources = new List<Source>();
+ {
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
+ Source source = entry.getKey();
+ SourceEntry sourceEntry = entry.getValue();
+ if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary) {
+ sources.add(source);
+ }
+ }
}
+ return new List.from(sources);
}
- CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.getResolvedCompilationUnit(unitSource, library);
- } else {
- return super.getResolvedCompilationUnit(unitSource, library);
+ List<Source> get launchableServerLibrarySources {
+ List<Source> sources = new List<Source>();
+ {
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
+ Source source = entry.getKey();
+ SourceEntry sourceEntry = entry.getValue();
+ if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary) {
+ sources.add(source);
+ }
+ }
}
+ return new List.from(sources);
}
- CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source librarySource) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.getResolvedCompilationUnit2(unitSource, librarySource);
- } else {
- return super.getResolvedCompilationUnit2(unitSource, librarySource);
+ List<Source> getLibrariesContaining(Source source) {
+ {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry == null || sourceEntry.kind != SourceKind.PART) {
+ return <Source> [source];
+ }
+ List<Source> librarySources = new List<Source>();
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
+ sourceEntry = entry.getValue();
+ if (identical(sourceEntry.kind, SourceKind.LIBRARY)) {
+ if (contains(((sourceEntry as DartEntry)).getValue(DartEntry.INCLUDED_PARTS), source)) {
+ librarySources.add(entry.getKey());
+ }
+ }
+ }
+ if (librarySources.isEmpty) {
+ return Source.EMPTY_ARRAY;
+ }
+ return new List.from(librarySources);
}
}
- bool isClientLibrary(Source librarySource) {
- if (librarySource.isInSystemLibrary) {
- return _sdkAnalysisContext.isClientLibrary(librarySource);
- } else {
- return super.isClientLibrary(librarySource);
+ List<Source> getLibrariesDependingOn(Source librarySource) {
+ {
+ List<Source> dependentLibraries = new List<Source>();
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
+ SourceEntry sourceEntry = entry.getValue();
+ if (identical(sourceEntry.kind, SourceKind.LIBRARY)) {
+ if (contains(((sourceEntry as DartEntry)).getValue(DartEntry.EXPORTED_LIBRARIES), librarySource)) {
+ dependentLibraries.add(entry.getKey());
+ }
+ if (contains(((sourceEntry as DartEntry)).getValue(DartEntry.IMPORTED_LIBRARIES), librarySource)) {
+ dependentLibraries.add(entry.getKey());
+ }
+ }
+ }
+ if (dependentLibraries.isEmpty) {
+ return Source.EMPTY_ARRAY;
+ }
+ return new List.from(dependentLibraries);
}
}
- bool isServerLibrary(Source librarySource) {
- if (librarySource.isInSystemLibrary) {
- return _sdkAnalysisContext.isServerLibrary(librarySource);
- } else {
- return super.isServerLibrary(librarySource);
+ LibraryElement getLibraryElement(Source source) {
+ SourceEntry sourceEntry = getReadableSourceEntry(source);
+ if (sourceEntry is DartEntry) {
+ return ((sourceEntry as DartEntry)).getValue(DartEntry.ELEMENT);
}
+ return null;
}
- CompilationUnit parseCompilationUnit(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.parseCompilationUnit(source);
- } else {
- return super.parseCompilationUnit(source);
+ List<Source> get librarySources => getSources(SourceKind.LIBRARY);
+ LineInfo getLineInfo(Source source) {
+ SourceEntry sourceEntry = getReadableSourceEntry(source);
+ if (sourceEntry != null) {
+ return sourceEntry.getValue(SourceEntry.LINE_INFO);
}
+ return null;
}
- HtmlUnit parseHtmlUnit(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.parseHtmlUnit(source);
- } else {
- return super.parseHtmlUnit(source);
+ Namespace getPublicNamespace(LibraryElement library) {
+ Source source = library.definingCompilationUnit.source;
+ DartEntry dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ return null;
}
- }
- void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
- if (elementMap.isEmpty) {
- return;
+ Namespace namespace = null;
+ if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
+ namespace = dartEntry.getValue(DartEntry.PUBLIC_NAMESPACE);
}
- Source source = new JavaIterator(elementMap.keys.toSet()).next();
- if (source.isInSystemLibrary) {
- _sdkAnalysisContext.recordLibraryElements(elementMap);
- } else {
- super.recordLibraryElements(elementMap);
+ if (namespace == null) {
+ NamespaceBuilder builder = new NamespaceBuilder();
+ namespace = builder.createPublicNamespace(library);
+ {
+ dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ AnalysisEngine.instance.logger.logError3(new AnalysisException.con1("A Dart file became a non-Dart file: ${source.fullName}"));
+ return null;
+ }
+ if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
+ DartEntryImpl dartCopy = getReadableDartEntry(source).writableCopy;
+ dartCopy.setValue(DartEntry.PUBLIC_NAMESPACE, namespace);
+ _cache.put(source, dartCopy);
+ }
+ }
}
+ return namespace;
}
- CompilationUnit resolveCompilationUnit(Source source, LibraryElement library) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.resolveCompilationUnit(source, library);
- } else {
- return super.resolveCompilationUnit(source, library);
+ Namespace getPublicNamespace2(Source source) {
+ DartEntry dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ return null;
}
- }
- CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.resolveCompilationUnit2(unitSource, librarySource);
- } else {
- return super.resolveCompilationUnit2(unitSource, librarySource);
+ Namespace namespace = dartEntry.getValue(DartEntry.PUBLIC_NAMESPACE);
+ if (namespace == null) {
+ LibraryElement library = computeLibraryElement(source);
+ if (library == null) {
+ return null;
+ }
+ NamespaceBuilder builder = new NamespaceBuilder();
+ namespace = builder.createPublicNamespace(library);
+ {
+ dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("A Dart file became a non-Dart file: ${source.fullName}");
+ }
+ if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
+ DartEntryImpl dartCopy = getReadableDartEntry(source).writableCopy;
+ dartCopy.setValue(DartEntry.PUBLIC_NAMESPACE, namespace);
+ _cache.put(source, dartCopy);
+ }
+ }
}
+ return namespace;
}
- HtmlUnit resolveHtmlUnit(Source unitSource) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.resolveHtmlUnit(unitSource);
- } else {
- return super.resolveHtmlUnit(unitSource);
+ CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library) {
+ if (library == null) {
+ return null;
}
+ return getResolvedCompilationUnit2(unitSource, library.source);
}
- void setContents(Source source, String contents) {
- if (source.isInSystemLibrary) {
- _sdkAnalysisContext.setContents(source, contents);
- } else {
- super.setContents(source, contents);
+ CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source librarySource) {
+ SourceEntry sourceEntry = getReadableSourceEntry(unitSource);
+ if (sourceEntry is DartEntry) {
+ return ((sourceEntry as DartEntry)).getValue2(DartEntry.RESOLVED_UNIT, librarySource);
}
+ return null;
}
- void set sourceFactory(SourceFactory factory) {
- super.sourceFactory = factory;
- DartSdk sdk = factory.dartSdk;
- if (sdk != null) {
- _sdkAnalysisContext = sdk.context as InternalAnalysisContext;
- if (_sdkAnalysisContext is DelegatingAnalysisContextImpl) {
- _sdkAnalysisContext = null;
- throw new IllegalStateException("The context provided by an SDK cannot itself be a delegating analysis context");
- }
- } else {
- throw new IllegalStateException("SourceFactorys provided to DelegatingAnalysisContextImpls must have a DartSdk associated with the provided SourceFactory.");
- }
- }
-}
-/**
- * Instances of the class `InstrumentedAnalysisContextImpl` implement an
- * [AnalysisContext] 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 [InstrumentedAnalysisContextImpl] which wraps a new
- * [AnalysisContextImpl] as the basis context.
- */
- InstrumentedAnalysisContextImpl() : this.con1(new AnalysisContextImpl());
+ SourceFactory get sourceFactory => _sourceFactory;
/**
- * Create a new [InstrumentedAnalysisContextImpl] with a specified basis context, aka the
- * context to wrap and instrument.
+ * Return a list of the sources that would be processed by [performAnalysisTask]. This
+ * method duplicates, and must therefore be kept in sync with, [getNextTaskAnalysisTask].
+ * This method is intended to be used for testing purposes only.
*
- * @param context some [InstrumentedAnalysisContext] to wrap and instrument
+ * @return a list of the sources that would be processed by [performAnalysisTask]
*/
- InstrumentedAnalysisContextImpl.con1(InternalAnalysisContext context) {
- _basis = context;
- }
- void addSourceInfo(Source source, SourceEntry 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<Source> get sourcesNeedingProcessing {
+ Set<Source> sources = new Set<Source>();
+ {
+ for (Source source in _cache.priorityOrder) {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry is DartEntry) {
+ DartEntry dartEntry = sourceEntry as DartEntry;
+ CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
+ if (identical(parseErrorsState, CacheState.INVALID) || identical(parseErrorsState, CacheState.FLUSHED)) {
+ javaSetAdd(sources, source);
+ }
+ CacheState parseUnitState = dartEntry.getState(DartEntry.PARSED_UNIT);
+ if (identical(parseUnitState, CacheState.INVALID) || identical(parseUnitState, CacheState.FLUSHED)) {
+ javaSetAdd(sources, source);
+ }
+ for (Source librarySource in getLibrariesContaining(source)) {
+ SourceEntry libraryEntry = _cache.get(librarySource);
+ if (libraryEntry is DartEntry) {
+ CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
+ if (identical(elementState, CacheState.INVALID) || identical(elementState, CacheState.FLUSHED)) {
+ javaSetAdd(sources, source);
+ }
+ CacheState resolvedUnitState = dartEntry.getState2(DartEntry.RESOLVED_UNIT, librarySource);
+ if (identical(resolvedUnitState, CacheState.INVALID) || identical(resolvedUnitState, CacheState.FLUSHED)) {
+ LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
+ if (libraryElement != null) {
+ javaSetAdd(sources, source);
+ }
+ }
+ }
+ }
+ } else if (sourceEntry is HtmlEntry) {
+ HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
+ CacheState parsedUnitState = htmlEntry.getState(HtmlEntry.PARSED_UNIT);
+ if (identical(parsedUnitState, CacheState.INVALID) || identical(parsedUnitState, CacheState.FLUSHED)) {
+ javaSetAdd(sources, source);
+ }
+ CacheState elementState = htmlEntry.getState(HtmlEntry.ELEMENT);
+ if (identical(elementState, CacheState.INVALID) || identical(elementState, CacheState.FLUSHED)) {
+ javaSetAdd(sources, source);
+ }
+ }
+ }
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
+ SourceEntry sourceEntry = entry.getValue();
+ if (sourceEntry is DartEntry) {
+ DartEntry dartEntry = sourceEntry as DartEntry;
+ if (identical(dartEntry.getState(DartEntry.PARSED_UNIT), CacheState.INVALID)) {
+ javaSetAdd(sources, entry.getKey());
+ }
+ } else if (sourceEntry is HtmlEntry) {
+ HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
+ if (identical(htmlEntry.getState(HtmlEntry.PARSED_UNIT), CacheState.INVALID)) {
+ javaSetAdd(sources, entry.getKey());
+ }
+ }
+ }
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
+ SourceEntry sourceEntry = entry.getValue();
+ if (sourceEntry is DartEntry && identical(sourceEntry.kind, SourceKind.LIBRARY)) {
+ DartEntry dartEntry = sourceEntry as DartEntry;
+ if (identical(dartEntry.getState(DartEntry.ELEMENT), CacheState.INVALID)) {
+ javaSetAdd(sources, entry.getKey());
+ }
+ } else if (sourceEntry is HtmlEntry) {
+ HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
+ if (identical(htmlEntry.getState(HtmlEntry.ELEMENT), CacheState.INVALID)) {
+ javaSetAdd(sources, entry.getKey());
+ }
+ }
+ }
}
+ return new List<Source>.from(sources);
}
- String computeDocumentationComment(Element element) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeDocumentationComment");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.computeDocumentationComment(element);
- } finally {
- instrumentation.log();
+ AnalysisContentStatistics get statistics {
+ AnalysisContentStatisticsImpl statistics = new AnalysisContentStatisticsImpl();
+ {
+ for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
+ SourceEntry entry = mapEntry.getValue();
+ if (entry is DartEntry) {
+ Source source = mapEntry.getKey();
+ DartEntry dartEntry = entry as DartEntry;
+ SourceKind kind = dartEntry.getValue(DartEntry.SOURCE_KIND);
+ statistics.putCacheItem(dartEntry, DartEntry.PARSE_ERRORS);
+ statistics.putCacheItem(dartEntry, DartEntry.PARSED_UNIT);
+ statistics.putCacheItem(dartEntry, DartEntry.SOURCE_KIND);
+ statistics.putCacheItem(dartEntry, DartEntry.LINE_INFO);
+ if (identical(kind, SourceKind.LIBRARY)) {
+ statistics.putCacheItem(dartEntry, DartEntry.ELEMENT);
+ statistics.putCacheItem(dartEntry, DartEntry.EXPORTED_LIBRARIES);
+ statistics.putCacheItem(dartEntry, DartEntry.IMPORTED_LIBRARIES);
+ statistics.putCacheItem(dartEntry, DartEntry.INCLUDED_PARTS);
+ statistics.putCacheItem(dartEntry, DartEntry.IS_CLIENT);
+ statistics.putCacheItem(dartEntry, DartEntry.IS_LAUNCHABLE);
+ }
+ List<Source> librarySources = getLibrariesContaining(source);
+ for (Source librarySource in librarySources) {
+ statistics.putCacheItem2(dartEntry, librarySource, DartEntry.RESOLUTION_ERRORS);
+ statistics.putCacheItem2(dartEntry, librarySource, DartEntry.RESOLVED_UNIT);
+ }
+ }
+ }
}
+ return statistics;
}
- 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();
+ bool isClientLibrary(Source librarySource) {
+ SourceEntry sourceEntry = getReadableSourceEntry(librarySource);
+ if (sourceEntry is DartEntry) {
+ DartEntry dartEntry = sourceEntry as DartEntry;
+ return dartEntry.getValue(DartEntry.IS_CLIENT) && dartEntry.getValue(DartEntry.IS_LAUNCHABLE);
}
+ return false;
}
- List<Source> computeExportedLibraries(Source source) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeExportedLibraries");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.computeExportedLibraries(source);
- } finally {
- instrumentation.log();
+ bool isServerLibrary(Source librarySource) {
+ SourceEntry sourceEntry = getReadableSourceEntry(librarySource);
+ if (sourceEntry is DartEntry) {
+ DartEntry dartEntry = sourceEntry as DartEntry;
+ return !dartEntry.getValue(DartEntry.IS_CLIENT) && dartEntry.getValue(DartEntry.IS_LAUNCHABLE);
}
+ return false;
}
- 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();
+ void mergeContext(AnalysisContext context) {
+ if (context is InstrumentedAnalysisContextImpl) {
+ context = ((context as InstrumentedAnalysisContextImpl)).basis;
}
- }
- List<Source> computeImportedLibraries(Source source) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeImportedLibraries");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.computeImportedLibraries(source);
- } finally {
- instrumentation.log();
+ if (context is! AnalysisContextImpl2) {
+ return;
}
- }
- SourceKind computeKindOf(Source source) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeKindOf");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.computeKindOf(source);
- } finally {
- instrumentation.log();
+ {
+ for (MapEntry<Source, SourceEntry> entry in ((context as AnalysisContextImpl2))._cache.entrySet()) {
+ Source newSource = entry.getKey();
+ SourceEntry existingEntry = getReadableSourceEntry(newSource);
+ if (existingEntry == null) {
+ _cache.put(newSource, entry.getValue().writableCopy);
+ } else {
+ }
+ }
}
}
- LibraryElement computeLibraryElement(Source source) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeLibraryElement");
+ CompilationUnit parseCompilationUnit(Source source) => getDartParseData2(source, DartEntry.PARSED_UNIT, null);
+ HtmlUnit parseHtmlUnit(Source source) => getHtmlParseData(source, HtmlEntry.PARSED_UNIT, null);
+ List<ChangeNotice> performAnalysisTask() {
+ AnalysisTask task = nextTaskAnalysisTask;
+ if (task == null) {
+ return getChangeNotices(true);
+ }
try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.computeLibraryElement(source);
- } on AnalysisException catch (e) {
- recordAnalysisException(instrumentation, e);
- throw e;
- } finally {
- instrumentation.log();
+ task.perform(_resultRecorder);
+ } on AnalysisException catch (exception) {
+ if (exception.cause is! JavaIOException) {
+ AnalysisEngine.instance.logger.logError2("Internal error while performing the task: ${task}", exception);
+ }
}
+ return getChangeNotices(false);
}
- 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();
+ void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
+ {
+ Source htmlSource = _sourceFactory.forUri(DartSdk.DART_HTML);
+ for (MapEntry<Source, LibraryElement> entry in getMapEntrySet(elementMap)) {
+ Source librarySource = entry.getKey();
+ LibraryElement library = entry.getValue();
+ DartEntry dartEntry = getReadableDartEntry(librarySource);
+ if (dartEntry != null) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ recordElementData(dartCopy, library, htmlSource);
+ _cache.put(librarySource, dartCopy);
+ }
+ }
}
}
- ResolvableCompilationUnit 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();
+ CompilationUnit resolveCompilationUnit(Source unitSource, LibraryElement library) {
+ if (library == null) {
+ return null;
}
+ return resolveCompilationUnit2(unitSource, library.source);
}
- InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext) => _basis.extractContextInto(container, newContext);
- AnalysisOptions get analysisOptions {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getAnalysisOptions");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.analysisOptions;
- } finally {
- instrumentation.log();
+ CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) => getDartResolutionData2(unitSource, librarySource, DartEntry.RESOLVED_UNIT, null);
+ HtmlUnit resolveHtmlUnit(Source htmlSource) => parseHtmlUnit(htmlSource);
+ void set analysisOptions(AnalysisOptions options2) {
+ {
+ this._options = options2;
+ invalidateAllResolutionInformation();
}
}
-
- /**
- * @return the underlying [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();
+ void set analysisPriorityOrder(List<Source> sources) {
+ {
+ if (sources == null || sources.isEmpty) {
+ _cache.priorityOrder = Source.EMPTY_ARRAY;
+ } else {
+ while (sources.remove(null)) {
+ }
+ if (sources.isEmpty) {
+ _cache.priorityOrder = Source.EMPTY_ARRAY;
+ }
+ int count = Math.min(sources.length, _MAX_PRIORITY_LIST_SIZE);
+ List<Source> priorityOrder = new List<Source>(count);
+ for (int i = 0; i < count; i++) {
+ priorityOrder[i] = sources[i];
+ }
+ _cache.priorityOrder = priorityOrder;
+ }
}
}
- 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);
+ void setContents(Source source, String contents) {
+ {
+ if (_sourceFactory.setContents(source, contents)) {
+ sourceChanged(source);
}
- 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();
+ 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;
+ invalidateAllResolutionInformation();
}
}
- 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);
+ 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 ret;
- } finally {
- instrumentation.log();
}
+ return librarySources;
}
- 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);
+
+ /**
+ * Add all of the sources contained in the given source container to the given list of sources.
+ *
+ * Note: This method must only be invoked while we are synchronized on [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 (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
+ Source source = entry.getKey();
+ if (container.contains(source)) {
+ sources.add(source);
}
- 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();
+
+ /**
+ * Return `true` if the modification times of the sources used by the given library resolver
+ * to resolve one or more libraries are consistent with the modification times in the cache.
+ *
+ * @param resolver the library resolver used to resolve one or more libraries
+ * @return `true` if we should record the results of the resolution
+ * @throws AnalysisException if any of the modification times could not be determined (this should
+ * not happen)
+ */
+ bool allModificationTimesMatch(LibraryResolver resolver) {
+ bool allTimesMatch = true;
+ for (Library library in resolver.resolvedLibraries) {
+ for (Source source in library.compilationUnitSources) {
+ DartEntry dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("Internal error: attempting to reolve non-Dart file as a Dart file: ${source.fullName}");
+ }
+ int sourceTime = source.modificationStamp;
+ int resultTime = library.getModificationTime(source);
+ if (sourceTime != resultTime) {
+ sourceChanged(source);
+ allTimesMatch = false;
+ }
+ }
}
+ return allTimesMatch;
}
- 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);
+
+ /**
+ * Given a source for a Dart file, return a cache entry in which the data represented by the given
+ * descriptor is available. This method assumes that the data can be produced by parsing the
+ * source if it is not already cached.
+ *
+ * @param source the source representing the Dart file
+ * @param dartEntry the cache entry associated with the Dart file
+ * @param descriptor the descriptor representing the data to be returned
+ * @return a cache entry containing the required data
+ * @throws AnalysisException if data could not be returned because the source could not be
+ * resolved
+ */
+ DartEntry cacheDartParseData(Source source, DartEntry dartEntry, DataDescriptor descriptor) {
+ if (identical(descriptor, DartEntry.PARSED_UNIT)) {
+ CompilationUnit unit = dartEntry.anyParsedCompilationUnit;
+ if (unit != null) {
+ return dartEntry;
}
- return ret;
- } finally {
- instrumentation.log();
}
+ CacheState state = dartEntry.getState(descriptor);
+ while (state != CacheState.ERROR && state != CacheState.VALID) {
+ dartEntry = new ParseDartTask(this, source).perform(_resultRecorder) as DartEntry;
+ state = dartEntry.getState(descriptor);
+ }
+ return dartEntry;
}
- 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();
+
+ /**
+ * Given a source for a Dart file and the library that contains it, return a cache entry in which
+ * the data represented by the given descriptor is available. This method assumes that the data
+ * can be produced by resolving the source in the context of the library if it is not already
+ * cached.
+ *
+ * @param unitSource the source representing the Dart file
+ * @param librarySource the source representing the library containing the Dart file
+ * @param dartEntry the cache entry associated with the Dart file
+ * @param descriptor the descriptor representing the data to be returned
+ * @return a cache entry containing the required data
+ * @throws AnalysisException if data could not be returned because the source could not be parsed
+ */
+ DartEntry cacheDartResolutionData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
+ CacheState state = (identical(descriptor, DartEntry.ELEMENT)) ? dartEntry.getState(descriptor) : dartEntry.getState2(descriptor, librarySource);
+ while (state != CacheState.ERROR && state != CacheState.VALID) {
+ dartEntry = new ResolveDartLibraryTask(this, unitSource, librarySource).perform(_resultRecorder) as DartEntry;
+ state = (identical(descriptor, DartEntry.ELEMENT)) ? dartEntry.getState(descriptor) : dartEntry.getState2(descriptor, librarySource);
}
+ return dartEntry;
}
- 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.log2(2);
+
+ /**
+ * Given a source for an HTML file, return a cache entry in which all of the data represented by
+ * the given descriptors is available. This method assumes that the data can be produced by
+ * parsing the source if it is not already cached.
+ *
+ * @param source the source representing the HTML file
+ * @param htmlEntry the cache entry associated with the HTML file
+ * @param descriptor the descriptor representing the data to be returned
+ * @return a cache entry containing the required data
+ * @throws AnalysisException if data could not be returned because the source could not be
+ * resolved
+ */
+ HtmlEntry cacheHtmlParseData(Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
+ CacheState state = htmlEntry.getState(descriptor);
+ while (state != CacheState.ERROR && state != CacheState.VALID) {
+ htmlEntry = new ParseHtmlTask(this, source).perform(_resultRecorder) as HtmlEntry;
+ state = htmlEntry.getState(descriptor);
}
+ return htmlEntry;
}
- List<Source> getLibrariesDependingOn(Source librarySource) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getLibrariesDependingOn");
- try {
- instrumentation.metric3("contextId", _contextId);
- List<Source> ret = _basis.getLibrariesDependingOn(librarySource);
- if (ret != null) {
- instrumentation.metric2("Source-count", ret.length);
- }
- return ret;
- } finally {
- instrumentation.log();
+
+ /**
+ * Given a source for an HTML file, return a cache entry in which the the data represented by the
+ * given descriptor is available. This method assumes that the data can be produced by resolving
+ * the source if it is not already cached.
+ *
+ * @param source the source representing the HTML file
+ * @param dartEntry the cache entry associated with the HTML file
+ * @param descriptor the descriptor representing the data to be returned
+ * @return a cache entry containing the required data
+ * @throws AnalysisException if data could not be returned because the source could not be
+ * resolved
+ */
+ HtmlEntry cacheHtmlResolutionData(Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
+ CacheState state = htmlEntry.getState(descriptor);
+ while (state != CacheState.ERROR && state != CacheState.VALID) {
+ htmlEntry = new ResolveHtmlTask(this, source).perform(_resultRecorder) as HtmlEntry;
+ state = htmlEntry.getState(descriptor);
}
+ return htmlEntry;
}
- LibraryElement getLibraryElement(Source source) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getLibraryElement");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.getLibraryElement(source);
- } finally {
- instrumentation.log();
+
+ /**
+ * Given the encoded form of a source, use the source factory to reconstitute the original source.
+ *
+ * @param encoding the encoded form of a source
+ * @return the source represented by the encoding
+ */
+ Source computeSourceFromEncoding(String encoding) {
+ {
+ return _sourceFactory.fromEncoding(encoding);
}
}
- 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 `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 `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 ret;
- } finally {
- instrumentation.log();
}
+ return false;
}
- LineInfo getLineInfo(Source source) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getLineInfo");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.getLineInfo(source);
- } finally {
- instrumentation.log();
+
+ /**
+ * Return `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 `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;
}
- 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();
+
+ /**
+ * Create a source information object suitable for the given source. Return the source information
+ * object that was created, or `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
+ */
+ SourceEntry createSourceEntry(Source source) {
+ String name = source.shortName;
+ if (AnalysisEngine.isHtmlFileName(name)) {
+ HtmlEntryImpl htmlEntry = new HtmlEntryImpl();
+ htmlEntry.modificationTime = source.modificationStamp;
+ _cache.put(source, htmlEntry);
+ return htmlEntry;
+ } else {
+ DartEntryImpl dartEntry = new DartEntryImpl();
+ dartEntry.modificationTime = source.modificationStamp;
+ _cache.put(source, dartEntry);
+ return dartEntry;
}
}
- CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source librarySource) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getResolvedCompilationUnit");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.getResolvedCompilationUnit2(unitSource, librarySource);
- } finally {
- instrumentation.log2(2);
+
+ /**
+ * Return an array containing all of the change notices that are waiting to be returned. If there
+ * are no notices, then return either `null` or an empty array, depending on the value of
+ * the argument.
+ *
+ * @param nullIfEmpty `true` if `null` should be returned when there are no notices
+ * @return the change notices that are waiting to be returned
+ */
+ List<ChangeNotice> getChangeNotices(bool nullIfEmpty) {
+ {
+ if (_pendingNotices.isEmpty) {
+ if (nullIfEmpty) {
+ return null;
+ }
+ return ChangeNoticeImpl.EMPTY_ARRAY;
+ }
+ List<ChangeNotice> notices = new List.from(_pendingNotices.values);
+ _pendingNotices.clear();
+ return notices;
}
}
- SourceFactory get sourceFactory {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getSourceFactory");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.sourceFactory;
- } finally {
- instrumentation.log2(2);
+
+ /**
+ * Given a source for a Dart file, return the data represented by the given descriptor that is
+ * associated with that source. This method assumes that the data can be produced by parsing the
+ * source if it is not already cached.
+ *
+ * @param source the source representing the Dart file
+ * @param dartEntry the cache entry associated with the Dart file
+ * @param descriptor the descriptor representing the data to be returned
+ * @return the requested data about the given source
+ * @throws AnalysisException if data could not be returned because the source could not be parsed
+ */
+ Object getDartParseData(Source source, DartEntry dartEntry, DataDescriptor descriptor) {
+ dartEntry = cacheDartParseData(source, dartEntry, descriptor);
+ if (identical(descriptor, DartEntry.PARSED_UNIT)) {
+ return dartEntry.anyParsedCompilationUnit as Object;
}
+ return dartEntry.getValue(descriptor);
}
- AnalysisContentStatistics get statistics => _basis.statistics;
- bool isClientLibrary(Source librarySource) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-isClientLibrary");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.isClientLibrary(librarySource);
- } finally {
- instrumentation.log();
+
+ /**
+ * Given a source for a Dart file, return the data represented by the given descriptor that is
+ * associated with that source, or the given default value if the source is not a Dart file. This
+ * method assumes that the data can be produced by parsing the source if it is not already cached.
+ *
+ * @param source the source representing the Dart file
+ * @param descriptor the descriptor representing the data to be returned
+ * @param defaultValue the value to be returned if the source is not a Dart file
+ * @return the requested data about the given source
+ * @throws AnalysisException if data could not be returned because the source could not be parsed
+ */
+ Object getDartParseData2(Source source, DataDescriptor descriptor, Object defaultValue) {
+ DartEntry dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ return defaultValue;
}
+ return getDartParseData(source, dartEntry, descriptor);
}
- bool isServerLibrary(Source librarySource) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-isServerLibrary");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.isServerLibrary(librarySource);
- } finally {
- instrumentation.log();
+
+ /**
+ * Given a source for a Dart file and the library that contains it, return the data represented by
+ * the given descriptor that is associated with that source. This method assumes that the data can
+ * be produced by resolving the source in the context of the library if it is not already cached.
+ *
+ * @param unitSource the source representing the Dart file
+ * @param librarySource the source representing the library containing the Dart file
+ * @param dartEntry the entry representing the Dart file
+ * @param descriptor the descriptor representing the data to be returned
+ * @return the requested data about the given source
+ * @throws AnalysisException if data could not be returned because the source could not be
+ * resolved
+ */
+ Object getDartResolutionData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
+ dartEntry = cacheDartResolutionData(unitSource, librarySource, dartEntry, descriptor);
+ if (identical(descriptor, DartEntry.ELEMENT)) {
+ return dartEntry.getValue(descriptor);
}
+ return dartEntry.getValue2(descriptor, librarySource);
}
- 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();
+
+ /**
+ * Given a source for a Dart file and the library that contains it, return the data represented by
+ * the given descriptor that is associated with that source, or the given default value if the
+ * source is not a Dart file. This method assumes that the data can be produced by resolving the
+ * source in the context of the library if it is not already cached.
+ *
+ * @param unitSource the source representing the Dart file
+ * @param librarySource the source representing the library containing the Dart file
+ * @param descriptor the descriptor representing the data to be returned
+ * @param defaultValue the value to be returned if the source is not a Dart file
+ * @return the requested data about the given source
+ * @throws AnalysisException if data could not be returned because the source could not be
+ * resolved
+ */
+ Object getDartResolutionData2(Source unitSource, Source librarySource, DataDescriptor descriptor, Object defaultValue) {
+ DartEntry dartEntry = getReadableDartEntry(unitSource);
+ if (dartEntry == null) {
+ return defaultValue;
}
+ return getDartResolutionData(unitSource, librarySource, dartEntry, descriptor);
}
- 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();
+
+ /**
+ * Given a source for an HTML file, return the data represented by the given descriptor that is
+ * associated with that source, or the given default value if the source is not an HTML file. This
+ * method assumes that the data can be produced by parsing the source if it is not already cached.
+ *
+ * @param source the source representing the Dart file
+ * @param descriptor the descriptor representing the data to be returned
+ * @param defaultValue the value to be returned if the source is not an HTML file
+ * @return the requested data about the given source
+ * @throws AnalysisException if data could not be returned because the source could not be parsed
+ */
+ Object getHtmlParseData(Source source, DataDescriptor descriptor, Object defaultValue) {
+ HtmlEntry htmlEntry = getReadableHtmlEntry(source);
+ if (htmlEntry == null) {
+ return defaultValue;
}
+ htmlEntry = cacheHtmlParseData(source, htmlEntry, descriptor);
+ return htmlEntry.getValue(descriptor);
}
- HtmlUnit parseHtmlUnit(Source source) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-parseHtmlUnit");
+
+ /**
+ * Given a source for an HTML file, return the data represented by the given descriptor that is
+ * associated with that source, or the given default value if the source is not an HTML file. This
+ * method assumes that the data can be produced by resolving the source if it is not already
+ * cached.
+ *
+ * @param source the source representing the HTML file
+ * @param descriptor the descriptor representing the data to be returned
+ * @param defaultValue the value to be returned if the source is not an HTML file
+ * @return the requested data about the given source
+ * @throws AnalysisException if data could not be returned because the source could not be
+ * resolved
+ */
+ Object getHtmlResolutionData(Source source, DataDescriptor descriptor, Object defaultValue) {
+ HtmlEntry htmlEntry = getReadableHtmlEntry(source);
+ if (htmlEntry == null) {
+ return defaultValue;
+ }
+ return getHtmlResolutionData2(source, htmlEntry, descriptor);
+ }
+
+ /**
+ * Given a source for an HTML file, return the data represented by the given descriptor that is
+ * associated with that source. This method assumes that the data can be produced by resolving the
+ * source if it is not already cached.
+ *
+ * @param source the source representing the HTML file
+ * @param htmlEntry the entry representing the HTML file
+ * @param descriptor the descriptor representing the data to be returned
+ * @return the requested data about the given source
+ * @throws AnalysisException if data could not be returned because the source could not be
+ * resolved
+ */
+ Object getHtmlResolutionData2(Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
+ htmlEntry = cacheHtmlResolutionData(source, htmlEntry, descriptor);
+ return htmlEntry.getValue(descriptor);
+ }
+
+ /**
+ * Look through the cache for a task that needs to be performed. Return the task that was found,
+ * or `null` if there is no more work to be done.
+ *
+ * @return the next task that needs to be performed
+ */
+ AnalysisTask get nextTaskAnalysisTask {
+ {
+ for (Source source in _cache.priorityOrder) {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry is DartEntry) {
+ DartEntry dartEntry = sourceEntry as DartEntry;
+ CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
+ if (identical(parseErrorsState, CacheState.INVALID) || identical(parseErrorsState, CacheState.FLUSHED)) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setState(DartEntry.PARSE_ERRORS, CacheState.IN_PROCESS);
+ _cache.put(source, dartCopy);
+ return new ParseDartTask(this, source);
+ }
+ CacheState parseUnitState = dartEntry.getState(DartEntry.PARSED_UNIT);
+ if (identical(parseUnitState, CacheState.INVALID) || identical(parseUnitState, CacheState.FLUSHED)) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.IN_PROCESS);
+ _cache.put(source, dartCopy);
+ return new ParseDartTask(this, source);
+ }
+ for (Source librarySource in getLibrariesContaining(source)) {
+ SourceEntry libraryEntry = _cache.get(librarySource);
+ if (libraryEntry is DartEntry) {
+ CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
+ if (identical(elementState, CacheState.INVALID) || identical(elementState, CacheState.FLUSHED)) {
+ DartEntryImpl libraryCopy = ((libraryEntry as DartEntry)).writableCopy;
+ libraryCopy.setState(DartEntry.ELEMENT, CacheState.IN_PROCESS);
+ _cache.put(librarySource, libraryCopy);
+ return new ResolveDartLibraryTask(this, source, librarySource);
+ }
+ CacheState resolvedUnitState = dartEntry.getState2(DartEntry.RESOLVED_UNIT, librarySource);
+ if (identical(resolvedUnitState, CacheState.INVALID) || identical(resolvedUnitState, CacheState.FLUSHED)) {
+ LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
+ if (libraryElement != null) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.IN_PROCESS);
+ _cache.put(source, dartCopy);
+ return new ResolveDartUnitTask(this, source, libraryElement);
+ }
+ }
+ }
+ }
+ } else if (sourceEntry is HtmlEntry) {
+ HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
+ CacheState parsedUnitState = htmlEntry.getState(HtmlEntry.PARSED_UNIT);
+ if (identical(parsedUnitState, CacheState.INVALID) || identical(parsedUnitState, CacheState.FLUSHED)) {
+ HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+ htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.IN_PROCESS);
+ _cache.put(source, htmlCopy);
+ return new ParseHtmlTask(this, source);
+ }
+ CacheState elementState = htmlEntry.getState(HtmlEntry.ELEMENT);
+ if (identical(elementState, CacheState.INVALID) || identical(elementState, CacheState.FLUSHED)) {
+ HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+ htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.IN_PROCESS);
+ _cache.put(source, htmlCopy);
+ return new ResolveHtmlTask(this, source);
+ }
+ }
+ }
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
+ SourceEntry sourceEntry = entry.getValue();
+ if (sourceEntry is DartEntry) {
+ DartEntry dartEntry = sourceEntry as DartEntry;
+ if (identical(dartEntry.getState(DartEntry.PARSED_UNIT), CacheState.INVALID)) {
+ Source source = entry.getKey();
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setState(DartEntry.PARSE_ERRORS, CacheState.IN_PROCESS);
+ _cache.put(source, dartCopy);
+ return new ParseDartTask(this, source);
+ }
+ } else if (sourceEntry is HtmlEntry) {
+ HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
+ if (identical(htmlEntry.getState(HtmlEntry.PARSED_UNIT), CacheState.INVALID)) {
+ Source source = entry.getKey();
+ HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+ htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.IN_PROCESS);
+ _cache.put(source, htmlCopy);
+ return new ParseHtmlTask(this, source);
+ }
+ }
+ }
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
+ SourceEntry sourceEntry = entry.getValue();
+ if (sourceEntry is DartEntry && identical(sourceEntry.kind, SourceKind.LIBRARY)) {
+ DartEntry dartEntry = sourceEntry as DartEntry;
+ if (identical(dartEntry.getState(DartEntry.ELEMENT), CacheState.INVALID)) {
+ Source source = entry.getKey();
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setState(DartEntry.ELEMENT, CacheState.IN_PROCESS);
+ _cache.put(source, dartCopy);
+ return new ResolveDartLibraryTask(this, source, source);
+ }
+ } else if (sourceEntry is HtmlEntry) {
+ HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
+ if (identical(htmlEntry.getState(HtmlEntry.ELEMENT), CacheState.INVALID)) {
+ Source source = entry.getKey();
+ HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+ htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.IN_PROCESS);
+ _cache.put(source, htmlCopy);
+ return new ResolveHtmlTask(this, source);
+ }
+ }
+ }
+ return null;
+ }
+ }
+
+ /**
+ * 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 cache entry associated with the given source, or `null` if the source is not a
+ * Dart file.
+ *
+ * @param source the source for which a cache entry is being sought
+ * @return the source cache entry associated with the given source
+ */
+ DartEntry getReadableDartEntry(Source source) {
+ {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry == null) {
+ sourceEntry = createSourceEntry(source);
+ }
+ if (sourceEntry is DartEntry) {
+ _cache.accessed(source);
+ return sourceEntry as DartEntry;
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Return the cache entry associated with the given source, or `null` if the source is not
+ * an HTML file.
+ *
+ * @param source the source for which a cache entry is being sought
+ * @return the source cache entry associated with the given source
+ */
+ HtmlEntry getReadableHtmlEntry(Source source) {
+ {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry == null) {
+ sourceEntry = createSourceEntry(source);
+ }
+ if (sourceEntry is HtmlEntry) {
+ _cache.accessed(source);
+ return sourceEntry as HtmlEntry;
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Return the cache entry associated with the given source, or `null` if there is no entry
+ * associated with the source.
+ *
+ * @param source the source for which a cache entry is being sought
+ * @return the source cache entry associated with the given source
+ */
+ SourceEntry getReadableSourceEntry(Source source) {
+ {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry == null) {
+ sourceEntry = createSourceEntry(source);
+ }
+ if (sourceEntry != null) {
+ _cache.accessed(source);
+ }
+ return sourceEntry;
+ }
+ }
+
+ /**
+ * 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, SourceEntry> entry in _cache.entrySet()) {
+ if (identical(entry.getValue().kind, kind2)) {
+ sources.add(entry.getKey());
+ }
+ }
+ }
+ return new List.from(sources);
+ }
+
+ /**
+ * Invalidate all of the resolution results computed by this context.
+ *
+ * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
+ */
+ void invalidateAllResolutionInformation() {
+ for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
+ SourceEntry sourceEntry = mapEntry.getValue();
+ if (sourceEntry is HtmlEntry) {
+ HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
+ htmlCopy.invalidateAllResolutionInformation();
+ mapEntry.setValue(htmlCopy);
+ } else if (sourceEntry is DartEntry) {
+ DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
+ dartCopy.invalidateAllResolutionInformation();
+ mapEntry.setValue(dartCopy);
+ }
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
+ *
+ * @param librarySource the source of the library being invalidated
+ */
+ void invalidateLibraryResolution(Source librarySource) {
+ DartEntry libraryEntry = getReadableDartEntry(librarySource);
+ if (libraryEntry != null) {
+ List<Source> includedParts = libraryEntry.getValue(DartEntry.INCLUDED_PARTS);
+ DartEntryImpl libraryCopy = libraryEntry.writableCopy;
+ libraryCopy.invalidateAllResolutionInformation();
+ libraryCopy.setState(DartEntry.INCLUDED_PARTS, CacheState.INVALID);
+ _cache.put(librarySource, libraryCopy);
+ for (Source partSource in includedParts) {
+ DartEntry partEntry = getReadableDartEntry(partSource);
+ if (partEntry != null) {
+ DartEntryImpl partCopy = partEntry.writableCopy;
+ partCopy.invalidateAllResolutionInformation();
+ _cache.put(partSource, partCopy);
+ }
+ }
+ }
+ }
+
+ /**
+ * Return `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 `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;
+ }
+
+ /**
+ * Given a cache entry and a library element, record the library element and other information
+ * gleaned from the element in the cache entry.
+ *
+ * @param dartCopy the cache entry in which data is to be recorded
+ * @param library the library element used to record information
+ * @param htmlSource the source for the HTML library
+ */
+ void recordElementData(DartEntryImpl dartCopy, LibraryElement library, Source htmlSource) {
+ dartCopy.setValue(DartEntry.ELEMENT, library);
+ dartCopy.setValue(DartEntry.IS_LAUNCHABLE, library.entryPoint != null);
+ dartCopy.setValue(DartEntry.IS_CLIENT, isClient(library, htmlSource, new Set<LibraryElement>()));
+ List<Source> unitSources = new List<Source>();
+ unitSources.add(library.definingCompilationUnit.source);
+ for (CompilationUnitElement part in library.parts) {
+ Source partSource = part.source;
+ unitSources.add(partSource);
+ }
+ dartCopy.setValue(DartEntry.INCLUDED_PARTS, new List.from(unitSources));
+ }
+
+ /**
+ * Record the results produced by performing a [ParseDartTask]. If the results were computed
+ * from data that is now out-of-date, then the results will not be recorded.
+ *
+ * @param task the task that was performed
+ * @return an entry containing the computed results
+ * @throws AnalysisException if the results could not be recorded
+ */
+ DartEntry recordParseDartTaskResults(ParseDartTask task) {
+ Source source = task.source;
+ AnalysisException thrownException = task.exception;
+ DartEntry dartEntry = null;
+ {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry is! DartEntry) {
+ throw new AnalysisException.con1("Internal error: attempting to parse non-Dart file as a Dart file: ${source.fullName}");
+ }
+ dartEntry = sourceEntry as DartEntry;
+ _cache.accessed(source);
+ int sourceTime = source.modificationStamp;
+ int resultTime = task.modificationTime;
+ if (sourceTime == resultTime) {
+ if (dartEntry.modificationTime != sourceTime) {
+ sourceChanged(source);
+ dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("A Dart file became a non-Dart file: ${source.fullName}");
+ }
+ }
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null) {
+ LineInfo lineInfo = task.lineInfo;
+ dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
+ if (task.hasPartOfDirective() && !task.hasLibraryDirective()) {
+ dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.PART);
+ } else {
+ dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
+ }
+ dartCopy.setValue(DartEntry.PARSED_UNIT, task.compilationUnit);
+ dartCopy.setValue(DartEntry.PARSE_ERRORS, task.errors);
+ dartCopy.setValue(DartEntry.EXPORTED_LIBRARIES, task.exportedSources);
+ dartCopy.setValue(DartEntry.IMPORTED_LIBRARIES, task.importedSources);
+ dartCopy.setValue(DartEntry.INCLUDED_PARTS, task.includedSources);
+ } else {
+ dartCopy.recordParseError();
+ }
+ _cache.put(source, dartCopy);
+ dartEntry = dartCopy;
+ } else {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.recordParseNotInProcess();
+ _cache.put(source, dartCopy);
+ dartEntry = dartCopy;
+ }
+ }
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ return dartEntry;
+ }
+
+ /**
+ * Record the results produced by performing a [ParseHtmlTask]. If the results were computed
+ * from data that is now out-of-date, then the results will not be recorded.
+ *
+ * @param task the task that was performed
+ * @return an entry containing the computed results
+ * @throws AnalysisException if the results could not be recorded
+ */
+ HtmlEntry recordParseHtmlTaskResults(ParseHtmlTask task) {
+ Source source = task.source;
+ AnalysisException thrownException = task.exception;
+ HtmlEntry htmlEntry = null;
+ {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry is! HtmlEntry) {
+ throw new AnalysisException.con1("Internal error: attempting to parse non-HTML file as a HTML file: ${source.fullName}");
+ }
+ htmlEntry = sourceEntry as HtmlEntry;
+ _cache.accessed(source);
+ int sourceTime = source.modificationStamp;
+ int resultTime = task.modificationTime;
+ if (sourceTime == resultTime) {
+ if (htmlEntry.modificationTime != sourceTime) {
+ sourceChanged(source);
+ htmlEntry = getReadableHtmlEntry(source);
+ if (htmlEntry == null) {
+ throw new AnalysisException.con1("An HTML file became a non-HTML file: ${source.fullName}");
+ }
+ }
+ HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
+ if (thrownException == null) {
+ LineInfo lineInfo = task.lineInfo;
+ HtmlUnit unit = task.htmlUnit;
+ htmlCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
+ htmlCopy.setValue(HtmlEntry.PARSED_UNIT, unit);
+ htmlCopy.setValue(HtmlEntry.REFERENCED_LIBRARIES, task.referencedLibraries);
+ ChangeNoticeImpl notice = getNotice(source);
+ notice.setErrors(htmlEntry.allErrors, lineInfo);
+ } else {
+ htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.ERROR);
+ htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.ERROR);
+ htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.ERROR);
+ }
+ _cache.put(source, htmlCopy);
+ htmlEntry = htmlCopy;
+ } else {
+ HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
+ if (identical(htmlCopy.getState(SourceEntry.LINE_INFO), CacheState.IN_PROCESS)) {
+ htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.INVALID);
+ }
+ if (identical(htmlCopy.getState(HtmlEntry.PARSED_UNIT), CacheState.IN_PROCESS)) {
+ htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.INVALID);
+ }
+ if (identical(htmlCopy.getState(HtmlEntry.REFERENCED_LIBRARIES), CacheState.IN_PROCESS)) {
+ htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.INVALID);
+ }
+ _cache.put(source, htmlCopy);
+ htmlEntry = htmlCopy;
+ }
+ }
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ return htmlEntry;
+ }
+
+ /**
+ * Record the results produced by performing a [ResolveDartLibraryTask]. If the results were
+ * computed from data that is now out-of-date, then the results will not be recorded.
+ *
+ * @param task the task that was performed
+ * @return an entry containing the computed results
+ * @throws AnalysisException if the results could not be recorded
+ */
+ DartEntry recordResolveDartLibraryTaskResults(ResolveDartLibraryTask task) {
+ LibraryResolver resolver = task.libraryResolver;
+ AnalysisException thrownException = task.exception;
+ DartEntry unitEntry = null;
+ {
+ if (allModificationTimesMatch(resolver)) {
+ Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
+ Source unitSource = task.unitSource;
+ RecordingErrorListener errorListener = resolver.errorListener;
+ for (Library library in resolver.resolvedLibraries) {
+ Source librarySource = library.librarySource;
+ for (Source source in library.compilationUnitSources) {
+ CompilationUnit unit = library.getAST(source);
+ List<AnalysisError> errors = errorListener.getErrors2(source);
+ unit.resolutionErrors = errors;
+ LineInfo lineInfo = unit.lineInfo;
+ DartEntry dartEntry = _cache.get(source) as DartEntry;
+ int sourceTime = source.modificationStamp;
+ if (dartEntry.modificationTime != sourceTime) {
+ sourceChanged(source);
+ dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("A Dart file became a non-Dart file: ${source.fullName}");
+ }
+ }
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null) {
+ dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
+ dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
+ dartCopy.setValue2(DartEntry.RESOLVED_UNIT, librarySource, unit);
+ dartCopy.setValue2(DartEntry.RESOLUTION_ERRORS, librarySource, errors);
+ if (identical(source, librarySource)) {
+ recordElementData(dartCopy, library.libraryElement, htmlSource);
+ }
+ } else {
+ dartCopy.recordResolutionError();
+ }
+ _cache.put(source, dartCopy);
+ if (source == unitSource) {
+ unitEntry = dartCopy;
+ }
+ ChangeNoticeImpl notice = getNotice(source);
+ notice.compilationUnit = unit;
+ notice.setErrors(dartCopy.allErrors, lineInfo);
+ }
+ }
+ } else {
+ for (Library library in resolver.resolvedLibraries) {
+ for (Source source in library.compilationUnitSources) {
+ DartEntry dartEntry = getReadableDartEntry(source);
+ if (dartEntry != null) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.recordResolutionNotInProcess();
+ _cache.put(source, dartCopy);
+ }
+ }
+ }
+ }
+ }
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ return unitEntry;
+ }
+
+ /**
+ * Record the results produced by performing a [ResolveDartUnitTask]. If the results were
+ * computed from data that is now out-of-date, then the results will not be recorded.
+ *
+ * @param task the task that was performed
+ * @return an entry containing the computed results
+ * @throws AnalysisException if the results could not be recorded
+ */
+ SourceEntry recordResolveDartUnitTaskResults(ResolveDartUnitTask task) {
+ Source source = task.source;
+ AnalysisException thrownException = task.exception;
+ DartEntry dartEntry = null;
+ {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry is! DartEntry) {
+ throw new AnalysisException.con1("Internal error: attempting to reolve non-Dart file as a Dart file: ${source.fullName}");
+ }
+ dartEntry = sourceEntry as DartEntry;
+ _cache.accessed(source);
+ int sourceTime = source.modificationStamp;
+ int resultTime = task.modificationTime;
+ if (sourceTime == resultTime) {
+ if (dartEntry.modificationTime != sourceTime) {
+ sourceChanged(source);
+ dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("A Dart file became a non-Dart file: ${source.fullName}");
+ }
+ }
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null) {
+ dartCopy.setValue2(DartEntry.RESOLVED_UNIT, task.librarySource, task.resolvedUnit);
+ } else {
+ dartCopy.setState(DartEntry.RESOLVED_UNIT, CacheState.ERROR);
+ }
+ _cache.put(source, dartCopy);
+ dartEntry = dartCopy;
+ } else {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (identical(dartCopy.getState(DartEntry.RESOLVED_UNIT), CacheState.IN_PROCESS)) {
+ dartCopy.setState(DartEntry.RESOLVED_UNIT, CacheState.INVALID);
+ }
+ _cache.put(source, dartCopy);
+ dartEntry = dartCopy;
+ }
+ }
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ return dartEntry;
+ }
+
+ /**
+ * Record the results produced by performing a [ResolveHtmlTask]. If the results were
+ * computed from data that is now out-of-date, then the results will not be recorded.
+ *
+ * @param task the task that was performed
+ * @return an entry containing the computed results
+ * @throws AnalysisException if the results could not be recorded
+ */
+ SourceEntry recordResolveHtmlTaskResults(ResolveHtmlTask task) {
+ Source source = task.source;
+ AnalysisException thrownException = task.exception;
+ HtmlEntry htmlEntry = null;
+ {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry is! HtmlEntry) {
+ throw new AnalysisException.con1("Internal error: attempting to reolve non-HTML file as an HTML file: ${source.fullName}");
+ }
+ htmlEntry = sourceEntry as HtmlEntry;
+ _cache.accessed(source);
+ int sourceTime = source.modificationStamp;
+ int resultTime = task.modificationTime;
+ if (sourceTime == resultTime) {
+ if (htmlEntry.modificationTime != sourceTime) {
+ sourceChanged(source);
+ htmlEntry = getReadableHtmlEntry(source);
+ if (htmlEntry == null) {
+ throw new AnalysisException.con1("An HTML file became a non-HTML file: ${source.fullName}");
+ }
+ }
+ HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+ if (thrownException == null) {
+ htmlCopy.setValue(HtmlEntry.ELEMENT, task.element);
+ htmlCopy.setValue(HtmlEntry.RESOLUTION_ERRORS, task.resolutionErrors);
+ } else {
+ htmlCopy.recordResolutionError();
+ }
+ _cache.put(source, htmlCopy);
+ htmlEntry = htmlCopy;
+ } else {
+ HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+ if (identical(htmlCopy.getState(HtmlEntry.ELEMENT), CacheState.IN_PROCESS)) {
+ htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.INVALID);
+ }
+ if (identical(htmlCopy.getState(HtmlEntry.RESOLUTION_ERRORS), CacheState.IN_PROCESS)) {
+ htmlCopy.setState(HtmlEntry.RESOLUTION_ERRORS, CacheState.INVALID);
+ }
+ _cache.put(source, htmlCopy);
+ htmlEntry = htmlCopy;
+ }
+ }
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ return htmlEntry;
+ }
+
+ /**
+ * Create an entry for the newly added source. Return `true` if the new source is a Dart
+ * file.
+ *
+ * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
+ *
+ * @param source the source that has been added
+ * @return `true` if the new source is a Dart file
+ */
+ bool sourceAvailable(Source source) {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry == null) {
+ sourceEntry = createSourceEntry(source);
+ } else {
+ SourceEntryImpl sourceCopy = sourceEntry.writableCopy;
+ sourceCopy.modificationTime = source.modificationStamp;
+ _cache.put(source, sourceCopy);
+ }
+ return sourceEntry is DartEntry;
+ }
+
+ /**
+ * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
+ *
+ * @param source the source that has been changed
+ */
+ void sourceChanged(Source source) {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry is HtmlEntry) {
+ HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
+ htmlCopy.modificationTime = source.modificationStamp;
+ htmlCopy.invalidateAllInformation();
+ _cache.put(source, htmlCopy);
+ } else if (sourceEntry is DartEntry) {
+ List<Source> containingLibraries = getLibrariesContaining(source);
+ for (Source library in containingLibraries) {
+ invalidateLibraryResolution(library);
+ }
+ DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
+ dartCopy.modificationTime = source.modificationStamp;
+ dartCopy.invalidateAllInformation();
+ _cache.put(source, dartCopy);
+ }
+ }
+
+ /**
+ * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
+ *
+ * @param source the source that has been deleted
+ */
+ void sourceRemoved(Source source) {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry is DartEntry) {
+ Set<Source> libraries = new Set<Source>();
+ for (Source librarySource in getLibrariesContaining(source)) {
+ javaSetAdd(libraries, librarySource);
+ for (Source dependentLibrary in getLibrariesDependingOn(librarySource)) {
+ javaSetAdd(libraries, dependentLibrary);
+ }
+ }
+ for (Source librarySource in libraries) {
+ invalidateLibraryResolution(librarySource);
+ }
+ }
+ _cache.remove(source);
+ }
+}
+/**
+ * Instances of the class `AnalysisTaskResultRecorder` are used by an analysis context to
+ * record the results of a task.
+ */
+class AnalysisContextImpl2_AnalysisTaskResultRecorder implements AnalysisTaskVisitor<SourceEntry> {
+ final AnalysisContextImpl2 AnalysisContextImpl2_this;
+ AnalysisContextImpl2_AnalysisTaskResultRecorder(this.AnalysisContextImpl2_this);
+ DartEntry visitParseDartTask(ParseDartTask task) => AnalysisContextImpl2_this.recordParseDartTaskResults(task);
+ HtmlEntry visitParseHtmlTask(ParseHtmlTask task) => AnalysisContextImpl2_this.recordParseHtmlTaskResults(task);
+ DartEntry visitResolveDartLibraryTask(ResolveDartLibraryTask task) => AnalysisContextImpl2_this.recordResolveDartLibraryTaskResults(task);
+ SourceEntry visitResolveDartUnitTask(ResolveDartUnitTask task) => AnalysisContextImpl2_this.recordResolveDartUnitTaskResults(task);
+ SourceEntry visitResolveHtmlTask(ResolveHtmlTask task) => AnalysisContextImpl2_this.recordResolveHtmlTaskResults(task);
+}
+/**
+ * Instances of the class `AnalysisErrorInfoImpl` represent the analysis errors and line info
+ * associated with a source.
+ */
+class AnalysisErrorInfoImpl implements AnalysisErrorInfo {
+
+ /**
+ * The analysis errors associated with a source, or `null` if there are no errors.
+ */
+ List<AnalysisError> _errors;
+
+ /**
+ * The line information associated with the errors, or `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 `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 `null` if there were no
+ * errors.
+ *
+ * @return the line information associated with the errors
+ */
+ LineInfo get lineInfo => _lineInfo;
+}
+/**
+ * Instances of the class `AnalysisOptions` represent a set of analysis options used to
+ * control the behavior of an analysis context.
+ */
+class AnalysisOptionsImpl implements AnalysisOptions {
+
+ /**
+ * A flag indicating whether analysis is to use strict mode. In strict mode, error reporting is
+ * based exclusively on the static type information.
+ */
+ bool _strictMode = true;
+
+ /**
+ * A flag indicating whether analysis is to generate hint results (e.g. type inference based
+ * information and pub best practices).
+ */
+ bool _hint = true;
+ bool get hint => _hint;
+
+ /**
+ * Return `true` if analysis is to use strict mode. In strict mode, error reporting is based
+ * exclusively on the static type information.
+ *
+ * @return `true` if analysis is to use strict mode
+ */
+ bool get strictMode => _strictMode;
+
+ /**
+ * Set whether analysis is to generate hint results (e.g. type inference based information and pub
+ * best practices).
+ *
+ * @param hint `true` if analysis is to generate hint results
+ */
+ void set hint(bool hint2) {
+ this._hint = hint2;
+ }
+
+ /**
+ * Set whether analysis is to use strict mode to the given value. In strict mode, error reporting
+ * is based exclusively on the static type information.
+ *
+ * @param isStrict `true` if analysis is to use strict mode
+ */
+ void set strictMode(bool isStrict) {
+ _strictMode = isStrict;
+ }
+}
+/**
+ * The enumeration `CacheState` defines the possible states of cached data.
+ */
+class CacheState extends Enum<CacheState> {
+
+ /**
+ * The data is not in the cache and the last time an attempt was made to compute the data an
+ * exception occurred, making it pointless to attempt.
+ *
+ * Valid Transitions:
+ *
+ * * [INVALID] if a source was modified that might cause the data to be computable
+ *
+ */
+ static final CacheState ERROR = new CacheState('ERROR', 0);
+
+ /**
+ * The data is not in the cache because it was flushed from the cache in order to control memory
+ * usage. If the data is recomputed, results do not need to be reported.
+ *
+ * Valid Transitions:
+ *
+ * * [IN_PROCESS] if the data is being recomputed
+ * * [INVALID] if a source was modified that causes the data to need to be recomputed
+ *
+ */
+ static final CacheState FLUSHED = new CacheState('FLUSHED', 1);
+
+ /**
+ * The data might or might not be in the cache but is in the process of being recomputed.
+ *
+ * Valid Transitions:
+ *
+ * * [ERROR] if an exception occurred while trying to compute the data
+ * * [VALID] if the data was successfully computed and stored in the cache
+ *
+ */
+ static final CacheState IN_PROCESS = new CacheState('IN_PROCESS', 2);
+
+ /**
+ * The data is not in the cache and needs to be recomputed so that results can be reported.
+ *
+ * Valid Transitions:
+ *
+ * * [IN_PROCESS] if an attempt is being made to recompute the data
+ *
+ */
+ static final CacheState INVALID = new CacheState('INVALID', 3);
+
+ /**
+ * The data is in the cache and up-to-date.
+ *
+ * Valid Transitions:
+ *
+ * * [FLUSHED] if the data is removed in order to manage memory usage
+ * * [INVALID] if a source was modified in such a way as to invalidate the previous data
+ *
+ */
+ static final CacheState VALID = new CacheState('VALID', 4);
+ static final List<CacheState> values = [ERROR, FLUSHED, IN_PROCESS, INVALID, VALID];
+ CacheState(String name, int ordinal) : super(name, ordinal);
+}
+/**
+ * Instances of the class `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 `null` if the AST was
+ * not changed.
+ */
+ CompilationUnit _compilationUnit;
+
+ /**
+ * The errors that changed as a result of the analysis, or `null` if errors were not
+ * changed.
+ */
+ List<AnalysisError> _errors;
+
+ /**
+ * The line information associated with the source, or `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 `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 `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 `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 `DelegatingAnalysisContextImpl` extend [AnalysisContextImpl
+ ] to delegate sources to the appropriate analysis context. For instance, if the
+ * source is in a system library then the analysis context from the [DartSdk] is used.
+ *
+ * @coverage dart.engine
+ */
+class DelegatingAnalysisContextImpl extends AnalysisContextImpl {
+
+ /**
+ * This references the [InternalAnalysisContext] held onto by the [DartSdk] which is
+ * used (instead of this [AnalysisContext]) for SDK sources. This field is set when
+ * #setSourceFactory(SourceFactory) is called, and references the analysis context in the
+ * [DartUriResolver] in the [SourceFactory], this analysis context assumes that there
+ * will be such a resolver.
+ */
+ InternalAnalysisContext _sdkAnalysisContext;
+ void addSourceInfo(Source source, SourceEntry 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);
+ }
+ }
+ List<Source> computeExportedLibraries(Source source) {
+ if (source.isInSystemLibrary) {
+ return _sdkAnalysisContext.computeExportedLibraries(source);
+ } else {
+ return super.computeExportedLibraries(source);
+ }
+ }
+ HtmlElement computeHtmlElement(Source source) {
+ if (source.isInSystemLibrary) {
+ return _sdkAnalysisContext.computeHtmlElement(source);
+ } else {
+ return super.computeHtmlElement(source);
+ }
+ }
+ List<Source> computeImportedLibraries(Source source) {
+ if (source.isInSystemLibrary) {
+ return _sdkAnalysisContext.computeImportedLibraries(source);
+ } else {
+ return super.computeImportedLibraries(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);
+ }
+ }
+ ResolvableCompilationUnit 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);
+ }
+ }
+ List<Source> getLibrariesDependingOn(Source librarySource) {
+ if (librarySource.isInSystemLibrary) {
+ return _sdkAnalysisContext.getLibrariesDependingOn(librarySource);
+ } else {
+ return super.getLibrariesDependingOn(librarySource);
+ }
+ }
+ 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 source = library.source;
+ if (source.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);
+ }
+ }
+ 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;
+ if (_sdkAnalysisContext is DelegatingAnalysisContextImpl) {
+ _sdkAnalysisContext = null;
+ throw new IllegalStateException("The context provided by an SDK cannot itself be a delegating analysis context");
+ }
+ } else {
+ throw new IllegalStateException("SourceFactorys provided to DelegatingAnalysisContextImpls must have a DartSdk associated with the provided SourceFactory.");
+ }
+ }
+}
+/**
+ * Instances of the class `DelegatingAnalysisContextImpl` extend [AnalysisContextImpl
+ ] to delegate sources to the appropriate analysis context. For instance, if the
+ * source is in a system library then the analysis context from the [DartSdk] is used.
+ *
+ * @coverage dart.engine
+ */
+class DelegatingAnalysisContextImpl2 extends AnalysisContextImpl2 {
+
+ /**
+ * This references the [InternalAnalysisContext] held onto by the [DartSdk] which is
+ * used (instead of this [AnalysisContext]) for SDK sources. This field is set when
+ * #setSourceFactory(SourceFactory) is called, and references the analysis context in the
+ * [DartUriResolver] in the [SourceFactory], this analysis context assumes that there
+ * will be such a resolver.
+ */
+ InternalAnalysisContext _sdkAnalysisContext;
+ void addSourceInfo(Source source, SourceEntry 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);
+ }
+ }
+ List<Source> computeExportedLibraries(Source source) {
+ if (source.isInSystemLibrary) {
+ return _sdkAnalysisContext.computeExportedLibraries(source);
+ } else {
+ return super.computeExportedLibraries(source);
+ }
+ }
+ HtmlElement computeHtmlElement(Source source) {
+ if (source.isInSystemLibrary) {
+ return _sdkAnalysisContext.computeHtmlElement(source);
+ } else {
+ return super.computeHtmlElement(source);
+ }
+ }
+ List<Source> computeImportedLibraries(Source source) {
+ if (source.isInSystemLibrary) {
+ return _sdkAnalysisContext.computeImportedLibraries(source);
+ } else {
+ return super.computeImportedLibraries(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);
+ }
+ }
+ ResolvableCompilationUnit 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);
+ }
+ }
+ List<Source> getLibrariesDependingOn(Source librarySource) {
+ if (librarySource.isInSystemLibrary) {
+ return _sdkAnalysisContext.getLibrariesDependingOn(librarySource);
+ } else {
+ return super.getLibrariesDependingOn(librarySource);
+ }
+ }
+ 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 source = library.source;
+ if (source.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);
+ }
+ }
+ 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;
+ if (_sdkAnalysisContext is DelegatingAnalysisContextImpl2) {
+ _sdkAnalysisContext = null;
+ throw new IllegalStateException("The context provided by an SDK cannot itself be a delegating analysis context");
+ }
+ } else {
+ throw new IllegalStateException("SourceFactorys provided to DelegatingAnalysisContextImpls must have a DartSdk associated with the provided SourceFactory.");
+ }
+ }
+}
+/**
+ * Instances of the class `InstrumentedAnalysisContextImpl` implement an
+ * [AnalysisContext] 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 [InstrumentedAnalysisContextImpl] which wraps a new
+ * [AnalysisContextImpl] as the basis context.
+ */
+ InstrumentedAnalysisContextImpl() : this.con1(AnalysisEngine.instance.useExperimentalContext ? new DelegatingAnalysisContextImpl2() : new DelegatingAnalysisContextImpl());
+
+ /**
+ * Create a new [InstrumentedAnalysisContextImpl] with a specified basis context, aka the
+ * context to wrap and instrument.
+ *
+ * @param context some [InstrumentedAnalysisContext] to wrap and instrument
+ */
+ InstrumentedAnalysisContextImpl.con1(InternalAnalysisContext context) {
+ _basis = context;
+ }
+ void addSourceInfo(Source source, SourceEntry 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();
+ }
+ }
+ String computeDocumentationComment(Element element) {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeDocumentationComment");
+ try {
+ instrumentation.metric3("contextId", _contextId);
+ return _basis.computeDocumentationComment(element);
+ } 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();
+ }
+ }
+ List<Source> computeExportedLibraries(Source source) {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeExportedLibraries");
+ try {
+ instrumentation.metric3("contextId", _contextId);
+ return _basis.computeExportedLibraries(source);
+ } 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();
+ }
+ }
+ List<Source> computeImportedLibraries(Source source) {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeImportedLibraries");
+ try {
+ instrumentation.metric3("contextId", _contextId);
+ return _basis.computeImportedLibraries(source);
+ } 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();
+ }
+ }
+ ResolvableCompilationUnit computeResolvableCompilationUnit(Source source) => _basis.computeResolvableCompilationUnit(source);
+ ResolvableHtmlUnit computeResolvableHtmlUnit(Source source) => _basis.computeResolvableHtmlUnit(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);
+ AnalysisOptions get analysisOptions {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getAnalysisOptions");
+ try {
+ instrumentation.metric3("contextId", _contextId);
+ return _basis.analysisOptions;
+ } finally {
+ instrumentation.log();
+ }
+ }
+
+ /**
+ * @return the underlying [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.log2(2);
+ }
+ }
+ List<Source> getLibrariesDependingOn(Source librarySource) {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getLibrariesDependingOn");
+ try {
+ instrumentation.metric3("contextId", _contextId);
+ List<Source> ret = _basis.getLibrariesDependingOn(librarySource);
+ 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.log2(2);
+ }
+ }
+ SourceFactory get sourceFactory {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getSourceFactory");
+ try {
+ instrumentation.metric3("contextId", _contextId);
+ return _basis.sourceFactory;
+ } finally {
+ instrumentation.log2(2);
+ }
+ }
+ AnalysisContentStatistics get statistics => _basis.statistics;
+ 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.log2(2);
+ }
+ }
+ void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
+ _basis.recordLibraryElements(elementMap);
+ }
+ 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 set analysisOptions(AnalysisOptions options) {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-setAnalysisOptions");
+ try {
+ instrumentation.metric3("contextId", _contextId);
+ _basis.analysisOptions = options;
+ } finally {
+ instrumentation.log();
+ }
+ }
+ void set analysisPriorityOrder(List<Source> sources) {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-setAnalysisPriorityOrder");
+ try {
+ instrumentation.metric3("contextId", _contextId);
+ _basis.analysisPriorityOrder = sources;
+ } 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 `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, SourceEntry info);
+
+ /**
+ * Return an array containing the sources of the libraries that are exported by the library with
+ * the given source. The array will be empty if the given source is invalid, if the given source
+ * does not represent a library, or if the library does not export any other libraries.
+ *
+ * @param source the source representing the library whose exports are to be returned
+ * @return the sources of the libraries that are exported by the given library
+ * @throws AnalysisException if the exported libraries could not be computed
+ */
+ List<Source> computeExportedLibraries(Source source);
+
+ /**
+ * Return an array containing the sources of the libraries that are imported by the library with
+ * the given source. The array will be empty if the given source is invalid, if the given source
+ * does not represent a library, or if the library does not import any other libraries.
+ *
+ * @param source the source representing the library whose imports are to be returned
+ * @return the sources of the libraries that are imported by the given library
+ * @throws AnalysisException if the imported libraries could not be computed
+ */
+ List<Source> computeImportedLibraries(Source source);
+
+ /**
+ * 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
+ */
+ ResolvableCompilationUnit computeResolvableCompilationUnit(Source source);
+
+ /**
+ * 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.
+ *
+ * @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
+ */
+ ResolvableHtmlUnit computeResolvableHtmlUnit(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);
+
+ /**
+ * Returns a statistics about this context.
+ */
+ AnalysisContentStatistics get statistics;
+
+ /**
+ * 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);
+}
+/**
+ * Instances of the class `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 [Source].
+ */
+ Map<Source, List<AnalysisError>> _errors = new Map<Source, List<AnalysisError>>();
+
+ /**
+ * Add all of the errors recorded by the given listener to this listener.
+ *
+ * @param listener the listener that has recorded the errors to be added
+ */
+ void addAll(RecordingErrorListener listener) {
+ for (AnalysisError error in listener.errors) {
+ onError(error);
+ }
+ }
+
+ /**
+ * Answer the errors collected by the listener.
+ *
+ * @return an array of errors (not `null`, contains no `null`s)
+ */
+ List<AnalysisError> get errors {
+ Iterable<MapEntry<Source, List<AnalysisError>>> entrySet = getMapEntrySet(_errors);
+ int numEntries = entrySet.length;
+ if (numEntries == 0) {
+ return AnalysisError.NO_ERRORS;
+ }
+ List<AnalysisError> resultList = new List<AnalysisError>();
+ for (MapEntry<Source, List<AnalysisError>> entry in entrySet) {
+ resultList.addAll(entry.getValue());
+ }
+ return new List.from(resultList);
+ }
+
+ /**
+ * Answer the errors collected by the listener for some passed [Source].
+ *
+ * @param source some [Source] for which the caller wants the set of [AnalysisError]s
+ * collected by this listener
+ * @return the errors collected by the listener for the passed [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 source = event.source;
+ List<AnalysisError> errorsForSource = _errors[source];
+ if (_errors[source] == null) {
+ errorsForSource = new List<AnalysisError>();
+ _errors[source] = errorsForSource;
+ }
+ errorsForSource.add(event);
+ }
+}
+/**
+ * Instances of the class `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.staticElement = null;
+ node.propagatedElement = null;
+ return super.visitAssignmentExpression(node);
+ }
+ Object visitBinaryExpression(BinaryExpression node) {
+ node.staticElement = null;
+ node.propagatedElement = 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.staticElement = null;
+ 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.staticElement = null;
+ node.propagatedElement = null;
+ return super.visitFunctionExpressionInvocation(node);
+ }
+ Object visitIndexExpression(IndexExpression node) {
+ node.staticElement = null;
+ node.propagatedElement = null;
+ return super.visitIndexExpression(node);
+ }
+ Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ node.staticElement = null;
+ node.element = null;
+ return super.visitInstanceCreationExpression(node);
+ }
+ Object visitPostfixExpression(PostfixExpression node) {
+ node.staticElement = null;
+ node.propagatedElement = null;
+ return super.visitPostfixExpression(node);
+ }
+ Object visitPrefixExpression(PrefixExpression node) {
+ node.staticElement = null;
+ node.propagatedElement = null;
+ return super.visitPrefixExpression(node);
+ }
+ Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
+ node.staticElement = null;
+ node.element = null;
+ return super.visitRedirectingConstructorInvocation(node);
+ }
+ Object visitSimpleIdentifier(SimpleIdentifier node) {
+ node.staticElement = null;
+ node.propagatedElement = null;
+ return super.visitSimpleIdentifier(node);
+ }
+ Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ node.staticElement = null;
+ node.element = null;
+ return super.visitSuperConstructorInvocation(node);
+ }
+}
+/**
+ * Instances of the class `ResolvableCompilationUnit` represent a compilation unit that is not
+ * referenced by any other objects and for which we have modification stamp information. It is used
+ * by the [LibraryResolver] to resolve a library.
+ */
+class ResolvableCompilationUnit {
+
+ /**
+ * The modification time of the source from which the AST was created.
+ */
+ int _modificationTime = 0;
+
+ /**
+ * The AST that was created from the source.
+ */
+ CompilationUnit _unit;
+
+ /**
+ * Initialize a newly created holder to hold the given values.
+ *
+ * @param modificationTime the modification time of the source from which the AST was created
+ * @param unit the AST that was created from the source
+ */
+ ResolvableCompilationUnit(int modificationTime, CompilationUnit unit) {
+ this._modificationTime = modificationTime;
+ this._unit = unit;
+ }
+
+ /**
+ * Return the AST that was created from the source.
+ *
+ * @return the AST that was created from the source
+ */
+ CompilationUnit get compilationUnit => _unit;
+
+ /**
+ * Return the modification time of the source from which the AST was created.
+ *
+ * @return the modification time of the source from which the AST was created
+ */
+ int get modificationTime => _modificationTime;
+}
+/**
+ * Instances of the class `ResolvableHtmlUnit` represent an HTML unit that is not referenced
+ * by any other objects and for which we have modification stamp information. It is used by the
+ * [ResolveHtmlTask] to resolve an HTML source.
+ */
+class ResolvableHtmlUnit {
+
+ /**
+ * The modification time of the source from which the AST was created.
+ */
+ int _modificationTime = 0;
+
+ /**
+ * The AST that was created from the source.
+ */
+ HtmlUnit _unit;
+
+ /**
+ * Initialize a newly created holder to hold the given values.
+ *
+ * @param modificationTime the modification time of the source from which the AST was created
+ * @param unit the AST that was created from the source
+ */
+ ResolvableHtmlUnit(int modificationTime, HtmlUnit unit) {
+ this._modificationTime = modificationTime;
+ this._unit = unit;
+ }
+
+ /**
+ * Return the AST that was created from the source.
+ *
+ * @return the AST that was created from the source
+ */
+ HtmlUnit get compilationUnit => _unit;
+
+ /**
+ * Return the modification time of the source from which the AST was created.
+ *
+ * @return the modification time of the source from which the AST was created
+ */
+ int get modificationTime => _modificationTime;
+}
+/**
+ * The abstract class `AnalysisTask` defines the behavior of objects used to perform an
+ * analysis task.
+ */
+abstract class AnalysisTask {
+
+ /**
+ * The context in which the task is to be performed.
+ */
+ InternalAnalysisContext _context;
+
+ /**
+ * The exception that was thrown while performing this task, or `null` if the task completed
+ * successfully.
+ */
+ AnalysisException _thrownException;
+
+ /**
+ * Initialize a newly created task to perform analysis within the given context.
+ *
+ * @param context the context in which the task is to be performed
+ */
+ AnalysisTask(InternalAnalysisContext context) {
+ this._context = context;
+ }
+
+ /**
+ * Use the given visitor to visit this task.
+ *
+ * @param visitor the visitor that should be used to visit this task
+ * @return the value returned by the visitor
+ * @throws AnalysisException if the visitor throws the exception
+ */
+ accept(AnalysisTaskVisitor visitor);
+
+ /**
+ * Return the exception that was thrown while performing this task, or `null` if the task
+ * completed successfully.
+ *
+ * @return the exception that was thrown while performing this task
+ */
+ AnalysisException get exception => _thrownException;
+
+ /**
+ * Perform this analysis task and use the given visitor to visit this task after it has completed.
+ *
+ * @param visitor the visitor used to visit this task after it has completed
+ * @return the value returned by the visitor
+ * @throws AnalysisException if the visitor throws the exception
+ */
+ Object perform(AnalysisTaskVisitor visitor) {
+ try {
+ safelyPerform();
+ } on AnalysisException catch (exception) {
+ _thrownException = exception;
+ AnalysisEngine.instance.logger.logInformation2("Task failed: ${taskDescription}", exception);
+ }
+ return accept(visitor);
+ }
+ String toString() => taskDescription;
+
+ /**
+ * Return the context in which the task is to be performed.
+ *
+ * @return the context in which the task is to be performed
+ */
+ InternalAnalysisContext get context => _context;
+
+ /**
+ * Return a textual description of this task.
+ *
+ * @return a textual description of this task
+ */
+ String get taskDescription;
+
+ /**
+ * Perform this analysis task, protected by an exception handler.
+ *
+ * @throws AnalysisException if an exception occurs while performing the task
+ */
+ void internalPerform();
+
+ /**
+ * Perform this analysis task, ensuring that all exceptions are wrapped in an
+ * [AnalysisException].
+ *
+ * @throws AnalysisException if any exception occurs while performing the task
+ */
+ void safelyPerform() {
+ try {
+ internalPerform();
+ } on AnalysisException catch (exception) {
+ throw exception;
+ } catch (exception) {
+ throw new AnalysisException.con3(exception);
+ }
+ }
+}
+/**
+ * The interface `AnalysisTaskVisitor` defines the behavior of objects that can visit tasks.
+ * While tasks are not structured in any interesting way, this class provides the ability to
+ * dispatch to an appropriate method.
+ */
+abstract class AnalysisTaskVisitor<E> {
+
+ /**
+ * Visit a [ParseDartTask].
+ *
+ * @param task the task to be visited
+ * @return the result of visiting the task
+ * @throws AnalysisException if the visitor throws an exception for some reason
+ */
+ E visitParseDartTask(ParseDartTask task);
+
+ /**
+ * Visit a [ParseHtmlTask].
+ *
+ * @param task the task to be visited
+ * @return the result of visiting the task
+ * @throws AnalysisException if the visitor throws an exception for some reason
+ */
+ E visitParseHtmlTask(ParseHtmlTask task);
+
+ /**
+ * Visit a [ResolveDartLibraryTask].
+ *
+ * @param task the task to be visited
+ * @return the result of visiting the task
+ * @throws AnalysisException if the visitor throws an exception for some reason
+ */
+ E visitResolveDartLibraryTask(ResolveDartLibraryTask task);
+
+ /**
+ * Visit a [ResolveDartUnitTask].
+ *
+ * @param task the task to be visited
+ * @return the result of visiting the task
+ * @throws AnalysisException if the visitor throws an exception for some reason
+ */
+ E visitResolveDartUnitTask(ResolveDartUnitTask task);
+
+ /**
+ * Visit a [ResolveHtmlTask].
+ *
+ * @param task the task to be visited
+ * @return the result of visiting the task
+ * @throws AnalysisException if the visitor throws an exception for some reason
+ */
+ E visitResolveHtmlTask(ResolveHtmlTask task);
+}
+/**
+ * Instances of the class `ParseDartTask` parse a specific source as a Dart file.
+ */
+class ParseDartTask extends AnalysisTask {
+
+ /**
+ * The source to be parsed.
+ */
+ Source _source;
+
+ /**
+ * The time at which the contents of the source were last modified.
+ */
+ int _modificationTime = -1;
+
+ /**
+ * The line information that was produced.
+ */
+ LineInfo _lineInfo;
+
+ /**
+ * The compilation unit that was produced by parsing the source.
+ */
+ CompilationUnit _unit;
+
+ /**
+ * The errors that were produced by scanning and parsing the source.
+ */
+ List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
+
+ /**
+ * A flag indicating whether the source contains a 'part of' directive.
+ */
+ bool _hasPartOfDirective2 = false;
+
+ /**
+ * A flag indicating whether the source contains a 'library' directive.
+ */
+ bool _hasLibraryDirective2 = false;
+
+ /**
+ * A set containing the sources referenced by 'export' directives.
+ */
+ Set<Source> _exportedSources = new Set<Source>();
+
+ /**
+ * A set containing the sources referenced by 'import' directives.
+ */
+ Set<Source> _importedSources = new Set<Source>();
+
+ /**
+ * A set containing the sources referenced by 'part' directives.
+ */
+ Set<Source> _includedSources = new Set<Source>();
+
+ /**
+ * Initialize a newly created task to perform analysis within the given context.
+ *
+ * @param context the context in which the task is to be performed
+ * @param source the source to be parsed
+ */
+ ParseDartTask(InternalAnalysisContext context, Source source) : super(context) {
+ this._source = source;
+ }
+ accept(AnalysisTaskVisitor visitor) => visitor.visitParseDartTask(this);
+
+ /**
+ * Return the compilation unit that was produced by parsing the source, or `null` if the
+ * task has not yet been performed or if an exception occurred.
+ *
+ * @return the compilation unit that was produced by parsing the source
+ */
+ CompilationUnit get compilationUnit => _unit;
+
+ /**
+ * Return the errors that were produced by scanning and parsing the source, or `null` if the
+ * task has not yet been performed or if an exception occurred.
+ *
+ * @return the errors that were produced by scanning and parsing the source
+ */
+ List<AnalysisError> get errors => _errors;
+
+ /**
+ * Return an array containing the sources referenced by 'export' directives, or an empty array if
+ * the task has not yet been performed or if an exception occurred.
+ *
+ * @return an array containing the sources referenced by 'export' directives
+ */
+ List<Source> get exportedSources => toArray(_exportedSources);
+
+ /**
+ * Return an array containing the sources referenced by 'import' directives, or an empty array if
+ * the task has not yet been performed or if an exception occurred.
+ *
+ * @return an array containing the sources referenced by 'import' directives
+ */
+ List<Source> get importedSources => toArray(_importedSources);
+
+ /**
+ * Return an array containing the sources referenced by 'part' directives, or an empty array if
+ * the task has not yet been performed or if an exception occurred.
+ *
+ * @return an array containing the sources referenced by 'part' directives
+ */
+ List<Source> get includedSources => toArray(_includedSources);
+
+ /**
+ * Return the line information that was produced, or `null` if the task has not yet been
+ * performed or if an exception occurred.
+ *
+ * @return the line information that was produced
+ */
+ LineInfo get lineInfo => _lineInfo;
+
+ /**
+ * Return the time at which the contents of the source that was parsed were last modified, or a
+ * negative value if the task has not yet been performed or if an exception occurred.
+ *
+ * @return the time at which the contents of the source that was parsed were last modified
+ */
+ int get modificationTime => _modificationTime;
+
+ /**
+ * Return the source that is to be parsed.
+ *
+ * @return the source to be parsed
+ */
+ Source get source => _source;
+
+ /**
+ * Return `true` if the source contains a 'library' directive, or `false` if the task
+ * has not yet been performed or if an exception occurred.
+ *
+ * @return `true` if the source contains a 'library' directive
+ */
+ bool hasLibraryDirective() => _hasLibraryDirective2;
+
+ /**
+ * Return `true` if the source contains a 'part of' directive, or `false` if the task
+ * has not yet been performed or if an exception occurred.
+ *
+ * @return `true` if the source contains a 'part of' directive
+ */
+ bool hasPartOfDirective() => _hasPartOfDirective2;
+ String get taskDescription => "parse as dart ${_source.fullName}";
+ void internalPerform() {
+ RecordingErrorListener errorListener = new RecordingErrorListener();
+ List<Token> token = [null];
+ Source_ContentReceiver receiver = new Source_ContentReceiver_10(this, errorListener, token);
try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.parseHtmlUnit(source);
- } on AnalysisException catch (e) {
- recordAnalysisException(instrumentation, e);
- throw e;
- } finally {
- instrumentation.log();
+ _source.getContents(receiver);
+ } catch (exception) {
+ _modificationTime = _source.modificationStamp;
+ throw new AnalysisException.con3(exception);
}
- }
- 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);
+ Parser parser = new Parser(_source, errorListener);
+ _unit = parser.parseCompilationUnit(token[0]);
+ _errors = errorListener.getErrors2(_source);
+ for (Directive directive in _unit.directives) {
+ if (directive is ExportDirective) {
+ Source exportSource = resolveSource(_source, directive as ExportDirective);
+ if (exportSource != null) {
+ javaSetAdd(_exportedSources, exportSource);
+ }
+ } else if (directive is ImportDirective) {
+ Source importSource = resolveSource(_source, directive as ImportDirective);
+ if (importSource != null) {
+ javaSetAdd(_importedSources, importSource);
+ }
+ } else if (directive is LibraryDirective) {
+ _hasLibraryDirective2 = true;
+ } else if (directive is PartDirective) {
+ Source partSource = resolveSource(_source, directive as PartDirective);
+ if (partSource != null) {
+ javaSetAdd(_includedSources, partSource);
+ }
+ } else if (directive is PartOfDirective) {
+ _hasPartOfDirective2 = true;
}
- return ret;
- } finally {
- instrumentation.log2(2);
}
+ _unit.parsingErrors = _errors;
+ _unit.lineInfo = _lineInfo;
}
- void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
- _basis.recordLibraryElements(elementMap);
- }
- 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();
+
+ /**
+ * Return the result of resolving the URI of the given URI-based directive against the URI of the
+ * given library, or `null` if the URI is not valid.
+ *
+ * @param librarySource the source representing the library containing the directive
+ * @param directive the directive which URI should be resolved
+ * @return the result of resolving the URI against the URI of the library
+ */
+ Source resolveSource(Source librarySource, UriBasedDirective directive) {
+ StringLiteral uriLiteral = directive.uri;
+ if (uriLiteral is StringInterpolation) {
+ return null;
}
- }
- 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();
+ String uriContent = uriLiteral.stringValue.trim();
+ if (uriContent == null) {
+ return null;
}
- }
- HtmlUnit resolveHtmlUnit(Source htmlSource) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-resolveHtmlUnit");
+ uriContent = Uri.encodeFull(uriContent);
try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.resolveHtmlUnit(htmlSource);
- } on AnalysisException catch (e) {
- recordAnalysisException(instrumentation, e);
- throw e;
- } finally {
- instrumentation.log();
+ parseUriWithException(uriContent);
+ return context.sourceFactory.resolveUri(librarySource, uriContent);
+ } on URISyntaxException catch (exception) {
+ return null;
}
}
- void set analysisOptions(AnalysisOptions options) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-setAnalysisOptions");
- try {
- instrumentation.metric3("contextId", _contextId);
- _basis.analysisOptions = options;
- } finally {
- instrumentation.log();
+
+ /**
+ * Efficiently convert the given set of sources to an array.
+ *
+ * @param sources the set to be converted
+ * @return an array containing all of the sources in the given set
+ */
+ List<Source> toArray(Set<Source> sources) {
+ int size = sources.length;
+ if (size == 0) {
+ return Source.EMPTY_ARRAY;
}
+ return new List.from(sources);
}
- void set analysisPriorityOrder(List<Source> sources) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-setAnalysisPriorityOrder");
- try {
- instrumentation.metric3("contextId", _contextId);
- _basis.analysisPriorityOrder = sources;
- } finally {
- instrumentation.log();
- }
+}
+class Source_ContentReceiver_10 implements Source_ContentReceiver {
+ final ParseDartTask ParseDartTask_this;
+ RecordingErrorListener errorListener;
+ List<Token> token;
+ Source_ContentReceiver_10(this.ParseDartTask_this, this.errorListener, this.token);
+ void accept(CharBuffer contents, int modificationTime2) {
+ ParseDartTask_this._modificationTime = modificationTime2;
+ CharBufferScanner scanner = new CharBufferScanner(ParseDartTask_this._source, contents, errorListener);
+ token[0] = scanner.tokenize();
+ ParseDartTask_this._lineInfo = new LineInfo(scanner.lineStarts);
}
- void setContents(Source source, String contents) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-setContents");
+ void accept2(String contents, int modificationTime2) {
+ ParseDartTask_this._modificationTime = modificationTime2;
+ StringScanner scanner = new StringScanner(ParseDartTask_this._source, contents, errorListener);
+ token[0] = scanner.tokenize();
+ ParseDartTask_this._lineInfo = new LineInfo(scanner.lineStarts);
+ }
+}
+/**
+ * Instances of the class `ParseHtmlTask` parse a specific source as an HTML file.
+ */
+class ParseHtmlTask extends AnalysisTask {
+
+ /**
+ * The source to be parsed.
+ */
+ Source _source;
+
+ /**
+ * The time at which the contents of the source were last modified.
+ */
+ int _modificationTime = -1;
+
+ /**
+ * The line information that was produced.
+ */
+ LineInfo _lineInfo;
+
+ /**
+ * The HTML unit that was produced by parsing the source.
+ */
+ HtmlUnit _unit;
+
+ /**
+ * An array containing the sources of the libraries that are referenced within the HTML.
+ */
+ List<Source> _referencedLibraries = Source.EMPTY_ARRAY;
+
+ /**
+ * The name of the 'src' attribute in a HTML tag.
+ */
+ static String _ATTRIBUTE_SRC = "src";
+
+ /**
+ * The name of the 'type' attribute in a HTML tag.
+ */
+ static String _ATTRIBUTE_TYPE = "type";
+
+ /**
+ * The name of the 'script' tag in an HTML file.
+ */
+ static String _TAG_SCRIPT = "script";
+
+ /**
+ * The value of the 'type' attribute of a 'script' tag that indicates that the script is written
+ * in Dart.
+ */
+ static String _TYPE_DART = "application/dart";
+
+ /**
+ * Initialize a newly created task to perform analysis within the given context.
+ *
+ * @param context the context in which the task is to be performed
+ * @param source the source to be parsed
+ */
+ ParseHtmlTask(InternalAnalysisContext context, Source source) : super(context) {
+ this._source = source;
+ }
+ accept(AnalysisTaskVisitor visitor) => visitor.visitParseHtmlTask(this);
+
+ /**
+ * Return the HTML unit that was produced by parsing the source.
+ *
+ * @return the HTML unit that was produced by parsing the source
+ */
+ HtmlUnit get htmlUnit => _unit;
+
+ /**
+ * Return the line information that was produced, or `null` if the task has not yet been
+ * performed or if an exception occurred.
+ *
+ * @return the line information that was produced
+ */
+ LineInfo get lineInfo => _lineInfo;
+
+ /**
+ * Return the time at which the contents of the source that was parsed were last modified, or a
+ * negative value if the task has not yet been performed or if an exception occurred.
+ *
+ * @return the time at which the contents of the source that was parsed were last modified
+ */
+ int get modificationTime => _modificationTime;
+
+ /**
+ * Return an array containing the sources of the libraries that are referenced within the HTML.
+ *
+ * @return the sources of the libraries that are referenced within the HTML
+ */
+ List<Source> get referencedLibraries => _referencedLibraries;
+
+ /**
+ * Return the source that was or is to be parsed.
+ *
+ * @return the source was or is to be parsed
+ */
+ Source get source => _source;
+ String get taskDescription => "parse as html ${_source.fullName}";
+ void internalPerform() {
+ HtmlScanner scanner = new HtmlScanner(_source);
try {
- instrumentation.metric3("contextId", _contextId);
- _basis.setContents(source, contents);
- } finally {
- instrumentation.log();
+ _source.getContents(scanner);
+ } catch (exception) {
+ throw new AnalysisException.con3(exception);
}
+ HtmlScanResult scannerResult = scanner.result;
+ _modificationTime = scannerResult.modificationTime;
+ _lineInfo = new LineInfo(scannerResult.lineStarts);
+ HtmlParseResult result = new HtmlParser(_source).parse(scannerResult);
+ _unit = result.htmlUnit;
+ _referencedLibraries = librarySources;
}
- void set sourceFactory(SourceFactory factory) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-setSourceFactory");
- try {
- instrumentation.metric3("contextId", _contextId);
- _basis.sourceFactory = factory;
- } finally {
- instrumentation.log();
+
+ /**
+ * Return the sources of libraries that are referenced in the specified HTML file.
+ *
+ * @return the sources of libraries that are referenced in the HTML file
+ */
+ List<Source> get librarySources {
+ List<Source> libraries = new List<Source>();
+ _unit.accept(new RecursiveXmlVisitor_11(this, libraries));
+ if (libraries.isEmpty) {
+ return Source.EMPTY_ARRAY;
}
+ return new List.from(libraries);
}
- Iterable<Source> sourcesToResolve(List<Source> changedSources) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-sourcesToResolve");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.sourcesToResolve(changedSources);
- } finally {
- instrumentation.log();
+}
+class RecursiveXmlVisitor_11 extends RecursiveXmlVisitor<Object> {
+ final ParseHtmlTask ParseHtmlTask_this;
+ List<Source> libraries;
+ RecursiveXmlVisitor_11(this.ParseHtmlTask_this, this.libraries) : super();
+ Object visitXmlTagNode(XmlTagNode node) {
+ if (javaStringEqualsIgnoreCase(node.tag.lexeme, ParseHtmlTask._TAG_SCRIPT)) {
+ bool isDartScript = false;
+ XmlAttributeNode scriptAttribute = null;
+ for (XmlAttributeNode attribute in node.attributes) {
+ if (javaStringEqualsIgnoreCase(attribute.name.lexeme, ParseHtmlTask._ATTRIBUTE_SRC)) {
+ scriptAttribute = attribute;
+ } else if (javaStringEqualsIgnoreCase(attribute.name.lexeme, ParseHtmlTask._ATTRIBUTE_TYPE)) {
+ if (javaStringEqualsIgnoreCase(attribute.text, ParseHtmlTask._TYPE_DART)) {
+ isDartScript = true;
+ }
+ }
+ }
+ if (isDartScript && scriptAttribute != null) {
+ try {
+ Uri uri = new Uri(path: scriptAttribute.text);
+ String fileName = uri.path;
+ Source librarySource = ParseHtmlTask_this.context.sourceFactory.resolveUri(ParseHtmlTask_this._source, fileName);
+ if (librarySource.exists()) {
+ libraries.add(librarySource);
+ }
+ } catch (exception) {
+ AnalysisEngine.instance.logger.logInformation2("Invalid URL ('${scriptAttribute.text}') in script tag in '${ParseHtmlTask_this._source.fullName}'", exception);
+ }
+ }
}
+ return super.visitXmlTagNode(node);
}
}
/**
- * The interface `InternalAnalysisContext` defines additional behavior for an analysis context
- * that is required by internal users of the context.
+ * Instances of the class `ResolveDartLibraryTask` parse a specific Dart library.
*/
-abstract class InternalAnalysisContext implements AnalysisContext {
+class ResolveDartLibraryTask extends AnalysisTask {
+
+ /**
+ * The source representing the file whose compilation unit is to be returned.
+ */
+ Source _unitSource;
+
+ /**
+ * The source representing the library to be resolved.
+ */
+ Source _librarySource;
/**
- * 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
+ * The library resolver holding information about the libraries that were resolved.
*/
- void addSourceInfo(Source source, SourceEntry info);
+ LibraryResolver _resolver;
/**
- * Return an array containing the sources of the libraries that are exported by the library with
- * the given source. The array will be empty if the given source is invalid, if the given source
- * does not represent a library, or if the library does not export any other libraries.
+ * Initialize a newly created task to perform analysis within the given context.
*
- * @param source the source representing the library whose exports are to be returned
- * @return the sources of the libraries that are exported by the given library
- * @throws AnalysisException if the exported libraries could not be computed
+ * @param context the context in which the task is to be performed
+ * @param unitSource the source representing the file whose compilation unit is to be returned
+ * @param librarySource the source representing the library to be resolved
*/
- List<Source> computeExportedLibraries(Source source);
+ ResolveDartLibraryTask(InternalAnalysisContext context, Source unitSource, Source librarySource) : super(context) {
+ this._unitSource = unitSource;
+ this._librarySource = librarySource;
+ }
+ accept(AnalysisTaskVisitor visitor) => visitor.visitResolveDartLibraryTask(this);
/**
- * Return an array containing the sources of the libraries that are imported by the library with
- * the given source. The array will be empty if the given source is invalid, if the given source
- * does not represent a library, or if the library does not import any other libraries.
+ * Return the library resolver holding information about the libraries that were resolved.
*
- * @param source the source representing the library whose imports are to be returned
- * @return the sources of the libraries that are imported by the given library
- * @throws AnalysisException if the imported libraries could not be computed
+ * @return the library resolver holding information about the libraries that were resolved
*/
- List<Source> computeImportedLibraries(Source source);
+ LibraryResolver get libraryResolver => _resolver;
/**
- * 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.
+ * Return the source representing the library to be resolved.
*
- * @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
+ * @return the source representing the library to be resolved
*/
- ResolvableCompilationUnit computeResolvableCompilationUnit(Source source);
+ Source get librarySource => _librarySource;
/**
- * Initialize the specified context by removing the specified sources from the receiver and adding
- * them to the specified context.
+ * Return the source representing the file whose compilation unit is to be returned.
*
- * @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
+ * @return the source representing the file whose compilation unit is to be returned
*/
- InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext);
+ Source get unitSource => _unitSource;
+ String get taskDescription => "resolve library ${_librarySource.fullName}";
+ void internalPerform() {
+ _resolver = new LibraryResolver(context);
+ _resolver.resolveLibrary(_librarySource, true);
+ }
+}
+/**
+ * Instances of the class `ResolveDartUnitTask` resolve a single Dart file based on a existing
+ * element model.
+ */
+class ResolveDartUnitTask extends AnalysisTask {
/**
- * 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
+ * The source that is to be resolved.
*/
- Namespace getPublicNamespace(LibraryElement library);
+ Source _source;
/**
- * 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
+ * The element model for the library containing the source.
*/
- Namespace getPublicNamespace2(Source source);
+ LibraryElement _libraryElement;
/**
- * Returns a statistics about this context.
+ * The time at which the contents of the source were last modified.
*/
- AnalysisContentStatistics get statistics;
+ int _modificationTime = -1;
/**
- * Given a table mapping the source for the libraries represented by the corresponding elements to
- * the elements representing the libraries, record those mappings.
+ * The compilation unit that was resolved by this task.
+ */
+ CompilationUnit _resolvedUnit;
+
+ /**
+ * Initialize a newly created task to perform analysis within the given context.
*
- * @param elementMap a table mapping the source for the libraries represented by the elements to
- * the elements representing the libraries
+ * @param context the context in which the task is to be performed
+ * @param source the source to be parsed
+ * @param libraryElement the element model for the library containing the source
*/
- void recordLibraryElements(Map<Source, LibraryElement> elementMap);
-}
-/**
- * Instances of the class `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 {
+ ResolveDartUnitTask(InternalAnalysisContext context, Source source, LibraryElement libraryElement) : super(context) {
+ this._source = source;
+ this._libraryElement = libraryElement;
+ }
+ accept(AnalysisTaskVisitor visitor) => visitor.visitResolveDartUnitTask(this);
/**
- * A HashMap of lists containing the errors that were collected, keyed by each [Source].
+ * Return the source for the library containing the source that is to be resolved.
+ *
+ * @return the source for the library containing the source that is to be resolved
*/
- Map<Source, List<AnalysisError>> _errors = new Map<Source, List<AnalysisError>>();
+ Source get librarySource => _libraryElement.source;
/**
- * Add all of the errors recorded by the given listener to this listener.
+ * Return the time at which the contents of the source that was parsed were last modified, or a
+ * negative value if the task has not yet been performed or if an exception occurred.
*
- * @param listener the listener that has recorded the errors to be added
+ * @return the time at which the contents of the source that was parsed were last modified
*/
- void addAll(RecordingErrorListener listener) {
- for (AnalysisError error in listener.errors) {
- onError(error);
- }
- }
+ int get modificationTime => _modificationTime;
/**
- * Answer the errors collected by the listener.
+ * Return the compilation unit that was resolved by this task.
*
- * @return an array of errors (not `null`, contains no `null`s)
+ * @return the compilation unit that was resolved by this task
*/
- List<AnalysisError> get errors {
- Iterable<MapEntry<Source, List<AnalysisError>>> entrySet = getMapEntrySet(_errors);
- int numEntries = entrySet.length;
- if (numEntries == 0) {
- return AnalysisError.NO_ERRORS;
- }
- List<AnalysisError> resultList = new List<AnalysisError>();
- for (MapEntry<Source, List<AnalysisError>> entry in entrySet) {
- resultList.addAll(entry.getValue());
+ CompilationUnit get resolvedUnit => _resolvedUnit;
+
+ /**
+ * Return the source that is to be resolved.
+ *
+ * @return the source to be resolved
+ */
+ Source get source => _source;
+ String get taskDescription => "resolve unit ${_libraryElement.source.fullName}";
+ void internalPerform() {
+ Source coreLibrarySource = _libraryElement.context.sourceFactory.forUri(DartSdk.DART_CORE);
+ LibraryElement coreElement = context.computeLibraryElement(coreLibrarySource);
+ TypeProvider typeProvider = new TypeProviderImpl(coreElement);
+ ResolvableCompilationUnit resolvableUnit = context.computeResolvableCompilationUnit(_source);
+ _modificationTime = resolvableUnit.modificationTime;
+ CompilationUnit unit = resolvableUnit.compilationUnit;
+ if (unit == null) {
+ throw new AnalysisException.con1("Internal error: computeResolvableCompilationUnit returned a value without a parsed Dart unit");
+ }
+ new DeclarationResolver().resolve(unit, find(_libraryElement, _source));
+ RecordingErrorListener errorListener = new RecordingErrorListener();
+ TypeResolverVisitor typeResolverVisitor = new TypeResolverVisitor.con2(_libraryElement, _source, typeProvider, errorListener);
+ unit.accept(typeResolverVisitor);
+ InheritanceManager inheritanceManager = new InheritanceManager(_libraryElement);
+ ResolverVisitor resolverVisitor = new ResolverVisitor.con2(_libraryElement, _source, typeProvider, inheritanceManager, errorListener);
+ unit.accept(resolverVisitor);
+ for (ProxyConditionalAnalysisError conditionalCode in resolverVisitor.proxyConditionalAnalysisErrors) {
+ if (conditionalCode.shouldIncludeErrorCode()) {
+ resolverVisitor.reportError(conditionalCode.analysisError);
+ }
}
- return new List.from(resultList);
+ ErrorReporter errorReporter = new ErrorReporter(errorListener, _source);
+ ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, _libraryElement, typeProvider, inheritanceManager);
+ unit.accept(errorVerifier);
+ ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, typeProvider);
+ unit.accept(constantVerifier);
+ unit.resolutionErrors = errorListener.errors;
+ _resolvedUnit = unit;
}
/**
- * Answer the errors collected by the listener for some passed [Source].
+ * Search the compilation units that are part of the given library and return the element
+ * representing the compilation unit with the given source. Return `null` if there is no
+ * such compilation unit.
*
- * @param source some [Source] for which the caller wants the set of [AnalysisError]s
- * collected by this listener
- * @return the errors collected by the listener for the passed [Source]
+ * @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
*/
- List<AnalysisError> getErrors2(Source source) {
- List<AnalysisError> errorsForSource = _errors[source];
- if (errorsForSource == null) {
- return AnalysisError.NO_ERRORS;
- } else {
- return new List.from(errorsForSource);
+ CompilationUnitElement find(LibraryElement libraryElement, Source unitSource) {
+ CompilationUnitElement element = libraryElement.definingCompilationUnit;
+ if (element.source == unitSource) {
+ return element;
}
- }
- void onError(AnalysisError event) {
- Source source = event.source;
- List<AnalysisError> errorsForSource = _errors[source];
- if (_errors[source] == null) {
- errorsForSource = new List<AnalysisError>();
- _errors[source] = errorsForSource;
+ for (CompilationUnitElement partElement in libraryElement.parts) {
+ if (partElement.source == unitSource) {
+ return partElement;
+ }
}
- errorsForSource.add(event);
- }
-}
-/**
- * Instances of the class `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.staticElement = null;
- node.propagatedElement = null;
- return super.visitAssignmentExpression(node);
- }
- Object visitBinaryExpression(BinaryExpression node) {
- node.staticElement = null;
- node.propagatedElement = 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.staticElement = null;
- 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.staticElement = null;
- node.propagatedElement = null;
- return super.visitFunctionExpressionInvocation(node);
- }
- Object visitIndexExpression(IndexExpression node) {
- node.staticElement = null;
- node.propagatedElement = null;
- return super.visitIndexExpression(node);
- }
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
- node.staticElement = null;
- node.element = null;
- return super.visitInstanceCreationExpression(node);
- }
- Object visitPostfixExpression(PostfixExpression node) {
- node.staticElement = null;
- node.propagatedElement = null;
- return super.visitPostfixExpression(node);
- }
- Object visitPrefixExpression(PrefixExpression node) {
- node.staticElement = null;
- node.propagatedElement = null;
- return super.visitPrefixExpression(node);
- }
- Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
- node.staticElement = null;
- node.element = null;
- return super.visitRedirectingConstructorInvocation(node);
- }
- Object visitSimpleIdentifier(SimpleIdentifier node) {
- node.staticElement = null;
- node.propagatedElement = null;
- return super.visitSimpleIdentifier(node);
- }
- Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
- node.staticElement = null;
- node.element = null;
- return super.visitSuperConstructorInvocation(node);
+ return null;
}
}
/**
- * Instances of the class `ResolvableCompilationUnit` represent a compilation unit that is not
- * referenced by any other objects and for which we have modification stamp information. It is used
- * by the [LibraryResolver] to resolve a library.
+ * Instances of the class `ResolveHtmlTask` resolve a specific source as an HTML file.
*/
-class ResolvableCompilationUnit {
+class ResolveHtmlTask extends AnalysisTask {
/**
- * The modification time of the source from which the AST was created.
+ * The source to be resolved.
*/
- int _modificationStamp = 0;
+ Source _source;
/**
- * The AST that was created from the source.
+ * The time at which the contents of the source were last modified.
*/
- CompilationUnit _unit;
+ int _modificationTime = -1;
/**
- * Initialize a newly created holder to hold the given values.
+ * The element produced by resolving the source.
+ */
+ HtmlElement _element = null;
+
+ /**
+ * The resolution errors that were discovered while resolving the source.
+ */
+ List<AnalysisError> _resolutionErrors = AnalysisError.NO_ERRORS;
+
+ /**
+ * Initialize a newly created task to perform analysis within the given context.
*
- * @param modificationStamp the modification time of the source from which the AST was created
- * @param unit the AST that was created from the source
+ * @param context the context in which the task is to be performed
+ * @param source the source to be resolved
*/
- ResolvableCompilationUnit(int modificationStamp, CompilationUnit unit) {
- this._modificationStamp = modificationStamp;
- this._unit = unit;
+ ResolveHtmlTask(InternalAnalysisContext context, Source source) : super(context) {
+ this._source = source;
}
+ accept(AnalysisTaskVisitor visitor) => visitor.visitResolveHtmlTask(this);
+ HtmlElement get element => _element;
/**
- * Return the AST that was created from the source.
+ * Return the time at which the contents of the source that was parsed were last modified, or a
+ * negative value if the task has not yet been performed or if an exception occurred.
*
- * @return the AST that was created from the source
+ * @return the time at which the contents of the source that was parsed were last modified
*/
- CompilationUnit get compilationUnit => _unit;
+ int get modificationTime => _modificationTime;
+ List<AnalysisError> get resolutionErrors => _resolutionErrors;
/**
- * Return the modification time of the source from which the AST was created.
+ * Return the source that was or is to be resolved.
*
- * @return the modification time of the source from which the AST was created
+ * @return the source was or is to be resolved
*/
- int get modificationStamp => _modificationStamp;
+ Source get source => _source;
+ String get taskDescription => "resolve as html ${_source.fullName}";
+ void internalPerform() {
+ ResolvableHtmlUnit resolvableHtmlUnit = context.computeResolvableHtmlUnit(_source);
+ HtmlUnit unit = resolvableHtmlUnit.compilationUnit;
+ if (unit == null) {
+ throw new AnalysisException.con1("Internal error: computeResolvableHtmlUnit returned a value without a parsed HTML unit");
+ }
+ _modificationTime = resolvableHtmlUnit.modificationTime;
+ HtmlUnitBuilder builder = new HtmlUnitBuilder(context);
+ _element = builder.buildHtmlElement2(_source, _modificationTime, unit);
+ _resolutionErrors = builder.errorListener.getErrors2(_source);
+ }
}
/**
* The interface `Logger` defines the behavior of objects that can be used to receive

Powered by Google App Engine
This is Rietveld 408576698