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

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

Issue 243263004: New analyzer snapshot. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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
« no previous file with comments | « pkg/analyzer/lib/src/generated/element.dart ('k') | pkg/analyzer/lib/src/generated/error.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/engine.dart
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 18d00f7e832db4ad2e638172fdf9a383b1cf0ad3..3f91c7482bba5c29318af5be391f63af60a04acd 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -87,6 +87,11 @@ class AnalysisEngine {
Logger _logger = Logger.NULL;
/**
+ * The partition manager being used to manage the shared partitions.
+ */
+ final PartitionManager partitionManager = new PartitionManager();
+
+ /**
* Create a new context in which analysis can be performed.
*
* @return the analysis context that was created
@@ -96,9 +101,9 @@ class AnalysisEngine {
// If instrumentation is ignoring data, return an uninstrumented analysis context.
//
if (Instrumentation.isNullLogger) {
- return new DelegatingAnalysisContextImpl();
+ return new AnalysisContextImpl();
}
- return new InstrumentedAnalysisContextImpl.con1(new DelegatingAnalysisContextImpl());
+ return new InstrumentedAnalysisContextImpl.con1(new AnalysisContextImpl());
}
/**
@@ -959,24 +964,42 @@ abstract class ChangeNotice implements AnalysisErrorInfo {
}
/**
- * Instances of the class `ChangeSet` indicate what sources have been added, changed, or
- * removed.
+ * Instances of the class `ChangeSet` indicate which sources have been added, changed,
+ * removed, or deleted. In the case of a changed source, there are multiple ways of indicating the
+ * nature of the change.
+ *
+ * No source should be added to the change set more than once, either with the same or a different
+ * kind of change. It does not make sense, for example, for a source to be both added and removed,
+ * and it is redundant for a source to be marked as changed in its entirety and changed in some
+ * specific range.
*/
class ChangeSet {
/**
* A list containing the sources that have been added.
*/
- List<Source> _added = new List<Source>();
+ final List<Source> addedSources = new List<Source>();
/**
* A list containing the sources that have been changed.
*/
- List<Source> _changed = new List<Source>();
+ final List<Source> changedSources = new List<Source>();
+
+ /**
+ * A table mapping the sources whose content has been changed to the current content of those
+ * sources.
+ */
+ Map<Source, String> _changedContent = new Map<Source, String>();
+
+ /**
+ * A table mapping the sources whose content has been changed within a single range to the current
+ * content of those sources and information about the affected range.
+ */
+ final Map<Source, ChangeSet_ContentChange> changedRanges = new Map<Source, ChangeSet_ContentChange>();
/**
* A list containing the sources that have been removed.
*/
- List<Source> _removed = new List<Source>();
+ final List<Source> removedSources = new List<Source>();
/**
* A list containing the source containers specifying additional sources that have been removed.
@@ -984,52 +1007,78 @@ class ChangeSet {
final List<SourceContainer> removedContainers = new List<SourceContainer>();
/**
- * Record that the specified source has been added and that it's content is the default contents
- * of the source.
+ * A list containing the sources that have been deleted.
+ */
+ final List<Source> deletedSources = new List<Source>();
+
+ /**
+ * Record that the specified source has been added and that its content is the default contents of
+ * the source.
*
* @param source the source that was added
*/
void addedSource(Source source) {
- _added.add(source);
+ addedSources.add(source);
}
/**
- * Record that the specified source has been changed and that it's content is the default contents
- * of the source.
+ * Record that the specified source has been changed and that its content is the given contents.
*
* @param source the source that was changed
+ * @param contents the new contents of the source, or `null` if the default contents of the
+ * source are to be used
*/
- void changedSource(Source source) {
- _changed.add(source);
+ void changedContent(Source source, String contents) {
+ _changedContent[source] = contents;
+ }
+
+ /**
+ * Record that the specified source has been changed and that its content is the given contents.
+ *
+ * @param source the source that was changed
+ * @param contents the new contents of the source
+ * @param offset the offset into the current contents
+ * @param oldLength the number of characters in the original contents that were replaced
+ * @param newLength the number of characters in the replacement text
+ */
+ void changedRange(Source source, String contents, int offset, int oldLength, int newLength) {
+ changedRanges[source] = new ChangeSet_ContentChange(contents, offset, oldLength, newLength);
}
/**
- * Return a collection of the sources that have been added.
+ * Record that the specified source has been changed. If the content of the source was previously
+ * overridden, use [changedContent] instead.
*
- * @return a collection of the sources that have been added
+ * @param source the source that was changed
*/
- List<Source> get addedSources => _added;
+ void changedSource(Source source) {
+ changedSources.add(source);
+ }
/**
- * Return a collection of sources that have been changed.
+ * Record that the specified source has been deleted.
*
- * @return a collection of sources that have been changed
+ * @param source the source that was deleted
*/
- List<Source> get changedSources => _changed;
+ void deletedSource(Source source) {
+ deletedSources.add(source);
+ }
/**
- * Return a list containing the sources that were removed.
+ * Return a table mapping the sources whose content has been changed to the current content of
+ * those sources.
*
- * @return a list containing the sources that were removed
+ * @return a table mapping the sources whose content has been changed to the current content of
+ * those sources
*/
- List<Source> get removedSources => _removed;
+ Map<Source, String> get changedContents => _changedContent;
/**
* Return `true` if this change set does not contain any changes.
*
* @return `true` if this change set does not contain any changes
*/
- bool get isEmpty => _added.isEmpty && _changed.isEmpty && _removed.isEmpty && removedContainers.isEmpty;
+ bool get isEmpty => addedSources.isEmpty && changedSources.isEmpty && _changedContent.isEmpty && changedRanges.isEmpty && removedSources.isEmpty && removedContainers.isEmpty && deletedSources.isEmpty;
/**
* Record that the specified source container has been removed.
@@ -1049,19 +1098,22 @@ class ChangeSet {
*/
void removedSource(Source source) {
if (source != null) {
- _removed.add(source);
+ removedSources.add(source);
}
}
@override
String toString() {
JavaStringBuilder builder = new JavaStringBuilder();
- bool needsSeparator = _appendSources(builder, _added, false, "added");
- needsSeparator = _appendSources(builder, _changed, needsSeparator, "changed");
- _appendSources(builder, _removed, needsSeparator, "removed");
+ bool needsSeparator = _appendSources(builder, addedSources, false, "addedSources");
+ needsSeparator = _appendSources(builder, changedSources, needsSeparator, "changedSources");
+ needsSeparator = _appendSources2(builder, _changedContent, needsSeparator, "changedContent");
+ needsSeparator = _appendSources2(builder, changedRanges, needsSeparator, "changedRanges");
+ needsSeparator = _appendSources(builder, deletedSources, needsSeparator, "deletedSources");
+ needsSeparator = _appendSources(builder, removedSources, needsSeparator, "removedSources");
int count = removedContainers.length;
if (count > 0) {
- if (_removed.isEmpty) {
+ if (removedSources.isEmpty) {
if (needsSeparator) {
builder.append("; ");
}
@@ -1103,6 +1155,68 @@ class ChangeSet {
}
return true;
}
+
+ /**
+ * 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 _appendSources2(JavaStringBuilder builder, Map<Source, dynamic> sources, bool needsSeparator, String label) {
+ if (sources.isEmpty) {
+ return needsSeparator;
+ }
+ if (needsSeparator) {
+ builder.append("; ");
+ }
+ builder.append(label);
+ String prefix = " ";
+ for (Source source in sources.keys.toSet()) {
+ builder.append(prefix);
+ builder.append(source.fullName);
+ prefix = ", ";
+ }
+ return true;
+ }
+}
+
+/**
+ * Instances of the class `ContentChange` represent a change to the content of a source.
+ */
+class ChangeSet_ContentChange {
+ /**
+ * The new contents of the source.
+ */
+ final String contents;
+
+ /**
+ * The offset into the current contents.
+ */
+ final int offset;
+
+ /**
+ * The number of characters in the original contents that were replaced
+ */
+ final int oldLength;
+
+ /**
+ * The number of characters in the replacement text.
+ */
+ final int newLength;
+
+ /**
+ * Initialize a newly created change object to represent a change to the content of a source.
+ *
+ * @param contents the new contents of the source
+ * @param offset the offset into the current contents
+ * @param oldLength the number of characters in the original contents that were replaced
+ * @param newLength the number of characters in the replacement text
+ */
+ ChangeSet_ContentChange(this.contents, this.offset, this.oldLength, this.newLength);
}
/**
@@ -1139,6 +1253,148 @@ class ObsoleteSourceAnalysisException extends AnalysisException {
*/
class AnalysisCache {
/**
+ * An array containing the partitions of which this cache is comprised.
+ */
+ final List<CachePartition> _partitions;
+
+ /**
+ * Initialize a newly created cache to have the given partitions. The partitions will be searched
+ * in the order in which they appear in the array, so the most specific partition (usually an
+ * [SdkCachePartition]) should be first and the most general (usually a
+ * [UniversalCachePartition]) last.
+ *
+ * @param partitions the partitions for the newly created cache
+ */
+ AnalysisCache(this._partitions);
+
+ /**
+ * Record that the AST associated with the given source was just read from the cache.
+ *
+ * @param source the source whose AST was accessed
+ */
+ void accessedAst(Source source) {
+ int count = _partitions.length;
+ for (int i = 0; i < count; i++) {
+ if (_partitions[i].contains(source)) {
+ _partitions[i].accessedAst(source);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Return the entry associated with the given source.
+ *
+ * @param source the source whose entry is to be returned
+ * @return the entry associated with the given source
+ */
+ SourceEntry get(Source source) {
+ int count = _partitions.length;
+ for (int i = 0; i < count; i++) {
+ if (_partitions[i].contains(source)) {
+ return _partitions[i].get(source);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return an iterator returning all of the map entries mapping sources to cache entries.
+ *
+ * @return an iterator returning all of the map entries mapping sources to cache entries
+ */
+ MapIterator<Source, SourceEntry> iterator() {
+ int count = _partitions.length;
+ List<Map<Source, SourceEntry>> maps = new List<Map>(count);
+ for (int i = 0; i < count; i++) {
+ maps[i] = _partitions[i].map;
+ }
+ return new MultipleMapIterator<Source, SourceEntry>(maps);
+ }
+
+ /**
+ * Associate the given entry with the given source.
+ *
+ * @param source the source with which the entry is to be associated
+ * @param entry the entry to be associated with the source
+ */
+ void put(Source source, SourceEntry entry) {
+ (entry as SourceEntryImpl).fixExceptionState();
+ int count = _partitions.length;
+ for (int i = 0; i < count; i++) {
+ if (_partitions[i].contains(source)) {
+ _partitions[i].put(source, entry);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Remove all information related to the given source from this cache.
+ *
+ * @param source the source to be removed
+ */
+ void remove(Source source) {
+ int count = _partitions.length;
+ for (int i = 0; i < count; i++) {
+ if (_partitions[i].contains(source)) {
+ _partitions[i].remove(source);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Record that the AST associated with the given source was just removed from the cache.
+ *
+ * @param source the source whose AST was removed
+ */
+ void removedAst(Source source) {
+ int count = _partitions.length;
+ for (int i = 0; i < count; i++) {
+ if (_partitions[i].contains(source)) {
+ _partitions[i].removedAst(source);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Return the number of sources that are mapped to cache entries.
+ *
+ * @return the number of sources that are mapped to cache entries
+ */
+ int size() {
+ int size = 0;
+ int count = _partitions.length;
+ for (int i = 0; i < count; i++) {
+ size += _partitions[i].size();
+ }
+ return size;
+ }
+
+ /**
+ * Record that the AST associated with the given source was just stored to the cache.
+ *
+ * @param source the source whose AST was stored
+ */
+ void storedAst(Source source) {
+ int count = _partitions.length;
+ for (int i = 0; i < count; i++) {
+ if (_partitions[i].contains(source)) {
+ _partitions[i].storedAst(source);
+ return;
+ }
+ }
+ }
+}
+
+/**
+ * Instances of the class `CachePartition` implement a single partition in an LRU cache of
+ * information related to analysis.
+ */
+abstract class CachePartition {
+ /**
* A table mapping the sources known to the context to the information known about the source.
*/
Map<Source, SourceEntry> _sourceMap = new Map<Source, SourceEntry>();
@@ -1169,7 +1425,7 @@ class AnalysisCache {
* @param retentionPolicy the policy used to determine which pieces of data to remove from the
* cache
*/
- AnalysisCache(int maxCacheSize, this._retentionPolicy) {
+ CachePartition(int maxCacheSize, this._retentionPolicy) {
this._maxCacheSize = maxCacheSize;
_recentlyUsed = new List<Source>();
}
@@ -1193,6 +1449,14 @@ class AnalysisCache {
}
/**
+ * Return `true` if the given source is contained in this partition.
+ *
+ * @param source the source being tested
+ * @return `true` if the source is contained in this partition
+ */
+ bool contains(Source source);
+
+ /**
* Return the entry associated with the given source.
*
* @param source the source whose entry is to be returned
@@ -1201,6 +1465,18 @@ class AnalysisCache {
SourceEntry get(Source source) => _sourceMap[source];
/**
+ * Return a table mapping the sources known to the context to the information known about the
+ * source.
+ *
+ * <b>Note:</b> This method is only visible for use by [AnalysisCache] and should not be
+ * used for any other purpose.
+ *
+ * @return a table mapping the sources known to the context to the information known about the
+ * source
+ */
+ Map<Source, SourceEntry> get map => _sourceMap;
+
+ /**
* Return an iterator returning all of the map entries mapping sources to cache entries.
*
* @return an iterator returning all of the map entries mapping sources to cache entries
@@ -1303,11 +1579,6 @@ class AnalysisCache {
* 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.
*
- * It is possible for there to be no AST that can be flushed, in which case `null` will be
- * returned. This happens, for example, if the context is reserving the AST's needed to resolve a
- * cycle of libraries and the number of AST's being reserved is larger than the current cache
- * size.
- *
* @return the source that was removed
*/
Source _removeAstToFlush() {
@@ -1322,6 +1593,7 @@ class AnalysisCache {
}
}
if (sourceToRemove < 0) {
+ AnalysisEngine.instance.logger.logError2("Internal error: Could not flush data from the cache", new JavaException());
return null;
}
return _recentlyUsed.removeAt(sourceToRemove);
@@ -2823,6 +3095,38 @@ class DataDescriptor<E> {
}
/**
+ * Instances of the class `DefaultRetentionPolicy` implement a retention policy that will keep
+ * AST's in the cache if there is analysis information that needs to be computed for a source, where
+ * the computation is dependent on having the AST.
+ */
+class DefaultRetentionPolicy implements CacheRetentionPolicy {
+ /**
+ * An instance of this class that can be shared.
+ */
+ static DefaultRetentionPolicy POLICY = new DefaultRetentionPolicy();
+
+ @override
+ RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) {
+ if (sourceEntry is DartEntry) {
+ DartEntry dartEntry = sourceEntry;
+ if (astIsNeeded(dartEntry)) {
+ return RetentionPriority.MEDIUM;
+ }
+ }
+ return RetentionPriority.LOW;
+ }
+
+ /**
+ * Return `true` if there is analysis information in the given entry that needs to be
+ * computed, where the computation is dependent on having the AST.
+ *
+ * @param dartEntry the entry being tested
+ * @return `true` if there is analysis information that needs to be computed from the AST
+ */
+ bool astIsNeeded(DartEntry dartEntry) => dartEntry.hasInvalidData(DartEntry.HINTS) || dartEntry.hasInvalidData(DartEntry.VERIFICATION_ERRORS) || dartEntry.hasInvalidData(DartEntry.RESOLUTION_ERRORS);
+}
+
+/**
* The interface `HtmlEntry` defines the behavior of objects that maintain the information
* cached by an analysis context about an individual HTML file.
*/
@@ -3426,6 +3730,37 @@ class HtmlEntryImpl extends SourceEntryImpl implements HtmlEntry {
}
/**
+ * Instances of the class `PartitionManager` manage the partitions that can be shared between
+ * analysis contexts.
+ */
+class PartitionManager {
+ /**
+ * A table mapping SDK's to the partitions used for those SDK's.
+ */
+ Map<DartSdk, SdkCachePartition> _sdkPartitions = new Map<DartSdk, SdkCachePartition>();
+
+ /**
+ * The default cache size for a Dart SDK partition.
+ */
+ static int _DEFAULT_SDK_CACHE_SIZE = 256;
+
+ /**
+ * Return the partition being used for the given SDK, creating the partition if necessary.
+ *
+ * @param sdk the SDK for which a partition is being requested
+ * @return the partition being used for the given SDK
+ */
+ SdkCachePartition forSdk(DartSdk sdk) {
+ SdkCachePartition partition = _sdkPartitions[sdk];
+ if (partition == null) {
+ partition = new SdkCachePartition(_DEFAULT_SDK_CACHE_SIZE);
+ _sdkPartitions[sdk] = partition;
+ }
+ return partition;
+ }
+}
+
+/**
* The enumerated type `RetentionPriority` represents the priority of data in the cache in
* terms of the desirability of retaining some specified data about a specified source.
*/
@@ -3455,6 +3790,23 @@ class RetentionPriority extends Enum<RetentionPriority> {
}
/**
+ * Instances of the class `SdkCachePartition` implement a cache partition that contains all of
+ * the sources in the SDK.
+ */
+class SdkCachePartition extends CachePartition {
+ /**
+ * Initialize a newly created partition.
+ *
+ * @param maxCacheSize the maximum number of sources for which AST structures should be kept in
+ * the cache
+ */
+ SdkCachePartition(int maxCacheSize) : super(maxCacheSize, DefaultRetentionPolicy.POLICY);
+
+ @override
+ bool contains(Source source) => source.isInSystemLibrary;
+}
+
+/**
* The interface `SourceEntry` defines the behavior of objects that maintain the information
* cached by an analysis context about an individual source, no matter what kind of source it is.
*
@@ -3633,7 +3985,7 @@ abstract class SourceEntryImpl implements SourceEntry {
*/
void invalidateAllInformation() {
_content = null;
- _contentState = CacheState.INVALID;
+ _contentState = _checkContentState(CacheState.INVALID);
_lineInfo = null;
_lineInfoState = CacheState.INVALID;
}
@@ -3676,7 +4028,7 @@ abstract class SourceEntryImpl implements SourceEntry {
void setState(DataDescriptor descriptor, CacheState state) {
if (identical(descriptor, SourceEntry.CONTENT)) {
_content = updatedValue(state, _content, null);
- _contentState = state;
+ _contentState = _checkContentState(state);
} else if (identical(descriptor, SourceEntry.LINE_INFO)) {
_lineInfo = updatedValue(state, _lineInfo, null);
_lineInfoState = state;
@@ -3694,7 +4046,7 @@ abstract class SourceEntryImpl implements SourceEntry {
void setValue(DataDescriptor descriptor, Object value) {
if (identical(descriptor, SourceEntry.CONTENT)) {
_content = value as String;
- _contentState = CacheState.VALID;
+ _contentState = _checkContentState(CacheState.VALID);
} else if (identical(descriptor, SourceEntry.LINE_INFO)) {
_lineInfo = value as LineInfo;
_lineInfoState = CacheState.VALID;
@@ -3796,6 +4148,43 @@ abstract class SourceEntryImpl implements SourceEntry {
builder.append("; lineInfo = ");
builder.append(_lineInfoState);
}
+
+ /**
+ * If the state is changing from ERROR to anything else, capture the information. This is an
+ * attempt to discover the underlying cause of a long-standing bug.
+ *
+ * @param newState the new state of the content
+ * @return the new state of the content
+ */
+ CacheState _checkContentState(CacheState newState) {
+ if (_contentState == CacheState.ERROR) {
+ InstrumentationBuilder builder = Instrumentation.builder2("SourceEntryImpl-checkContentState");
+ builder.data3("message", "contentState changing from ${_contentState} to ${newState}");
+ //builder.data("source", source.getFullName());
+ builder.record(new AnalysisException());
+ builder.log();
+ }
+ return newState;
+ }
+}
+
+/**
+ * Instances of the class `UniversalCachePartition` implement a cache partition that contains
+ * all sources not contained in other partitions.
+ */
+class UniversalCachePartition extends CachePartition {
+ /**
+ * Initialize a newly created partition.
+ *
+ * @param maxCacheSize the maximum number of sources for which AST structures should be kept in
+ * the cache
+ * @param retentionPolicy the policy used to determine which pieces of data to remove from the
+ * cache
+ */
+ UniversalCachePartition(int maxCacheSize, CacheRetentionPolicy retentionPolicy) : super(maxCacheSize, retentionPolicy);
+
+ @override
+ bool contains(Source source) => true;
}
/**
@@ -3954,6 +4343,11 @@ class AnalysisContextImpl implements InternalAnalysisContext {
Source _coreLibrarySource;
/**
+ * The partition that contains analysis results that are not shared with other contexts.
+ */
+ CachePartition _privatePartition;
+
+ /**
* A table mapping the sources known to the context to the information known about the source.
*/
AnalysisCache _cache;
@@ -3989,7 +4383,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* results are for the same version (modification time) of the source as our current cache
* content.
*/
- Object _cacheLock = new Object();
+ static Object _cacheLock = new Object();
/**
* The object used to record the results of performing an analysis task.
@@ -4017,7 +4411,8 @@ class AnalysisContextImpl implements InternalAnalysisContext {
*/
AnalysisContextImpl() : super() {
_resultRecorder = new AnalysisContextImpl_AnalysisTaskResultRecorder(this);
- _cache = new AnalysisCache(AnalysisOptionsImpl.DEFAULT_CACHE_SIZE, new AnalysisContextImpl_ContextRetentionPolicy(this));
+ _privatePartition = new UniversalCachePartition(AnalysisOptionsImpl.DEFAULT_CACHE_SIZE, new AnalysisContextImpl_ContextRetentionPolicy(this));
+ _cache = _createCacheFromSourceFactory(null);
}
@override
@@ -4052,6 +4447,16 @@ class AnalysisContextImpl implements InternalAnalysisContext {
for (Source source in changeSet.changedSources) {
_sourceChanged(source);
}
+ for (MapEntry<Source, String> entry in getMapEntrySet(changeSet.changedContents)) {
+ setContents(entry.getKey(), entry.getValue());
+ }
+ for (MapEntry<Source, ChangeSet_ContentChange> entry in getMapEntrySet(changeSet.changedRanges)) {
+ ChangeSet_ContentChange change = entry.getValue();
+ setChangedContents(entry.getKey(), change.contents, change.offset, change.oldLength, change.newLength);
+ }
+ for (Source source in changeSet.deletedSources) {
+ _sourceDeleted(source);
+ }
for (Source source in removedSources) {
_sourceRemoved(source);
}
@@ -4751,9 +5156,9 @@ class AnalysisContextImpl implements InternalAnalysisContext {
@override
void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
Source htmlSource = _sourceFactory.forUri(DartSdk.DART_HTML);
- for (MapIterator<Source, LibraryElement> iter = SingleMapIterator.forMap(elementMap); iter.moveNext();) {
- Source librarySource = iter.key;
- LibraryElement library = iter.value;
+ for (MapEntry<Source, LibraryElement> entry in getMapEntrySet(elementMap)) {
+ Source librarySource = entry.getKey();
+ LibraryElement library = entry.getValue();
//
// Cache the element in the library's info.
//
@@ -4761,6 +5166,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
if (dartEntry != null) {
DartEntryImpl dartCopy = dartEntry.writableCopy;
_recordElementData(dartCopy, library, library.source, htmlSource);
+ dartCopy.setValue(DartEntry.SCAN_ERRORS, AnalysisError.NO_ERRORS);
+ dartCopy.setValue(DartEntry.PARSE_ERRORS, AnalysisError.NO_ERRORS);
+ dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
+ dartCopy.setValueInLibrary(DartEntry.BUILD_ELEMENT_ERRORS, librarySource, AnalysisError.NO_ERRORS);
+ dartCopy.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource, AnalysisError.NO_ERRORS);
+ dartCopy.setStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource, CacheState.FLUSHED);
+ dartCopy.setValueInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource, AnalysisError.NO_ERRORS);
+ dartCopy.setValue(DartEntry.ANGULAR_ERRORS, AnalysisError.NO_ERRORS);
+ dartCopy.setValueInLibrary(DartEntry.HINTS, librarySource, AnalysisError.NO_ERRORS);
_cache.put(librarySource, dartCopy);
}
}
@@ -4789,7 +5203,8 @@ class AnalysisContextImpl implements InternalAnalysisContext {
int cacheSize = options.cacheSize;
if (this._options.cacheSize != cacheSize) {
this._options.cacheSize = cacheSize;
- _cache.maxCacheSize = cacheSize;
+ //cache.setMaxCacheSize(cacheSize);
+ _privatePartition.maxCacheSize = cacheSize;
//
// Cap the size of the priority list to being less than the cache size. Failure to do so can
// result in an infinite loop in performAnalysisTask() because re-caching one AST structure
@@ -4810,7 +5225,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
this._options.preserveComments = options.preserveComments;
_generateSdkErrors = options.generateSdkErrors;
if (needsRecompute) {
- _invalidateAllResolutionInformation();
+ _invalidateAllLocalResolutionInformation();
}
}
@@ -4896,7 +5311,8 @@ class AnalysisContextImpl implements InternalAnalysisContext {
factory.context = this;
_sourceFactory = factory;
_coreLibrarySource = _sourceFactory.forUri(DartSdk.DART_CORE);
- _invalidateAllResolutionInformation();
+ _cache = _createCacheFromSourceFactory(factory);
+ _invalidateAllLocalResolutionInformation();
}
/**
@@ -5419,7 +5835,11 @@ class AnalysisContextImpl implements InternalAnalysisContext {
// change, this loop will eventually terminate.
//
LibraryElement library = computeLibraryElement(librarySource);
- dartEntry = new GenerateDartErrorsTask(this, unitSource, dartEntry.modificationTime, resolveCompilationUnit(unitSource, library), library).perform(_resultRecorder) as DartEntry;
+ CompilationUnit unit = resolveCompilationUnit(unitSource, library);
+ if (unit == null) {
+ throw new AnalysisException.con1("Could not resolve compilation unit ${unitSource.fullName} in ${librarySource.fullName}");
+ }
+ dartEntry = new GenerateDartErrorsTask(this, unitSource, dartEntry.modificationTime, unit, library).perform(_resultRecorder) as DartEntry;
state = dartEntry.getStateInLibrary(descriptor, librarySource);
}
return dartEntry;
@@ -5544,6 +5964,25 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
/**
+ * Create an analysis cache based on the given source factory.
+ *
+ * @param factory the source factory containing the information needed to create the cache
+ * @return the cache that was created
+ */
+ AnalysisCache _createCacheFromSourceFactory(SourceFactory factory) {
+ if (factory == null) {
+ return new AnalysisCache(<CachePartition> [_privatePartition]);
+ }
+ DartSdk sdk = factory.dartSdk;
+ if (sdk == null) {
+ return new AnalysisCache(<CachePartition> [_privatePartition]);
+ }
+ return new AnalysisCache(<CachePartition> [
+ AnalysisEngine.instance.partitionManager.forSdk(sdk),
+ _privatePartition]);
+ }
+
+ /**
* Create a [GenerateDartErrorsTask] for the given source, marking the verification errors
* as being in-process. The compilation unit and the library can be the same if the compilation
* unit is the defining compilation unit of the library.
@@ -5559,6 +5998,13 @@ class AnalysisContextImpl implements InternalAnalysisContext {
return _createResolveDartLibraryTask(librarySource, libraryEntry);
}
CompilationUnit unit = unitEntry.getValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource);
+ if (unit == null) {
+ AnalysisEngine.instance.logger.logInformation2("Entry has VALID state for RESOLVED_UNIT but null value for ${unitSource.fullName} in ${librarySource.fullName}", new AnalysisException());
+ DartEntryImpl dartCopy = unitEntry.writableCopy;
+ dartCopy.recordResolutionError();
+ _cache.put(unitSource, dartCopy);
+ return new AnalysisContextImpl_TaskData(null, false);
+ }
LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
DartEntryImpl dartCopy = unitEntry.writableCopy;
dartCopy.setStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource, CacheState.IN_PROCESS);
@@ -6592,9 +7038,9 @@ class AnalysisContextImpl implements InternalAnalysisContext {
*
* <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
*/
- void _invalidateAllResolutionInformation() {
+ void _invalidateAllLocalResolutionInformation() {
Map<Source, List<Source>> oldPartMap = new Map<Source, List<Source>>();
- MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+ MapIterator<Source, SourceEntry> iterator = _privatePartition.iterator();
while (iterator.moveNext()) {
Source source = iterator.key;
SourceEntry sourceEntry = iterator.value;
@@ -7027,9 +7473,9 @@ class AnalysisContextImpl implements InternalAnalysisContext {
_cache.put(librarySource, dartCopy);
throw thrownException;
}
- for (MapIterator<Source, TimestampedData<List<AnalysisError>>> iter = SingleMapIterator.forMap(hintMap); iter.moveNext();) {
- Source unitSource = iter.key;
- TimestampedData<List<AnalysisError>> results = iter.value;
+ 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) {
// This shouldn't be possible because we should never have performed the task if the source
@@ -7943,9 +8389,9 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* @param oldPartMap the table containing the parts associated with each library
*/
void _removeFromPartsUsingMap(Map<Source, List<Source>> oldPartMap) {
- for (MapIterator<Source, List<Source>> iter = SingleMapIterator.forMap(oldPartMap); iter.moveNext();) {
- Source librarySource = iter.key;
- List<Source> oldParts = iter.value;
+ for (MapEntry<Source, List<Source>> entry in getMapEntrySet(oldPartMap)) {
+ Source librarySource = entry.getKey();
+ List<Source> oldParts = entry.getValue();
for (int i = 0; i < oldParts.length; i++) {
Source partSource = oldParts[i];
if (partSource != librarySource) {
@@ -8059,6 +8505,37 @@ class AnalysisContextImpl implements InternalAnalysisContext {
*
* @param source the source that has been deleted
*/
+ void _sourceDeleted(Source source) {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry is HtmlEntry) {
+ HtmlEntryImpl htmlCopy = sourceEntry.writableCopy;
+ _invalidateAngularResolution(htmlCopy);
+ htmlCopy.recordContentError();
+ _cache.put(source, htmlCopy);
+ } else if (sourceEntry is DartEntry) {
+ Set<Source> libraries = new Set<Source>();
+ for (Source librarySource in getLibrariesContaining(source)) {
+ libraries.add(librarySource);
+ for (Source dependentLibrary in getLibrariesDependingOn(librarySource)) {
+ libraries.add(dependentLibrary);
+ }
+ }
+ for (Source librarySource in libraries) {
+ _invalidateLibraryResolution(librarySource);
+ }
+ DartEntryImpl dartCopy = sourceEntry.writableCopy;
+ dartCopy.recordContentError();
+ _cache.put(source, dartCopy);
+ }
+ _workManager.remove(source);
+ _removeFromPriorityOrder(source);
+ }
+
+ /**
+ * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
+ *
+ * @param source the source that has been removed
+ */
void _sourceRemoved(Source source) {
SourceEntry sourceEntry = _cache.get(source);
if (sourceEntry is HtmlEntry) {
@@ -8684,7 +9161,8 @@ class AnalysisContextImpl_CycleBuilder {
* @param dartEntry the entry associated with the source
*/
void _ensureResolvableCompilationUnit(Source source, DartEntry dartEntry) {
- if (!dartEntry.hasResolvableCompilationUnit) {
+ // The entry will be null if the source represents a non-Dart file.
+ if (dartEntry != null && !dartEntry.hasResolvableCompilationUnit) {
if (_taskData == null) {
_taskData = AnalysisContextImpl_this._createParseDartTask(source, dartEntry);
}
@@ -8964,319 +9442,6 @@ class ChangeNoticeImpl implements ChangeNotice {
}
/**
- * 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.
- */
-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;
-
- @override
- void addSourceInfo(Source source, SourceEntry info) {
- if (source.isInSystemLibrary) {
- _sdkAnalysisContext.addSourceInfo(source, info);
- } else {
- super.addSourceInfo(source, info);
- }
- }
-
- @override
- List<AnalysisError> computeErrors(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeErrors(source);
- } else {
- return super.computeErrors(source);
- }
- }
-
- @override
- List<Source> computeExportedLibraries(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeExportedLibraries(source);
- } else {
- return super.computeExportedLibraries(source);
- }
- }
-
- @override
- HtmlElement computeHtmlElement(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeHtmlElement(source);
- } else {
- return super.computeHtmlElement(source);
- }
- }
-
- @override
- List<Source> computeImportedLibraries(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeImportedLibraries(source);
- } else {
- return super.computeImportedLibraries(source);
- }
- }
-
- @override
- SourceKind computeKindOf(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeKindOf(source);
- } else {
- return super.computeKindOf(source);
- }
- }
-
- @override
- LibraryElement computeLibraryElement(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeLibraryElement(source);
- } else {
- return super.computeLibraryElement(source);
- }
- }
-
- @override
- LineInfo computeLineInfo(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeLineInfo(source);
- } else {
- return super.computeLineInfo(source);
- }
- }
-
- @override
- ResolvableCompilationUnit computeResolvableCompilationUnit(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.computeResolvableCompilationUnit(source);
- } else {
- return super.computeResolvableCompilationUnit(source);
- }
- }
-
- @override
- AnalysisErrorInfo getErrors(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getErrors(source);
- } else {
- return super.getErrors(source);
- }
- }
-
- @override
- HtmlElement getHtmlElement(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getHtmlElement(source);
- } else {
- return super.getHtmlElement(source);
- }
- }
-
- @override
- List<Source> getHtmlFilesReferencing(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getHtmlFilesReferencing(source);
- } else {
- return super.getHtmlFilesReferencing(source);
- }
- }
-
- @override
- SourceKind getKindOf(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getKindOf(source);
- } else {
- return super.getKindOf(source);
- }
- }
-
- @override
- List<Source> getLibrariesContaining(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getLibrariesContaining(source);
- } else {
- return super.getLibrariesContaining(source);
- }
- }
-
- @override
- List<Source> getLibrariesDependingOn(Source librarySource) {
- if (librarySource.isInSystemLibrary) {
- return _sdkAnalysisContext.getLibrariesDependingOn(librarySource);
- } else {
- return super.getLibrariesDependingOn(librarySource);
- }
- }
-
- @override
- LibraryElement getLibraryElement(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getLibraryElement(source);
- } else {
- return super.getLibraryElement(source);
- }
- }
-
- @override
- List<Source> get librarySources => ArrayUtils.addAll(super.librarySources, _sdkAnalysisContext.librarySources);
-
- @override
- LineInfo getLineInfo(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getLineInfo(source);
- } else {
- return super.getLineInfo(source);
- }
- }
-
- @override
- Namespace getPublicNamespace(LibraryElement library) {
- Source source = library.source;
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.getPublicNamespace(library);
- } else {
- return super.getPublicNamespace(library);
- }
- }
-
- @override
- CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.getResolvedCompilationUnit(unitSource, library);
- } else {
- return super.getResolvedCompilationUnit(unitSource, library);
- }
- }
-
- @override
- CompilationUnit getResolvedCompilationUnit2(Source unitSource, Source librarySource) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.getResolvedCompilationUnit2(unitSource, librarySource);
- } else {
- return super.getResolvedCompilationUnit2(unitSource, librarySource);
- }
- }
-
- @override
- bool isClientLibrary(Source librarySource) {
- if (librarySource.isInSystemLibrary) {
- return _sdkAnalysisContext.isClientLibrary(librarySource);
- } else {
- return super.isClientLibrary(librarySource);
- }
- }
-
- @override
- bool isServerLibrary(Source librarySource) {
- if (librarySource.isInSystemLibrary) {
- return _sdkAnalysisContext.isServerLibrary(librarySource);
- } else {
- return super.isServerLibrary(librarySource);
- }
- }
-
- @override
- CompilationUnit parseCompilationUnit(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.parseCompilationUnit(source);
- } else {
- return super.parseCompilationUnit(source);
- }
- }
-
- @override
- ht.HtmlUnit parseHtmlUnit(Source source) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.parseHtmlUnit(source);
- } else {
- return super.parseHtmlUnit(source);
- }
- }
-
- @override
- void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
- if (elementMap.isEmpty) {
- return;
- }
- // TODO(jwren) we are making the assumption here that the elementMap will have sources from only
- // one library, while this is true with our use of the Analysis Engine, it is not required by
- // the API, revisit to fix cases where the elementMap can have sources both in the sdk and other
- // libraries
- Source source = new JavaIterator(elementMap.keys.toSet()).next();
- if (source.isInSystemLibrary) {
- _sdkAnalysisContext.recordLibraryElements(elementMap);
- } else {
- super.recordLibraryElements(elementMap);
- }
- }
-
- @override
- CompilationUnit resolveCompilationUnit(Source source, LibraryElement library) {
- if (source.isInSystemLibrary) {
- return _sdkAnalysisContext.resolveCompilationUnit(source, library);
- } else {
- return super.resolveCompilationUnit(source, library);
- }
- }
-
- @override
- CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.resolveCompilationUnit2(unitSource, librarySource);
- } else {
- return super.resolveCompilationUnit2(unitSource, librarySource);
- }
- }
-
- @override
- ht.HtmlUnit resolveHtmlUnit(Source unitSource) {
- if (unitSource.isInSystemLibrary) {
- return _sdkAnalysisContext.resolveHtmlUnit(unitSource);
- } else {
- return super.resolveHtmlUnit(unitSource);
- }
- }
-
- @override
- void setChangedContents(Source source, String contents, int offset, int oldLength, int newLength) {
- if (source.isInSystemLibrary) {
- _sdkAnalysisContext.setChangedContents(source, contents, offset, oldLength, newLength);
- } else {
- super.setChangedContents(source, contents, offset, oldLength, newLength);
- }
- }
-
- @override
- void setContents(Source source, String contents) {
- if (source.isInSystemLibrary) {
- _sdkAnalysisContext.setContents(source, contents);
- } else {
- super.setContents(source, contents);
- }
- }
-
- @override
- void set sourceFactory(SourceFactory factory) {
- super.sourceFactory = factory;
- DartSdk sdk = factory.dartSdk;
- if (sdk != null) {
- _sdkAnalysisContext = sdk.context as InternalAnalysisContext;
- if (_sdkAnalysisContext is DelegatingAnalysisContextImpl) {
- _sdkAnalysisContext = null;
- throw new IllegalStateException("The context provided by an SDK cannot itself be a delegating analysis context");
- }
- } else {
- throw new IllegalStateException("SourceFactorys provided to DelegatingAnalysisContextImpls must have a DartSdk associated with the provided SourceFactory.");
- }
- }
-}
-
-/**
* Instances of the class `IncrementalAnalysisCache` hold information used to perform
* incremental analysis.
*
@@ -9382,7 +9547,7 @@ class IncrementalAnalysisCache {
*/
static IncrementalAnalysisCache verifyStructure(IncrementalAnalysisCache cache, Source source, CompilationUnit unit) {
if (cache != null && unit != null && cache.source == source) {
- if (!AstComparator.equalUnits(cache.resolvedUnit, unit)) {
+ if (!AstComparator.equalNodes(cache.resolvedUnit, unit)) {
return null;
}
}
@@ -9487,7 +9652,7 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext {
* Create a new [InstrumentedAnalysisContextImpl] which wraps a new
* [AnalysisContextImpl] as the basis context.
*/
- InstrumentedAnalysisContextImpl() : this.con1(new DelegatingAnalysisContextImpl());
+ InstrumentedAnalysisContextImpl() : this.con1(new AnalysisContextImpl());
/**
* Create a new [InstrumentedAnalysisContextImpl] with a specified basis context, aka the
@@ -10360,14 +10525,14 @@ class RecordingErrorListener implements AnalysisErrorListener {
* @return an array of errors (not `null`, contains no `null`s)
*/
List<AnalysisError> get errors {
- Iterable<Set<AnalysisError>> errorsSets = _errors.values;
- int numEntries = errorsSets.length;
+ Iterable<MapEntry<Source, Set<AnalysisError>>> entrySet = getMapEntrySet(_errors);
+ int numEntries = entrySet.length;
if (numEntries == 0) {
return AnalysisError.NO_ERRORS;
}
List<AnalysisError> resultList = new List<AnalysisError>();
- for (Set<AnalysisError> errorsSet in errorsSets) {
- resultList.addAll(errorsSet);
+ for (MapEntry<Source, Set<AnalysisError>> entry in entrySet) {
+ resultList.addAll(entry.getValue());
}
return new List.from(resultList);
}
@@ -11274,8 +11439,13 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
Token filterToken = tokens[i];
Token barToken = filterToken;
filterToken = filterToken.next;
- // TODO(scheglov) report missing identifier
- SimpleIdentifier name = _parseDartExpressionInToken(filterToken) as SimpleIdentifier;
+ // parse name
+ Expression nameExpression = _parseDartExpressionInToken(filterToken);
+ if (nameExpression is! SimpleIdentifier) {
+ _reportErrorForNode(AngularCode.INVALID_FILTER_NAME, nameExpression, []);
+ continue;
+ }
+ SimpleIdentifier name = nameExpression as SimpleIdentifier;
filterToken = name.endToken.next;
// parse arguments
List<AngularFilterArgument> arguments = [];
@@ -11570,10 +11740,6 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
}
_libraryElement.imports = new List.from(imports);
}
- // push conditional errors
- for (ProxyConditionalAnalysisError conditionalCode in _resolver.proxyConditionalAnalysisErrors) {
- _resolver.reportError(conditionalCode.analysisError);
- }
}
void _resolveXmlExpression(AngularXmlExpression angularXmlExpression) {
@@ -14279,12 +14445,6 @@ class ResolveDartUnitTask extends AnalysisTask {
InheritanceManager inheritanceManager = new InheritanceManager(_libraryElement);
ResolverVisitor resolverVisitor = new ResolverVisitor.con2(_libraryElement, source, typeProvider, inheritanceManager, errorListener);
unit.accept(resolverVisitor);
- // TODO (jwren) Move this logic/ loop into the ResolverVisitor and then make the reportError protected again.
- for (ProxyConditionalAnalysisError conditionalCode in resolverVisitor.proxyConditionalAnalysisErrors) {
- if (conditionalCode.shouldIncludeErrorCode()) {
- resolverVisitor.reportError(conditionalCode.analysisError);
- }
- }
//
// Perform additional error checking.
//
« no previous file with comments | « pkg/analyzer/lib/src/generated/element.dart ('k') | pkg/analyzer/lib/src/generated/error.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698