| 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 0173e14eee6594710a324d5cc626798fa70a6169..ff12a07ae0ca52884e2fd06388651d92b0f1aaf7 100644
|
| --- a/pkg/analyzer/lib/src/generated/engine.dart
|
| +++ b/pkg/analyzer/lib/src/generated/engine.dart
|
| @@ -1327,6 +1327,11 @@ class CacheState extends Enum<CacheState> {
|
| */
|
| abstract class DartEntry implements SourceEntry {
|
| /**
|
| + * The data descriptor representing the errors reported during Angular resolution.
|
| + */
|
| + static final DataDescriptor<List<AnalysisError>> ANGULAR_ERRORS = new DataDescriptor<List<AnalysisError>>("DartEntry.ANGULAR_ERRORS");
|
| +
|
| + /**
|
| * The data descriptor representing the list of libraries that contain this compilation unit.
|
| */
|
| static final DataDescriptor<List<Source>> CONTAINING_LIBRARIES = new DataDescriptor<List<Source>>("DartEntry.CONTAINING_LIBRARIES");
|
| @@ -1399,14 +1404,14 @@ abstract class DartEntry implements SourceEntry {
|
| static final DataDescriptor<CompilationUnit> RESOLVED_UNIT = new DataDescriptor<CompilationUnit>("DartEntry.RESOLVED_UNIT");
|
|
|
| /**
|
| - * The data descriptor representing the source kind.
|
| + * The data descriptor representing the token stream.
|
| */
|
| - static final DataDescriptor<SourceKind> SOURCE_KIND = new DataDescriptor<SourceKind>("DartEntry.SOURCE_KIND");
|
| + static final DataDescriptor<List<AnalysisError>> SCAN_ERRORS = new DataDescriptor<List<AnalysisError>>("DartEntry.SCAN_ERRORS");
|
|
|
| /**
|
| - * The data descriptor representing the token stream.
|
| + * The data descriptor representing the source kind.
|
| */
|
| - static final DataDescriptor<List<AnalysisError>> SCAN_ERRORS = new DataDescriptor<List<AnalysisError>>("DartEntry.SCAN_ERRORS");
|
| + static final DataDescriptor<SourceKind> SOURCE_KIND = new DataDescriptor<SourceKind>("DartEntry.SOURCE_KIND");
|
|
|
| /**
|
| * The data descriptor representing the token stream.
|
| @@ -1419,11 +1424,6 @@ abstract class DartEntry implements SourceEntry {
|
| static final DataDescriptor<List<AnalysisError>> VERIFICATION_ERRORS = new DataDescriptor<List<AnalysisError>>("DartEntry.VERIFICATION_ERRORS");
|
|
|
| /**
|
| - * The data descriptor representing the errors reported during Angular resolution.
|
| - */
|
| - static final DataDescriptor<List<AnalysisError>> ANGULAR_ERRORS = new DataDescriptor<List<AnalysisError>>("DartEntry.ANGULAR_ERRORS");
|
| -
|
| - /**
|
| * Return all of the errors associated with the compilation unit that are currently cached.
|
| *
|
| * @return all of the errors associated with the compilation unit
|
| @@ -1973,6 +1973,11 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
|
| return true;
|
| }
|
|
|
| + void recordContentError() {
|
| + super.recordContentError();
|
| + recordScanError();
|
| + }
|
| +
|
| /**
|
| * Record that an error occurred while attempting to resolve the directives in the source
|
| * represented by this entry.
|
| @@ -3026,6 +3031,11 @@ class HtmlEntryImpl extends SourceEntryImpl implements HtmlEntry {
|
| _hintsState = CacheState.INVALID;
|
| }
|
|
|
| + void recordContentError() {
|
| + super.recordContentError();
|
| + recordParseError();
|
| + }
|
| +
|
| /**
|
| * Record that an error was encountered while attempting to parse the source associated with this
|
| * entry.
|
| @@ -3221,6 +3231,11 @@ class RetentionPriority extends Enum<RetentionPriority> {
|
| */
|
| abstract class SourceEntry {
|
| /**
|
| + * The data descriptor representing the contents of the source.
|
| + */
|
| + static final DataDescriptor<String> CONTENT = new DataDescriptor<String>("DartEntry.CONTENT");
|
| +
|
| + /**
|
| * The data descriptor representing the line information.
|
| */
|
| static final DataDescriptor<LineInfo> LINE_INFO = new DataDescriptor<LineInfo>("SourceEntry.LINE_INFO");
|
| @@ -3291,6 +3306,16 @@ abstract class SourceEntryImpl implements SourceEntry {
|
| AnalysisException exception;
|
|
|
| /**
|
| + * The state of the cached content.
|
| + */
|
| + CacheState _contentState = CacheState.INVALID;
|
| +
|
| + /**
|
| + * The content of the source, or `null` if the content is not currently cached.
|
| + */
|
| + String _content;
|
| +
|
| + /**
|
| * The state of the cached line information.
|
| */
|
| CacheState _lineInfoState = CacheState.INVALID;
|
| @@ -3321,7 +3346,9 @@ abstract class SourceEntryImpl implements SourceEntry {
|
| int get modificationTime => _modificationTime;
|
|
|
| CacheState getState(DataDescriptor descriptor) {
|
| - if (identical(descriptor, SourceEntry.LINE_INFO)) {
|
| + if (identical(descriptor, SourceEntry.CONTENT)) {
|
| + return _contentState;
|
| + } else if (identical(descriptor, SourceEntry.LINE_INFO)) {
|
| return _lineInfoState;
|
| } else {
|
| throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
|
| @@ -3329,7 +3356,9 @@ abstract class SourceEntryImpl implements SourceEntry {
|
| }
|
|
|
| Object getValue(DataDescriptor descriptor) {
|
| - if (identical(descriptor, SourceEntry.LINE_INFO)) {
|
| + if (identical(descriptor, SourceEntry.CONTENT)) {
|
| + return _content;
|
| + } else if (identical(descriptor, SourceEntry.LINE_INFO)) {
|
| return _lineInfo;
|
| } else {
|
| throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
|
| @@ -3340,11 +3369,23 @@ abstract class SourceEntryImpl implements SourceEntry {
|
| * Invalidate all of the information associated with this source.
|
| */
|
| void invalidateAllInformation() {
|
| + _content = null;
|
| + _contentState = CacheState.INVALID;
|
| _lineInfo = null;
|
| _lineInfoState = CacheState.INVALID;
|
| }
|
|
|
| /**
|
| + * Record that an error occurred while attempting to get the contents of the source represented by
|
| + * this entry. This will set the state of all information, including any resolution-based
|
| + * information, as being in error.
|
| + */
|
| + void recordContentError() {
|
| + _content = null;
|
| + _contentState = CacheState.ERROR;
|
| + }
|
| +
|
| + /**
|
| * Set the most recent time at which the state of the source matched the state represented by this
|
| * entry to the given time.
|
| *
|
| @@ -3361,7 +3402,10 @@ abstract class SourceEntryImpl implements SourceEntry {
|
| * @param the new state of the data represented by the given descriptor
|
| */
|
| void setState(DataDescriptor descriptor, CacheState state) {
|
| - if (identical(descriptor, SourceEntry.LINE_INFO)) {
|
| + if (identical(descriptor, SourceEntry.CONTENT)) {
|
| + _content = updatedValue(state, _content, null);
|
| + _contentState = state;
|
| + } else if (identical(descriptor, SourceEntry.LINE_INFO)) {
|
| _lineInfo = updatedValue(state, _lineInfo, null);
|
| _lineInfoState = state;
|
| } else {
|
| @@ -3376,7 +3420,10 @@ abstract class SourceEntryImpl implements SourceEntry {
|
| * @param value the new value of the data represented by the given descriptor
|
| */
|
| void setValue(DataDescriptor descriptor, Object value) {
|
| - if (identical(descriptor, SourceEntry.LINE_INFO)) {
|
| + if (identical(descriptor, SourceEntry.CONTENT)) {
|
| + _content = value as String;
|
| + _contentState = CacheState.VALID;
|
| + } else if (identical(descriptor, SourceEntry.LINE_INFO)) {
|
| _lineInfo = value as LineInfo;
|
| _lineInfoState = CacheState.VALID;
|
| } else {
|
| @@ -3398,6 +3445,8 @@ abstract class SourceEntryImpl implements SourceEntry {
|
| void copyFrom(SourceEntryImpl entry) {
|
| _modificationTime = entry._modificationTime;
|
| exception = entry.exception;
|
| + _contentState = entry._contentState;
|
| + _content = entry._content;
|
| _lineInfoState = entry._lineInfoState;
|
| _lineInfo = entry._lineInfo;
|
| }
|
| @@ -3407,7 +3456,7 @@ abstract class SourceEntryImpl implements SourceEntry {
|
| *
|
| * @return `true` if the state of any data value is [CacheState#ERROR]
|
| */
|
| - bool hasErrorState() => identical(_lineInfoState, CacheState.ERROR);
|
| + bool hasErrorState() => identical(_contentState, CacheState.ERROR) || identical(_lineInfoState, CacheState.ERROR);
|
|
|
| /**
|
| * Given that some data is being transitioned to the given state, return the value that should be
|
| @@ -3438,7 +3487,9 @@ abstract class SourceEntryImpl implements SourceEntry {
|
| */
|
| void writeOn(JavaStringBuilder builder) {
|
| builder.append("time = ");
|
| - builder.append(_modificationTime.toRadixString(16));
|
| + builder.append(_modificationTime);
|
| + builder.append("; content = ");
|
| + builder.append(_contentState);
|
| builder.append("; lineInfo = ");
|
| builder.append(_lineInfoState);
|
| }
|
| @@ -3861,8 +3912,10 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| if (source == null) {
|
| return false;
|
| }
|
| - if (_contentCache.getContents(source) != null) {
|
| - return true;
|
| + {
|
| + if (_contentCache.getContents(source) != null) {
|
| + return true;
|
| + }
|
| }
|
| return source.exists();
|
| }
|
| @@ -3905,18 +3958,22 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| }
|
|
|
| TimestampedData<String> getContents(Source source) {
|
| - String contents = _contentCache.getContents(source);
|
| - if (contents != null) {
|
| - return new TimestampedData<String>(_contentCache.getModificationStamp(source), contents);
|
| + {
|
| + String contents = _contentCache.getContents(source);
|
| + if (contents != null) {
|
| + return new TimestampedData<String>(_contentCache.getModificationStamp(source), contents);
|
| + }
|
| }
|
| return source.contents;
|
| }
|
|
|
| void getContentsToReceiver(Source source, Source_ContentReceiver receiver) {
|
| - String contents = _contentCache.getContents(source);
|
| - if (contents != null) {
|
| - receiver.accept(contents, _contentCache.getModificationStamp(source));
|
| - return;
|
| + {
|
| + String contents = _contentCache.getContents(source);
|
| + if (contents != null) {
|
| + receiver.accept(contents, _contentCache.getModificationStamp(source));
|
| + return;
|
| + }
|
| }
|
| source.getContentsToReceiver(receiver);
|
| }
|
| @@ -4083,9 +4140,11 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| }
|
|
|
| int getModificationStamp(Source source) {
|
| - int stamp = _contentCache.getModificationStamp(source);
|
| - if (stamp != null) {
|
| - return stamp;
|
| + {
|
| + int stamp = _contentCache.getModificationStamp(source);
|
| + if (stamp != null) {
|
| + return stamp;
|
| + }
|
| }
|
| return source.modificationStamp;
|
| }
|
| @@ -4471,6 +4530,13 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| _incrementalAnalysisCache = IncrementalAnalysisCache.update(_incrementalAnalysisCache, source, originalContents, contents, offset, oldLength, newLength, getReadableSourceEntry(source));
|
| }
|
| sourceChanged(source);
|
| + SourceEntry sourceEntry = _cache.get(source);
|
| + if (sourceEntry != null) {
|
| + SourceEntryImpl sourceCopy = sourceEntry.writableCopy;
|
| + sourceCopy.modificationTime = _contentCache.getModificationStamp(source);
|
| + sourceCopy.setValue(SourceEntry.CONTENT, contents);
|
| + _cache.put(source, sourceCopy);
|
| + }
|
| }
|
| } else if (originalContents != null) {
|
| _incrementalAnalysisCache = IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
|
| @@ -4487,6 +4553,13 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| if (contents != originalContents) {
|
| _incrementalAnalysisCache = IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
|
| sourceChanged(source);
|
| + SourceEntry sourceEntry = _cache.get(source);
|
| + if (sourceEntry != null) {
|
| + SourceEntryImpl sourceCopy = sourceEntry.writableCopy;
|
| + sourceCopy.modificationTime = _contentCache.getModificationStamp(source);
|
| + sourceCopy.setValue(SourceEntry.CONTENT, contents);
|
| + _cache.put(source, sourceCopy);
|
| + }
|
| }
|
| } else if (originalContents != null) {
|
| _incrementalAnalysisCache = IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
|
| @@ -4922,7 +4995,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| // If not, compute the information. Unless the modification date of the source continues to
|
| // change, this loop will eventually terminate.
|
| //
|
| - htmlEntry = new ParseHtmlTask(this, source).perform(_resultRecorder) as HtmlEntry;
|
| + // TODO(brianwilkerson) Convert this to get the contents from the cache. (I'm not sure how
|
| + // that would work in an asynchronous environment.)
|
| + try {
|
| + htmlEntry = new ParseHtmlTask(this, source, getContents(source)).perform(_resultRecorder) as HtmlEntry;
|
| + } on AnalysisException catch (exception) {
|
| + throw exception;
|
| + } on JavaException catch (exception) {
|
| + throw new AnalysisException.con3(exception);
|
| + }
|
| state = htmlEntry.getState(descriptor);
|
| }
|
| return htmlEntry;
|
| @@ -5349,6 +5430,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| {
|
| bool hintsEnabled = _options.hint;
|
| bool sdkErrorsEnabled = _options.generateSdkErrors;
|
| + bool hasBlockedTask = false;
|
| //
|
| // Look for incremental analysis
|
| //
|
| @@ -5361,9 +5443,12 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| // Look for a priority source that needs to be analyzed.
|
| //
|
| for (Source source in _priorityOrder) {
|
| - AnalysisTask task = getNextAnalysisTask2(source, _cache.get(source), true, hintsEnabled, sdkErrorsEnabled);
|
| + AnalysisContextImpl_TaskData taskData = getNextNondependentAnalysisTask(source, hintsEnabled, sdkErrorsEnabled);
|
| + AnalysisTask task = taskData.task;
|
| if (task != null) {
|
| return task;
|
| + } else if (taskData.isBlocked) {
|
| + hasBlockedTask = true;
|
| }
|
| }
|
| //
|
| @@ -5371,11 +5456,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| //
|
| Source source = _workManager.nextSource;
|
| while (source != null) {
|
| - AnalysisTask task = getNextAnalysisTask2(source, _cache.get(source), false, hintsEnabled, sdkErrorsEnabled);
|
| + AnalysisContextImpl_TaskData taskData = getNextNondependentAnalysisTask(source, hintsEnabled, sdkErrorsEnabled);
|
| + AnalysisTask task = taskData.task;
|
| if (task != null) {
|
| return task;
|
| + } else if (taskData.isBlocked) {
|
| + hasBlockedTask = true;
|
| + } else {
|
| + _workManager.remove(source);
|
| }
|
| - _workManager.remove(source);
|
| source = _workManager.nextSource;
|
| }
|
| // //
|
| @@ -5383,12 +5472,16 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| // //
|
| // for (Map.Entry<Source, SourceEntry> entry : cache.entrySet()) {
|
| // source = entry.getKey();
|
| - // AnalysisTask task = getNextAnalysisTask(source, entry.getValue(), false, hintsEnabled);
|
| + // TaskData taskData = getNextAnalysisTaskForSource(source, entry.getValue(), false, hintsEnabled);
|
| + // AnalysisTask task = taskData.getTask();
|
| // if (task != null) {
|
| // System.out.println("Failed to analyze " + source.getFullName());
|
| // return task;
|
| // }
|
| // }
|
| + if (hasBlockedTask) {
|
| + return WaitForAsyncTask.instance;
|
| + }
|
| return null;
|
| }
|
| }
|
| @@ -5408,7 +5501,21 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| * sources in the SDK
|
| * @return the next task that needs to be performed for the given source
|
| */
|
| - AnalysisTask getNextAnalysisTask2(Source source, SourceEntry sourceEntry, bool isPriority, bool hintsEnabled, bool sdkErrorsEnabled) {
|
| + AnalysisContextImpl_TaskData getNextAnalysisTaskForSource(Source source, SourceEntry sourceEntry, bool isPriority, bool hintsEnabled, bool sdkErrorsEnabled) {
|
| + if (sourceEntry == null) {
|
| + return new AnalysisContextImpl_TaskData(null, false, null);
|
| + }
|
| + CacheState contentState = sourceEntry.getState(SourceEntry.CONTENT);
|
| + if (identical(contentState, CacheState.INVALID)) {
|
| + SourceEntryImpl sourceCopy = sourceEntry.writableCopy;
|
| + sourceCopy.setState(SourceEntry.CONTENT, CacheState.IN_PROCESS);
|
| + _cache.put(source, sourceCopy);
|
| + return new AnalysisContextImpl_TaskData(new GetContentTask(this, source), false, null);
|
| + } else if (identical(contentState, CacheState.IN_PROCESS)) {
|
| + // We are in the process of getting the content. There's nothing else we can do with this
|
| + // source until that's complete.
|
| + return new AnalysisContextImpl_TaskData(null, true, null);
|
| + }
|
| if (sourceEntry is DartEntry) {
|
| DartEntry dartEntry = sourceEntry;
|
| CacheState scanErrorsState = dartEntry.getState(DartEntry.SCAN_ERRORS);
|
| @@ -5418,8 +5525,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| try {
|
| DartEntryImpl dartCopy = dartEntry.writableCopy;
|
| dartCopy.setState(DartEntry.SCAN_ERRORS, CacheState.IN_PROCESS);
|
| + TimestampedData<String> contentData;
|
| + if (identical(contentState, CacheState.VALID)) {
|
| + contentData = new TimestampedData<String>(dartCopy.modificationTime, dartCopy.getValue(SourceEntry.CONTENT));
|
| + dartCopy.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
|
| + } else {
|
| + contentData = getContents(source);
|
| + }
|
| _cache.put(source, dartCopy);
|
| - return new ScanDartTask(this, source, getContents(source));
|
| + return new AnalysisContextImpl_TaskData(new ScanDartTask(this, source, contentData), false, null);
|
| } on JavaException catch (exception) {
|
| DartEntryImpl dartCopy = dartEntry.writableCopy;
|
| dartCopy.recordScanError();
|
| @@ -5432,7 +5546,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| DartEntryImpl dartCopy = dartEntry.writableCopy;
|
| dartCopy.setState(DartEntry.PARSE_ERRORS, CacheState.IN_PROCESS);
|
| _cache.put(source, dartCopy);
|
| - return new ParseDartTask(this, source);
|
| + return new AnalysisContextImpl_TaskData(new ParseDartTask(this, source), false, null);
|
| }
|
| if (isPriority && parseErrorsState != CacheState.ERROR) {
|
| CompilationUnit parseUnit = dartEntry.anyParsedCompilationUnit;
|
| @@ -5440,7 +5554,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| DartEntryImpl dartCopy = dartEntry.writableCopy;
|
| dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.IN_PROCESS);
|
| _cache.put(source, dartCopy);
|
| - return new ParseDartTask(this, source);
|
| + return new AnalysisContextImpl_TaskData(new ParseDartTask(this, source), false, null);
|
| }
|
| }
|
| CacheState exportState = dartEntry.getState(DartEntry.EXPORTED_LIBRARIES);
|
| @@ -5448,7 +5562,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| DartEntryImpl dartCopy = dartEntry.writableCopy;
|
| dartCopy.setState(DartEntry.EXPORTED_LIBRARIES, CacheState.IN_PROCESS);
|
| _cache.put(source, dartCopy);
|
| - return new ResolveDartDependenciesTask(this, source);
|
| + return new AnalysisContextImpl_TaskData(new ResolveDartDependenciesTask(this, source), false, null);
|
| }
|
| List<Source> librariesContaining = dartEntry.getValue(DartEntry.CONTAINING_LIBRARIES);
|
| for (Source librarySource in librariesContaining) {
|
| @@ -5459,7 +5573,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| DartEntryImpl libraryCopy = libraryEntry.writableCopy;
|
| libraryCopy.setState(DartEntry.ELEMENT, CacheState.IN_PROCESS);
|
| _cache.put(librarySource, libraryCopy);
|
| - return new ResolveDartLibraryTask(this, source, librarySource);
|
| + return new AnalysisContextImpl_TaskData(new ResolveDartLibraryTask(this, source, librarySource), false, null);
|
| }
|
| CacheState resolvedUnitState = dartEntry.getState2(DartEntry.RESOLVED_UNIT, librarySource);
|
| if (identical(resolvedUnitState, CacheState.INVALID) || (isPriority && identical(resolvedUnitState, CacheState.FLUSHED))) {
|
| @@ -5474,7 +5588,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| dartCopy.setState2(DartEntry.RESOLVED_UNIT, librarySource, CacheState.IN_PROCESS);
|
| _cache.put(source, dartCopy);
|
| //return new ResolveDartUnitTask(this, source, libraryElement);
|
| - return new ResolveDartLibraryTask(this, source, librarySource);
|
| + return new AnalysisContextImpl_TaskData(new ResolveDartLibraryTask(this, source, librarySource), false, null);
|
| }
|
| if (sdkErrorsEnabled || !source.isInSystemLibrary) {
|
| CacheState verificationErrorsState = dartEntry.getState2(DartEntry.VERIFICATION_ERRORS, librarySource);
|
| @@ -5484,7 +5598,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| DartEntryImpl dartCopy = dartEntry.writableCopy;
|
| dartCopy.setState2(DartEntry.VERIFICATION_ERRORS, librarySource, CacheState.IN_PROCESS);
|
| _cache.put(source, dartCopy);
|
| - return new GenerateDartErrorsTask(this, source, libraryElement);
|
| + return new AnalysisContextImpl_TaskData(new GenerateDartErrorsTask(this, source, libraryElement), false, null);
|
| }
|
| }
|
| if (hintsEnabled) {
|
| @@ -5495,7 +5609,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| DartEntryImpl dartCopy = dartEntry.writableCopy;
|
| dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.IN_PROCESS);
|
| _cache.put(source, dartCopy);
|
| - return new GenerateDartHintsTask(this, libraryElement);
|
| + return new AnalysisContextImpl_TaskData(new GenerateDartHintsTask(this, libraryElement), false, null);
|
| }
|
| }
|
| }
|
| @@ -5506,18 +5620,46 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| HtmlEntry htmlEntry = sourceEntry;
|
| CacheState parseErrorsState = htmlEntry.getState(HtmlEntry.PARSE_ERRORS);
|
| if (identical(parseErrorsState, CacheState.INVALID) || (isPriority && identical(parseErrorsState, CacheState.FLUSHED))) {
|
| - HtmlEntryImpl dartCopy = htmlEntry.writableCopy;
|
| - dartCopy.setState(HtmlEntry.PARSE_ERRORS, CacheState.IN_PROCESS);
|
| - _cache.put(source, dartCopy);
|
| - return new ParseHtmlTask(this, source);
|
| + try {
|
| + HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
|
| + htmlCopy.setState(HtmlEntry.PARSE_ERRORS, CacheState.IN_PROCESS);
|
| + TimestampedData<String> contentData;
|
| + if (identical(contentState, CacheState.VALID)) {
|
| + contentData = new TimestampedData<String>(htmlCopy.modificationTime, htmlCopy.getValue(SourceEntry.CONTENT));
|
| + htmlCopy.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
|
| + } else {
|
| + contentData = getContents(source);
|
| + }
|
| + _cache.put(source, htmlCopy);
|
| + return new AnalysisContextImpl_TaskData(new ParseHtmlTask(this, source, contentData), false, null);
|
| + } on JavaException catch (exception) {
|
| + HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
|
| + htmlCopy.recordParseError();
|
| + htmlCopy.exception = new AnalysisException.con3(exception);
|
| + _cache.put(source, htmlCopy);
|
| + }
|
| }
|
| if (isPriority && parseErrorsState != CacheState.ERROR) {
|
| ht.HtmlUnit parsedUnit = htmlEntry.anyParsedUnit;
|
| if (parsedUnit == null) {
|
| - HtmlEntryImpl dartCopy = htmlEntry.writableCopy;
|
| - dartCopy.setState(HtmlEntry.PARSED_UNIT, CacheState.IN_PROCESS);
|
| - _cache.put(source, dartCopy);
|
| - return new ParseHtmlTask(this, source);
|
| + try {
|
| + HtmlEntryImpl dartCopy = htmlEntry.writableCopy;
|
| + dartCopy.setState(HtmlEntry.PARSE_ERRORS, CacheState.IN_PROCESS);
|
| + TimestampedData<String> contentData;
|
| + if (identical(contentState, CacheState.VALID)) {
|
| + contentData = new TimestampedData<String>(dartCopy.modificationTime, dartCopy.getValue(SourceEntry.CONTENT));
|
| + dartCopy.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
|
| + } else {
|
| + contentData = getContents(source);
|
| + }
|
| + _cache.put(source, dartCopy);
|
| + return new AnalysisContextImpl_TaskData(new ParseHtmlTask(this, source, contentData), false, null);
|
| + } on JavaException catch (exception) {
|
| + HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
|
| + htmlCopy.recordParseError();
|
| + htmlCopy.exception = new AnalysisException.con3(exception);
|
| + _cache.put(source, htmlCopy);
|
| + }
|
| }
|
| }
|
| CacheState resolvedUnitState = htmlEntry.getState(HtmlEntry.RESOLVED_UNIT);
|
| @@ -5525,7 +5667,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
|
| htmlCopy.setState(HtmlEntry.RESOLVED_UNIT, CacheState.IN_PROCESS);
|
| _cache.put(source, htmlCopy);
|
| - return new ResolveHtmlTask(this, source);
|
| + return new AnalysisContextImpl_TaskData(new ResolveHtmlTask(this, source), false, null);
|
| }
|
| // Angular support
|
| if (_options.analyzeAngular) {
|
| @@ -5535,7 +5677,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
|
| htmlCopy.setState(HtmlEntry.ANGULAR_ENTRY, CacheState.IN_PROCESS);
|
| _cache.put(source, htmlCopy);
|
| - return new ResolveAngularEntryHtmlTask(this, source);
|
| + return new AnalysisContextImpl_TaskData(new ResolveAngularEntryHtmlTask(this, source), false, null);
|
| }
|
| // try to resolve as an Angular application part
|
| CacheState angularErrorsState = htmlEntry.getState(HtmlEntry.ANGULAR_ERRORS);
|
| @@ -5546,11 +5688,25 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
|
| htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.IN_PROCESS);
|
| _cache.put(source, htmlCopy);
|
| - return new ResolveAngularComponentTemplateTask(this, source, component, application);
|
| + return new AnalysisContextImpl_TaskData(new ResolveAngularComponentTemplateTask(this, source, component, application), false, null);
|
| }
|
| }
|
| }
|
| - return null;
|
| + return new AnalysisContextImpl_TaskData(null, false, null);
|
| + }
|
| +
|
| + AnalysisContextImpl_TaskData getNextNondependentAnalysisTask(Source source, bool hintsEnabled, bool sdkErrorsEnabled) {
|
| + AnalysisContextImpl_TaskData taskData = getNextAnalysisTaskForSource(source, _cache.get(source), true, hintsEnabled, sdkErrorsEnabled);
|
| + if (taskData.task != null || taskData.isBlocked) {
|
| + return taskData;
|
| + }
|
| + while (taskData.dependentSource != null) {
|
| + taskData = getNextAnalysisTaskForSource(source, _cache.get(source), true, hintsEnabled, sdkErrorsEnabled);
|
| + if (taskData.task != null || taskData.isBlocked) {
|
| + return taskData;
|
| + }
|
| + }
|
| + return new AnalysisContextImpl_TaskData(null, false, null);
|
| }
|
|
|
| /**
|
| @@ -6198,6 +6354,43 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| }
|
|
|
| /**
|
| + * Record the results produced by performing a [GetContentTask].
|
| + *
|
| + * @param task the task that was performed
|
| + * @return an entry containing the computed results
|
| + * @throws AnalysisException if the results could not be recorded
|
| + */
|
| + SourceEntry recordGetContentsTask(GetContentTask task) {
|
| + if (!task.isComplete) {
|
| + return null;
|
| + }
|
| + Source source = task.source;
|
| + AnalysisException thrownException = task.exception;
|
| + SourceEntry sourceEntry = null;
|
| + {
|
| + sourceEntry = _cache.get(source);
|
| + if (sourceEntry == null) {
|
| + throw new ObsoleteSourceAnalysisException(source);
|
| + }
|
| + SourceEntryImpl sourceCopy = sourceEntry.writableCopy;
|
| + if (thrownException == null) {
|
| + sourceCopy.modificationTime = task.modificationTime;
|
| + sourceCopy.setValue(SourceEntry.CONTENT, task.content);
|
| + } else {
|
| + sourceCopy.exception = thrownException;
|
| + sourceCopy.recordContentError();
|
| + _workManager.remove(source);
|
| + }
|
| + _cache.put(source, sourceCopy);
|
| + sourceEntry = sourceCopy;
|
| + }
|
| + if (thrownException != null) {
|
| + throw thrownException;
|
| + }
|
| + return sourceEntry;
|
| + }
|
| +
|
| + /**
|
| * Record the results produced by performing a [IncrementalAnalysisTask].
|
| *
|
| * @param task the task that was performed
|
| @@ -6667,7 +6860,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| * @return an entry containing the computed results
|
| * @throws AnalysisException if the results could not be recorded
|
| */
|
| - SourceEntry recordResolveDartUnitTaskResults(ResolveDartUnitTask task) {
|
| + DartEntry recordResolveDartUnitTaskResults(ResolveDartUnitTask task) {
|
| Source unitSource = task.source;
|
| Source librarySource = task.librarySource;
|
| AnalysisException thrownException = task.exception;
|
| @@ -6747,7 +6940,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| * @return an entry containing the computed results
|
| * @throws AnalysisException if the results could not be recorded
|
| */
|
| - SourceEntry recordResolveHtmlTaskResults(ResolveHtmlTask task) {
|
| + HtmlEntry recordResolveHtmlTaskResults(ResolveHtmlTask task) {
|
| Source source = task.source;
|
| AnalysisException thrownException = task.exception;
|
| HtmlEntry htmlEntry = null;
|
| @@ -6926,7 +7119,11 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| if (partEntry != null && partEntry != dartEntry) {
|
| DartEntryImpl partCopy = partEntry.writableCopy;
|
| partCopy.removeContainingLibrary(librarySource);
|
| - _cache.put(partSource, partCopy);
|
| + if (partCopy.librariesContaining.length == 0 && !exists(partSource)) {
|
| + _cache.remove(partSource);
|
| + } else {
|
| + _cache.put(partSource, partCopy);
|
| + }
|
| }
|
| }
|
| }
|
| @@ -7121,11 +7318,13 @@ class AnalysisContextImpl_AnalysisTaskResultRecorder implements AnalysisTaskVisi
|
|
|
| AnalysisContextImpl_AnalysisTaskResultRecorder(this.AnalysisContextImpl_this);
|
|
|
| - SourceEntry visitGenerateDartErrorsTask(GenerateDartErrorsTask task) => AnalysisContextImpl_this.recordGenerateDartErrorsTask(task);
|
| + DartEntry visitGenerateDartErrorsTask(GenerateDartErrorsTask task) => AnalysisContextImpl_this.recordGenerateDartErrorsTask(task);
|
| +
|
| + DartEntry visitGenerateDartHintsTask(GenerateDartHintsTask task) => AnalysisContextImpl_this.recordGenerateDartHintsTask(task);
|
|
|
| - SourceEntry visitGenerateDartHintsTask(GenerateDartHintsTask task) => AnalysisContextImpl_this.recordGenerateDartHintsTask(task);
|
| + SourceEntry visitGetContentTask(GetContentTask task) => AnalysisContextImpl_this.recordGetContentsTask(task);
|
|
|
| - SourceEntry visitIncrementalAnalysisTask(IncrementalAnalysisTask task) => AnalysisContextImpl_this.recordIncrementalAnalysisTaskResults(task);
|
| + DartEntry visitIncrementalAnalysisTask(IncrementalAnalysisTask task) => AnalysisContextImpl_this.recordIncrementalAnalysisTaskResults(task);
|
|
|
| DartEntry visitParseDartTask(ParseDartTask task) => AnalysisContextImpl_this.recordParseDartTaskResults(task);
|
|
|
| @@ -7133,17 +7332,17 @@ class AnalysisContextImpl_AnalysisTaskResultRecorder implements AnalysisTaskVisi
|
|
|
| HtmlEntry visitResolveAngularComponentTemplateTask(ResolveAngularComponentTemplateTask task) => AnalysisContextImpl_this.recordResolveAngularComponentTemplateTaskResults(task);
|
|
|
| - SourceEntry visitResolveAngularEntryHtmlTask(ResolveAngularEntryHtmlTask task) => AnalysisContextImpl_this.recordResolveAngularEntryHtmlTaskResults(task);
|
| + HtmlEntry visitResolveAngularEntryHtmlTask(ResolveAngularEntryHtmlTask task) => AnalysisContextImpl_this.recordResolveAngularEntryHtmlTaskResults(task);
|
|
|
| DartEntry visitResolveDartDependenciesTask(ResolveDartDependenciesTask task) => AnalysisContextImpl_this.recordResolveDartDependenciesTaskResults(task);
|
|
|
| DartEntry visitResolveDartLibraryTask(ResolveDartLibraryTask task) => AnalysisContextImpl_this.recordResolveDartLibraryTaskResults(task);
|
|
|
| - SourceEntry visitResolveDartUnitTask(ResolveDartUnitTask task) => AnalysisContextImpl_this.recordResolveDartUnitTaskResults(task);
|
| + DartEntry visitResolveDartUnitTask(ResolveDartUnitTask task) => AnalysisContextImpl_this.recordResolveDartUnitTaskResults(task);
|
|
|
| - SourceEntry visitResolveHtmlTask(ResolveHtmlTask task) => AnalysisContextImpl_this.recordResolveHtmlTaskResults(task);
|
| + HtmlEntry visitResolveHtmlTask(ResolveHtmlTask task) => AnalysisContextImpl_this.recordResolveHtmlTaskResults(task);
|
|
|
| - SourceEntry visitScanDartTask(ScanDartTask task) => AnalysisContextImpl_this.recordScanDartTaskResults(task);
|
| + DartEntry visitScanDartTask(ScanDartTask task) => AnalysisContextImpl_this.recordScanDartTaskResults(task);
|
| }
|
|
|
| class AnalysisContextImpl_ContextRetentionPolicy implements CacheRetentionPolicy {
|
| @@ -7170,6 +7369,57 @@ class AnalysisContextImpl_ContextRetentionPolicy implements CacheRetentionPolicy
|
| }
|
|
|
| /**
|
| + * Instances of the class `TaskData` represent information about the next task to be
|
| + * performed. Each data has an implicit associated source: the source that might need to be
|
| + * analyzed. There are essentially three states that can be represented:
|
| + * * If [getTask] returns a non-`null` value, then that is the task that should
|
| + * be executed to further analyze the associated source.
|
| + * * Otherwise, if [isBlocked] returns `true`, then there is no work that can be
|
| + * done, but analysis for the associated source is not complete.
|
| + * * Otherwise, [getDependentSource] should return a source that needs to be analyzed
|
| + * before the analysis of the associated source can be completed.
|
| + */
|
| +class AnalysisContextImpl_TaskData {
|
| + /**
|
| + * The task that is to be performed.
|
| + */
|
| + final AnalysisTask task;
|
| +
|
| + /**
|
| + * A flag indicating whether the associated source is blocked waiting for its contents to be
|
| + * loaded.
|
| + */
|
| + bool _blocked = false;
|
| +
|
| + /**
|
| + * The source that needs to be analyzed before further progress can be made on the associated
|
| + * source.
|
| + */
|
| + final Source dependentSource;
|
| +
|
| + /**
|
| + * Initialize a newly created data holder.
|
| + *
|
| + * @param task the task that is to be performed
|
| + * @param blocked `true` if the associated source is blocked waiting for its contents to
|
| + * be loaded
|
| + * @param dependentSource t
|
| + */
|
| + AnalysisContextImpl_TaskData(this.task, bool blocked, this.dependentSource) {
|
| + this._blocked = blocked;
|
| + }
|
| +
|
| + /**
|
| + * Return `true` if the associated source is blocked waiting for its contents to be
|
| + * loaded.
|
| + *
|
| + * @return `true` if the associated source is blocked waiting for its contents to be
|
| + * loaded
|
| + */
|
| + bool get isBlocked => _blocked;
|
| +}
|
| +
|
| +/**
|
| * Instances of the class `AnalysisErrorInfoImpl` represent the analysis errors and line info
|
| * associated with a source.
|
| */
|
| @@ -9083,7 +9333,7 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
|
| * @param angularElements the list to fill with top-level [AngularElement]s
|
| * @param classElement the [ClassElement] to get [AngularElement]s from
|
| */
|
| - static void addAngularElements(Set<AngularElement> angularElements, ClassElement classElement) {
|
| + static void addAngularElementsFromClass(Set<AngularElement> angularElements, ClassElement classElement) {
|
| for (ToolkitObjectElement toolkitObject in classElement.toolkitObjects) {
|
| if (toolkitObject is AngularElement) {
|
| angularElements.add(toolkitObject);
|
| @@ -9097,7 +9347,7 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
|
| * @param libraryElement the [LibraryElement] to analyze
|
| * @return the array of all top-level Angular elements that could be used in this library
|
| */
|
| - static void addAngularElements2(Set<AngularElement> angularElements, LibraryElement library, Set<LibraryElement> visited) {
|
| + static void addAngularElementsFromLibrary(Set<AngularElement> angularElements, LibraryElement library, Set<LibraryElement> visited) {
|
| if (library == null) {
|
| return;
|
| }
|
| @@ -9108,13 +9358,13 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
|
| for (CompilationUnitElement unit in library.units) {
|
| angularElements.addAll(unit.angularViews);
|
| for (ClassElement type in unit.types) {
|
| - addAngularElements(angularElements, type);
|
| + addAngularElementsFromClass(angularElements, type);
|
| }
|
| }
|
| // handle imports
|
| for (ImportElement importElement in library.imports) {
|
| LibraryElement importedLibrary = importElement.importedLibrary;
|
| - addAngularElements2(angularElements, importedLibrary, visited);
|
| + addAngularElementsFromLibrary(angularElements, importedLibrary, visited);
|
| }
|
| }
|
|
|
| @@ -9128,7 +9378,7 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
|
| */
|
| static List<AngularElement> getAngularElements(Set<LibraryElement> libraries, LibraryElement libraryElement) {
|
| Set<AngularElement> angularElements = new Set();
|
| - addAngularElements2(angularElements, libraryElement, libraries);
|
| + addAngularElementsFromLibrary(angularElements, libraryElement, libraries);
|
| return new List.from(angularElements);
|
| }
|
|
|
| @@ -9279,7 +9529,7 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
|
| }
|
|
|
| Object visitXmlAttributeNode(ht.XmlAttributeNode node) {
|
| - parseEmbeddedExpressions2(node);
|
| + parseEmbeddedExpressionsInAttribute(node);
|
| resolveExpressions(node.expressions);
|
| return super.visitXmlAttributeNode(node);
|
| }
|
| @@ -9299,7 +9549,7 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
|
| // process node in separate name scope
|
| pushNameScope();
|
| try {
|
| - parseEmbeddedExpressions3(node);
|
| + parseEmbeddedExpressions2(node);
|
| // apply processors
|
| for (NgProcessor processor in _processors) {
|
| if (processor.canApply(node)) {
|
| @@ -9409,7 +9659,7 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
|
| if (identical(colonToken.type, TokenType.COLON)) {
|
| filterToken = filterToken.next;
|
| } else {
|
| - reportError8(colonToken, AngularCode.MISSING_FILTER_COLON, []);
|
| + reportErrorForToken(AngularCode.MISSING_FILTER_COLON, colonToken, []);
|
| }
|
| // parse argument
|
| Expression argument = parseDartExpression3(filterToken);
|
| @@ -9449,22 +9699,22 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
|
| /**
|
| * Reports given [ErrorCode] at the given [AstNode].
|
| */
|
| - void reportError(AstNode node, ErrorCode errorCode, List<Object> arguments) {
|
| - reportError7(node.offset, node.length, errorCode, arguments);
|
| + void reportErrorForNode(ErrorCode errorCode, AstNode node, List<Object> arguments) {
|
| + reportErrorForOffset(errorCode, node.offset, node.length, arguments);
|
| }
|
|
|
| /**
|
| * Reports given [ErrorCode] at the given position.
|
| */
|
| - void reportError7(int offset, int length, ErrorCode errorCode, List<Object> arguments) {
|
| + void reportErrorForOffset(ErrorCode errorCode, int offset, int length, List<Object> arguments) {
|
| _errorListener.onError(new AnalysisError.con2(_source, offset, length, errorCode, arguments));
|
| }
|
|
|
| /**
|
| * Reports given [ErrorCode] at the given [Token].
|
| */
|
| - void reportError8(Token token, ErrorCode errorCode, List<Object> arguments) {
|
| - reportError7(token.offset, token.length, errorCode, arguments);
|
| + void reportErrorForToken(ErrorCode errorCode, Token token, List<Object> arguments) {
|
| + reportErrorForOffset(errorCode, token.offset, token.length, arguments);
|
| }
|
|
|
| void resolveExpression(AngularExpression angularExpression) {
|
| @@ -9588,15 +9838,7 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
|
| }
|
| }
|
|
|
| - void parseEmbeddedExpressions2(ht.XmlAttributeNode node) {
|
| - List<AngularMoustacheXmlExpression> expressions = [];
|
| - parseEmbeddedExpressions(expressions, node.valueToken);
|
| - if (!expressions.isEmpty) {
|
| - node.expressions = new List.from(expressions);
|
| - }
|
| - }
|
| -
|
| - void parseEmbeddedExpressions3(ht.XmlTagNode node) {
|
| + void parseEmbeddedExpressions2(ht.XmlTagNode node) {
|
| List<AngularMoustacheXmlExpression> expressions = [];
|
| ht.Token token = node.attributeEnd;
|
| ht.Token endToken = node.endToken;
|
| @@ -9620,6 +9862,14 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
|
| node.expressions = new List.from(expressions);
|
| }
|
|
|
| + void parseEmbeddedExpressionsInAttribute(ht.XmlAttributeNode node) {
|
| + List<AngularMoustacheXmlExpression> expressions = [];
|
| + parseEmbeddedExpressions(expressions, node.valueToken);
|
| + if (!expressions.isEmpty) {
|
| + node.expressions = new List.from(expressions);
|
| + }
|
| + }
|
| +
|
| void recordDefinedVariable(LocalVariableElementImpl variable) {
|
| _definedVariables.add(variable);
|
| _functionElement.localVariables = new List.from(_definedVariables);
|
| @@ -9839,20 +10089,20 @@ abstract class AngularXmlExpression extends ht.XmlExpression {
|
|
|
| ht.XmlExpression_Reference getReference(int offset) {
|
| // main expression
|
| - ht.XmlExpression_Reference reference = getReference2(expression.expression, offset);
|
| + ht.XmlExpression_Reference reference = getReferenceAtNode(expression.expression, offset);
|
| if (reference != null) {
|
| return reference;
|
| }
|
| // filters
|
| for (AngularFilterNode filter in expression.filters) {
|
| // filter name
|
| - reference = getReference2(filter.name, offset);
|
| + reference = getReferenceAtNode(filter.name, offset);
|
| if (reference != null) {
|
| return reference;
|
| }
|
| // filter arguments
|
| for (AngularFilterArgument filterArgument in filter.arguments) {
|
| - reference = getReference2(filterArgument.expression, offset);
|
| + reference = getReferenceAtNode(filterArgument.expression, offset);
|
| if (reference != null) {
|
| return reference;
|
| }
|
| @@ -9865,7 +10115,7 @@ abstract class AngularXmlExpression extends ht.XmlExpression {
|
| * If the given [AstNode] has an [Element] at the given offset, then returns
|
| * [Reference] with this [Element].
|
| */
|
| - ht.XmlExpression_Reference getReference2(AstNode root, int offset) {
|
| + ht.XmlExpression_Reference getReferenceAtNode(AstNode root, int offset) {
|
| AstNode node = new NodeLocator.con1(offset).searchWithin(root);
|
| if (node != null) {
|
| Element element = ElementLocator.locate(node);
|
| @@ -10264,6 +10514,15 @@ abstract class AnalysisTaskVisitor<E> {
|
| E visitGenerateDartHintsTask(GenerateDartHintsTask task);
|
|
|
| /**
|
| + * Visit a [GetContentTask].
|
| + *
|
| + * @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 visitGetContentTask(GetContentTask task);
|
| +
|
| + /**
|
| * Visit an [IncrementalAnalysisTask].
|
| *
|
| * @param task the task to be visited
|
| @@ -10533,6 +10792,86 @@ class GenerateDartHintsTask extends AnalysisTask {
|
| }
|
|
|
| /**
|
| + * Instances of the class `GetContentTask` get the contents of a source.
|
| + */
|
| +class GetContentTask extends AnalysisTask {
|
| + /**
|
| + * The source to be read.
|
| + */
|
| + final Source source;
|
| +
|
| + /**
|
| + * A flag indicating whether this task is complete.
|
| + */
|
| + bool _complete = false;
|
| +
|
| + /**
|
| + * The contents of the source.
|
| + */
|
| + String _content;
|
| +
|
| + /**
|
| + * The time at which the contents of the source were last modified.
|
| + */
|
| + int _modificationTime = -1;
|
| +
|
| + /**
|
| + * Initialize a newly created task to perform analysis within the given context.
|
| + *
|
| + * @param context the context in which the task is to be performed
|
| + * @param source the source to be parsed
|
| + * @param contentData the time-stamped contents of the source
|
| + */
|
| + GetContentTask(InternalAnalysisContext context, this.source) : super(context) {
|
| + if (source == null) {
|
| + throw new IllegalArgumentException("Cannot get contents of null source");
|
| + }
|
| + }
|
| +
|
| + accept(AnalysisTaskVisitor visitor) => visitor.visitGetContentTask(this);
|
| +
|
| + /**
|
| + * Return the contents of the source, or `null` if the task has not completed or if there
|
| + * was an exception while getting the contents.
|
| + *
|
| + * @return the contents of the source
|
| + */
|
| + String get content => _content;
|
| +
|
| + /**
|
| + * Return the time at which the contents of the source that was parsed were last modified, or a
|
| + * negative value if the task has not yet been performed or if an exception occurred.
|
| + *
|
| + * @return the time at which the contents of the source that was parsed were last modified
|
| + */
|
| + int get modificationTime => _modificationTime;
|
| +
|
| + /**
|
| + * Return `true` if this task is complete. Unlike most tasks, this task is allowed to be
|
| + * visited more than once in order to support asynchronous IO. If the task is not complete when it
|
| + * is visited synchronously as part of the [AnalysisTask#perform]
|
| + * method, it will be visited again, using the same visitor, when the IO operation has been
|
| + * performed.
|
| + *
|
| + * @return `true` if this task is complete
|
| + */
|
| + bool get isComplete => _complete;
|
| +
|
| + String get taskDescription => "get contents of ${source.fullName}";
|
| +
|
| + void internalPerform() {
|
| + _complete = true;
|
| + try {
|
| + TimestampedData<String> data = context.getContents(source);
|
| + _content = data.data;
|
| + _modificationTime = data.modificationTime;
|
| + } on JavaException catch (exception) {
|
| + throw new AnalysisException.con2("Could not get contents of ${source}", exception);
|
| + }
|
| + }
|
| +}
|
| +
|
| +/**
|
| * Instances of the class `IncrementalAnalysisTask` incrementally update existing analysis.
|
| */
|
| class IncrementalAnalysisTask extends AnalysisTask {
|
| @@ -10648,12 +10987,12 @@ class ParseDartTask extends AnalysisTask {
|
| /**
|
| * A flag indicating whether the source contains a 'part of' directive.
|
| */
|
| - bool _hasPartOfDirective2 = false;
|
| + bool _containsPartOfDirective = false;
|
|
|
| /**
|
| * A flag indicating whether the source contains a 'library' directive.
|
| */
|
| - bool _hasLibraryDirective2 = false;
|
| + bool _containsLibraryDirective = false;
|
|
|
| /**
|
| * Initialize a newly created task to perform analysis within the given context.
|
| @@ -10695,7 +11034,7 @@ class ParseDartTask extends AnalysisTask {
|
| *
|
| * @return `true` if the source contains a 'library' directive
|
| */
|
| - bool hasLibraryDirective() => _hasLibraryDirective2;
|
| + bool hasLibraryDirective() => _containsLibraryDirective;
|
|
|
| /**
|
| * Return `true` if the source contains a 'part of' directive, or `false` if the task
|
| @@ -10703,7 +11042,7 @@ class ParseDartTask extends AnalysisTask {
|
| *
|
| * @return `true` if the source contains a 'part of' directive
|
| */
|
| - bool hasPartOfDirective() => _hasPartOfDirective2;
|
| + bool hasPartOfDirective() => _containsPartOfDirective;
|
|
|
| String get taskDescription {
|
| if (source == null) {
|
| @@ -10732,9 +11071,9 @@ class ParseDartTask extends AnalysisTask {
|
| _errors = errorListener.getErrors2(source);
|
| for (Directive directive in _unit.directives) {
|
| if (directive is LibraryDirective) {
|
| - _hasLibraryDirective2 = true;
|
| + _containsLibraryDirective = true;
|
| } else if (directive is PartOfDirective) {
|
| - _hasPartOfDirective2 = true;
|
| + _containsPartOfDirective = true;
|
| }
|
| }
|
| _unit.lineInfo = context.getLineInfo(source);
|
| @@ -10754,9 +11093,14 @@ class ParseHtmlTask extends AnalysisTask {
|
| final Source source;
|
|
|
| /**
|
| + * The contents of the source.
|
| + */
|
| + String _content;
|
| +
|
| + /**
|
| * The time at which the contents of the source were last modified.
|
| */
|
| - int _modificationTime = -1;
|
| + int _modificationTime = 0;
|
|
|
| /**
|
| * The line information that was produced.
|
| @@ -10793,8 +11137,12 @@ class ParseHtmlTask extends AnalysisTask {
|
| *
|
| * @param context the context in which the task is to be performed
|
| * @param source the source to be parsed
|
| + * @param contentData the time-stamped contents of the source
|
| */
|
| - ParseHtmlTask(InternalAnalysisContext context, this.source) : super(context);
|
| + ParseHtmlTask(InternalAnalysisContext context, this.source, TimestampedData<String> contentData) : super(context) {
|
| + _content = contentData.data;
|
| + _modificationTime = contentData.modificationTime;
|
| + }
|
|
|
| accept(AnalysisTaskVisitor visitor) => visitor.visitParseHtmlTask(this);
|
|
|
| @@ -10845,9 +11193,7 @@ class ParseHtmlTask extends AnalysisTask {
|
|
|
| void internalPerform() {
|
| try {
|
| - TimestampedData<String> contents = context.getContents(source);
|
| - _modificationTime = contents.modificationTime;
|
| - ht.AbstractScanner scanner = new ht.StringScanner(source, contents.data);
|
| + ht.AbstractScanner scanner = new ht.StringScanner(source, _content);
|
| scanner.passThroughElements = <String> [_TAG_SCRIPT];
|
| ht.Token token = scanner.tokenize();
|
| _lineInfo = new LineInfo(scanner.lineStarts);
|
| @@ -11625,6 +11971,37 @@ class ScanDartTask extends AnalysisTask {
|
| }
|
|
|
| /**
|
| + * The unique instances of the class `WaitForAsyncTask` represents a state in which there is
|
| + * no analysis work that can be done until some asynchronous task (such as IO) has completed, but
|
| + * where analysis is not yet complete.
|
| + */
|
| +class WaitForAsyncTask extends AnalysisTask {
|
| + /**
|
| + * The unique instance of this class.
|
| + */
|
| + static WaitForAsyncTask _UniqueInstance = new WaitForAsyncTask();
|
| +
|
| + /**
|
| + * Return the unique instance of this class.
|
| + *
|
| + * @return the unique instance of this class
|
| + */
|
| + static WaitForAsyncTask get instance => _UniqueInstance;
|
| +
|
| + /**
|
| + * Prevent the creation of instances of this class.
|
| + */
|
| + WaitForAsyncTask() : super(null);
|
| +
|
| + accept(AnalysisTaskVisitor visitor) => null;
|
| +
|
| + String get taskDescription => "Waiting for async analysis";
|
| +
|
| + void internalPerform() {
|
| + }
|
| +}
|
| +
|
| +/**
|
| * The interface `Logger` defines the behavior of objects that can be used to receive
|
| * information about errors within the analysis engine. Implementations usually write this
|
| * information to a file, but can also record the information for later use (such as during testing)
|
|
|