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

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

Issue 24481002: 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 eb510b8b8e252b2bce206a30de5601cc59e67c55..44685da8e85e68922a86c5148f6fb5a736d796cf 100644
--- a/pkg/analyzer_experimental/lib/src/generated/engine.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/engine.dart
@@ -4,6 +4,7 @@ library engine;
import 'java_core.dart';
import 'java_engine.dart';
import 'utilities_collection.dart';
+import 'utilities_general.dart';
import 'instrumentation.dart';
import 'error.dart';
import 'source.dart';
@@ -75,25 +76,14 @@ 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();
}
- if (_useExperimentalContext) {
- return new InstrumentedAnalysisContextImpl.con1(new DelegatingAnalysisContextImpl2());
- }
return new InstrumentedAnalysisContextImpl.con1(new DelegatingAnalysisContextImpl());
}
@@ -105,13 +95,6 @@ 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.
*
@@ -121,15 +104,6 @@ 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].
@@ -137,7 +111,16 @@ class AnalysisEngine {
abstract class AnalysisContentStatistics {
/**
- * @return the statistics for each kind of cached data.
+ * Return the exceptions that caused some entries to have a state of [CacheState#ERROR].
+ *
+ * @return the exceptions that caused some entries to have a state of [CacheState#ERROR]
+ */
+ List<AnalysisException> get exceptions;
+
+ /**
+ * Return the statistics for each kind of cached data.
+ *
+ * @return the statistics for each kind of cached data
*/
List<AnalysisContentStatistics_CacheRow> get cacheRows;
}
@@ -677,6 +660,13 @@ class AnalysisException extends JavaException {
abstract class AnalysisOptions {
/**
+ * Return `true` if analysis is to generate dart2js related hint results.
+ *
+ * @return `true` if analysis is to generate dart2js related hint results
+ */
+ bool get dart2jsHint;
+
+ /**
* Return `true` if analysis is to generate hint results (e.g. type inference based
* information and pub best practices).
*
@@ -791,6 +781,55 @@ class ChangeSet {
removedContainers.add(container);
}
}
+ String toString() {
+ JavaStringBuilder builder = new JavaStringBuilder();
+ bool needsSeparator = appendSources(builder, added3, false, "added");
+ needsSeparator = appendSources(builder, changed3, needsSeparator, "changed");
+ appendSources(builder, removed3, needsSeparator, "removed");
+ int count = removedContainers.length;
+ if (count > 0) {
+ if (removed3.isEmpty) {
+ if (needsSeparator) {
+ builder.append("; ");
+ }
+ builder.append("removed: from ");
+ builder.append(count);
+ builder.append(" containers");
+ } else {
+ builder.append(", and more from ");
+ builder.append(count);
+ builder.append(" containers");
+ }
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Append the given sources to the given builder, prefixed with the given label and possibly a
+ * separator.
+ *
+ * @param builder the builder to which the sources are to be appended
+ * @param sources the sources to be appended
+ * @param needsSeparator `true` if a separator is needed before the label
+ * @param label the label used to prefix the sources
+ * @return `true` if future lists of sources will need a separator
+ */
+ bool appendSources(JavaStringBuilder builder, List<Source> sources, bool needsSeparator, String label) {
+ if (sources.isEmpty) {
+ return needsSeparator;
+ }
+ if (needsSeparator) {
+ builder.append("; ");
+ }
+ builder.append(label);
+ String prefix = " ";
+ for (Source source in sources) {
+ builder.append(prefix);
+ builder.append(source.fullName);
+ prefix = ", ";
+ }
+ return true;
+ }
}
/**
* Instances of the class `AnalysisCache` implement an LRU cache of information related to
@@ -877,12 +916,12 @@ class AnalysisCache {
}
/**
- * Return a set containing all of the map entries mapping sources to cache entries. Clients should
- * not modify the returned set.
+ * Return a collection containing all of the map entries mapping sources to cache entries. Clients
+ * should not modify the returned collection.
*
- * @return a set containing all of the map entries mapping sources to cache entries
+ * @return a collection containing all of the map entries mapping sources to cache entries
*/
- Set<MapEntry<Source, SourceEntry>> entrySet() => getMapEntrySet(_sourceMap);
+ Iterable<MapEntry<Source, SourceEntry>> entrySet() => getMapEntrySet(_sourceMap);
/**
* Return the entry associated with the given source.
@@ -1285,15 +1324,17 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
int _bitmask = 0;
/**
- * Mask indicating that this library is launchable: that the file has a main method.
+ * The index of the bit in the [bitmask] indicating that this library is launchable: that
+ * the file has a main method.
*/
- static int _LAUNCHABLE = 1 << 1;
+ static int _LAUNCHABLE_INDEX = 1;
/**
- * Mask indicating that the library is client code: that the library depends on the html library.
- * If the library is not "client code", then it is referenced as "server code".
+ * The index of the bit in the [bitmask] indicating that the library is client code: that
+ * the library depends on the html library. If the library is not "client code", then it is
+ * referred to as "server code".
*/
- static int _CLIENT_CODE = 1 << 2;
+ static int _CLIENT_CODE_INDEX = 2;
/**
* Flush any AST structures being maintained by this entry.
@@ -1404,11 +1445,11 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
while (state != null) {
if (librarySource2 == state._librarySource) {
if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
- return _resolutionState._resolutionErrorsState;
+ return state._resolutionErrorsState;
} else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
- return _resolutionState._resolvedUnitState;
+ return state._resolvedUnitState;
} else if (identical(descriptor, DartEntry.HINTS)) {
- return _resolutionState._hintsState;
+ return state._hintsState;
} else {
throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
}
@@ -1432,9 +1473,9 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
} else if (identical(descriptor, DartEntry.INCLUDED_PARTS)) {
return _includedParts as Object;
} else if (identical(descriptor, DartEntry.IS_CLIENT)) {
- return ((_bitmask & _CLIENT_CODE) != 0 ? true : false) as Object;
+ return (BooleanArray.get2(_bitmask, _CLIENT_CODE_INDEX) as bool) as Object;
} else if (identical(descriptor, DartEntry.IS_LAUNCHABLE)) {
- return ((_bitmask & _LAUNCHABLE) != 0 ? true : false) as Object;
+ return (BooleanArray.get2(_bitmask, _LAUNCHABLE_INDEX) as bool) as Object;
} else if (identical(descriptor, DartEntry.PARSE_ERRORS)) {
return _parseErrors as Object;
} else if (identical(descriptor, DartEntry.PARSED_UNIT)) {
@@ -1695,10 +1736,10 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
_includedParts = updatedValue(state, _includedParts, Source.EMPTY_ARRAY);
_includedPartsState = state;
} else if (identical(descriptor, DartEntry.IS_CLIENT)) {
- _bitmask = updatedValue2(state, _bitmask, _CLIENT_CODE);
+ _bitmask = updatedValue2(state, _bitmask, _CLIENT_CODE_INDEX);
_clientServerState = state;
} else if (identical(descriptor, DartEntry.IS_LAUNCHABLE)) {
- _bitmask = updatedValue2(state, _bitmask, _LAUNCHABLE);
+ _bitmask = updatedValue2(state, _bitmask, _LAUNCHABLE_INDEX);
_launchableState = state;
} else if (identical(descriptor, DartEntry.PARSE_ERRORS)) {
_parseErrors = updatedValue(state, _parseErrors, AnalysisError.NO_ERRORS);
@@ -1759,18 +1800,10 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
_includedParts = value == null ? Source.EMPTY_ARRAY : (value as List<Source>);
_includedPartsState = CacheState.VALID;
} else if (identical(descriptor, DartEntry.IS_CLIENT)) {
- if (((value as bool))) {
- _bitmask |= _CLIENT_CODE;
- } else {
- _bitmask &= ~_CLIENT_CODE;
- }
+ _bitmask = BooleanArray.set2(_bitmask, _CLIENT_CODE_INDEX, value as bool);
_clientServerState = CacheState.VALID;
} else if (identical(descriptor, DartEntry.IS_LAUNCHABLE)) {
- if (((value as bool))) {
- _bitmask |= _LAUNCHABLE;
- } else {
- _bitmask &= ~_LAUNCHABLE;
- }
+ _bitmask = BooleanArray.set2(_bitmask, _LAUNCHABLE_INDEX, value as bool);
_launchableState = CacheState.VALID;
} else if (identical(descriptor, DartEntry.PARSE_ERRORS)) {
_parseErrors = value == null ? AnalysisError.NO_ERRORS : (value as List<AnalysisError>);
@@ -1898,13 +1931,13 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
* @param bitMask the mask used to access the bit whose state is being set
* @return the value of the data that should be kept in the cache
*/
- int updatedValue2(CacheState state, int currentValue, int bitMask) {
+ int updatedValue2(CacheState state, int currentValue, int bitIndex) {
if (identical(state, CacheState.VALID)) {
throw new IllegalArgumentException("Use setValue() to set the state to VALID");
} else if (identical(state, CacheState.IN_PROCESS)) {
return currentValue;
}
- return currentValue &= ~bitMask;
+ return BooleanArray.set2(currentValue, bitIndex, false);
}
}
/**
@@ -2345,6 +2378,14 @@ abstract class SourceEntry {
static final DataDescriptor<LineInfo> LINE_INFO = new DataDescriptor<LineInfo>("SourceEntry.LINE_INFO");
/**
+ * Return the exception that caused one or more values to have a state of [CacheState#ERROR]
+ * .
+ *
+ * @return the exception that caused one or more values to be uncomputable
+ */
+ AnalysisException get exception;
+
+ /**
* Return the kind of the source, or `null` if the kind is not currently cached.
*
* @return the kind of the source
@@ -2399,6 +2440,11 @@ abstract class SourceEntryImpl implements SourceEntry {
int _modificationTime = 0;
/**
+ * The exception that caused one or more values to have a state of [CacheState#ERROR].
+ */
+ AnalysisException _exception;
+
+ /**
* The state of the cached line information.
*/
CacheState _lineInfoState = CacheState.INVALID;
@@ -2408,6 +2454,14 @@ abstract class SourceEntryImpl implements SourceEntry {
* currently cached.
*/
LineInfo _lineInfo;
+
+ /**
+ * Return the exception that caused one or more values to have a state of [CacheState#ERROR]
+ * .
+ *
+ * @return the exception that caused one or more values to be uncomputable
+ */
+ AnalysisException get exception => _exception;
int get modificationTime => _modificationTime;
CacheState getState(DataDescriptor descriptor) {
if (identical(descriptor, SourceEntry.LINE_INFO)) {
@@ -2425,6 +2479,16 @@ abstract class SourceEntryImpl implements SourceEntry {
}
/**
+ * Set the exception that caused one or more values to have a state of [CacheState#ERROR] to
+ * the given exception.
+ *
+ * @param exception the exception that caused one or more values to be uncomputable
+ */
+ void set exception(AnalysisException exception2) {
+ this._exception = exception2;
+ }
+
+ /**
* Set the most recent time at which the state of the source matched the state represented by this
* entry to the given time.
*
@@ -2516,17 +2580,19 @@ abstract class SourceEntryImpl implements SourceEntry {
*/
class AnalysisContentStatisticsImpl implements AnalysisContentStatistics {
Map<String, AnalysisContentStatistics_CacheRow> _dataMap = new Map<String, AnalysisContentStatistics_CacheRow>();
+ Set<AnalysisException> _exceptions = new Set<AnalysisException>();
List<AnalysisContentStatistics_CacheRow> get cacheRows {
Iterable<AnalysisContentStatistics_CacheRow> items = _dataMap.values;
return new List.from(items);
}
+ List<AnalysisException> get exceptions => new List.from(_exceptions);
void putCacheItem(DartEntry dartEntry, DataDescriptor descriptor) {
- putCacheItem3(descriptor, dartEntry.getState(descriptor));
+ putCacheItem3(dartEntry, descriptor, dartEntry.getState(descriptor));
}
void putCacheItem2(DartEntry dartEntry, Source librarySource, DataDescriptor descriptor) {
- putCacheItem3(descriptor, dartEntry.getState2(descriptor, librarySource));
+ putCacheItem3(dartEntry, descriptor, dartEntry.getState2(descriptor, librarySource));
}
- void putCacheItem3(DataDescriptor rowDesc, CacheState state) {
+ void putCacheItem3(SourceEntry dartEntry, DataDescriptor rowDesc, CacheState state) {
String rowName = rowDesc.toString();
AnalysisContentStatisticsImpl_CacheRowImpl row = _dataMap[rowName] as AnalysisContentStatisticsImpl_CacheRowImpl;
if (row == null) {
@@ -2534,6 +2600,12 @@ class AnalysisContentStatisticsImpl implements AnalysisContentStatistics {
_dataMap[rowName] = row;
}
row.incState(state);
+ if (identical(state, CacheState.ERROR)) {
+ AnalysisException exception = dartEntry.exception;
+ if (exception != null) {
+ javaSetAdd(_exceptions, exception);
+ }
+ }
}
}
class AnalysisContentStatisticsImpl_CacheRowImpl implements AnalysisContentStatistics_CacheRow {
@@ -2580,22 +2652,6 @@ class AnalysisContentStatisticsImpl_CacheRowImpl implements AnalysisContentStati
class AnalysisContextImpl implements InternalAnalysisContext {
/**
- * Helper for [getStatistics], puts the library-specific state into the given statistics
- * object.
- */
- static void putStatCacheItem(AnalysisContentStatisticsImpl statistics, DartEntry dartEntry, Source librarySource, DataDescriptor key) {
- statistics.putCacheItem3(key, dartEntry.getState2(key, librarySource));
- }
-
- /**
- * Helper for [getStatistics], puts the library independent state into the given
- * statistics object.
- */
- static void putStatCacheItem2(AnalysisContentStatisticsImpl statistics, SourceEntry entry, DataDescriptor key) {
- statistics.putCacheItem3(key, entry.getState(key));
- }
-
- /**
* The set of analysis options controlling the behavior of this context.
*/
AnalysisOptions _options = new AnalysisOptionsImpl();
@@ -2608,13 +2664,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
/**
* A table mapping the sources known to the context to the information known about the source.
*/
- Map<Source, SourceEntry> _sourceMap = new Map<Source, SourceEntry>();
-
- /**
- * An array containing the order in which sources will be analyzed by the method
- * [performAnalysisTask].
- */
- List<Source> _priorityOrder = Source.EMPTY_ARRAY;
+ AnalysisCache _cache = new AnalysisCache(_MAX_CACHE_SIZE);
/**
* A table mapping sources to the change notices that are waiting to be returned related to that
@@ -2623,22 +2673,21 @@ class AnalysisContextImpl implements InternalAnalysisContext {
Map<Source, ChangeNoticeImpl> _pendingNotices = new Map<Source, ChangeNoticeImpl>();
/**
- * A list containing the most recently accessed sources with the most recently used at the end of
- * the list. When more sources are added than the maximum allowed then the least recently used
- * source will be removed and will have it's cached AST structure flushed.
- */
- List<Source> _recentlyUsed = new List<Source>();
-
- /**
- * The number of times that the flushing of information from the cache has been disabled without
- * being re-enabled.
+ * 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.
+ *
*/
- int _cacheRemovalCount = 0;
+ Object _cacheLock = new Object();
/**
- * The object used to synchronize access to all of the caches.
+ * The object used to record the results of performing an analysis task.
*/
- Object _cacheLock = new Object();
+ AnalysisContextImpl_AnalysisTaskResultRecorder _resultRecorder;
/**
* The maximum number of sources for which data should be kept in the cache.
@@ -2654,36 +2703,13 @@ class AnalysisContextImpl implements InternalAnalysisContext {
static int _MAX_PRIORITY_LIST_SIZE = _MAX_CACHE_SIZE - 4;
/**
- * 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 analysis context.
*/
AnalysisContextImpl() : super() {
- if (AnalysisEngine.instance.useExperimentalContext) {
- throw new RuntimeException("Should not be creating an instance of AnalysisContextImpl");
- }
+ _resultRecorder = new AnalysisContextImpl_AnalysisTaskResultRecorder(this);
}
void addSourceInfo(Source source, SourceEntry info) {
- _sourceMap[source] = info;
+ _cache.put(source, info);
}
void applyChanges(ChangeSet changeSet) {
if (changeSet.isEmpty) {
@@ -2707,9 +2733,10 @@ class AnalysisContextImpl implements InternalAnalysisContext {
sourceRemoved(source);
}
if (addedDartSource) {
- for (MapEntry<Source, SourceEntry> mapEntry in getMapEntrySet(_sourceMap)) {
- if (!mapEntry.getKey().isInSystemLibrary && mapEntry.getValue() is DartEntry) {
- DartEntryImpl dartCopy = ((mapEntry.getValue() as DartEntry)).writableCopy;
+ for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
+ SourceEntry sourceEntry = mapEntry.getValue();
+ if (!mapEntry.getKey().isInSystemLibrary && sourceEntry is DartEntry) {
+ DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
dartCopy.invalidateAllResolutionInformation();
mapEntry.setValue(dartCopy);
}
@@ -2756,13 +2783,16 @@ class AnalysisContextImpl implements InternalAnalysisContext {
if (sourceEntry is DartEntry) {
List<AnalysisError> errors = new List<AnalysisError>();
DartEntry dartEntry = sourceEntry as DartEntry;
- ListUtilities.addAll(errors, internalGetDartParseData(source, dartEntry, DartEntry.PARSE_ERRORS));
+ ListUtilities.addAll(errors, getDartParseData(source, dartEntry, DartEntry.PARSE_ERRORS));
+ dartEntry = getReadableDartEntry(source);
if (identical(dartEntry.getValue(DartEntry.SOURCE_KIND), SourceKind.LIBRARY)) {
- ListUtilities.addAll(errors, internalGetDartResolutionData(source, source, dartEntry, DartEntry.RESOLUTION_ERRORS));
+ ListUtilities.addAll(errors, getDartResolutionData(source, source, dartEntry, DartEntry.RESOLUTION_ERRORS));
+ ListUtilities.addAll(errors, getDartHintData(source, source, dartEntry, DartEntry.HINTS));
} else {
List<Source> libraries = getLibrariesContaining(source);
for (Source librarySource in libraries) {
- ListUtilities.addAll(errors, internalGetDartResolutionData(source, librarySource, dartEntry, DartEntry.RESOLUTION_ERRORS));
+ ListUtilities.addAll(errors, getDartResolutionData(source, librarySource, dartEntry, DartEntry.RESOLUTION_ERRORS));
+ ListUtilities.addAll(errors, getDartHintData(source, librarySource, dartEntry, DartEntry.HINTS));
}
}
if (errors.isEmpty) {
@@ -2771,86 +2801,54 @@ class AnalysisContextImpl implements InternalAnalysisContext {
return new List.from(errors);
} else if (sourceEntry is HtmlEntry) {
HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
- return internalGetHtmlResolutionData(source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS, AnalysisError.NO_ERRORS);
+ return getHtmlResolutionData2(source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS);
}
return AnalysisError.NO_ERRORS;
}
- List<Source> computeExportedLibraries(Source source) => internalGetDartParseData2(source, DartEntry.EXPORTED_LIBRARIES, Source.EMPTY_ARRAY);
- HtmlElement computeHtmlElement(Source source) {
- HtmlEntry htmlEntry = getReadableHtmlEntry(source);
- if (htmlEntry == null) {
- return null;
- }
- CacheState elementState = htmlEntry.getState(HtmlEntry.ELEMENT);
- if (elementState != CacheState.ERROR && elementState != CacheState.VALID) {
- htmlEntry = internalResolveHtml(source);
- }
- return htmlEntry.getValue(HtmlEntry.ELEMENT);
- }
- List<Source> computeImportedLibraries(Source source) => internalGetDartParseData2(source, DartEntry.IMPORTED_LIBRARIES, Source.EMPTY_ARRAY);
+ 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 internalGetDartParseData(source, sourceEntry as DartEntry, DartEntry.SOURCE_KIND);
+ return getDartParseData(source, sourceEntry as DartEntry, DartEntry.SOURCE_KIND);
} on AnalysisException catch (exception) {
return SourceKind.UNKNOWN;
}
}
return sourceEntry.kind;
}
- LibraryElement computeLibraryElement(Source source) {
- {
- DartEntry dartEntry = getDartEntry(source);
- if (dartEntry == null) {
- return null;
- }
- LibraryElement element = dartEntry.getValue(DartEntry.ELEMENT);
- if (element == null) {
- LibraryResolver resolver = new LibraryResolver(this);
- try {
- element = resolver.resolveLibrary(source, true);
- recordResolutionResults(resolver);
- } on AnalysisException catch (exception) {
- DartEntryImpl dartCopy = getDartEntry(source).writableCopy;
- dartCopy.recordResolutionError();
- _sourceMap[source] = dartCopy;
- AnalysisEngine.instance.logger.logError2("Could not resolve the library ${source.fullName}", exception);
- }
- }
- return element;
- }
- }
+ LibraryElement computeLibraryElement(Source source) => getDartResolutionData2(source, source, DartEntry.ELEMENT, null);
LineInfo computeLineInfo(Source source) {
SourceEntry sourceEntry = getReadableSourceEntry(source);
if (sourceEntry is HtmlEntry) {
- return internalGetHtmlParseData(source, SourceEntry.LINE_INFO, null);
+ return getHtmlParseData(source, SourceEntry.LINE_INFO, null);
} else if (sourceEntry is DartEntry) {
- return internalGetDartParseData2(source, SourceEntry.LINE_INFO, null);
+ return getDartParseData2(source, SourceEntry.LINE_INFO, null);
}
return null;
}
ResolvableCompilationUnit computeResolvableCompilationUnit(Source source) {
while (true) {
{
- SourceEntry sourceEntry = getSourceEntry(source);
- if (sourceEntry is! DartEntry) {
+ DartEntry dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
throw new AnalysisException.con1("computeResolvableCompilationUnit for non-Dart: ${source.fullName}");
}
- DartEntry dartEntry = sourceEntry as DartEntry;
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) {
- _sourceMap[source] = dartCopy;
+ _cache.put(source, dartCopy);
return new ResolvableCompilationUnit(dartCopy.modificationTime, unit);
}
}
- internalParseDart(source);
+ cacheDartParseData(source, getReadableDartEntry(source), DartEntry.PARSED_UNIT);
}
}
ResolvableHtmlUnit computeResolvableHtmlUnit(Source source) {
@@ -2858,7 +2856,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
if (htmlEntry == null) {
throw new AnalysisException.con1("computeResolvableHtmlUnit invoked for non-HTML file: ${source.fullName}");
}
- htmlEntry = internalCacheHtmlParseData(source, htmlEntry, [HtmlEntry.PARSED_UNIT]);
+ 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}");
@@ -2869,7 +2867,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext) {
List<Source> sourcesToRemove = new List<Source>();
{
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
Source source = entry.getKey();
if (container.contains(source)) {
sourcesToRemove.add(source);
@@ -2925,7 +2923,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
if (sourceKind == SourceKind.LIBRARY) {
} else if (sourceKind == SourceKind.PART) {
List<Source> librarySources = getLibrariesContaining(source);
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
+ 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);
@@ -2954,7 +2952,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
List<Source> get launchableClientLibrarySources {
List<Source> sources = new List<Source>();
{
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
Source source = entry.getKey();
SourceEntry sourceEntry = entry.getValue();
if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary) {
@@ -2967,7 +2965,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
List<Source> get launchableServerLibrarySources {
List<Source> sources = new List<Source>();
{
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
Source source = entry.getKey();
SourceEntry sourceEntry = entry.getValue();
if (identical(sourceEntry.kind, SourceKind.LIBRARY) && !source.isInSystemLibrary) {
@@ -2979,12 +2977,12 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
List<Source> getLibrariesContaining(Source source) {
{
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry != null && identical(sourceEntry.kind, SourceKind.LIBRARY)) {
+ 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 getMapEntrySet(_sourceMap)) {
+ 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)) {
@@ -3001,7 +2999,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
List<Source> getLibrariesDependingOn(Source librarySource) {
{
List<Source> dependentLibraries = new List<Source>();
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
+ 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)) {
@@ -3039,38 +3037,54 @@ class AnalysisContextImpl implements InternalAnalysisContext {
if (dartEntry == null) {
return null;
}
- {
- Namespace namespace = dartEntry.getValue(DartEntry.PUBLIC_NAMESPACE);
- if (namespace == null) {
- NamespaceBuilder builder = new NamespaceBuilder();
- namespace = builder.createPublicNamespace(library);
- DartEntryImpl dartCopy = getDartEntry(source).writableCopy;
- dartCopy.setValue(DartEntry.PUBLIC_NAMESPACE, namespace);
- _sourceMap[source] = dartCopy;
+ Namespace namespace = null;
+ if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
+ namespace = dartEntry.getValue(DartEntry.PUBLIC_NAMESPACE);
+ }
+ 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;
}
+ return namespace;
}
Namespace getPublicNamespace2(Source source) {
DartEntry dartEntry = getReadableDartEntry(source);
if (dartEntry == null) {
return null;
}
- {
- Namespace namespace = dartEntry.getValue(DartEntry.PUBLIC_NAMESPACE);
- if (namespace == null) {
- LibraryElement library = computeLibraryElement(source);
- if (library == null) {
- return null;
+ 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);
}
- NamespaceBuilder builder = new NamespaceBuilder();
- namespace = builder.createPublicNamespace(library);
- DartEntryImpl dartCopy = getDartEntry(source).writableCopy;
- dartCopy.setValue(DartEntry.PUBLIC_NAMESPACE, namespace);
- _sourceMap[source] = dartCopy;
}
- return namespace;
}
+ return namespace;
}
CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library) {
if (library == null) {
@@ -3089,65 +3103,135 @@ class AnalysisContextImpl implements InternalAnalysisContext {
/**
* Return a list of the sources that would be processed by [performAnalysisTask]. This
- * method is intended to be used for testing purposes only.
+ * method duplicates, and must therefore be kept in sync with, [getNextTaskAnalysisTask].
+ * This method is intended to be used for testing purposes only.
*
* @return a list of the sources that would be processed by [performAnalysisTask]
*/
List<Source> get sourcesNeedingProcessing {
- List<Source> sources = new List<Source>();
+ Set<Source> sources = new Set<Source>();
{
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- SourceEntry sourceEntry = entry.getValue();
+ for (Source source in _cache.priorityOrder) {
+ SourceEntry sourceEntry = _cache.get(source);
if (sourceEntry is DartEntry) {
DartEntry dartEntry = sourceEntry as DartEntry;
- CacheState parsedUnitState = dartEntry.getState(DartEntry.PARSED_UNIT);
- CacheState elementState = dartEntry.getState(DartEntry.ELEMENT);
- if (identical(parsedUnitState, CacheState.INVALID) || identical(elementState, CacheState.INVALID)) {
- sources.add(entry.getKey());
+ CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
+ if (identical(parseErrorsState, CacheState.INVALID) || identical(parseErrorsState, CacheState.FLUSHED)) {
+ javaSetAdd(sources, source);
+ }
+ CompilationUnit parseUnit = dartEntry.anyParsedCompilationUnit;
+ if (parseUnit == null) {
+ 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);
+ }
+ }
+ CacheState hintsState = dartEntry.getState2(DartEntry.HINTS, librarySource);
+ if (identical(hintsState, CacheState.INVALID) || identical(hintsState, 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(parsedUnitState, CacheState.INVALID) || identical(elementState, CacheState.INVALID)) {
- sources.add(entry.getKey());
+ if (identical(elementState, CacheState.INVALID) || identical(elementState, CacheState.FLUSHED)) {
+ javaSetAdd(sources, source);
}
}
}
- }
- return sources;
- }
- AnalysisContentStatistics get statistics {
- AnalysisContentStatisticsImpl statistics = new AnalysisContentStatisticsImpl();
- {
- for (MapEntry<Source, SourceEntry> mapEntry in getMapEntrySet(_sourceMap)) {
- SourceEntry entry = mapEntry.getValue();
- if (entry is DartEntry) {
- Source source = mapEntry.getKey();
- DartEntry dartEntry = entry as DartEntry;
- SourceKind kind = dartEntry.getValue(DartEntry.SOURCE_KIND);
- putStatCacheItem2(statistics, dartEntry, DartEntry.PARSE_ERRORS);
- putStatCacheItem2(statistics, dartEntry, DartEntry.PARSED_UNIT);
- putStatCacheItem2(statistics, dartEntry, DartEntry.SOURCE_KIND);
- putStatCacheItem2(statistics, dartEntry, DartEntry.LINE_INFO);
- if (identical(kind, SourceKind.LIBRARY)) {
- putStatCacheItem2(statistics, dartEntry, DartEntry.ELEMENT);
- putStatCacheItem2(statistics, dartEntry, DartEntry.EXPORTED_LIBRARIES);
- putStatCacheItem2(statistics, dartEntry, DartEntry.IMPORTED_LIBRARIES);
- putStatCacheItem2(statistics, dartEntry, DartEntry.INCLUDED_PARTS);
- putStatCacheItem2(statistics, dartEntry, DartEntry.IS_CLIENT);
- putStatCacheItem2(statistics, dartEntry, DartEntry.IS_LAUNCHABLE);
- }
+ 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) {
+ DartEntry dartEntry = sourceEntry as DartEntry;
+ if (identical(dartEntry.kind, SourceKind.LIBRARY) && identical(dartEntry.getState(DartEntry.ELEMENT), CacheState.INVALID)) {
+ javaSetAdd(sources, entry.getKey());
+ } else if (identical(dartEntry.getState2(DartEntry.HINTS, entry.getKey()), 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);
+ }
+ 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) {
- putStatCacheItem(statistics, dartEntry, librarySource, DartEntry.RESOLUTION_ERRORS);
- putStatCacheItem(statistics, dartEntry, librarySource, DartEntry.RESOLVED_UNIT);
+ statistics.putCacheItem2(dartEntry, librarySource, DartEntry.HINTS);
+ statistics.putCacheItem2(dartEntry, librarySource, DartEntry.RESOLUTION_ERRORS);
+ statistics.putCacheItem2(dartEntry, librarySource, DartEntry.RESOLVED_UNIT);
}
}
}
}
return statistics;
}
+ TimestampedData<CompilationUnit> internalResolveCompilationUnit(Source unitSource, LibraryElement libraryElement) {
+ DartEntry dartEntry = getReadableDartEntry(unitSource);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("internalResolveCompilationUnit invoked for non-Dart file: ${unitSource.fullName}");
+ }
+ Source librarySource = libraryElement.source;
+ dartEntry = cacheDartResolutionData(unitSource, librarySource, dartEntry, DartEntry.RESOLVED_UNIT);
+ return new TimestampedData<CompilationUnit>(dartEntry.modificationTime, dartEntry.getValue2(DartEntry.RESOLVED_UNIT, librarySource));
+ }
bool isClientLibrary(Source librarySource) {
SourceEntry sourceEntry = getReadableSourceEntry(librarySource);
if (sourceEntry is DartEntry) {
@@ -3172,45 +3256,31 @@ class AnalysisContextImpl implements InternalAnalysisContext {
return;
}
{
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(((context as AnalysisContextImpl))._sourceMap)) {
+ for (MapEntry<Source, SourceEntry> entry in ((context as AnalysisContextImpl))._cache.entrySet()) {
Source newSource = entry.getKey();
- SourceEntry existingEntry = getSourceEntry(newSource);
+ SourceEntry existingEntry = getReadableSourceEntry(newSource);
if (existingEntry == null) {
- _sourceMap[newSource] = entry.getValue().writableCopy;
+ _cache.put(newSource, entry.getValue().writableCopy);
} else {
}
}
}
}
- CompilationUnit parseCompilationUnit(Source source) {
- DartEntry dartEntry = getReadableDartEntry(source);
- if (dartEntry == null) {
- return null;
- }
- CompilationUnit unit = dartEntry.anyParsedCompilationUnit;
- if (unit == null) {
- CacheState state = dartEntry.getState(DartEntry.PARSED_UNIT);
- while (state != CacheState.VALID && state != CacheState.ERROR) {
- dartEntry = internalParseDart(source);
- state = dartEntry.getState(DartEntry.PARSED_UNIT);
- }
- unit = dartEntry.anyParsedCompilationUnit;
- }
- return unit;
- }
- HtmlUnit parseHtmlUnit(Source source) => internalGetHtmlParseData(source, HtmlEntry.PARSED_UNIT, null);
+ CompilationUnit parseCompilationUnit(Source source) => getDartParseData2(source, DartEntry.PARSED_UNIT, null);
+ HtmlUnit parseHtmlUnit(Source source) => getHtmlParseData(source, HtmlEntry.PARSED_UNIT, null);
List<ChangeNotice> performAnalysisTask() {
- {
- if (!performSingleAnalysisTask() && _pendingNotices.isEmpty) {
- return null;
- }
- if (_pendingNotices.isEmpty) {
- return ChangeNoticeImpl.EMPTY_ARRAY;
+ AnalysisTask task = nextTaskAnalysisTask;
+ if (task == null) {
+ return getChangeNotices(true);
+ }
+ try {
+ task.perform(_resultRecorder);
+ } on AnalysisException catch (exception) {
+ if (exception.cause is! JavaIOException) {
+ AnalysisEngine.instance.logger.logError2("Internal error while performing the task: ${task}", exception);
}
- List<ChangeNotice> notices = new List.from(_pendingNotices.values);
- _pendingNotices.clear();
- return notices;
}
+ return getChangeNotices(false);
}
void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
{
@@ -3218,89 +3288,45 @@ class AnalysisContextImpl implements InternalAnalysisContext {
for (MapEntry<Source, LibraryElement> entry in getMapEntrySet(elementMap)) {
Source librarySource = entry.getKey();
LibraryElement library = entry.getValue();
- DartEntry dartEntry = getDartEntry(librarySource);
+ DartEntry dartEntry = getReadableDartEntry(librarySource);
if (dartEntry != null) {
DartEntryImpl dartCopy = dartEntry.writableCopy;
recordElementData(dartCopy, library, htmlSource);
- _sourceMap[librarySource] = dartCopy;
+ _cache.put(librarySource, dartCopy);
}
}
}
}
- CompilationUnit resolveCompilationUnit(Source source2, LibraryElement library) {
+ CompilationUnit resolveCompilationUnit(Source unitSource, LibraryElement library) {
if (library == null) {
return null;
}
- return resolveCompilationUnit2(source2, library.source);
- }
- CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) {
- {
- accessed(unitSource);
- DartEntry dartEntry = getDartEntry(unitSource);
- if (dartEntry == null) {
- return null;
- }
- CompilationUnit unit = dartEntry.getValue2(DartEntry.RESOLVED_UNIT, librarySource);
- if (unit == null) {
- disableCacheRemoval();
- try {
- LibraryElement libraryElement = computeLibraryElement(librarySource);
- unit = dartEntry.getValue2(DartEntry.RESOLVED_UNIT, librarySource);
- if (unit == null && libraryElement != null) {
- Source coreLibrarySource = libraryElement.context.sourceFactory.forUri(DartSdk.DART_CORE);
- LibraryElement coreElement = computeLibraryElement(coreLibrarySource);
- TypeProvider typeProvider = new TypeProviderImpl(coreElement);
- ResolvableCompilationUnit resolvableUnit = computeResolvableCompilationUnit(unitSource);
- CompilationUnit unitAST = resolvableUnit.compilationUnit;
- new DeclarationResolver().resolve(unitAST, find(libraryElement, unitSource));
- RecordingErrorListener errorListener = new RecordingErrorListener();
- TypeResolverVisitor typeResolverVisitor = new TypeResolverVisitor.con2(libraryElement, unitSource, typeProvider, errorListener);
- unitAST.accept(typeResolverVisitor);
- InheritanceManager inheritanceManager = new InheritanceManager(libraryElement);
- ResolverVisitor resolverVisitor = new ResolverVisitor.con2(libraryElement, unitSource, typeProvider, inheritanceManager, errorListener);
- unitAST.accept(resolverVisitor);
- for (ProxyConditionalAnalysisError conditionalCode in resolverVisitor.proxyConditionalAnalysisErrors) {
- if (conditionalCode.shouldIncludeErrorCode()) {
- resolverVisitor.reportError(conditionalCode.analysisError);
- }
- }
- ErrorReporter errorReporter = new ErrorReporter(errorListener, unitSource);
- ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, libraryElement, typeProvider, inheritanceManager);
- unitAST.accept(errorVerifier);
- ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, typeProvider);
- unitAST.accept(constantVerifier);
- unitAST.resolutionErrors = errorListener.errors;
- DartEntryImpl dartCopy = getDartEntry(unitSource).writableCopy;
- dartCopy.setValue2(DartEntry.RESOLVED_UNIT, librarySource, unitAST);
- _sourceMap[unitSource] = dartCopy;
- unit = unitAST;
- }
- } finally {
- enableCacheRemoval();
- }
- }
- return unit;
- }
+ return resolveCompilationUnit2(unitSource, library.source);
}
- HtmlUnit resolveHtmlUnit(Source source) => parseHtmlUnit(source);
+ 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;
- invalidateAllResults();
+ invalidateAllResolutionInformation();
}
}
void set analysisPriorityOrder(List<Source> sources) {
{
if (sources == null || sources.isEmpty) {
- _priorityOrder = Source.EMPTY_ARRAY;
+ _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);
- _priorityOrder = new List<Source>(count);
+ List<Source> priorityOrder = new List<Source>(count);
for (int i = 0; i < count; i++) {
- _priorityOrder[i] = sources[i];
+ priorityOrder[i] = sources[i];
}
+ _cache.priorityOrder = priorityOrder;
}
}
}
@@ -3323,7 +3349,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
factory.context = this;
_sourceFactory = factory;
- invalidateAllResults();
+ invalidateAllResolutionInformation();
}
}
Iterable<Source> sourcesToResolve(List<Source> changedSources) {
@@ -3337,24 +3363,6 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
/**
- * Record that the given source was just accessed for some unspecified purpose.
- *
- * Note: This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source that was accessed
- */
- void accessed(Source source) {
- if (_recentlyUsed.remove(source)) {
- _recentlyUsed.add(source);
- return;
- }
- if (_cacheRemovalCount == 0 && _recentlyUsed.length >= _MAX_CACHE_SIZE) {
- flushAstFromCache();
- }
- _recentlyUsed.add(source);
- }
-
- /**
* 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].
@@ -3363,7 +3371,8 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* @param container the source container containing the sources to be added to the list
*/
void addSourcesInContainer(List<Source> sources, SourceContainer container) {
- for (Source source in _sourceMap.keys.toSet()) {
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
+ Source source = entry.getKey();
if (container.contains(source)) {
sources.add(source);
}
@@ -3371,516 +3380,290 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
/**
- * Given the encoded form of a source, use the source factory to reconstitute the original source.
+ * 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 encoding the encoded form of a source
- * @return the source represented by the encoding
+ * @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)
*/
- Source computeSourceFromEncoding(String encoding) {
- {
- return _sourceFactory.fromEncoding(encoding);
+ 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;
}
/**
- * Return `true` if the given array of sources contains the given source.
+ * 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 generating hints for the library if the data is not already cached.
*
- * @param sources the sources being searched
- * @param targetSource the source being searched for
- * @return `true` if the given source is in the array
+ * @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
*/
- bool contains(List<Source> sources, Source targetSource) {
- for (Source source in sources) {
- if (source == targetSource) {
- return true;
- }
+ DartEntry cacheDartHintData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
+ CacheState state = dartEntry.getState2(descriptor, librarySource);
+ while (state != CacheState.ERROR && state != CacheState.VALID) {
+ dartEntry = new GenerateDartHintsTask(this, getLibraryElement(librarySource)).perform(_resultRecorder) as DartEntry;
+ state = dartEntry.getState2(descriptor, librarySource);
}
- return false;
+ return dartEntry;
}
/**
- * Return `true` if the given array of sources contains any of the given target sources.
+ * 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 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
+ * @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
*/
- bool containsAny(List<Source> sources, List<Source> targetSources) {
- for (Source targetSource in targetSources) {
- if (contains(sources, targetSource)) {
- return true;
+ DartEntry cacheDartParseData(Source source, DartEntry dartEntry, DataDescriptor descriptor) {
+ if (identical(descriptor, DartEntry.PARSED_UNIT)) {
+ CompilationUnit unit = dartEntry.anyParsedCompilationUnit;
+ if (unit != null) {
+ return dartEntry;
}
}
- return false;
+ 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;
}
/**
- * 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.
+ * 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 source the source for which an information object is being created
- * @return the source information object that was created
+ * @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
*/
- SourceEntry createSourceEntry(Source source) {
- String name = source.shortName;
- if (AnalysisEngine.isHtmlFileName(name)) {
- HtmlEntryImpl htmlEntry = new HtmlEntryImpl();
- htmlEntry.modificationTime = source.modificationStamp;
- _sourceMap[source] = htmlEntry;
- return htmlEntry;
- } else {
- DartEntryImpl dartEntry = new DartEntryImpl();
- dartEntry.modificationTime = source.modificationStamp;
- _sourceMap[source] = dartEntry;
- return dartEntry;
+ 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;
}
/**
- * Disable flushing information from the cache until [enableCacheRemoval] has been
- * called.
+ * 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
*/
- void disableCacheRemoval() {
- _cacheRemovalCount++;
+ 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;
}
/**
- * Re-enable flushing information from the cache.
+ * 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
*/
- void enableCacheRemoval() {
- if (_cacheRemovalCount > 0) {
- _cacheRemovalCount--;
- }
- if (_cacheRemovalCount == 0) {
- while (_recentlyUsed.length >= _MAX_CACHE_SIZE) {
- flushAstFromCache();
- }
+ 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;
}
/**
- * 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.
+ * Given the encoded form of a source, use the source factory to reconstitute the original 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
+ * @param encoding the encoded form of a source
+ * @return the source represented by the encoding
*/
- CompilationUnitElement find(LibraryElement libraryElement, Source unitSource) {
- CompilationUnitElement element = libraryElement.definingCompilationUnit;
- if (element.source == unitSource) {
- return element;
- }
- for (CompilationUnitElement partElement in libraryElement.parts) {
- if (partElement.source == unitSource) {
- return partElement;
- }
+ Source computeSourceFromEncoding(String encoding) {
+ {
+ return _sourceFactory.fromEncoding(encoding);
}
- return null;
}
/**
- * Flush one AST structure from the cache.
+ * Return `true` if the given array of sources contains the given source.
*
- * Note: This method must only be invoked while we are synchronized on [cacheLock].
+ * @param sources the sources being searched
+ * @param targetSource the source being searched for
+ * @return `true` if the given source is in the array
*/
- void flushAstFromCache() {
- Source removedSource = removeAstToFlush();
- SourceEntry sourceEntry = _sourceMap[removedSource];
- if (sourceEntry is HtmlEntry) {
- HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
- htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.FLUSHED);
- _sourceMap[removedSource] = htmlCopy;
- } else if (sourceEntry is DartEntry) {
- DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
- dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
- for (Source librarySource in getLibrariesContaining(removedSource)) {
- dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.FLUSHED);
+ bool contains(List<Source> sources, Source targetSource) {
+ for (Source source in sources) {
+ if (source == targetSource) {
+ return true;
}
- _sourceMap[removedSource] = dartCopy;
}
+ return false;
}
/**
- * Return the compilation unit information associated with the given source, or `null` if
- * the source is not known to this context. This method should be used to access the compilation
- * unit information rather than accessing the compilation unit map directly because sources in the
- * SDK are implicitly part of every analysis context and are therefore only added to the map when
- * first accessed.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
+ * Return `true` if the given array of sources contains any of the given target sources.
*
- * @param source the source for which information is being sought
- * @return the compilation unit information associated with the given source
+ * @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
*/
- DartEntry getDartEntry(Source source) {
- SourceEntry sourceEntry = getSourceEntry(source);
- if (sourceEntry == null) {
- sourceEntry = new DartEntryImpl();
- _sourceMap[source] = sourceEntry;
- return sourceEntry as DartEntry;
- } else if (sourceEntry is DartEntry) {
- return sourceEntry as DartEntry;
+ bool containsAny(List<Source> sources, List<Source> targetSources) {
+ for (Source targetSource in targetSources) {
+ if (contains(sources, targetSource)) {
+ return true;
+ }
}
- return null;
+ return false;
}
/**
- * Return the sources of libraries that are referenced in the specified HTML file.
+ * 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 htmlSource the source of the HTML file being analyzed
- * @param htmlUnit the AST for the HTML file being analyzed
- * @return the sources of libraries that are referenced in the HTML file
+ * @param source the source for which an information object is being created
+ * @return the source information object that was created
*/
- List<Source> getLibrarySources2(Source htmlSource, HtmlUnit htmlUnit) {
- List<Source> libraries = new List<Source>();
- htmlUnit.accept(new RecursiveXmlVisitor_6(this, htmlSource, libraries));
- if (libraries.isEmpty) {
- return Source.EMPTY_ARRAY;
+ 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;
}
- return new List.from(libraries);
}
/**
- * 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 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.
*
- * @return the next task that needs to be performed
+ * @param nullIfEmpty `true` if `null` should be returned when there are no notices
+ * @return the change notices that are waiting to be returned
*/
- AnalysisContextImpl_AnalysisTask get nextTaskAnalysisTask {
+ List<ChangeNotice> getChangeNotices(bool nullIfEmpty) {
{
- for (Source source in _priorityOrder) {
- SourceEntry sourceEntry = _sourceMap[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);
- _sourceMap[source] = dartCopy;
- return new AnalysisContextImpl_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);
- _sourceMap[source] = dartCopy;
- return new AnalysisContextImpl_ParseDartTask(this, source);
- }
- for (Source librarySource in getLibrariesContaining(source)) {
- SourceEntry libraryEntry = _sourceMap[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);
- _sourceMap[librarySource] = libraryCopy;
- return new AnalysisContextImpl_ResolveDartLibraryTask(this, librarySource);
- }
- }
- CacheState resolvedUnitState = dartEntry.getState2(DartEntry.RESOLVED_UNIT, librarySource);
- if (identical(resolvedUnitState, CacheState.INVALID) || identical(resolvedUnitState, CacheState.FLUSHED)) {
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.IN_PROCESS);
- _sourceMap[source] = dartCopy;
- return new AnalysisContextImpl_ResolveDartUnitTask(this, source, librarySource);
- }
- }
- } 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);
- _sourceMap[source] = htmlCopy;
- return new AnalysisContextImpl_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);
- _sourceMap[source] = htmlCopy;
- return new AnalysisContextImpl_ResolveHtmlTask(this, source);
- }
- }
- }
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- 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);
- _sourceMap[source] = dartCopy;
- return new AnalysisContextImpl_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);
- _sourceMap[source] = htmlCopy;
- return new AnalysisContextImpl_ParseHtmlTask(this, source);
- }
- }
- }
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- 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);
- _sourceMap[source] = dartCopy;
- return new AnalysisContextImpl_ResolveDartLibraryTask(this, 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);
- _sourceMap[source] = htmlCopy;
- return new AnalysisContextImpl_ResolveHtmlTask(this, source);
- }
+ if (_pendingNotices.isEmpty) {
+ if (nullIfEmpty) {
+ return null;
}
+ return ChangeNoticeImpl.EMPTY_ARRAY;
}
- return null;
+ List<ChangeNotice> notices = new List.from(_pendingNotices.values);
+ _pendingNotices.clear();
+ return notices;
}
}
/**
- * Return a change notice for the given source, creating one if one does not already exist.
+ * 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 generating hints for the library if it is not already cached.
*
- * @param source the source for which changes are being reported
- * @return a change notice for the given source
+ * @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
*/
- ChangeNoticeImpl getNotice(Source source) {
- ChangeNoticeImpl notice = _pendingNotices[source];
- if (notice == null) {
- notice = new ChangeNoticeImpl(source);
- _pendingNotices[source] = notice;
+ Object getDartHintData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
+ dartEntry = cacheDartHintData(unitSource, librarySource, dartEntry, descriptor);
+ if (identical(descriptor, DartEntry.ELEMENT)) {
+ return dartEntry.getValue(descriptor);
}
- return notice;
+ return dartEntry.getValue2(descriptor, librarySource);
}
/**
- * Return the cache entry associated with the given source, or `null` if the source is not a
- * Dart file.
+ * 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 for which a cache entry is being sought
- * @return the source cache entry associated with the given source
+ * @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
*/
- DartEntry getReadableDartEntry(Source source) {
- {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry == null) {
- sourceEntry = createSourceEntry(source);
- }
- if (sourceEntry is DartEntry) {
- accessed(source);
- return sourceEntry as DartEntry;
- }
- return null;
+ 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);
}
/**
- * Return the cache entry associated with the given source, or `null` if the source is not
- * an HTML file.
+ * 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 for which a cache entry is being sought
- * @return the source cache entry associated with the given source
+ * @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
*/
- HtmlEntry getReadableHtmlEntry(Source source) {
- {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry == null) {
- sourceEntry = createSourceEntry(source);
- }
- if (sourceEntry is HtmlEntry) {
- 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 = _sourceMap[source];
- if (sourceEntry == null) {
- sourceEntry = createSourceEntry(source);
- }
- if (sourceEntry != null) {
- accessed(source);
- }
- return sourceEntry;
- }
- }
-
- /**
- * Return the source information associated with the given source, or `null` if the source
- * is not known to this context. This method should be used to access the source information
- * rather than accessing the source map directly because sources in the SDK are implicitly part of
- * every analysis context and are therefore only added to the map when first accessed.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source for which information is being sought
- * @return the source information associated with the given source
- */
- SourceEntry getSourceEntry(Source source) {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry == null) {
- sourceEntry = createSourceEntry(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 getMapEntrySet(_sourceMap)) {
- if (identical(entry.getValue().kind, kind2)) {
- sources.add(entry.getKey());
- }
- }
- }
- return new List.from(sources);
- }
-
- /**
- * 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 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
- */
- bool hasHtmlParseDataCached(HtmlEntry htmlEntry, List<DataDescriptor> descriptors) {
- for (DataDescriptor descriptor in descriptors) {
- CacheState state = htmlEntry.getState(descriptor);
- if (state != CacheState.VALID && state != CacheState.ERROR) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * 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 internalCacheDartParseData(Source source, DartEntry dartEntry, DataDescriptor descriptor) {
- CacheState state = dartEntry.getState(descriptor);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- dartEntry = internalParseDart(source);
- state = dartEntry.getState(descriptor);
- }
- return dartEntry;
- }
-
- /**
- * Given a source for a Dart file and the library that contains it, 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 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 the requested data about the given source
- * @throws AnalysisException if data could not be returned because the source could not be parsed
- */
- DartEntry internalCacheDartResolutionData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
- CacheState state = dartEntry.getState2(descriptor, librarySource);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- dartEntry = internalResolveDart(unitSource, librarySource);
- state = dartEntry.getState2(descriptor, librarySource);
- }
- return dartEntry;
- }
-
- /**
- * 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 internalCacheHtmlParseData(Source source, HtmlEntry htmlEntry, List<DataDescriptor> descriptors) {
- while (!hasHtmlParseDataCached(htmlEntry, descriptors)) {
- htmlEntry = internalParseHtml(source);
- }
- return htmlEntry;
- }
-
- /**
- * 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 internalGetDartParseData(Source source, DartEntry dartEntry, DataDescriptor descriptor) {
- dartEntry = internalCacheDartParseData(source, dartEntry, descriptor);
- return dartEntry.getValue(descriptor);
- }
-
- /**
- * 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 internalGetDartParseData2(Source source, DataDescriptor descriptor, Object defaultValue) {
+ Object getDartParseData2(Source source, DataDescriptor descriptor, Object defaultValue) {
DartEntry dartEntry = getReadableDartEntry(source);
if (dartEntry == null) {
return defaultValue;
}
- return internalGetDartParseData(source, dartEntry, descriptor);
+ return getDartParseData(source, dartEntry, descriptor);
}
/**
@@ -3893,32 +3676,37 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* @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 parsed
+ * @throws AnalysisException if data could not be returned because the source could not be
+ * resolved
*/
- Object internalGetDartResolutionData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
- dartEntry = internalCacheDartResolutionData(unitSource, librarySource, dartEntry, descriptor);
+ 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);
}
/**
* 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.
+ * 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 file is not a Dart file
+ * @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
+ * @throws AnalysisException if data could not be returned because the source could not be
+ * resolved
*/
- Object internalGetDartResolutionData2(Source unitSource, Source librarySource, DataDescriptor descriptor, Object defaultValue) {
+ Object getDartResolutionData2(Source unitSource, Source librarySource, DataDescriptor descriptor, Object defaultValue) {
DartEntry dartEntry = getReadableDartEntry(unitSource);
if (dartEntry == null) {
return defaultValue;
}
- dartEntry = internalCacheDartResolutionData(unitSource, librarySource, dartEntry, descriptor);
- return dartEntry.getValue(descriptor);
+ return getDartResolutionData(unitSource, librarySource, dartEntry, descriptor);
}
/**
@@ -3928,16 +3716,16 @@ class AnalysisContextImpl implements InternalAnalysisContext {
*
* @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
+ * @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 internalGetHtmlParseData(Source source, DataDescriptor descriptor, Object defaultValue) {
+ Object getHtmlParseData(Source source, DataDescriptor descriptor, Object defaultValue) {
HtmlEntry htmlEntry = getReadableHtmlEntry(source);
if (htmlEntry == null) {
return defaultValue;
}
- htmlEntry = internalCacheHtmlParseData(source, htmlEntry, [descriptor]);
+ htmlEntry = cacheHtmlParseData(source, htmlEntry, descriptor);
return htmlEntry.getValue(descriptor);
}
@@ -3954,361 +3742,266 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* @throws AnalysisException if data could not be returned because the source could not be
* resolved
*/
- Object internalGetHtmlResolutionData(Source source, HtmlEntry htmlEntry, DataDescriptor descriptor, Object defaultValue) {
+ Object getHtmlResolutionData(Source source, DataDescriptor descriptor, Object defaultValue) {
+ HtmlEntry htmlEntry = getReadableHtmlEntry(source);
if (htmlEntry == null) {
return defaultValue;
}
- CacheState state = htmlEntry.getState(descriptor);
- while (state != CacheState.ERROR && state != CacheState.VALID) {
- htmlEntry = internalResolveHtml(source);
- state = htmlEntry.getState(descriptor);
- }
- return htmlEntry.getValue(descriptor);
- }
- CompilationUnit internalParseCompilationUnit(DartEntryImpl dartCopy, Source source) {
- try {
- accessed(source);
- RecordingErrorListener errorListener = new RecordingErrorListener();
- AnalysisContextImpl_ScanResult scanResult = internalScan(source, errorListener);
- Parser parser = new Parser(source, errorListener);
- CompilationUnit unit = parser.parseCompilationUnit(scanResult._token);
- LineInfo lineInfo = new LineInfo(scanResult._lineStarts);
- List<AnalysisError> errors = errorListener.getErrors2(source);
- bool hasPartOfDirective = false;
- bool hasLibraryDirective = false;
- Set<Source> exportedSources = new Set<Source>();
- Set<Source> importedSources = new Set<Source>();
- Set<Source> includedSources = new Set<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) {
- hasLibraryDirective = true;
- } else if (directive is PartDirective) {
- Source partSource = resolveSource(source, directive as PartDirective);
- if (partSource != null) {
- javaSetAdd(includedSources, partSource);
- }
- } else if (directive is PartOfDirective) {
- hasPartOfDirective = true;
- }
- }
- unit.parsingErrors = errors;
- unit.lineInfo = lineInfo;
- if (identical(dartCopy.getState(DartEntry.SOURCE_KIND), CacheState.INVALID)) {
- if (hasPartOfDirective && !hasLibraryDirective) {
- dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.PART);
- } else {
- dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
- }
- }
- dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
- dartCopy.setValue(DartEntry.PARSED_UNIT, unit);
- dartCopy.setValue(DartEntry.PARSE_ERRORS, errors);
- dartCopy.setValue(DartEntry.EXPORTED_LIBRARIES, toArray(exportedSources));
- dartCopy.setValue(DartEntry.IMPORTED_LIBRARIES, toArray(importedSources));
- dartCopy.setValue(DartEntry.INCLUDED_PARTS, toArray(includedSources));
- return dartCopy.getValue(DartEntry.PARSED_UNIT);
- } on AnalysisException catch (exception) {
- dartCopy.setState(SourceEntry.LINE_INFO, CacheState.ERROR);
- dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.ERROR);
- dartCopy.setState(DartEntry.PARSE_ERRORS, CacheState.ERROR);
- dartCopy.setState(DartEntry.EXPORTED_LIBRARIES, CacheState.ERROR);
- dartCopy.setState(DartEntry.IMPORTED_LIBRARIES, CacheState.ERROR);
- dartCopy.setState(DartEntry.INCLUDED_PARTS, CacheState.ERROR);
- throw exception;
- }
+ return getHtmlResolutionData2(source, htmlEntry, descriptor);
}
/**
- * Scan and parse the given Dart file, updating the cache as appropriate, and return the updated
- * cache entry associated with the source.
+ * 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 compilation unit to be parsed
- * @return the updated cache entry associated with the source
- * @throws AnalysisException if the source does not represent a Dart compilation unit or if the
- * compilation unit cannot be parsed for some reason
+ * @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
*/
- DartEntry internalParseDart(Source source) {
- AnalysisContextImpl_ScanResult scanResult = null;
- LineInfo lineInfo = null;
- CompilationUnit unit = null;
- List<AnalysisError> errors = null;
- bool hasPartOfDirective = false;
- bool hasLibraryDirective = false;
- Set<Source> exportedSources = new Set<Source>();
- Set<Source> importedSources = new Set<Source>();
- Set<Source> includedSources = new Set<Source>();
- AnalysisException thrownException = null;
- try {
- RecordingErrorListener errorListener = new RecordingErrorListener();
- scanResult = internalScan(source, errorListener);
- Parser parser = new Parser(source, errorListener);
- unit = parser.parseCompilationUnit(scanResult._token);
- lineInfo = new LineInfo(scanResult._lineStarts);
- 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) {
- hasLibraryDirective = true;
- } else if (directive is PartDirective) {
- Source partSource = resolveSource(source, directive as PartDirective);
- if (partSource != null) {
- javaSetAdd(includedSources, partSource);
- }
- } else if (directive is PartOfDirective) {
- hasPartOfDirective = true;
- }
- }
- unit.parsingErrors = errors;
- unit.lineInfo = lineInfo;
- } on AnalysisException catch (exception) {
- thrownException = exception;
- }
- DartEntry dartEntry = null;
- {
- SourceEntry sourceEntry = _sourceMap[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;
- accessed(source);
- int sourceTime = source.modificationStamp;
- int resultTime = scanResult == null ? sourceTime : scanResult.modificationTime;
- if (sourceTime == resultTime) {
- if (dartEntry.modificationTime != sourceTime) {
- sourceChanged(source);
- dartEntry = getReadableDartEntry(source);
- }
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- if (thrownException == null) {
- dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
- if (hasPartOfDirective && !hasLibraryDirective) {
- dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.PART);
- } else {
- dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
- }
- dartCopy.setValue(DartEntry.PARSED_UNIT, unit);
- dartCopy.setValue(DartEntry.PARSE_ERRORS, errors);
- dartCopy.setValue(DartEntry.EXPORTED_LIBRARIES, toArray(exportedSources));
- dartCopy.setValue(DartEntry.IMPORTED_LIBRARIES, toArray(importedSources));
- dartCopy.setValue(DartEntry.INCLUDED_PARTS, toArray(includedSources));
- } else {
- dartCopy.recordParseError();
- }
- _sourceMap[source] = dartCopy;
- dartEntry = dartCopy;
- }
- }
- if (thrownException != null) {
- if (thrownException.cause is! JavaIOException) {
- AnalysisEngine.instance.logger.logError2("Could not parse ${source.fullName}", thrownException);
- }
- throw thrownException;
- }
- return dartEntry;
+ Object getHtmlResolutionData2(Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
+ htmlEntry = cacheHtmlResolutionData(source, htmlEntry, descriptor);
+ return htmlEntry.getValue(descriptor);
}
/**
- * Scan and parse the given HTML file, updating the cache as appropriate, and return the updated
- * cache entry associated with the source.
+ * 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.
*
- * @param source the source representing the HTML file to be parsed
- * @return the updated cache entry associated with the source
- * @throws AnalysisException if the source does not represent an HTML file or if the file cannot
- * be parsed for some reason
+ * @return the next task that needs to be performed
*/
- HtmlEntry internalParseHtml(Source source) {
- HtmlParseResult result = null;
- LineInfo lineInfo = null;
- AnalysisException thrownException = null;
- try {
- result = new HtmlParser(source).parse(scanHtml(source));
- lineInfo = new LineInfo(result.lineStarts);
- } on AnalysisException catch (exception) {
- thrownException = exception;
- }
- HtmlEntry htmlEntry = null;
+ AnalysisTask get nextTaskAnalysisTask {
{
- SourceEntry sourceEntry = _sourceMap[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;
- accessed(source);
- int sourceTime = source.modificationStamp;
- int resultTime = result == null ? sourceTime : result.modificationTime;
- if (sourceTime == resultTime) {
- if (htmlEntry.modificationTime != sourceTime) {
- sourceChanged(source);
- htmlEntry = getReadableHtmlEntry(source);
+ bool enableHints = analysisOptions.hint;
+ 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);
+ }
+ CompilationUnit parseUnit = dartEntry.anyParsedCompilationUnit;
+ if (parseUnit == null) {
+ 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);
+ }
+ }
+ CacheState hintsState = dartEntry.getState2(DartEntry.HINTS, librarySource);
+ if (enableHints && (identical(hintsState, CacheState.INVALID) || identical(hintsState, CacheState.FLUSHED))) {
+ LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
+ if (libraryElement != null) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.IN_PROCESS);
+ _cache.put(source, dartCopy);
+ return new GenerateDartHintsTask(this, 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);
+ }
}
- HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
- if (thrownException == null) {
- HtmlUnit unit = result.htmlUnit;
- htmlCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
- htmlCopy.setValue(HtmlEntry.PARSED_UNIT, unit);
- htmlCopy.setValue(HtmlEntry.REFERENCED_LIBRARIES, getLibrarySources2(source, unit));
- } else {
- htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.ERROR);
- htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.ERROR);
- htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.ERROR);
+ }
+ 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);
+ }
}
- _sourceMap[source] = htmlCopy;
- htmlEntry = htmlCopy;
}
+ for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
+ SourceEntry sourceEntry = entry.getValue();
+ if (sourceEntry is DartEntry) {
+ Source source = entry.getKey();
+ DartEntry dartEntry = sourceEntry as DartEntry;
+ if (identical(dartEntry.kind, SourceKind.LIBRARY) && identical(dartEntry.getState(DartEntry.ELEMENT), CacheState.INVALID)) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setState(DartEntry.ELEMENT, CacheState.IN_PROCESS);
+ _cache.put(source, dartCopy);
+ return new ResolveDartLibraryTask(this, source, source);
+ } else if (enableHints && identical(dartEntry.getState2(DartEntry.HINTS, source), CacheState.INVALID)) {
+ LibraryElement libraryElement = dartEntry.getValue(DartEntry.ELEMENT);
+ if (libraryElement != null) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setState2(DartEntry.HINTS, source, CacheState.IN_PROCESS);
+ _cache.put(source, dartCopy);
+ return new GenerateDartHintsTask(this, libraryElement);
+ }
+ }
+ } 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;
}
- if (thrownException != null) {
- AnalysisEngine.instance.logger.logError2("Could not parse ${source.fullName}", thrownException);
- throw thrownException;
- }
- ChangeNoticeImpl notice = getNotice(source);
- notice.setErrors(htmlEntry.allErrors, lineInfo);
- return htmlEntry;
}
- DartEntry internalResolveDart(Source unitSource, Source librarySource) {
- DartEntry dartEntry = getReadableDartEntry(unitSource);
- if (dartEntry == null) {
- throw new AnalysisException.con1("Internal error: attempting to parse non-Dart file as a Dart file: ${unitSource.fullName}");
- }
- LibraryResolver resolver = null;
- AnalysisException thrownException = null;
- try {
- resolver = new LibraryResolver(this);
- resolver.resolveLibrary(librarySource, true);
- } on AnalysisException catch (exception) {
- thrownException = exception;
+
+ /**
+ * 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;
}
- if (thrownException == null) {
- {
- accessed(unitSource);
- }
- recordResolutionResults(resolver);
- dartEntry = getReadableDartEntry(unitSource);
- } else {
- AnalysisEngine.instance.logger.logError2("Could not resolve ${unitSource.fullName}", thrownException);
- bool unitIsLibrary = unitSource == librarySource;
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- dartCopy.setState2(DartEntry.RESOLUTION_ERRORS, librarySource, CacheState.ERROR);
- if (unitIsLibrary) {
- dartCopy.setState(DartEntry.ELEMENT, CacheState.ERROR);
+ 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);
}
- _sourceMap[unitSource] = dartCopy;
- if (!unitIsLibrary) {
- DartEntry libraryEntry = getReadableDartEntry(librarySource);
- if (libraryEntry != null) {
- DartEntryImpl libraryCopy = dartEntry.writableCopy;
- libraryCopy.setState2(DartEntry.RESOLUTION_ERRORS, librarySource, CacheState.ERROR);
- libraryCopy.setState(DartEntry.ELEMENT, CacheState.ERROR);
- _sourceMap[librarySource] = libraryCopy;
- }
+ if (sourceEntry is DartEntry) {
+ _cache.accessed(source);
+ return sourceEntry as DartEntry;
}
- throw thrownException;
+ return null;
}
- ChangeNoticeImpl notice = getNotice(unitSource);
- notice.setErrors(dartEntry.allErrors, dartEntry.getValue(SourceEntry.LINE_INFO));
- return dartEntry;
}
/**
- * Scan and parse the given HTML file, updating the cache as appropriate, and return the updated
- * cache entry associated with the source.
+ * Return the cache entry associated with the given source, or `null` if the source is not
+ * an HTML file.
*
- * @param source the source representing the HTML file to be parsed
- * @return the updated cache entry associated with the source
- * @throws AnalysisException if the source does not represent an HTML file or if the file cannot
- * be parsed for some reason
+ * @param source the source for which a cache entry is being sought
+ * @return the source cache entry associated with the given source
*/
- HtmlEntry internalResolveHtml(Source source) {
- HtmlEntry htmlEntry = getReadableHtmlEntry(source);
- if (htmlEntry == null) {
- throw new AnalysisException.con1("Internal error: attempting to parse non-HTML file as a HTML file: ${source.fullName}");
- }
- int resultTime = 0;
- HtmlElement element = null;
- List<AnalysisError> resolutionErrors = null;
- AnalysisException thrownException = null;
- try {
- htmlEntry = internalCacheHtmlParseData(source, htmlEntry, [HtmlEntry.PARSED_UNIT]);
- HtmlUnit unit = htmlEntry.getValue(HtmlEntry.PARSED_UNIT);
- if (unit == null) {
- throw new AnalysisException.con1("Internal error: internalCacheHtmlParseData returned an entry without a parsed HTML unit");
+ HtmlEntry getReadableHtmlEntry(Source source) {
+ {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry == null) {
+ sourceEntry = createSourceEntry(source);
}
- resultTime = htmlEntry.modificationTime;
- HtmlUnitBuilder builder = new HtmlUnitBuilder(this);
- element = builder.buildHtmlElement2(source, resultTime, unit);
- resolutionErrors = builder.errorListener.getErrors2(source);
- } on AnalysisException catch (exception) {
- thrownException = exception;
+ 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 = _sourceMap[source];
- if (sourceEntry is! HtmlEntry) {
- throw new AnalysisException.con1("Internal error: attempting to resolve non-HTML file as a HTML file: ${source.fullName}");
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry == null) {
+ sourceEntry = createSourceEntry(source);
}
- htmlEntry = sourceEntry as HtmlEntry;
- accessed(source);
- int sourceTime = source.modificationStamp;
- if (sourceTime == resultTime) {
- if (htmlEntry.modificationTime != sourceTime) {
- sourceChanged(source);
- htmlEntry = getReadableHtmlEntry(source);
- }
- HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
- if (thrownException == null) {
- htmlCopy.setValue(HtmlEntry.RESOLUTION_ERRORS, resolutionErrors);
- htmlCopy.setValue(HtmlEntry.ELEMENT, element);
- } else {
- htmlCopy.setState(HtmlEntry.RESOLUTION_ERRORS, CacheState.ERROR);
- htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.ERROR);
- }
- _sourceMap[source] = htmlCopy;
- htmlEntry = htmlCopy;
+ if (sourceEntry != null) {
+ _cache.accessed(source);
}
+ return sourceEntry;
}
- if (thrownException != null) {
- AnalysisEngine.instance.logger.logError2("Could not resolve ${source.fullName}", thrownException);
- throw thrownException;
- }
- ChangeNoticeImpl notice = getNotice(source);
- notice.setErrors(htmlEntry.allErrors, htmlEntry.getValue(SourceEntry.LINE_INFO));
- return htmlEntry;
}
- AnalysisContextImpl_ScanResult internalScan(Source source, AnalysisErrorListener errorListener) {
- AnalysisContextImpl_ScanResult result = new AnalysisContextImpl_ScanResult();
- Source_ContentReceiver receiver = new Source_ContentReceiver_7(source, errorListener, result);
- try {
- source.getContents(receiver);
- } catch (exception) {
- throw new AnalysisException.con3(exception);
+
+ /**
+ * Return 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 result;
+ return new List.from(sources);
}
/**
- * Invalidate all of the results computed by this context.
+ * 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 invalidateAllResults() {
- for (MapEntry<Source, SourceEntry> mapEntry in getMapEntrySet(_sourceMap)) {
+ void invalidateAllResolutionInformation() {
+ for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
SourceEntry sourceEntry = mapEntry.getValue();
if (sourceEntry is HtmlEntry) {
HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
@@ -4326,22 +4019,24 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* 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 = getDartEntry(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);
- _sourceMap[librarySource] = libraryCopy;
- for (Source unitSource in includedParts) {
- DartEntry partEntry = getDartEntry(unitSource);
- if (partEntry != null) {
- DartEntryImpl dartCopy = partEntry.writableCopy;
- dartCopy.invalidateAllResolutionInformation();
- _sourceMap[unitSource] = dartCopy;
+ _cache.put(librarySource, libraryCopy);
+ for (Source partSource in includedParts) {
+ SourceEntry partEntry = _cache.get(partSource);
+ if (partEntry is DartEntry) {
+ DartEntryImpl partCopy = ((partEntry as DartEntry)).writableCopy;
+ partCopy.invalidateAllResolutionInformation();
+ _cache.put(partSource, partCopy);
}
}
}
@@ -4377,301 +4072,461 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
/**
- * Return `true` if the given source is in the array of priority sources.
+ * Given a cache entry and a library element, record the library element and other information
+ * gleaned from the element in the cache entry.
*
- * Note: This method must only be invoked while we are synchronized on [cacheLock].
+ * @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
*/
- bool isPrioritySource(Source source) {
- for (Source prioritySource in _priorityOrder) {
- if (source == prioritySource) {
- return true;
- }
+ 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);
}
- return false;
+ dartCopy.setValue(DartEntry.INCLUDED_PARTS, new List.from(unitSources));
}
/**
- * Perform a single analysis task.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
+ * Record the results produced by performing a [GenerateDartHintsTask]. If the results were
+ * computed from data that is now out-of-date, then the results will not be recorded.
*
- * @return `true` if work was done, implying that there might be more work to be done
+ * @param task the task that was performed
+ * @return an entry containing the computed results
+ * @throws AnalysisException if the results could not be recorded
*/
- bool performSingleAnalysisTask() {
- for (Source source in _priorityOrder) {
- SourceEntry sourceEntry = _sourceMap[source];
- if (sourceEntry is DartEntry) {
- DartEntry dartEntry = sourceEntry as DartEntry;
- CacheState parsedUnitState = dartEntry.getState(DartEntry.PARSED_UNIT);
- if (identical(parsedUnitState, CacheState.INVALID) || identical(parsedUnitState, CacheState.FLUSHED)) {
- safelyParseCompilationUnit(source, dartEntry);
- return true;
- }
- for (Source librarySource in getLibrariesContaining(source)) {
- SourceEntry libraryEntry = _sourceMap[librarySource];
- if (libraryEntry is DartEntry) {
- CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
- if (identical(elementState, CacheState.INVALID) || identical(elementState, CacheState.FLUSHED)) {
- safelyResolveCompilationUnit(librarySource);
- return true;
- }
- }
- if (identical(dartEntry.getState2(DartEntry.RESOLVED_UNIT, librarySource), CacheState.FLUSHED)) {
- safelyResolveCompilationUnit2(source, librarySource);
- return true;
- }
- }
- } 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)) {
- safelyParseHtmlUnit(source);
- return true;
+ DartEntry recordGenerateDartHintsTask(GenerateDartHintsTask task) {
+ Source librarySource = task.libraryElement.source;
+ AnalysisException thrownException = task.exception;
+ DartEntry libraryEntry = null;
+ Map<Source, TimestampedData<List<AnalysisError>>> hintMap = task.hintMap;
+ if (hintMap == null) {
+ {
+ SourceEntry sourceEntry = _cache.get(librarySource);
+ if (sourceEntry is! DartEntry) {
+ throw new AnalysisException.con1("Internal error: attempting to generate hints for non-Dart file as a Dart file: ${librarySource.fullName}");
}
- CacheState elementState = htmlEntry.getState(HtmlEntry.ELEMENT);
- if (identical(elementState, CacheState.INVALID) || identical(elementState, CacheState.FLUSHED)) {
- safelyResolveHtmlUnit(source);
- return true;
+ if (thrownException == null) {
+ thrownException = new AnalysisException.con1("GenerateDartHintsTask returned a null hint map without throwing an exception: ${librarySource.fullName}");
}
+ DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
+ dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.ERROR);
+ dartCopy.exception = thrownException;
+ _cache.put(librarySource, dartCopy);
}
+ throw thrownException;
}
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- SourceEntry sourceEntry = entry.getValue();
- if (sourceEntry is DartEntry) {
+ for (MapEntry<Source, TimestampedData<List<AnalysisError>>> entry in getMapEntrySet(hintMap)) {
+ Source unitSource = entry.getKey();
+ TimestampedData<List<AnalysisError>> results = entry.getValue();
+ {
+ SourceEntry sourceEntry = _cache.get(unitSource);
+ if (sourceEntry is! DartEntry) {
+ throw new AnalysisException.con1("Internal error: attempting to parse non-Dart file as a Dart file: ${unitSource.fullName}");
+ }
DartEntry dartEntry = sourceEntry as DartEntry;
- if (identical(dartEntry.getState(DartEntry.PARSED_UNIT), CacheState.INVALID)) {
- safelyParseCompilationUnit(entry.getKey(), dartEntry);
- return true;
+ if (unitSource == librarySource) {
+ libraryEntry = dartEntry;
}
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
- if (identical(htmlEntry.getState(HtmlEntry.PARSED_UNIT), CacheState.INVALID)) {
- safelyParseHtmlUnit(entry.getKey());
- return true;
+ _cache.accessed(unitSource);
+ int sourceTime = unitSource.modificationStamp;
+ int resultTime = results.modificationTime;
+ if (sourceTime == resultTime) {
+ if (dartEntry.modificationTime != sourceTime) {
+ sourceChanged(unitSource);
+ dartEntry = getReadableDartEntry(unitSource);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("A Dart file became a non-Dart file: ${unitSource.fullName}");
+ }
+ }
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null) {
+ dartCopy.setValue2(DartEntry.HINTS, librarySource, results.data);
+ ChangeNoticeImpl notice = getNotice(unitSource);
+ notice.setErrors(dartCopy.allErrors, dartCopy.getValue(SourceEntry.LINE_INFO));
+ } else {
+ dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.ERROR);
+ }
+ dartCopy.exception = thrownException;
+ _cache.put(unitSource, dartCopy);
+ dartEntry = dartCopy;
+ } else {
+ if (identical(dartEntry.getState2(DartEntry.HINTS, librarySource), CacheState.IN_PROCESS)) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null || resultTime >= 0) {
+ dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.INVALID);
+ } else {
+ dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.ERROR);
+ }
+ dartCopy.exception = thrownException;
+ _cache.put(unitSource, dartCopy);
+ dartEntry = dartCopy;
+ }
}
}
}
- for (MapEntry<Source, SourceEntry> entry in getMapEntrySet(_sourceMap)) {
- 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)) {
- safelyResolveCompilationUnit(entry.getKey());
- return true;
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ return libraryEntry;
+ }
+
+ /**
+ * 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();
}
- } else if (sourceEntry is HtmlEntry) {
- HtmlEntry htmlEntry = sourceEntry as HtmlEntry;
- if (identical(htmlEntry.getState(HtmlEntry.ELEMENT), CacheState.INVALID)) {
- safelyResolveHtmlUnit(entry.getKey());
- return true;
+ dartCopy.exception = thrownException;
+ _cache.put(source, dartCopy);
+ dartEntry = dartCopy;
+ } else {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null || resultTime >= 0) {
+ dartCopy.recordParseNotInProcess();
+ } else {
+ dartCopy.recordParseError();
}
+ dartCopy.exception = thrownException;
+ _cache.put(source, dartCopy);
+ dartEntry = dartCopy;
}
}
- return false;
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ return dartEntry;
}
/**
- * Given a cache entry and a library element, record the library element and other information
- * gleaned from the element in the cache entry.
+ * 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 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
+ * @param task the task that was performed
+ * @return an entry containing the computed results
+ * @throws AnalysisException if the results could not be recorded
*/
- 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);
+ 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);
+ }
+ htmlCopy.exception = thrownException;
+ _cache.put(source, htmlCopy);
+ htmlEntry = htmlCopy;
+ } else {
+ HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
+ if (thrownException == null || resultTime >= 0) {
+ 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);
+ }
+ } else {
+ htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.ERROR);
+ htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.ERROR);
+ htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.ERROR);
+ }
+ htmlCopy.exception = thrownException;
+ _cache.put(source, htmlCopy);
+ htmlEntry = htmlCopy;
+ }
}
- dartCopy.setValue(DartEntry.INCLUDED_PARTS, new List.from(unitSources));
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ return htmlEntry;
}
/**
- * Record the result of using the given resolver to resolve one or more libraries.
+ * 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 resolver the resolver that has the needed results
- * @throws AnalysisException if the results cannot be retrieved for some reason
+ * @param task the task that was performed
+ * @return an entry containing the computed results
+ * @throws AnalysisException if the results could not be recorded
*/
- void recordResolutionResults(LibraryResolver resolver) {
- Source htmlSource = _sourceFactory.forUri(DartSdk.DART_HTML);
- 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 = getDartEntry(source);
- if (dartEntry != null) {
- int sourceTime = source.modificationStamp;
- int resultTime = dartEntry.modificationTime;
- if (sourceTime == resultTime) {
+ DartEntry recordResolveDartLibraryTaskResults(ResolveDartLibraryTask task) {
+ LibraryResolver resolver = task.libraryResolver;
+ AnalysisException thrownException = task.exception;
+ DartEntry unitEntry = null;
+ Source unitSource = task.unitSource;
+ if (resolver != null) {
+ {
+ if (allModificationTimesMatch(resolver)) {
+ Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
+ 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;
- 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);
+ 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();
+ }
+ dartCopy.exception = thrownException;
+ _cache.put(source, dartCopy);
+ if (source == unitSource) {
+ unitEntry = dartCopy;
}
- _sourceMap[source] = dartCopy;
ChangeNoticeImpl notice = getNotice(source);
notice.compilationUnit = unit;
notice.setErrors(dartCopy.allErrors, lineInfo);
- } else {
- sourceChanged(source);
+ }
+ }
+ } else {
+ for (Library library in resolver.resolvedLibraries) {
+ for (Source source in library.compilationUnitSources) {
+ DartEntry dartEntry = getReadableDartEntry(source);
+ if (dartEntry != null) {
+ int resultTime = library.getModificationTime(source);
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null || resultTime >= 0) {
+ dartCopy.recordResolutionNotInProcess();
+ } else {
+ dartCopy.recordResolutionError();
+ }
+ dartCopy.exception = thrownException;
+ _cache.put(source, dartCopy);
+ if (source == unitSource) {
+ unitEntry = dartCopy;
+ }
+ }
}
}
}
}
}
- }
-
- /**
- * Remove and return one source from the list of recently used sources whose AST structure can be
- * flushed from the cache. The source that will be returned will be the source that has been
- * unreferenced for the longest period of time but that is not a priority for analysis.
- *
- * @return the source that was removed
- *
- * Note: This method must only be invoked while we are synchronized on [cacheLock].
- */
- Source removeAstToFlush() {
- for (int i = 0; i < _recentlyUsed.length; i++) {
- Source source = _recentlyUsed[i];
- if (!isPrioritySource(source)) {
- return _recentlyUsed.removeAt(i);
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ if (unitEntry == null) {
+ unitEntry = getReadableDartEntry(unitSource);
+ if (unitEntry == null) {
+ throw new AnalysisException.con1("A Dart file became a non-Dart file: ${unitSource.fullName}");
}
}
- AnalysisEngine.instance.logger.logError2("Internal error: The number of priority sources is greater than the maximum cache size", new JavaException());
- return _recentlyUsed.removeAt(0);
+ return unitEntry;
}
/**
- * 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.
+ * 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 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
+ * @param task the task that was performed
+ * @return an entry containing the computed results
+ * @throws AnalysisException if the results could not be recorded
*/
- Source resolveSource(Source librarySource, UriBasedDirective directive) {
- StringLiteral uriLiteral = directive.uri;
- if (uriLiteral is StringInterpolation) {
- return null;
- }
- String uriContent = uriLiteral.stringValue.trim();
- if (uriContent == null || uriContent.isEmpty) {
- return null;
- }
- uriContent = Uri.encodeFull(uriContent);
- try {
- parseUriWithException(uriContent);
- return _sourceFactory.resolveUri(librarySource, uriContent);
- } on URISyntaxException catch (exception) {
- return null;
- }
- }
-
- /**
- * Parse the given source and update the cache.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source to be parsed
- * @param dartEntry the cache entry associated with the source
- */
- void safelyParseCompilationUnit(Source source, DartEntry dartEntry) {
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- try {
- internalParseCompilationUnit(dartCopy, source);
- } on AnalysisException catch (exception) {
- if (exception.cause is! JavaIOException) {
- AnalysisEngine.instance.logger.logError2("Could not parse ${source.fullName}", exception);
+ SourceEntry recordResolveDartUnitTaskResults(ResolveDartUnitTask task) {
+ Source unitSource = task.source;
+ Source librarySource = task.librarySource;
+ AnalysisException thrownException = task.exception;
+ DartEntry dartEntry = null;
+ {
+ SourceEntry sourceEntry = _cache.get(unitSource);
+ if (sourceEntry is! DartEntry) {
+ throw new AnalysisException.con1("Internal error: attempting to reolve non-Dart file as a Dart file: ${unitSource.fullName}");
}
- }
- _sourceMap[source] = dartCopy;
- }
-
- /**
- * Parse the given source and update the cache.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source to be parsed
- */
- void safelyParseHtmlUnit(Source source) {
- try {
- parseHtmlUnit(source);
- } on AnalysisException catch (exception) {
- if (exception.cause is! JavaIOException) {
- AnalysisEngine.instance.logger.logError2("Could not parse ${source.fullName}", exception);
+ dartEntry = sourceEntry as DartEntry;
+ _cache.accessed(unitSource);
+ int sourceTime = unitSource.modificationStamp;
+ int resultTime = task.modificationTime;
+ if (sourceTime == resultTime) {
+ if (dartEntry.modificationTime != sourceTime) {
+ sourceChanged(unitSource);
+ dartEntry = getReadableDartEntry(unitSource);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("A Dart file became a non-Dart file: ${unitSource.fullName}");
+ }
+ }
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null) {
+ dartCopy.setValue2(DartEntry.RESOLVED_UNIT, librarySource, task.resolvedUnit);
+ } else {
+ dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.ERROR);
+ }
+ dartCopy.exception = thrownException;
+ _cache.put(unitSource, dartCopy);
+ dartEntry = dartCopy;
+ } else {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null || resultTime >= 0) {
+ if (identical(dartCopy.getState(DartEntry.RESOLVED_UNIT), CacheState.IN_PROCESS)) {
+ dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.INVALID);
+ }
+ } else {
+ dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.ERROR);
+ }
+ dartCopy.exception = thrownException;
+ _cache.put(unitSource, dartCopy);
+ dartEntry = dartCopy;
}
}
- }
-
- /**
- * Resolve the given source and update the cache.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param source the source to be resolved
- */
- void safelyResolveCompilationUnit(Source source) {
- try {
- computeLibraryElement(source);
- } on AnalysisException catch (exception) {
- }
- }
-
- /**
- * Resolve the given source within the given library and update the cache.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
- *
- * @param unitSource the source to be resolved
- * @param librarySource the source
- */
- void safelyResolveCompilationUnit2(Source unitSource, Source librarySource) {
- try {
- resolveCompilationUnit2(unitSource, librarySource);
- } on AnalysisException catch (exception) {
- DartEntryImpl dartCopy = getReadableDartEntry(unitSource).writableCopy;
- dartCopy.recordResolutionError();
- _sourceMap[unitSource] = dartCopy;
- AnalysisEngine.instance.logger.logError2("Could not resolve ${unitSource.fullName} in ${librarySource.fullName}", exception);
+ if (thrownException != null) {
+ throw thrownException;
}
+ return dartEntry;
}
/**
- * Resolve the given source and update the cache.
- *
- * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
+ * 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 source the source to be resolved
+ * @param task the task that was performed
+ * @return an entry containing the computed results
+ * @throws AnalysisException if the results could not be recorded
*/
- void safelyResolveHtmlUnit(Source source) {
- try {
- computeHtmlElement(source);
- } on AnalysisException catch (exception) {
- AnalysisEngine.instance.logger.logError2("Could not resolve ${source.fullName}", exception);
+ 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();
+ }
+ htmlCopy.exception = thrownException;
+ _cache.put(source, htmlCopy);
+ htmlEntry = htmlCopy;
+ } else {
+ HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+ if (thrownException == null || resultTime >= 0) {
+ 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);
+ }
+ } else {
+ htmlCopy.recordResolutionError();
+ }
+ htmlCopy.exception = thrownException;
+ _cache.put(source, htmlCopy);
+ htmlEntry = htmlCopy;
+ }
}
- }
- HtmlScanResult scanHtml(Source source) {
- HtmlScanner scanner = new HtmlScanner(source);
- try {
- source.getContents(scanner);
- } catch (exception) {
- throw new AnalysisException.con3(exception);
+ if (thrownException != null) {
+ throw thrownException;
}
- return scanner.result;
+ return htmlEntry;
}
/**
@@ -4684,13 +4539,13 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* @return `true` if the new source is a Dart file
*/
bool sourceAvailable(Source source) {
- SourceEntry sourceEntry = _sourceMap[source];
+ SourceEntry sourceEntry = _cache.get(source);
if (sourceEntry == null) {
sourceEntry = createSourceEntry(source);
} else {
SourceEntryImpl sourceCopy = sourceEntry.writableCopy;
sourceCopy.modificationTime = source.modificationStamp;
- _sourceMap[source] = sourceCopy;
+ _cache.put(source, sourceCopy);
}
return sourceEntry is DartEntry;
}
@@ -4701,29 +4556,21 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* @param source the source that has been changed
*/
void sourceChanged(Source source) {
- SourceEntry sourceEntry = _sourceMap[source];
+ SourceEntry sourceEntry = _cache.get(source);
if (sourceEntry is HtmlEntry) {
HtmlEntryImpl htmlCopy = ((sourceEntry as HtmlEntry)).writableCopy;
htmlCopy.modificationTime = source.modificationStamp;
- htmlCopy.setState(HtmlEntry.ELEMENT, CacheState.INVALID);
- htmlCopy.setState(SourceEntry.LINE_INFO, CacheState.INVALID);
- htmlCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.INVALID);
- htmlCopy.setState(HtmlEntry.REFERENCED_LIBRARIES, CacheState.INVALID);
- htmlCopy.setState(HtmlEntry.RESOLUTION_ERRORS, CacheState.INVALID);
- _sourceMap[source] = htmlCopy;
+ htmlCopy.invalidateAllInformation();
+ _cache.put(source, htmlCopy);
} else if (sourceEntry is DartEntry) {
List<Source> containingLibraries = getLibrariesContaining(source);
- DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
- dartCopy.modificationTime = source.modificationStamp;
- dartCopy.setState(DartEntry.ELEMENT, CacheState.INVALID);
- dartCopy.setState(SourceEntry.LINE_INFO, CacheState.INVALID);
- dartCopy.setState(DartEntry.PARSE_ERRORS, CacheState.INVALID);
- dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.INVALID);
- dartCopy.setState(DartEntry.SOURCE_KIND, CacheState.INVALID);
- _sourceMap[source] = dartCopy;
for (Source library in containingLibraries) {
invalidateLibraryResolution(library);
}
+ DartEntryImpl dartCopy = ((sourceEntry as DartEntry)).writableCopy;
+ dartCopy.modificationTime = source.modificationStamp;
+ dartCopy.invalidateAllInformation();
+ _cache.put(source, dartCopy);
}
}
@@ -4733,8 +4580,8 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* @param source the source that has been deleted
*/
void sourceRemoved(Source source) {
- DartEntry dartEntry = getDartEntry(source);
- if (dartEntry != null) {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry is DartEntry) {
Set<Source> libraries = new Set<Source>();
for (Source librarySource in getLibrariesContaining(source)) {
javaSetAdd(libraries, librarySource);
@@ -4746,2440 +4593,221 @@ class AnalysisContextImpl implements InternalAnalysisContext {
invalidateLibraryResolution(librarySource);
}
}
- _sourceMap.remove(source);
- }
-
- /**
- * 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);
+ _cache.remove(source);
}
}
/**
- * The interface `AnalysisTask` defines the behavior of objects used to perform an analysis
- * task.
+ * Instances of the class `AnalysisTaskResultRecorder` are used by an analysis context to
+ * record the results of a task.
*/
-abstract class AnalysisContextImpl_AnalysisTask {
-
- /**
- * Perform a single analysis task. Implementors should assume that the cache is not locked.
- */
- void perform();
+class AnalysisContextImpl_AnalysisTaskResultRecorder implements AnalysisTaskVisitor<SourceEntry> {
+ final AnalysisContextImpl AnalysisContextImpl_this;
+ AnalysisContextImpl_AnalysisTaskResultRecorder(this.AnalysisContextImpl_this);
+ SourceEntry visitGenerateDartHintsTask(GenerateDartHintsTask task) => AnalysisContextImpl_this.recordGenerateDartHintsTask(task);
+ DartEntry visitParseDartTask(ParseDartTask task) => AnalysisContextImpl_this.recordParseDartTaskResults(task);
+ HtmlEntry visitParseHtmlTask(ParseHtmlTask task) => AnalysisContextImpl_this.recordParseHtmlTaskResults(task);
+ DartEntry visitResolveDartLibraryTask(ResolveDartLibraryTask task) => AnalysisContextImpl_this.recordResolveDartLibraryTaskResults(task);
+ SourceEntry visitResolveDartUnitTask(ResolveDartUnitTask task) => AnalysisContextImpl_this.recordResolveDartUnitTaskResults(task);
+ SourceEntry visitResolveHtmlTask(ResolveHtmlTask task) => AnalysisContextImpl_this.recordResolveHtmlTaskResults(task);
}
/**
- * Instances of the class `ParseDartTask` parse a specific source as a Dart file.
+ * Instances of the class `AnalysisErrorInfoImpl` represent the analysis errors and line info
+ * associated with a source.
*/
-class AnalysisContextImpl_ParseDartTask implements AnalysisContextImpl_AnalysisTask {
- final AnalysisContextImpl AnalysisContextImpl_this;
-
- /**
- * The source to be parsed.
- */
- Source _source;
+class AnalysisErrorInfoImpl implements AnalysisErrorInfo {
/**
- * Initialize a newly created task to parse the given source as a Dart file.
- *
- * @param source the source to be resolved
+ * The analysis errors associated with a source, or `null` if there are no errors.
*/
- AnalysisContextImpl_ParseDartTask(this.AnalysisContextImpl_this, Source source) {
- this._source = source;
- }
- void perform() {
- try {
- AnalysisContextImpl_this.internalParseDart(_source);
- } on AnalysisException catch (exception) {
- AnalysisEngine.instance.logger.logError2("Could not parse ${_source.fullName}", exception);
- }
- }
-}
-/**
- * Instances of the class `ParseHtmlTask` parse a specific source as an HTML file.
- */
-class AnalysisContextImpl_ParseHtmlTask implements AnalysisContextImpl_AnalysisTask {
- final AnalysisContextImpl AnalysisContextImpl_this;
+ List<AnalysisError> _errors;
/**
- * The source to be parsed.
+ * The line information associated with the errors, or `null` if there are no errors.
*/
- Source _source;
+ LineInfo _lineInfo;
/**
- * Initialize a newly created task to parse the given source as an HTML file.
+ * Initialize an newly created error info with the errors and line information
*
- * @param source the source to be resolved
+ * @param errors the errors as a result of analysis
+ * @param lineinfo the line info for the errors
*/
- AnalysisContextImpl_ParseHtmlTask(this.AnalysisContextImpl_this, Source source) {
- this._source = source;
- }
- void perform() {
- try {
- AnalysisContextImpl_this.internalParseHtml(_source);
- } on AnalysisException catch (exception) {
- AnalysisEngine.instance.logger.logError2("Could not parse ${_source.fullName}", exception);
- }
+ AnalysisErrorInfoImpl(List<AnalysisError> errors, LineInfo lineInfo) {
+ this._errors = errors;
+ this._lineInfo = lineInfo;
}
-}
-/**
- * Instances of the class `ResolveDartLibraryTask` resolve a specific source as a Dart
- * library.
- */
-class AnalysisContextImpl_ResolveDartLibraryTask implements AnalysisContextImpl_AnalysisTask {
- final AnalysisContextImpl AnalysisContextImpl_this;
/**
- * The source to be resolved.
+ * Return the errors of analysis, or `null` if there were no errors.
+ *
+ * @return the errors as a result of the analysis
*/
- Source _source;
+ List<AnalysisError> get errors => _errors;
/**
- * Initialize a newly created task to resolve the given source as a Dart file.
+ * Return the line information associated with the errors, or `null` if there were no
+ * errors.
*
- * @param source the source to be resolved
+ * @return the line information associated with the errors
*/
- AnalysisContextImpl_ResolveDartLibraryTask(this.AnalysisContextImpl_this, Source source) {
- this._source = source;
- }
- void perform() {
- try {
- AnalysisContextImpl_this.computeLibraryElement(_source);
- } on AnalysisException catch (exception) {
- AnalysisEngine.instance.logger.logError2("Could not resolve ${_source.fullName}", exception);
- }
- }
+ LineInfo get lineInfo => _lineInfo;
}
/**
- * Instances of the class `ResolveDartUnitTask` resolve a specific source as a Dart file
- * within a library.
+ * Instances of the class `AnalysisOptions` represent a set of analysis options used to
+ * control the behavior of an analysis context.
*/
-class AnalysisContextImpl_ResolveDartUnitTask implements AnalysisContextImpl_AnalysisTask {
- final AnalysisContextImpl AnalysisContextImpl_this;
-
- /**
- * The source to be resolved.
- */
- Source _unitSource;
+class AnalysisOptionsImpl implements AnalysisOptions {
/**
- * The source of the library in which the source is to be resolved.
+ * A flag indicating whether analysis is to use strict mode. In strict mode, error reporting is
+ * based exclusively on the static type information.
*/
- Source _librarySource;
+ bool _strictMode = true;
/**
- * Initialize a newly created task to resolve the given source as a Dart file.
- *
- * @param unitSource the source to be resolved
- * @param librarySource the source of the library in which the source is to be resolved
+ * A flag indicating whether analysis is to generate hint results (e.g. type inference based
+ * information and pub best practices).
*/
- AnalysisContextImpl_ResolveDartUnitTask(this.AnalysisContextImpl_this, Source unitSource, Source librarySource) {
- this._unitSource = unitSource;
- this._librarySource = librarySource;
- }
- void perform() {
- try {
- AnalysisContextImpl_this.resolveCompilationUnit2(_unitSource, _librarySource);
- } on AnalysisException catch (exception) {
- DartEntryImpl dartCopy = AnalysisContextImpl_this.getReadableDartEntry(_unitSource).writableCopy;
- dartCopy.recordResolutionError();
- AnalysisContextImpl_this._sourceMap[_unitSource] = dartCopy;
- AnalysisEngine.instance.logger.logError2("Could not resolve ${_unitSource.fullName} in ${_librarySource.fullName}", exception);
- }
- }
-}
-/**
- * Instances of the class `ResolveHtmlTask` resolve a specific source as an HTML file.
- */
-class AnalysisContextImpl_ResolveHtmlTask implements AnalysisContextImpl_AnalysisTask {
- final AnalysisContextImpl AnalysisContextImpl_this;
+ bool _hint = true;
/**
- * The source to be resolved.
+ * A flag indicating whether analysis is to generate dart2js related hint results.
*/
- Source _source;
+ bool _dart2jsHint = true;
+ bool get dart2jsHint => _dart2jsHint;
+ bool get hint => _hint;
/**
- * Initialize a newly created task to resolve the given source as an HTML file.
- *
- * @param source the source to be resolved
- */
- AnalysisContextImpl_ResolveHtmlTask(this.AnalysisContextImpl_this, Source source) {
- this._source = source;
- }
- void perform() {
- try {
- AnalysisContextImpl_this.computeHtmlElement(_source);
- } on AnalysisException catch (exception) {
- AnalysisEngine.instance.logger.logError2("Could not resolve ${_source.fullName}", exception);
- }
- }
-}
-/**
- * Instances of the class `ScanResult` represent the results of scanning a source.
- */
-class AnalysisContextImpl_ScanResult {
-
- /**
- * The time at which the contents of the source were last modified.
- */
- int modificationTime = 0;
-
- /**
- * The first token in the token stream.
- */
- Token _token;
-
- /**
- * The line start information that was produced.
- */
- List<int> _lineStarts;
-}
-class RecursiveXmlVisitor_6 extends RecursiveXmlVisitor<Object> {
- final AnalysisContextImpl AnalysisContextImpl_this;
- Source htmlSource;
- List<Source> libraries;
- RecursiveXmlVisitor_6(this.AnalysisContextImpl_this, this.htmlSource, this.libraries) : super();
- Object visitXmlTagNode(XmlTagNode node) {
- if (javaStringEqualsIgnoreCase(node.tag.lexeme, AnalysisContextImpl._TAG_SCRIPT)) {
- bool isDartScript = false;
- XmlAttributeNode scriptAttribute = null;
- for (XmlAttributeNode attribute in node.attributes) {
- if (javaStringEqualsIgnoreCase(attribute.name.lexeme, AnalysisContextImpl._ATTRIBUTE_SRC)) {
- scriptAttribute = attribute;
- } else if (javaStringEqualsIgnoreCase(attribute.name.lexeme, AnalysisContextImpl._ATTRIBUTE_TYPE)) {
- String text = attribute.text;
- if (text != null && javaStringEqualsIgnoreCase(text, AnalysisContextImpl._TYPE_DART)) {
- isDartScript = true;
- }
- }
- }
- if (isDartScript && scriptAttribute != null) {
- String text = scriptAttribute.text;
- if (text != null) {
- try {
- Uri uri = new Uri(path: text);
- String fileName = uri.path;
- Source librarySource = AnalysisContextImpl_this._sourceFactory.resolveUri(htmlSource, fileName);
- if (librarySource != null && librarySource.exists()) {
- libraries.add(librarySource);
- }
- } catch (exception) {
- AnalysisEngine.instance.logger.logInformation2("Invalid URI ('${text}') in script tag in '${htmlSource.fullName}'", exception);
- }
- }
- }
- }
- return super.visitXmlTagNode(node);
- }
-}
-class Source_ContentReceiver_7 implements Source_ContentReceiver {
- Source source;
- AnalysisErrorListener errorListener;
- AnalysisContextImpl_ScanResult result;
- Source_ContentReceiver_7(this.source, this.errorListener, this.result);
- void accept(CharBuffer contents, int modificationTime2) {
- CharBufferScanner scanner = new CharBufferScanner(source, contents, errorListener);
- result.modificationTime = modificationTime2;
- result._token = scanner.tokenize();
- result._lineStarts = scanner.lineStarts;
- }
- void accept2(String contents, int modificationTime2) {
- StringScanner scanner = new StringScanner(source, contents, errorListener);
- result.modificationTime = modificationTime2;
- result._token = scanner.tokenize();
- result._lineStarts = scanner.lineStarts;
- }
-}
-/**
- * Instances of the class `AnalysisContextImpl` implement an [AnalysisContext].
- *
- * @coverage dart.engine
- */
-class AnalysisContextImpl2 implements InternalAnalysisContext {
-
- /**
- * The set of analysis options controlling the behavior of this context.
- */
- AnalysisOptions _options = new AnalysisOptionsImpl();
-
- /**
- * The source factory used to create the sources that can be analyzed in this context.
- */
- SourceFactory _sourceFactory;
-
- /**
- * A table mapping the sources known to the context to the information known about the source.
- */
- AnalysisCache _cache = new AnalysisCache(_MAX_CACHE_SIZE);
-
- /**
- * A table mapping sources to the change notices that are waiting to be returned related to that
- * source.
- */
- Map<Source, ChangeNoticeImpl> _pendingNotices = new Map<Source, ChangeNoticeImpl>();
-
- /**
- * 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.
- *
- */
- Object _cacheLock = new Object();
-
- /**
- * The object used to record the results of performing an analysis task.
- */
- AnalysisContextImpl2_AnalysisTaskResultRecorder _resultRecorder;
-
- /**
- * The maximum number of sources for which data should be kept in the cache.
- */
- static int _MAX_CACHE_SIZE = 64;
-
- /**
- * 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().
- *
- * @see #setAnalysisPriorityOrder(List)
- */
- static int _MAX_PRIORITY_LIST_SIZE = _MAX_CACHE_SIZE - 4;
-
- /**
- * Initialize a newly created analysis context.
- */
- AnalysisContextImpl2() : super() {
- _resultRecorder = new AnalysisContextImpl2_AnalysisTaskResultRecorder(this);
- }
- void addSourceInfo(Source source, SourceEntry info) {
- _cache.put(source, info);
- }
- void applyChanges(ChangeSet changeSet) {
- if (changeSet.isEmpty) {
- return;
- }
- {
- List<Source> removedSources = new List<Source>.from(changeSet.removed3);
- 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);
- }
- }
- }
- }
- }
- String computeDocumentationComment(Element element) {
- if (element == null) {
- return null;
- }
- Source source = element.source;
- if (source == null) {
- return null;
- }
- 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;
- }
- 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;
- }
- 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) {
- 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) {
- 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);
- }
- }
- ResolvableHtmlUnit computeResolvableHtmlUnit(Source source) {
- HtmlEntry htmlEntry = getReadableHtmlEntry(source);
- if (htmlEntry == null) {
- throw new AnalysisException.con1("computeResolvableHtmlUnit invoked for non-HTML file: ${source.fullName}");
- }
- 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);
- }
- 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;
- }
- 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;
- }
- }
- 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);
- }
- HtmlElement getHtmlElement(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntry(source);
- if (sourceEntry is HtmlEntry) {
- return ((sourceEntry as HtmlEntry)).getValue(HtmlEntry.ELEMENT);
- }
- return null;
- }
- List<Source> getHtmlFilesReferencing(Source source) {
- SourceKind sourceKind = getKindOf(source);
- if (sourceKind == null) {
- return Source.EMPTY_ARRAY;
- }
- {
- 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);
- }
- }
- List<Source> get htmlSources => getSources(SourceKind.HTML);
- SourceKind getKindOf(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntry(source);
- if (sourceEntry == null) {
- return SourceKind.UNKNOWN;
- }
- return sourceEntry.kind;
- }
- 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);
- }
- 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);
- }
- 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);
- }
- }
- 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);
- }
- }
- LibraryElement getLibraryElement(Source source) {
- SourceEntry sourceEntry = getReadableSourceEntry(source);
- if (sourceEntry is DartEntry) {
- return ((sourceEntry as DartEntry)).getValue(DartEntry.ELEMENT);
- }
- return null;
- }
- 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;
- }
- Namespace getPublicNamespace(LibraryElement library) {
- Source source = library.definingCompilationUnit.source;
- DartEntry dartEntry = getReadableDartEntry(source);
- if (dartEntry == null) {
- return null;
- }
- Namespace namespace = null;
- if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
- namespace = dartEntry.getValue(DartEntry.PUBLIC_NAMESPACE);
- }
- 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;
- }
- Namespace getPublicNamespace2(Source source) {
- DartEntry dartEntry = getReadableDartEntry(source);
- if (dartEntry == null) {
- return null;
- }
- 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;
- }
- CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library) {
- if (library == null) {
- return null;
- }
- return getResolvedCompilationUnit2(unitSource, library.source);
- }
- 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;
- }
- SourceFactory get sourceFactory => _sourceFactory;
-
- /**
- * 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.
- *
- * @return a list of the sources that would be processed by [performAnalysisTask]
- */
- 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);
- }
- 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;
- }
- 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;
- }
- 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;
- }
- void mergeContext(AnalysisContext context) {
- if (context is InstrumentedAnalysisContextImpl) {
- context = ((context as InstrumentedAnalysisContextImpl)).basis;
- }
- if (context is! AnalysisContextImpl2) {
- return;
- }
- {
- 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 {
- }
- }
- }
- }
- 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 {
- 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);
- }
- 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);
- }
- }
- }
- }
- CompilationUnit resolveCompilationUnit(Source unitSource, LibraryElement library) {
- if (library == null) {
- return null;
- }
- return resolveCompilationUnit2(unitSource, library.source);
- }
- 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();
- }
- }
- 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;
- }
- }
- }
- void setContents(Source source, String contents) {
- {
- if (_sourceFactory.setContents(source, contents)) {
- sourceChanged(source);
- }
- }
- }
- void set sourceFactory(SourceFactory factory) {
- {
- if (identical(_sourceFactory, factory)) {
- return;
- } else if (factory.context != null) {
- throw new IllegalStateException("Source factories cannot be shared between contexts");
- }
- if (_sourceFactory != null) {
- _sourceFactory.context = null;
- }
- factory.context = this;
- _sourceFactory = factory;
- invalidateAllResolutionInformation();
- }
- }
- Iterable<Source> sourcesToResolve(List<Source> changedSources) {
- List<Source> librarySources = new List<Source>();
- for (Source source in changedSources) {
- if (identical(computeKindOf(source), SourceKind.LIBRARY)) {
- librarySources.add(source);
- }
- }
- return librarySources;
- }
-
- /**
- * 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 `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;
- }
-
- /**
- * 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;
- }
- }
- 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;
- }
-
- /**
- * 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;
- }
-
- /**
- * 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;
- }
-
- /**
- * 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;
- }
-
- /**
- * 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);
- }
- }
-
- /**
- * 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 false;
- }
-
- /**
- * 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;
- }
-
- /**
- * 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;
- }
- }
-
- /**
- * 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;
- }
- }
-
- /**
- * 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);
- }
-
- /**
- * 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);
- }
-
- /**
- * 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);
- }
-
- /**
- * 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);
- }
-
- /**
- * 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);
- }
-
- /**
- * 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;
- }
-}
-/**
- * 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);
- }
+ * 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 dart2js related hint results.
+ *
+ * @param hint `true` if analysis is to generate dart2js related hint results
+ */
+ void set dart2jsHint(bool dart2jsHints) {
+ this._dart2jsHint = dart2jsHints;
}
- CompilationUnit resolveCompilationUnit(Source source, LibraryElement library) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.resolveCompilationUnit(source, library);
- } else {
- return super.resolveCompilationUnit(source, library);
- }
+
+ /**
+ * 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;
}
- CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.resolveCompilationUnit2(unitSource, librarySource);
- } else {
- return super.resolveCompilationUnit2(unitSource, librarySource);
- }
+
+ /**
+ * 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;
}
- HtmlUnit resolveHtmlUnit(Source unitSource) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.resolveHtmlUnit(unitSource);
- } else {
- return super.resolveHtmlUnit(unitSource);
- }
+}
+/**
+ * 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;
}
- void setContents(Source source, String contents) {
- if (source.isInSystemLibrary) {
- _sdkAnalysisContext.setContents(source, contents);
- } else {
- super.setContents(source, contents);
- }
+
+ /**
+ * 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;
}
- 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.");
- }
+
+ /**
+ * 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;
}
}
/**
@@ -7189,7 +4817,7 @@ class DelegatingAnalysisContextImpl extends AnalysisContextImpl {
*
* @coverage dart.engine
*/
-class DelegatingAnalysisContextImpl2 extends AnalysisContextImpl2 {
+class DelegatingAnalysisContextImpl extends AnalysisContextImpl {
/**
* This references the [InternalAnalysisContext] held onto by the [DartSdk] which is
@@ -7420,7 +5048,7 @@ class DelegatingAnalysisContextImpl2 extends AnalysisContextImpl2 {
DartSdk sdk = factory.dartSdk;
if (sdk != null) {
_sdkAnalysisContext = sdk.context as InternalAnalysisContext;
- if (_sdkAnalysisContext is DelegatingAnalysisContextImpl2) {
+ if (_sdkAnalysisContext is DelegatingAnalysisContextImpl) {
_sdkAnalysisContext = null;
throw new IllegalStateException("The context provided by an SDK cannot itself be a delegating analysis context");
}
@@ -7462,7 +5090,7 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext {
* Create a new [InstrumentedAnalysisContextImpl] which wraps a new
* [AnalysisContextImpl] as the basis context.
*/
- InstrumentedAnalysisContextImpl() : this.con1(AnalysisEngine.instance.useExperimentalContext ? new DelegatingAnalysisContextImpl2() : new DelegatingAnalysisContextImpl());
+ InstrumentedAnalysisContextImpl() : this.con1(new DelegatingAnalysisContextImpl());
/**
* Create a new [InstrumentedAnalysisContextImpl] with a specified basis context, aka the
@@ -7770,6 +5398,7 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext {
}
}
AnalysisContentStatistics get statistics => basis.statistics;
+ TimestampedData<CompilationUnit> internalResolveCompilationUnit(Source unitSource, LibraryElement libraryElement) => basis.internalResolveCompilationUnit(unitSource, libraryElement);
bool isClientLibrary(Source librarySource) {
InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-isClientLibrary");
try {
@@ -8015,6 +5644,19 @@ abstract class InternalAnalysisContext implements AnalysisContext {
AnalysisContentStatistics get statistics;
/**
+ * Return a time-stamped fully-resolved compilation unit for the given source in the given
+ * library.
+ *
+ * @param unitSource the source of the compilation unit for which a resolved AST structure is to
+ * be returned
+ * @param libraryElement the element representing the library in which the compilation unit is to
+ * be resolved
+ * @return a time-stamped fully-resolved compilation unit for the source
+ * @throws AnalysisException if the resolved compilation unit could not be computed
+ */
+ TimestampedData<CompilationUnit> internalResolveCompilationUnit(Source unitSource, LibraryElement libraryElement);
+
+ /**
* Given a table mapping the source for the libraries represented by the corresponding elements to
* the elements representing the libraries, record those mappings.
*
@@ -8024,6 +5666,36 @@ abstract class InternalAnalysisContext implements AnalysisContext {
void recordLibraryElements(Map<Source, LibraryElement> elementMap);
}
/**
+ * Container with global [AnalysisContext] performance statistics.
+ */
+class PerformanceStatistics {
+
+ /**
+ * The [TimeCounter] for time spent in scanning.
+ */
+ static TimeCounter scan = new TimeCounter();
+
+ /**
+ * The [TimeCounter] for time spent in parsing.
+ */
+ static TimeCounter parse = new TimeCounter();
+
+ /**
+ * The [TimeCounter] for time spent in resolving.
+ */
+ static TimeCounter resolve = new TimeCounter();
+
+ /**
+ * The [TimeCounter] for time spent in error verifier.
+ */
+ static TimeCounter errors = new TimeCounter();
+
+ /**
+ * The [TimeCounter] for time spent in hints generator.
+ */
+ static TimeCounter hints = new TimeCounter();
+}
+/**
* 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.
@@ -8116,7 +5788,6 @@ class ResolutionEraser extends GeneralizingASTVisitor<Object> {
}
Object visitConstructorName(ConstructorName node) {
node.staticElement = null;
- node.element = null;
return super.visitConstructorName(node);
}
Object visitDirective(Directive node) {
@@ -8144,7 +5815,6 @@ class ResolutionEraser extends GeneralizingASTVisitor<Object> {
}
Object visitInstanceCreationExpression(InstanceCreationExpression node) {
node.staticElement = null;
- node.element = null;
return super.visitInstanceCreationExpression(node);
}
Object visitPostfixExpression(PostfixExpression node) {
@@ -8159,7 +5829,6 @@ class ResolutionEraser extends GeneralizingASTVisitor<Object> {
}
Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
node.staticElement = null;
- node.element = null;
return super.visitRedirectingConstructorInvocation(node);
}
Object visitSimpleIdentifier(SimpleIdentifier node) {
@@ -8169,7 +5838,6 @@ class ResolutionEraser extends GeneralizingASTVisitor<Object> {
}
Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
node.staticElement = null;
- node.element = null;
return super.visitSuperConstructorInvocation(node);
}
}
@@ -8178,17 +5846,29 @@ class ResolutionEraser extends GeneralizingASTVisitor<Object> {
* 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 {
+class ResolvableCompilationUnit extends TimestampedData<CompilationUnit> {
/**
- * The modification time of the source from which the AST was created.
+ * 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
*/
- int modificationTime = 0;
+ ResolvableCompilationUnit(int modificationTime, CompilationUnit unit) : super(modificationTime, unit);
/**
- * The AST that was created from the source.
+ * Return the AST that was created from the source.
+ *
+ * @return the AST that was created from the source
*/
- CompilationUnit compilationUnit;
+ CompilationUnit get compilationUnit => data;
+}
+/**
+ * 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 extends TimestampedData<HtmlUnit> {
/**
* Initialize a newly created holder to hold the given values.
@@ -8196,37 +5876,40 @@ class ResolvableCompilationUnit {
* @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.compilationUnit = unit;
- }
+ ResolvableHtmlUnit(int modificationTime, HtmlUnit unit) : super(modificationTime, unit);
+
+ /**
+ * Return the AST that was created from the source.
+ *
+ * @return the AST that was created from the source
+ */
+ HtmlUnit get compilationUnit => data;
}
/**
- * 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.
+ * Instances of the class `TimestampedData` represent analysis data for which we have a
+ * modification time.
*/
-class ResolvableHtmlUnit {
+class TimestampedData<E> {
/**
- * The modification time of the source from which the AST was created.
+ * The modification time of the source from which the data was created.
*/
int modificationTime = 0;
/**
- * The AST that was created from the source.
+ * The data that was created from the source.
*/
- HtmlUnit compilationUnit;
+ E data;
/**
* 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
+ * @param modificationTime the modification time of the source from which the data was created
+ * @param unit the data that was created from the source
*/
- ResolvableHtmlUnit(int modificationTime, HtmlUnit unit) {
+ TimestampedData(int modificationTime, E data) {
this.modificationTime = modificationTime;
- this.compilationUnit = unit;
+ this.data = data;
}
}
/**
@@ -8320,6 +6003,15 @@ abstract class AnalysisTask {
abstract class AnalysisTaskVisitor<E> {
/**
+ * Visit a [GenerateDartHintsTask].
+ *
+ * @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 visitGenerateDartHintsTask(GenerateDartHintsTask task);
+
+ /**
* Visit a [ParseDartTask].
*
* @param task the task to be visited
@@ -8365,6 +6057,76 @@ abstract class AnalysisTaskVisitor<E> {
E visitResolveHtmlTask(ResolveHtmlTask task);
}
/**
+ * Instances of the class `GenerateDartHintsTask` generate hints for a single Dart library.
+ */
+class GenerateDartHintsTask extends AnalysisTask {
+
+ /**
+ * The element model for the library being analyzed.
+ */
+ LibraryElement libraryElement;
+
+ /**
+ * A table mapping the sources that were analyzed to the hints that were generated for the
+ * sources.
+ */
+ Map<Source, TimestampedData<List<AnalysisError>>> hintMap;
+
+ /**
+ * 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 libraryElement the element model for the library being analyzed
+ */
+ GenerateDartHintsTask(InternalAnalysisContext context, LibraryElement libraryElement) : super(context) {
+ this.libraryElement = libraryElement;
+ }
+ accept(AnalysisTaskVisitor visitor) => visitor.visitGenerateDartHintsTask(this);
+ String get taskDescription {
+ Source librarySource = libraryElement.source;
+ if (librarySource == null) {
+ return "generate Dart hints for library without source";
+ }
+ return "generate Dart hints for ${librarySource.fullName}";
+ }
+ void internalPerform() {
+ RecordingErrorListener errorListener = new RecordingErrorListener();
+ List<CompilationUnitElement> parts = libraryElement.parts;
+ int partCount = parts.length;
+ List<CompilationUnit> compilationUnits = new List<CompilationUnit>(partCount + 1);
+ Map<Source, TimestampedData<CompilationUnit>> timestampMap = new Map<Source, TimestampedData<CompilationUnit>>();
+ Source unitSource = libraryElement.definingCompilationUnit.source;
+ TimestampedData<CompilationUnit> resolvedUnit = getCompilationUnit(unitSource);
+ timestampMap[unitSource] = resolvedUnit;
+ compilationUnits[0] = resolvedUnit.data;
+ for (int i = 0; i < partCount; i++) {
+ unitSource = parts[i].source;
+ resolvedUnit = getCompilationUnit(unitSource);
+ timestampMap[unitSource] = resolvedUnit;
+ compilationUnits[i + 1] = resolvedUnit.data;
+ }
+ HintGenerator hintGenerator = new HintGenerator(compilationUnits, context, errorListener);
+ hintGenerator.generateForLibrary();
+ hintMap = new Map<Source, TimestampedData<List<AnalysisError>>>();
+ for (MapEntry<Source, TimestampedData<CompilationUnit>> entry in getMapEntrySet(timestampMap)) {
+ Source source = entry.getKey();
+ TimestampedData<CompilationUnit> unitData = entry.getValue();
+ List<AnalysisError> errors = errorListener.getErrors2(source);
+ hintMap[source] = new TimestampedData<List<AnalysisError>>(unitData.modificationTime, errors);
+ unitData.data.hints = errors;
+ }
+ }
+
+ /**
+ * Return the resolved compilation unit associated with the given source.
+ *
+ * @param unitSource the source for the compilation unit whose resolved AST is to be returned
+ * @return the resolved compilation unit associated with the given source
+ * @throws AnalysisException if the resolved compilation unit could not be computed
+ */
+ TimestampedData<CompilationUnit> getCompilationUnit(Source unitSource) => context.internalResolveCompilationUnit(unitSource, libraryElement);
+}
+/**
* Instances of the class `ParseDartTask` parse a specific source as a Dart file.
*/
class ParseDartTask extends AnalysisTask {
@@ -8469,17 +6231,25 @@ class ParseDartTask extends AnalysisTask {
* @return `true` if the source contains a 'part of' directive
*/
bool hasPartOfDirective() => _hasPartOfDirective2;
- String get taskDescription => "parse as dart ${source.fullName}";
+ String get taskDescription {
+ if (source == null) {
+ return "parse as dart null source";
+ }
+ return "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);
+ TimeCounter_TimeCounterHandle timeCounterScan = PerformanceStatistics.scan.start();
+ Source_ContentReceiver receiver = new Source_ContentReceiver_9(this, errorListener, token);
try {
source.getContents(receiver);
} catch (exception) {
modificationTime = source.modificationStamp;
throw new AnalysisException.con3(exception);
}
+ timeCounterScan.stop();
+ TimeCounter_TimeCounterHandle timeCounterParse = PerformanceStatistics.parse.start();
Parser parser = new Parser(source, errorListener);
compilationUnit = parser.parseCompilationUnit(token[0]);
errors = errorListener.getErrors2(source);
@@ -8507,6 +6277,7 @@ class ParseDartTask extends AnalysisTask {
}
compilationUnit.parsingErrors = errors;
compilationUnit.lineInfo = lineInfo;
+ timeCounterParse.stop();
}
/**
@@ -8549,11 +6320,11 @@ class ParseDartTask extends AnalysisTask {
return new List.from(sources);
}
}
-class Source_ContentReceiver_10 implements Source_ContentReceiver {
+class Source_ContentReceiver_9 implements Source_ContentReceiver {
final ParseDartTask ParseDartTask_this;
RecordingErrorListener errorListener;
List<Token> token;
- Source_ContentReceiver_10(this.ParseDartTask_this, this.errorListener, this.token);
+ Source_ContentReceiver_9(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);
@@ -8628,7 +6399,12 @@ class ParseHtmlTask extends AnalysisTask {
this.source = source;
}
accept(AnalysisTaskVisitor visitor) => visitor.visitParseHtmlTask(this);
- String get taskDescription => "parse as html ${source.fullName}";
+ String get taskDescription {
+ if (source == null) {
+ return "parse as html null source";
+ }
+ return "parse as html ${source.fullName}";
+ }
void internalPerform() {
HtmlScanner scanner = new HtmlScanner(source);
try {
@@ -8651,17 +6427,17 @@ class ParseHtmlTask extends AnalysisTask {
*/
List<Source> get librarySources {
List<Source> libraries = new List<Source>();
- htmlUnit.accept(new RecursiveXmlVisitor_11(this, libraries));
+ htmlUnit.accept(new RecursiveXmlVisitor_10(this, libraries));
if (libraries.isEmpty) {
return Source.EMPTY_ARRAY;
}
return new List.from(libraries);
}
}
-class RecursiveXmlVisitor_11 extends RecursiveXmlVisitor<Object> {
+class RecursiveXmlVisitor_10 extends RecursiveXmlVisitor<Object> {
final ParseHtmlTask ParseHtmlTask_this;
List<Source> libraries;
- RecursiveXmlVisitor_11(this.ParseHtmlTask_this, this.libraries) : super();
+ RecursiveXmlVisitor_10(this.ParseHtmlTask_this, this.libraries) : super();
Object visitXmlTagNode(XmlTagNode node) {
if (javaStringEqualsIgnoreCase(node.tag.lexeme, ParseHtmlTask._TAG_SCRIPT)) {
bool isDartScript = false;
@@ -8723,7 +6499,12 @@ class ResolveDartLibraryTask extends AnalysisTask {
this.librarySource = librarySource;
}
accept(AnalysisTaskVisitor visitor) => visitor.visitResolveDartLibraryTask(this);
- String get taskDescription => "resolve library ${librarySource.fullName}";
+ String get taskDescription {
+ if (librarySource == null) {
+ return "resolve library null source";
+ }
+ return "resolve library ${librarySource.fullName}";
+ }
void internalPerform() {
libraryResolver = new LibraryResolver(context);
libraryResolver.resolveLibrary(librarySource, true);
@@ -8774,7 +6555,13 @@ class ResolveDartUnitTask extends AnalysisTask {
* @return the source for the library containing the source that is to be resolved
*/
Source get librarySource => _libraryElement.source;
- String get taskDescription => "resolve unit ${_libraryElement.source.fullName}";
+ String get taskDescription {
+ Source librarySource = _libraryElement.source;
+ if (librarySource == null) {
+ return "resolve unit null source";
+ }
+ return "resolve unit ${librarySource.fullName}";
+ }
void internalPerform() {
Source coreLibrarySource = _libraryElement.context.sourceFactory.forUri(DartSdk.DART_CORE);
LibraryElement coreElement = context.computeLibraryElement(coreLibrarySource);
@@ -8797,11 +6584,13 @@ class ResolveDartUnitTask extends AnalysisTask {
resolverVisitor.reportError(conditionalCode.analysisError);
}
}
+ TimeCounter_TimeCounterHandle counterHandleErrors = PerformanceStatistics.errors.start();
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);
+ counterHandleErrors.stop();
unit.resolutionErrors = errorListener.errors;
resolvedUnit = unit;
}
@@ -8863,7 +6652,12 @@ class ResolveHtmlTask extends AnalysisTask {
this.source = source;
}
accept(AnalysisTaskVisitor visitor) => visitor.visitResolveHtmlTask(this);
- String get taskDescription => "resolve as html ${source.fullName}";
+ String get taskDescription {
+ if (source == null) {
+ return "resolve as html null source";
+ }
+ return "resolve as html ${source.fullName}";
+ }
void internalPerform() {
ResolvableHtmlUnit resolvableHtmlUnit = context.computeResolvableHtmlUnit(source);
HtmlUnit unit = resolvableHtmlUnit.compilationUnit;
« no previous file with comments | « pkg/analyzer_experimental/lib/src/generated/element.dart ('k') | pkg/analyzer_experimental/lib/src/generated/error.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698