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

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

Issue 184893003: New analyzer snapshot. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/lib/src/generated/engine.dart
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 99970733b873f4accf239c68ee3e23674fbc62fd..4cf91cef7db24ff9d0327f57598cbd8e38742feb 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -127,6 +127,13 @@ class AnalysisEngine {
*/
abstract class AnalysisContentStatistics {
/**
+ * Return the statistics for each kind of cached data.
+ *
+ * @return the statistics for each kind of cached data
+ */
+ List<AnalysisContentStatistics_CacheRow> get cacheRows;
+
+ /**
* Return the exceptions that caused some entries to have a state of [CacheState#ERROR].
*
* @return the exceptions that caused some entries to have a state of [CacheState#ERROR]
@@ -134,11 +141,11 @@ abstract class AnalysisContentStatistics {
List<AnalysisException> get exceptions;
/**
- * Return the statistics for each kind of cached data.
+ * Return an array containing all of the sources in the cache.
*
- * @return the statistics for each kind of cached data
+ * @return an array containing all of the sources in the cache
*/
- List<AnalysisContentStatistics_CacheRow> get cacheRows;
+ List<Source> get sources;
}
/**
@@ -281,6 +288,18 @@ abstract class AnalysisContext {
LineInfo computeLineInfo(Source source);
/**
+ * Return `true` if the given source exists.
+ *
+ * This method should be used rather than the method [Source#exists] because contexts can
+ * have local overrides of the content of a source that the source is not aware of and a source
+ * with local content is considered to exist even if there is no file on disk.
+ *
+ * @param source the source whose modification stamp is to be returned
+ * @return `true` if the source exists
+ */
+ bool exists(Source source);
+
+ /**
* Create a new context in which analysis can be performed. Any sources in the specified container
* will be removed from this context and added to the newly created context.
*
@@ -300,6 +319,43 @@ abstract class AnalysisContext {
AnalysisOptions get analysisOptions;
/**
+ * Return the element model corresponding to the compilation unit defined by the given source in
+ * the library defined by the given source, or `null` if the element model does not
+ * currently exist or if the library cannot be analyzed for some reason.
+ *
+ * @param unitSource the source of the compilation unit
+ * @param librarySource the source of the defining compilation unit of the library containing the
+ * compilation unit
+ * @return the element model corresponding to the compilation unit defined by the given source
+ */
+ CompilationUnitElement getCompilationUnitElement(Source unitSource, Source librarySource);
+
+ /**
+ * Get the contents and timestamp of the given source.
+ *
+ * This method should be used rather than the method [Source#getContents] because contexts
+ * can have local overrides of the content of a source that the source is not aware of.
+ *
+ * @param source the source whose content is to be returned
+ * @return the contents and timestamp of the source
+ * @throws Exception if the contents of the source could not be accessed
+ */
+ TimestampedData<String> getContents(Source source);
+
+ /**
+ * Get the contents of the given source and pass it to the given content receiver.
+ *
+ * This method should be used rather than the method [Source#getContentsToReceiver]
+ * because contexts can have local overrides of the content of a source that the source is not
+ * aware of.
+ *
+ * @param source the source whose content is to be returned
+ * @param receiver the content receiver to which the content of the source will be passed
+ * @throws Exception if the contents of the source could not be accessed
+ */
+ void getContents2(Source source, Source_ContentReceiver receiver);
+
+ /**
* Return the element referenced by the given location, or `null` if the element is not
* immediately available or if there is no element with the given location. The latter condition
* can occur, for example, if the location describes an element from a different context or if the
@@ -438,6 +494,21 @@ abstract class AnalysisContext {
LineInfo getLineInfo(Source source);
/**
+ * Return the modification stamp for the given source. A modification stamp is a non-negative
+ * integer with the property that if the contents of the source have not been modified since the
+ * last time the modification stamp was accessed then the same value will be returned, but if the
+ * contents of the source have been modified one or more times (even if the net change is zero)
+ * the stamps will be different.
+ *
+ * This method should be used rather than the method [Source#getModificationStamp] because
+ * contexts can have local overrides of the content of a source that the source is not aware of.
+ *
+ * @param source the source whose modification stamp is to be returned
+ * @return the modification stamp for the source
+ */
+ int getModificationStamp(Source source);
+
+ /**
* Return an array containing all of the sources known to this context and their resolution state
* is not valid or flush. So, these sources are not safe to update during refactoring, because we
* may be don't know all the references in them.
@@ -642,15 +713,6 @@ abstract class AnalysisContext {
* context
*/
void set sourceFactory(SourceFactory factory);
-
- /**
- * Given a collection of sources with content that has changed, return an [Iterable]
- * identifying the sources that need to be resolved.
- *
- * @param changedSources an array of sources (not `null`, contains no `null`s)
- * @return An iterable returning the sources to be resolved
- */
- Iterable<Source> sourcesToResolve(List<Source> changedSources);
}
/**
@@ -715,6 +777,13 @@ class AnalysisException extends JavaException {
*/
abstract class AnalysisOptions {
/**
+ * Return `true` if analysis is to analyze Angular.
+ *
+ * @return `true` if analysis is to analyze Angular
+ */
+ bool get analyzeAngular;
+
+ /**
* Return `true` if analysis is to parse and analyze function bodies.
*
* @return `true` if analysis is to parse and analyzer function bodies
@@ -736,6 +805,14 @@ abstract class AnalysisOptions {
bool get dart2jsHint;
/**
+ * Return `true` if errors, warnings and hints should be generated for sources in the SDK.
+ * The default value is `false`.
+ *
+ * @return `true` if errors, warnings and hints should be generated for the SDK
+ */
+ bool get generateSdkErrors;
+
+ /**
* Return `true` if analysis is to generate hint results (e.g. type inference based
* information and pub best practices).
*
@@ -756,13 +833,6 @@ abstract class AnalysisOptions {
* @return `true` if analysis is to parse comments
*/
bool get preserveComments;
-
- /**
- * Return `true` if analysis is to analyze Angular.
- *
- * @return `true` if analysis is to analyze Angular
- */
- bool get analyzeAngular;
}
/**
@@ -970,6 +1040,34 @@ class ChangeSet {
}
/**
+ * Instances of the class `ObsoleteSourceAnalysisException` represent an analysis attempt that
+ * failed because a source was deleted between the time the analysis started and the time the
+ * results of the analysis were ready to be recorded.
+ */
+class ObsoleteSourceAnalysisException extends AnalysisException {
+ /**
+ * The source that was removed while it was being analyzed.
+ */
+ Source _source;
+
+ /**
+ * Initialize a newly created exception to represent the removal of the given source.
+ *
+ * @param source the source that was removed while it was being analyzed
+ */
+ ObsoleteSourceAnalysisException(Source source) : super.con1("The source '${source.fullName}' was removed while it was being analyzed") {
+ this._source = source;
+ }
+
+ /**
+ * Return the source that was removed while it was being analyzed.
+ *
+ * @return the source that was removed
+ */
+ Source get source => _source;
+}
+
+/**
* Instances of the class `AnalysisCache` implement an LRU cache of information related to
* analysis.
*/
@@ -1163,17 +1261,6 @@ class AnalysisCache {
}
/**
- * Information about Angular application.
- */
-class AngularApplicationInfo {
- final Source entryPoint;
-
- final List<AngularElement> elements;
-
- AngularApplicationInfo(this.entryPoint, this.elements);
-}
-
-/**
* Instances of the class `CacheRetentionPolicy` define the behavior of objects that determine
* how important it is for data to be retained in the analysis cache.
*/
@@ -1337,11 +1424,26 @@ abstract class DartEntry implements SourceEntry {
static final DataDescriptor<SourceKind> SOURCE_KIND = new DataDescriptor<SourceKind>("DartEntry.SOURCE_KIND");
/**
+ * The data descriptor representing the token stream.
+ */
+ static final DataDescriptor<List<AnalysisError>> SCAN_ERRORS = new DataDescriptor<List<AnalysisError>>("DartEntry.SCAN_ERRORS");
+
+ /**
+ * The data descriptor representing the token stream.
+ */
+ static final DataDescriptor<Token> TOKEN_STREAM = new DataDescriptor<Token>("DartEntry.TOKEN_STREAM");
+
+ /**
* The data descriptor representing the errors resulting from verifying the source.
*/
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
@@ -1412,6 +1514,27 @@ abstract class DartEntry implements SourceEntry {
*/
class DartEntryImpl extends SourceEntryImpl implements DartEntry {
/**
+ * The state of the cached token stream.
+ */
+ CacheState _tokenStreamState = CacheState.INVALID;
+
+ /**
+ * The head of the token stream, or `null` if the token stream is not currently cached.
+ */
+ Token _tokenStream;
+
+ /**
+ * The state of the cached scan errors.
+ */
+ CacheState _scanErrorsState = CacheState.INVALID;
+
+ /**
+ * The errors produced while scanning the compilation unit, or `null` if the errors are not
+ * currently cached.
+ */
+ List<AnalysisError> _scanErrors = AnalysisError.NO_ERRORS;
+
+ /**
* The state of the cached source kind.
*/
CacheState _sourceKindState = CacheState.INVALID;
@@ -1444,8 +1567,8 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
CacheState _parseErrorsState = CacheState.INVALID;
/**
- * The errors produced while scanning and parsing the compilation unit, or `null` if the
- * errors are not currently cached.
+ * The errors produced while parsing the compilation unit, or `null` if the errors are not
+ * currently cached.
*/
List<AnalysisError> _parseErrors = AnalysisError.NO_ERRORS;
@@ -1530,6 +1653,12 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
int _bitmask = 0;
/**
+ * The error produced while performing Angular resolution, or an empty array if there are no
+ * errors if the error are not currently cached.
+ */
+ List<AnalysisError> _angularErrors = AnalysisError.NO_ERRORS;
+
+ /**
* The index of the bit in the [bitmask] indicating that this library is launchable: that
* the file has a main method.
*/
@@ -1556,6 +1685,10 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
* Flush any AST structures being maintained by this entry.
*/
void flushAstStructures() {
+ if (identical(_tokenStreamState, CacheState.VALID)) {
+ _tokenStreamState = CacheState.FLUSHED;
+ _tokenStream = null;
+ }
if (identical(_parsedUnitState, CacheState.VALID)) {
_parsedUnitState = CacheState.FLUSHED;
_parsedUnitAccessed = false;
@@ -1566,23 +1699,16 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
List<AnalysisError> get allErrors {
List<AnalysisError> errors = new List<AnalysisError>();
- for (AnalysisError error in _parseErrors) {
- errors.add(error);
- }
+ ListUtilities.addAll(errors, _scanErrors);
+ ListUtilities.addAll(errors, _parseErrors);
DartEntryImpl_ResolutionState state = _resolutionState;
while (state != null) {
- for (AnalysisError error in state._resolutionErrors) {
- errors.add(error);
- }
- for (AnalysisError error in state._verificationErrors) {
- errors.add(error);
- }
- for (AnalysisError error in state._hints) {
- errors.add(error);
- }
+ ListUtilities.addAll(errors, state._resolutionErrors);
+ ListUtilities.addAll(errors, state._verificationErrors);
+ ListUtilities.addAll(errors, state._hints);
state = state._nextState;
}
- ;
+ ListUtilities.addAll(errors, _angularErrors);
if (errors.length == 0) {
return AnalysisError.NO_ERRORS;
}
@@ -1673,8 +1799,12 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
return _parsedUnitState;
} else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) {
return _publicNamespaceState;
+ } else if (identical(descriptor, DartEntry.SCAN_ERRORS)) {
+ return _scanErrorsState;
} else if (identical(descriptor, DartEntry.SOURCE_KIND)) {
return _sourceKindState;
+ } else if (identical(descriptor, DartEntry.TOKEN_STREAM)) {
+ return _tokenStreamState;
} else {
return super.getState(descriptor);
}
@@ -1707,7 +1837,9 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
}
Object getValue(DataDescriptor descriptor) {
- if (identical(descriptor, DartEntry.CONTAINING_LIBRARIES)) {
+ if (identical(descriptor, DartEntry.ANGULAR_ERRORS)) {
+ return _angularErrors;
+ } else if (identical(descriptor, DartEntry.CONTAINING_LIBRARIES)) {
return new List.from(_containingLibraries);
} else if (identical(descriptor, DartEntry.ELEMENT)) {
return _element;
@@ -1728,8 +1860,12 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
return _parsedUnit;
} else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) {
return _publicNamespace;
+ } else if (identical(descriptor, DartEntry.SCAN_ERRORS)) {
+ return _scanErrors;
} else if (identical(descriptor, DartEntry.SOURCE_KIND)) {
return _sourceKind;
+ } else if (identical(descriptor, DartEntry.TOKEN_STREAM)) {
+ return _tokenStream;
}
return super.getValue(descriptor);
}
@@ -1787,8 +1923,12 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
return identical(_parsedUnitState, CacheState.INVALID);
} else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) {
return identical(_publicNamespaceState, CacheState.INVALID);
+ } else if (identical(descriptor, DartEntry.SCAN_ERRORS)) {
+ return identical(_scanErrorsState, CacheState.INVALID);
} else if (identical(descriptor, DartEntry.SOURCE_KIND)) {
return identical(_sourceKindState, CacheState.INVALID);
+ } else if (identical(descriptor, DartEntry.TOKEN_STREAM)) {
+ return identical(_tokenStreamState, CacheState.INVALID);
} else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.RESOLVED_UNIT) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
DartEntryImpl_ResolutionState state = _resolutionState;
while (state != null) {
@@ -1810,6 +1950,10 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
void invalidateAllInformation() {
super.invalidateAllInformation();
+ _scanErrors = AnalysisError.NO_ERRORS;
+ _scanErrorsState = CacheState.INVALID;
+ _tokenStream = null;
+ _tokenStreamState = CacheState.INVALID;
_sourceKind = SourceKind.UNKNOWN;
_sourceKindState = CacheState.INVALID;
_parseErrors = AnalysisError.NO_ERRORS;
@@ -1902,7 +2046,6 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
* as being in error.
*/
void recordParseError() {
- setState(SourceEntry.LINE_INFO, CacheState.ERROR);
_sourceKind = SourceKind.UNKNOWN;
_sourceKindState = CacheState.ERROR;
_parseErrors = AnalysisError.NO_ERRORS;
@@ -1919,9 +2062,6 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
* the current thread.
*/
void recordParseInProcess() {
- if (getState(SourceEntry.LINE_INFO) != CacheState.VALID) {
- setState(SourceEntry.LINE_INFO, CacheState.IN_PROCESS);
- }
if (_sourceKindState != CacheState.VALID) {
_sourceKindState = CacheState.IN_PROCESS;
}
@@ -1989,6 +2129,52 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
}
/**
+ * Record that an error occurred while attempting to scan or parse the entry represented by this
+ * entry. This will set the state of all information, including any resolution-based information,
+ * as being in error.
+ */
+ void recordScanError() {
+ setState(SourceEntry.LINE_INFO, CacheState.ERROR);
+ _scanErrors = AnalysisError.NO_ERRORS;
+ _scanErrorsState = CacheState.ERROR;
+ _tokenStream = null;
+ _tokenStreamState = CacheState.ERROR;
+ recordParseError();
+ }
+
+ /**
+ * Record that the scan-related information for the associated source is about to be computed by
+ * the current thread.
+ */
+ void recordScanInProcess() {
+ if (getState(SourceEntry.LINE_INFO) != CacheState.VALID) {
+ setState(SourceEntry.LINE_INFO, CacheState.IN_PROCESS);
+ }
+ if (_scanErrorsState != CacheState.VALID) {
+ _scanErrorsState = CacheState.IN_PROCESS;
+ }
+ if (_tokenStreamState != CacheState.VALID) {
+ _tokenStreamState = CacheState.IN_PROCESS;
+ }
+ }
+
+ /**
+ * Record that an in-process scan has stopped without recording results because the results were
+ * invalidated before they could be recorded.
+ */
+ void recordScanNotInProcess() {
+ if (identical(getState(SourceEntry.LINE_INFO), CacheState.IN_PROCESS)) {
+ setState(SourceEntry.LINE_INFO, CacheState.INVALID);
+ }
+ if (identical(_scanErrorsState, CacheState.IN_PROCESS)) {
+ _scanErrorsState = CacheState.INVALID;
+ }
+ if (identical(_tokenStreamState, CacheState.IN_PROCESS)) {
+ _tokenStreamState = CacheState.INVALID;
+ }
+ }
+
+ /**
* Remove the given library from the list of libraries that contain this part. This method should
* only be invoked on entries that represent a part.
*
@@ -2039,30 +2225,6 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
_containingLibraries.add(librarySource);
}
- /**
- * Set the results of parsing the compilation unit at the given time to the given values.
- *
- * @param modificationStamp the earliest time at which the source was last modified before the
- * parsing was started
- * @param lineInfo the line information resulting from parsing the compilation unit
- * @param unit the AST structure resulting from parsing the compilation unit
- * @param errors the parse errors resulting from parsing the compilation unit
- */
- void setParseResults(int modificationStamp, LineInfo lineInfo, CompilationUnit unit, List<AnalysisError> errors) {
- if (getState(SourceEntry.LINE_INFO) != CacheState.VALID) {
- setValue(SourceEntry.LINE_INFO, lineInfo);
- }
- if (_parsedUnitState != CacheState.VALID) {
- _parsedUnit = unit;
- _parsedUnitAccessed = false;
- _parsedUnitState = CacheState.VALID;
- }
- if (_parseErrorsState != CacheState.VALID) {
- _parseErrors = errors == null ? AnalysisError.NO_ERRORS : errors;
- _parseErrorsState = CacheState.VALID;
- }
- }
-
void setState(DataDescriptor descriptor, CacheState state) {
if (identical(descriptor, DartEntry.ELEMENT)) {
_element = updatedValue(state, _element, null);
@@ -2095,9 +2257,15 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
} else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) {
_publicNamespace = updatedValue(state, _publicNamespace, null);
_publicNamespaceState = state;
+ } else if (identical(descriptor, DartEntry.SCAN_ERRORS)) {
+ _scanErrors = updatedValue(state, _scanErrors, AnalysisError.NO_ERRORS);
+ _scanErrorsState = state;
} else if (identical(descriptor, DartEntry.SOURCE_KIND)) {
_sourceKind = updatedValue(state, _sourceKind, SourceKind.UNKNOWN);
_sourceKindState = state;
+ } else if (identical(descriptor, DartEntry.TOKEN_STREAM)) {
+ _tokenStream = updatedValue(state, _tokenStream, null);
+ _tokenStreamState = state;
} else {
super.setState(descriptor, state);
}
@@ -2132,7 +2300,9 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
}
void setValue(DataDescriptor descriptor, Object value) {
- if (identical(descriptor, DartEntry.ELEMENT)) {
+ if (identical(descriptor, DartEntry.ANGULAR_ERRORS)) {
+ _angularErrors = value == null ? AnalysisError.NO_ERRORS : (value as List<AnalysisError>);
+ } else if (identical(descriptor, DartEntry.ELEMENT)) {
_element = value as LibraryElement;
_elementState = CacheState.VALID;
} else if (identical(descriptor, DartEntry.EXPORTED_LIBRARIES)) {
@@ -2160,9 +2330,15 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
} else if (identical(descriptor, DartEntry.PUBLIC_NAMESPACE)) {
_publicNamespace = value as Namespace;
_publicNamespaceState = CacheState.VALID;
+ } else if (identical(descriptor, DartEntry.SCAN_ERRORS)) {
+ _scanErrors = value == null ? AnalysisError.NO_ERRORS : (value as List<AnalysisError>);
+ _scanErrorsState = CacheState.VALID;
} else if (identical(descriptor, DartEntry.SOURCE_KIND)) {
_sourceKind = value as SourceKind;
_sourceKindState = CacheState.VALID;
+ } else if (identical(descriptor, DartEntry.TOKEN_STREAM)) {
+ _tokenStream = value as Token;
+ _tokenStreamState = CacheState.VALID;
} else {
super.setValue(descriptor, value);
}
@@ -2197,6 +2373,10 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
void copyFrom(SourceEntryImpl entry) {
super.copyFrom(entry);
DartEntryImpl other = entry as DartEntryImpl;
+ _scanErrorsState = other._scanErrorsState;
+ _scanErrors = other._scanErrors;
+ _tokenStreamState = other._tokenStreamState;
+ _tokenStream = other._tokenStream;
_sourceKindState = other._sourceKindState;
_sourceKind = other._sourceKind;
_parsedUnitState = other._parsedUnitState;
@@ -2219,13 +2399,18 @@ class DartEntryImpl extends SourceEntryImpl implements DartEntry {
_clientServerState = other._clientServerState;
_launchableState = other._launchableState;
_bitmask = other._bitmask;
+ _angularErrors = other._angularErrors;
}
- bool hasErrorState() => super.hasErrorState() || identical(_sourceKindState, CacheState.ERROR) || identical(_parsedUnitState, CacheState.ERROR) || identical(_parseErrorsState, CacheState.ERROR) || identical(_importedLibrariesState, CacheState.ERROR) || identical(_exportedLibrariesState, CacheState.ERROR) || identical(_includedPartsState, CacheState.ERROR) || identical(_elementState, CacheState.ERROR) || identical(_publicNamespaceState, CacheState.ERROR) || identical(_clientServerState, CacheState.ERROR) || identical(_launchableState, CacheState.ERROR) || _resolutionState.hasErrorState();
+ bool hasErrorState() => super.hasErrorState() || identical(_scanErrorsState, CacheState.ERROR) || identical(_tokenStreamState, CacheState.ERROR) || identical(_sourceKindState, CacheState.ERROR) || identical(_parsedUnitState, CacheState.ERROR) || identical(_parseErrorsState, CacheState.ERROR) || identical(_importedLibrariesState, CacheState.ERROR) || identical(_exportedLibrariesState, CacheState.ERROR) || identical(_includedPartsState, CacheState.ERROR) || identical(_elementState, CacheState.ERROR) || identical(_publicNamespaceState, CacheState.ERROR) || identical(_clientServerState, CacheState.ERROR) || identical(_launchableState, CacheState.ERROR) || _resolutionState.hasErrorState();
void writeOn(JavaStringBuilder builder) {
builder.append("Dart: ");
super.writeOn(builder);
+ builder.append("; tokenStream = ");
+ builder.append(_tokenStreamState);
+ builder.append("; scanErrors = ");
+ builder.append(_scanErrorsState);
builder.append("; sourceKind = ");
builder.append(_sourceKindState);
builder.append("; parsedUnit = ");
@@ -2529,7 +2714,7 @@ abstract class HtmlEntry implements SourceEntry {
* The data descriptor representing the information about an Angular application this source is
* used in.
*/
- static final DataDescriptor<AngularApplicationInfo> ANGULAR_APPLICATION = new DataDescriptor<AngularApplicationInfo>("HtmlEntry.ANGULAR_APPLICATION");
+ static final DataDescriptor<AngularApplication> ANGULAR_APPLICATION = new DataDescriptor<AngularApplication>("HtmlEntry.ANGULAR_APPLICATION");
/**
* The data descriptor representing the information about an Angular component this source is used
@@ -2541,7 +2726,7 @@ abstract class HtmlEntry implements SourceEntry {
* The data descriptor representing the information about an Angular application this source is
* entry point for.
*/
- static final DataDescriptor<AngularApplicationInfo> ANGULAR_ENTRY = new DataDescriptor<AngularApplicationInfo>("HtmlEntry.ANGULAR_ENTRY");
+ static final DataDescriptor<AngularApplication> ANGULAR_ENTRY = new DataDescriptor<AngularApplication>("HtmlEntry.ANGULAR_ENTRY");
/**
* The data descriptor representing the errors reported during Angular resolution.
@@ -2678,17 +2863,17 @@ class HtmlEntryImpl extends SourceEntryImpl implements HtmlEntry {
/**
* Information about the Angular Application this unit is used in.
*/
- AngularApplicationInfo _angularApplication;
+ AngularApplication _angularApplication;
/**
* The state of the [angularEntry].
*/
- CacheState _angularEntryState = CacheState.VALID;
+ CacheState _angularEntryState = CacheState.INVALID;
/**
* Information about the Angular Application this unit is entry point for.
*/
- AngularApplicationInfo _angularEntry = null;
+ AngularApplication _angularEntry = null;
/**
* The state of the [angularComponent].
@@ -2855,6 +3040,8 @@ class HtmlEntryImpl extends SourceEntryImpl implements HtmlEntry {
* Invalidate all of the resolution information associated with the HTML file.
*/
void invalidateAllResolutionInformation() {
+ _angularEntry = null;
+ _angularEntryState = CacheState.INVALID;
_angularErrors = AnalysisError.NO_ERRORS;
_angularErrorsState = CacheState.INVALID;
_element = null;
@@ -2930,13 +3117,13 @@ class HtmlEntryImpl extends SourceEntryImpl implements HtmlEntry {
void setValue(DataDescriptor descriptor, Object value) {
if (identical(descriptor, HtmlEntry.ANGULAR_APPLICATION)) {
- _angularApplication = value as AngularApplicationInfo;
+ _angularApplication = value as AngularApplication;
_angularApplicationState = CacheState.VALID;
} else if (identical(descriptor, HtmlEntry.ANGULAR_COMPONENT)) {
_angularComponent = value as AngularComponentElement;
_angularComponentState = CacheState.VALID;
} else if (identical(descriptor, HtmlEntry.ANGULAR_ENTRY)) {
- _angularEntry = value as AngularApplicationInfo;
+ _angularEntry = value as AngularApplication;
_angularEntryState = CacheState.VALID;
} else if (identical(descriptor, HtmlEntry.ANGULAR_ERRORS)) {
_angularErrors = value as List<AnalysisError>;
@@ -3293,8 +3480,14 @@ abstract class SourceEntryImpl implements SourceEntry {
class AnalysisContentStatisticsImpl implements AnalysisContentStatistics {
Map<String, AnalysisContentStatistics_CacheRow> _dataMap = new Map<String, AnalysisContentStatistics_CacheRow>();
+ List<Source> _sources = new List<Source>();
+
Set<AnalysisException> _exceptions = new Set<AnalysisException>();
+ void addSource(Source source) {
+ _sources.add(source);
+ }
+
List<AnalysisContentStatistics_CacheRow> get cacheRows {
Iterable<AnalysisContentStatistics_CacheRow> items = _dataMap.values;
return new List.from(items);
@@ -3302,14 +3495,16 @@ class AnalysisContentStatisticsImpl implements AnalysisContentStatistics {
List<AnalysisException> get exceptions => new List.from(_exceptions);
- void putCacheItem(DartEntry dartEntry, DataDescriptor descriptor) {
- putCacheItem3(dartEntry, descriptor, dartEntry.getState(descriptor));
- }
+ List<Source> get sources => new List.from(_sources);
- void putCacheItem2(DartEntry dartEntry, Source librarySource, DataDescriptor descriptor) {
+ void putCacheItem(DartEntry dartEntry, Source librarySource, DataDescriptor descriptor) {
putCacheItem3(dartEntry, descriptor, dartEntry.getState2(descriptor, librarySource));
}
+ void putCacheItem2(SourceEntry dartEntry, DataDescriptor descriptor) {
+ putCacheItem3(dartEntry, descriptor, dartEntry.getState(descriptor));
+ }
+
void putCacheItem3(SourceEntry dartEntry, DataDescriptor rowDesc, CacheState state) {
String rowName = rowDesc.toString();
AnalysisContentStatisticsImpl_CacheRowImpl row = _dataMap[rowName] as AnalysisContentStatisticsImpl_CacheRowImpl;
@@ -3395,6 +3590,11 @@ class AnalysisContextImpl implements InternalAnalysisContext {
AnalysisOptionsImpl _options = new AnalysisOptionsImpl();
/**
+ * A cache of content used to override the default content of a source.
+ */
+ ContentCache _contentCache = new ContentCache();
+
+ /**
* The source factory used to create the sources that can be analyzed in this context.
*/
SourceFactory _sourceFactory;
@@ -3450,6 +3650,11 @@ class AnalysisContextImpl implements InternalAnalysisContext {
WorkManager _workManager = new WorkManager();
/**
+ * The set of [AngularApplication] in this context.
+ */
+ Set<AngularApplication> _angularApplications = new Set();
+
+ /**
* Initialize a newly created analysis context.
*/
AnalysisContextImpl() : super() {
@@ -3560,24 +3765,34 @@ class AnalysisContextImpl implements InternalAnalysisContext {
SourceEntry sourceEntry = getReadableSourceEntry(source);
if (sourceEntry is DartEntry) {
List<AnalysisError> errors = new List<AnalysisError>();
- DartEntry dartEntry = sourceEntry;
- ListUtilities.addAll(errors, getDartParseData(source, dartEntry, DartEntry.PARSE_ERRORS));
- dartEntry = getReadableDartEntry(source);
- if (identical(dartEntry.getValue(DartEntry.SOURCE_KIND), SourceKind.LIBRARY)) {
- ListUtilities.addAll(errors, getDartResolutionData(source, source, dartEntry, DartEntry.RESOLUTION_ERRORS));
- ListUtilities.addAll(errors, getDartVerificationData(source, source, dartEntry, DartEntry.VERIFICATION_ERRORS));
- if (enableHints) {
- ListUtilities.addAll(errors, getDartHintData(source, source, dartEntry, DartEntry.HINTS));
- }
- } else {
- List<Source> libraries = getLibrariesContaining(source);
- for (Source librarySource in libraries) {
- ListUtilities.addAll(errors, getDartResolutionData(source, librarySource, dartEntry, DartEntry.RESOLUTION_ERRORS));
- ListUtilities.addAll(errors, getDartVerificationData(source, librarySource, dartEntry, DartEntry.VERIFICATION_ERRORS));
+ try {
+ DartEntry dartEntry = sourceEntry;
+ ListUtilities.addAll(errors, getDartScanData(source, dartEntry, DartEntry.SCAN_ERRORS));
+ dartEntry = getReadableDartEntry(source);
+ ListUtilities.addAll(errors, getDartParseData(source, dartEntry, DartEntry.PARSE_ERRORS));
+ dartEntry = getReadableDartEntry(source);
+ if (identical(dartEntry.getValue(DartEntry.SOURCE_KIND), SourceKind.LIBRARY)) {
+ ListUtilities.addAll(errors, getDartResolutionData(source, source, dartEntry, DartEntry.RESOLUTION_ERRORS));
+ dartEntry = getReadableDartEntry(source);
+ ListUtilities.addAll(errors, getDartVerificationData(source, source, dartEntry, DartEntry.VERIFICATION_ERRORS));
if (enableHints) {
- ListUtilities.addAll(errors, getDartHintData(source, librarySource, dartEntry, DartEntry.HINTS));
+ dartEntry = getReadableDartEntry(source);
+ ListUtilities.addAll(errors, getDartHintData(source, source, dartEntry, DartEntry.HINTS));
+ }
+ } else {
+ List<Source> libraries = getLibrariesContaining(source);
+ for (Source librarySource in libraries) {
+ ListUtilities.addAll(errors, getDartResolutionData(source, librarySource, dartEntry, DartEntry.RESOLUTION_ERRORS));
+ dartEntry = getReadableDartEntry(source);
+ ListUtilities.addAll(errors, getDartVerificationData(source, librarySource, dartEntry, DartEntry.VERIFICATION_ERRORS));
+ if (enableHints) {
+ dartEntry = getReadableDartEntry(source);
+ ListUtilities.addAll(errors, getDartHintData(source, librarySource, dartEntry, DartEntry.HINTS));
+ }
}
}
+ } on ObsoleteSourceAnalysisException catch (exception) {
+ AnalysisEngine.instance.logger.logInformation3("Could not compute errors", exception);
}
if (errors.isEmpty) {
return AnalysisError.NO_ERRORS;
@@ -3585,7 +3800,11 @@ class AnalysisContextImpl implements InternalAnalysisContext {
return new List.from(errors);
} else if (sourceEntry is HtmlEntry) {
HtmlEntry htmlEntry = sourceEntry;
- return getHtmlResolutionData2(source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS);
+ try {
+ return getHtmlResolutionData2(source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS);
+ } on ObsoleteSourceAnalysisException catch (exception) {
+ AnalysisEngine.instance.logger.logInformation3("Could not compute errors", exception);
+ }
}
return AnalysisError.NO_ERRORS;
}
@@ -3614,10 +3833,14 @@ class AnalysisContextImpl implements InternalAnalysisContext {
LineInfo computeLineInfo(Source source) {
SourceEntry sourceEntry = getReadableSourceEntry(source);
- if (sourceEntry is HtmlEntry) {
- return getHtmlParseData(source, SourceEntry.LINE_INFO, null);
- } else if (sourceEntry is DartEntry) {
- return getDartParseData2(source, SourceEntry.LINE_INFO, null);
+ try {
+ if (sourceEntry is HtmlEntry) {
+ return getHtmlParseData(source, SourceEntry.LINE_INFO, null);
+ } else if (sourceEntry is DartEntry) {
+ return getDartScanData2(source, SourceEntry.LINE_INFO, null);
+ }
+ } on ObsoleteSourceAnalysisException catch (exception) {
+ AnalysisEngine.instance.logger.logInformation3("Could not compute ${SourceEntry.LINE_INFO.toString()}", exception);
}
return null;
}
@@ -3668,6 +3891,16 @@ class AnalysisContextImpl implements InternalAnalysisContext {
return new ResolvableHtmlUnit(htmlEntry.modificationTime, unit);
}
+ bool exists(Source source) {
+ if (source == null) {
+ return false;
+ }
+ if (_contentCache.getContents(source) != null) {
+ return true;
+ }
+ return source.exists();
+ }
+
AnalysisContext extractContext(SourceContainer container) => extractContextInto(container, AnalysisEngine.instance.createAnalysisContext() as InternalAnalysisContext);
InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext) {
@@ -3687,6 +3920,41 @@ class AnalysisContextImpl implements InternalAnalysisContext {
AnalysisOptions get analysisOptions => _options;
+ CompilationUnitElement getCompilationUnitElement(Source unitSource, Source librarySource) {
+ LibraryElement libraryElement = getLibraryElement(librarySource);
+ if (libraryElement != null) {
+ // try defining unit
+ CompilationUnitElement definingUnit = libraryElement.definingCompilationUnit;
+ if (definingUnit.source == unitSource) {
+ return definingUnit;
+ }
+ // try parts
+ for (CompilationUnitElement partUnit in libraryElement.parts) {
+ if (partUnit.source == unitSource) {
+ return partUnit;
+ }
+ }
+ }
+ return null;
+ }
+
+ TimestampedData<String> getContents(Source source) {
+ String contents = _contentCache.getContents(source);
+ if (contents != null) {
+ return new TimestampedData<String>(_contentCache.getModificationStamp(source), contents);
+ }
+ return source.contents;
+ }
+
+ void getContents2(Source source, Source_ContentReceiver receiver) {
+ String contents = _contentCache.getContents(source);
+ if (contents != null) {
+ receiver.accept(contents, _contentCache.getModificationStamp(source));
+ return;
+ }
+ source.getContentsToReceiver(receiver);
+ }
+
Element getElement(ElementLocation location) {
// TODO(brianwilkerson) This should not be a "get" method.
try {
@@ -3848,6 +4116,14 @@ class AnalysisContextImpl implements InternalAnalysisContext {
return null;
}
+ int getModificationStamp(Source source) {
+ int stamp = _contentCache.getModificationStamp(source);
+ if (stamp != null) {
+ return stamp;
+ }
+ return source.modificationStamp;
+ }
+
Namespace getPublicNamespace(LibraryElement library) {
// TODO(brianwilkerson) Rename this to not start with 'get'. Note that this is not part of the
// API of the interface.
@@ -3981,32 +4257,41 @@ class AnalysisContextImpl implements InternalAnalysisContext {
AnalysisContentStatisticsImpl statistics = new AnalysisContentStatisticsImpl();
{
for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
+ statistics.addSource(mapEntry.getKey());
SourceEntry entry = mapEntry.getValue();
if (entry is DartEntry) {
Source source = mapEntry.getKey();
DartEntry dartEntry = entry;
SourceKind kind = dartEntry.getValue(DartEntry.SOURCE_KIND);
// get library independent values
- statistics.putCacheItem(dartEntry, DartEntry.PARSE_ERRORS);
- statistics.putCacheItem(dartEntry, DartEntry.PARSED_UNIT);
- statistics.putCacheItem(dartEntry, DartEntry.SOURCE_KIND);
- statistics.putCacheItem(dartEntry, SourceEntry.LINE_INFO);
+ statistics.putCacheItem2(dartEntry, SourceEntry.LINE_INFO);
+ statistics.putCacheItem2(dartEntry, DartEntry.PARSE_ERRORS);
+ statistics.putCacheItem2(dartEntry, DartEntry.PARSED_UNIT);
+ statistics.putCacheItem2(dartEntry, DartEntry.SOURCE_KIND);
if (identical(kind, SourceKind.LIBRARY)) {
- statistics.putCacheItem(dartEntry, DartEntry.ELEMENT);
- statistics.putCacheItem(dartEntry, DartEntry.EXPORTED_LIBRARIES);
- statistics.putCacheItem(dartEntry, DartEntry.IMPORTED_LIBRARIES);
- statistics.putCacheItem(dartEntry, DartEntry.INCLUDED_PARTS);
- statistics.putCacheItem(dartEntry, DartEntry.IS_CLIENT);
- statistics.putCacheItem(dartEntry, DartEntry.IS_LAUNCHABLE);
+ statistics.putCacheItem2(dartEntry, DartEntry.ELEMENT);
+ statistics.putCacheItem2(dartEntry, DartEntry.EXPORTED_LIBRARIES);
+ statistics.putCacheItem2(dartEntry, DartEntry.IMPORTED_LIBRARIES);
+ statistics.putCacheItem2(dartEntry, DartEntry.INCLUDED_PARTS);
+ statistics.putCacheItem2(dartEntry, DartEntry.IS_CLIENT);
+ statistics.putCacheItem2(dartEntry, DartEntry.IS_LAUNCHABLE);
}
// get library-specific values
List<Source> librarySources = getLibrariesContaining(source);
for (Source librarySource in librarySources) {
- statistics.putCacheItem2(dartEntry, librarySource, DartEntry.HINTS);
- statistics.putCacheItem2(dartEntry, librarySource, DartEntry.RESOLUTION_ERRORS);
- statistics.putCacheItem2(dartEntry, librarySource, DartEntry.RESOLVED_UNIT);
- statistics.putCacheItem2(dartEntry, librarySource, DartEntry.VERIFICATION_ERRORS);
+ statistics.putCacheItem(dartEntry, librarySource, DartEntry.HINTS);
+ statistics.putCacheItem(dartEntry, librarySource, DartEntry.RESOLUTION_ERRORS);
+ statistics.putCacheItem(dartEntry, librarySource, DartEntry.RESOLVED_UNIT);
+ statistics.putCacheItem(dartEntry, librarySource, DartEntry.VERIFICATION_ERRORS);
}
+ } else if (entry is HtmlEntry) {
+ HtmlEntry htmlEntry = entry;
+ statistics.putCacheItem2(htmlEntry, SourceEntry.LINE_INFO);
+ statistics.putCacheItem2(htmlEntry, HtmlEntry.PARSE_ERRORS);
+ statistics.putCacheItem2(htmlEntry, HtmlEntry.PARSED_UNIT);
+ statistics.putCacheItem2(htmlEntry, HtmlEntry.RESOLUTION_ERRORS);
+ statistics.putCacheItem2(htmlEntry, HtmlEntry.RESOLVED_UNIT);
+ statistics.putCacheItem2(htmlEntry, HtmlEntry.HINTS);
}
}
}
@@ -4018,6 +4303,19 @@ class AnalysisContextImpl implements InternalAnalysisContext {
return new TypeProviderImpl(computeLibraryElement(coreSource));
}
+ TimestampedData<CompilationUnit> internalParseCompilationUnit(Source source) {
+ DartEntry dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("internalParseCompilationUnit invoked for non-Dart file: ${source.fullName}");
+ }
+ dartEntry = cacheDartParseData(source, dartEntry, DartEntry.PARSED_UNIT);
+ CompilationUnit unit = dartEntry.anyParsedCompilationUnit;
+ if (unit == null) {
+ throw new AnalysisException.con2("internalParseCompilationUnit could not cache a parsed unit: ${source.fullName}", dartEntry.exception);
+ }
+ return new TimestampedData<CompilationUnit>(dartEntry.modificationTime, unit);
+ }
+
TimestampedData<CompilationUnit> internalResolveCompilationUnit(Source unitSource, LibraryElement libraryElement) {
DartEntry dartEntry = getReadableDartEntry(unitSource);
if (dartEntry == null) {
@@ -4028,6 +4326,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
return new TimestampedData<CompilationUnit>(dartEntry.modificationTime, dartEntry.getValue2(DartEntry.RESOLVED_UNIT, librarySource));
}
+ TimestampedData<Token> internalScanTokenStream(Source source) {
+ DartEntry dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("internalScanTokenStream invoked for non-Dart file: ${source.fullName}");
+ }
+ dartEntry = cacheDartScanData(source, dartEntry, DartEntry.TOKEN_STREAM);
+ return new TimestampedData<Token>(dartEntry.modificationTime, dartEntry.getValue(DartEntry.TOKEN_STREAM));
+ }
+
bool isClientLibrary(Source librarySource) {
SourceEntry sourceEntry = getReadableSourceEntry(librarySource);
if (sourceEntry is DartEntry) {
@@ -4090,6 +4397,8 @@ class AnalysisContextImpl implements InternalAnalysisContext {
int performStart = JavaSystem.currentTimeMillis();
try {
task.perform(_resultRecorder);
+ } on ObsoleteSourceAnalysisException catch (exception) {
+ AnalysisEngine.instance.logger.logInformation3("Could not perform analysis task: ${taskDescriptor}", exception);
} on AnalysisException catch (exception) {
if (exception.cause is! JavaIOException) {
AnalysisEngine.instance.logger.logError2("Internal error while performing the task: ${task}", exception);
@@ -4189,7 +4498,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
void setChangedContents(Source source, String contents, int offset, int oldLength, int newLength) {
{
_recentTasks.clear();
- String originalContents = _sourceFactory.setContents(source, contents);
+ String originalContents = _contentCache.setContents(source, contents);
if (contents != null) {
if (contents != originalContents) {
if (_options.incremental) {
@@ -4207,7 +4516,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
void setContents(Source source, String contents) {
{
_recentTasks.clear();
- String originalContents = _sourceFactory.setContents(source, contents);
+ String originalContents = _contentCache.setContents(source, contents);
if (contents != null) {
if (contents != originalContents) {
_incrementalAnalysisCache = IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
@@ -4236,16 +4545,6 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
}
- Iterable<Source> sourcesToResolve(List<Source> changedSources) {
- List<Source> librarySources = new List<Source>();
- for (Source source in changedSources) {
- if (identical(computeKindOf(source), SourceKind.LIBRARY)) {
- librarySources.add(source);
- }
- }
- return librarySources;
- }
-
/**
* Record the results produced by performing a [ResolveDartLibraryTask]. If the results were
* computed from data that is now out-of-date, then the results will not be recorded.
@@ -4294,7 +4593,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
List<AnalysisError> errors = errorListener.getErrors2(source);
LineInfo lineInfo = getLineInfo(source);
DartEntry dartEntry = _cache.get(source) as DartEntry;
- int sourceTime = source.modificationStamp;
+ int sourceTime = getModificationStamp(source);
if (dartEntry.modificationTime != sourceTime) {
// The source has changed without the context being notified. Simulate notification.
sourceChanged(source);
@@ -4338,7 +4637,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
DartEntry dartEntry = getReadableDartEntry(source);
if (dartEntry != null) {
int resultTime = library.getModificationTime(source);
- writer.println(" ${debuggingString(source)}; sourceTime = ${source.modificationStamp}, resultTime = ${resultTime}, cacheTime = ${dartEntry.modificationTime}");
+ writer.println(" ${debuggingString(source)}; sourceTime = ${getModificationStamp(source)}, resultTime = ${resultTime}, cacheTime = ${dartEntry.modificationTime}");
DartEntryImpl dartCopy = dartEntry.writableCopy;
if (thrownException == null || resultTime >= 0) {
//
@@ -4361,7 +4660,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
unitEntry = dartCopy;
}
} else {
- writer.println(" ${debuggingString(source)}; sourceTime = ${source.modificationStamp}, no entry");
+ writer.println(" ${debuggingString(source)}; sourceTime = ${getModificationStamp(source)}, no entry");
}
}
}
@@ -4429,7 +4728,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
// source didn't represent a Dart file, but check to be safe.
throw new AnalysisException.con1("Internal error: attempting to resolve non-Dart file as a Dart file: ${source.fullName}");
}
- int sourceTime = source.modificationStamp;
+ int sourceTime = getModificationStamp(source);
int resultTime = library.getModificationTime(source);
if (sourceTime != resultTime) {
// The source has changed without the context being notified. Simulate notification.
@@ -4508,8 +4807,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* @param dartEntry the cache entry associated with the Dart file
* @param descriptor the descriptor representing the data to be returned
* @return a cache entry containing the required data
- * @throws AnalysisException if data could not be returned because the source could not be
- * resolved
+ * @throws AnalysisException if data could not be returned because the source could not be parsed
*/
DartEntry cacheDartParseData(Source source, DartEntry dartEntry, DataDescriptor descriptor) {
if (identical(descriptor, DartEntry.PARSED_UNIT)) {
@@ -4565,17 +4863,53 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
/**
- * Given a source for a Dart file and the library that contains it, return a cache entry in which
- * the state of the data represented by the given descriptor is either [CacheState#VALID] or
- * [CacheState#ERROR]. This method assumes that the data can be produced by verifying the
- * source in the given library if the data is not already cached.
+ * Given a source for a Dart file, return a cache entry in which the state of the data represented
+ * by the given descriptor is either [CacheState#VALID] or [CacheState#ERROR]. This
+ * method assumes that the data can be produced by scanning the source if it is not already
+ * cached.
*
- * @param unitSource the source representing the Dart file
- * @param librarySource the source representing the library containing the Dart file
+ * @param source the source representing the Dart file
* @param dartEntry the cache entry associated with the Dart file
* @param descriptor the descriptor representing the data to be returned
* @return a cache entry containing the required data
- * @throws AnalysisException if data could not be returned because the source could not be parsed
+ * @throws AnalysisException if data could not be returned because the source could not be scanned
+ */
+ DartEntry cacheDartScanData(Source source, DartEntry dartEntry, DataDescriptor descriptor) {
+ //
+ // Check to see whether we already have the information being requested.
+ //
+ CacheState state = dartEntry.getState(descriptor);
+ while (state != CacheState.ERROR && state != CacheState.VALID) {
+ //
+ // If not, compute the information. Unless the modification date of the source continues to
+ // change, this loop will eventually terminate.
+ //
+ // TODO(brianwilkerson) Convert this to get the contents from the cache. (I'm not sure how
+ // that would work in an asynchronous environment.)
+ try {
+ dartEntry = new ScanDartTask(this, source, getContents(source)).perform(_resultRecorder) as DartEntry;
+ } on AnalysisException catch (exception) {
+ throw exception;
+ } on JavaException catch (exception) {
+ throw new AnalysisException.con3(exception);
+ }
+ state = dartEntry.getState(descriptor);
+ }
+ return dartEntry;
+ }
+
+ /**
+ * Given a source for a Dart file and the library that contains it, return a cache entry in which
+ * the state of the data represented by the given descriptor is either [CacheState#VALID] or
+ * [CacheState#ERROR]. This method assumes that the data can be produced by verifying the
+ * source in the given library if the data is not already cached.
+ *
+ * @param unitSource the source representing the Dart file
+ * @param librarySource the source representing the library containing the Dart file
+ * @param dartEntry the cache entry associated with the Dart file
+ * @param descriptor the descriptor representing the data to be returned
+ * @return a cache entry containing the required data
+ * @throws AnalysisException if data could not be returned because the source could not be parsed
*/
DartEntry cacheDartVerificationData(Source unitSource, Source librarySource, DartEntry dartEntry, DataDescriptor descriptor) {
//
@@ -4712,12 +5046,12 @@ class AnalysisContextImpl implements InternalAnalysisContext {
String name = source.shortName;
if (AnalysisEngine.isHtmlFileName(name)) {
HtmlEntryImpl htmlEntry = new HtmlEntryImpl();
- htmlEntry.modificationTime = source.modificationStamp;
+ htmlEntry.modificationTime = getModificationStamp(source);
_cache.put(source, htmlEntry);
return htmlEntry;
} else {
DartEntryImpl dartEntry = new DartEntryImpl();
- dartEntry.modificationTime = source.modificationStamp;
+ dartEntry.modificationTime = getModificationStamp(source);
_cache.put(source, dartEntry);
return dartEntry;
}
@@ -4730,7 +5064,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* @param source the source for which a debugging string is to be produced
* @return debugging information about the given source
*/
- String debuggingString(Source source) => "'${source.fullName}' [${source.modificationStamp}]";
+ String debuggingString(Source source) => "'${source.fullName}' [${getModificationStamp(source)}]";
/**
* Return an array containing all of the change notices that are waiting to be returned. If there
@@ -4787,7 +5121,12 @@ class AnalysisContextImpl implements InternalAnalysisContext {
if (dartEntry == null) {
return defaultValue;
}
- return getDartDependencyData(source, dartEntry, descriptor);
+ try {
+ return getDartDependencyData(source, dartEntry, descriptor);
+ } on ObsoleteSourceAnalysisException catch (exception) {
+ AnalysisEngine.instance.logger.logInformation3("Could not compute ${descriptor.toString()}", exception);
+ return defaultValue;
+ }
}
/**
@@ -4847,7 +5186,12 @@ class AnalysisContextImpl implements InternalAnalysisContext {
if (dartEntry == null) {
return defaultValue;
}
- return getDartParseData(source, dartEntry, descriptor);
+ try {
+ return getDartParseData(source, dartEntry, descriptor);
+ } on ObsoleteSourceAnalysisException catch (exception) {
+ AnalysisEngine.instance.logger.logInformation3("Could not compute ${descriptor.toString()}", exception);
+ return defaultValue;
+ }
}
/**
@@ -4892,7 +5236,53 @@ class AnalysisContextImpl implements InternalAnalysisContext {
if (dartEntry == null) {
return defaultValue;
}
- return getDartResolutionData(unitSource, librarySource, dartEntry, descriptor);
+ try {
+ return getDartResolutionData(unitSource, librarySource, dartEntry, descriptor);
+ } on ObsoleteSourceAnalysisException catch (exception) {
+ AnalysisEngine.instance.logger.logInformation3("Could not compute ${descriptor.toString()}", exception);
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Given a source for a Dart file, return the data represented by the given descriptor that is
+ * associated with that source. This method assumes that the data can be produced by scanning the
+ * source if it is not already cached.
+ *
+ * @param source the source representing the Dart file
+ * @param dartEntry the cache entry associated with the Dart file
+ * @param descriptor the descriptor representing the data to be returned
+ * @return the requested data about the given source
+ * @throws AnalysisException if data could not be returned because the source could not be scanned
+ */
+ Object getDartScanData(Source source, DartEntry dartEntry, DataDescriptor descriptor) {
+ dartEntry = cacheDartScanData(source, dartEntry, descriptor);
+ return dartEntry.getValue(descriptor);
+ }
+
+ /**
+ * Given a source for a Dart file, return the data represented by the given descriptor that is
+ * associated with that source, or the given default value if the source is not a Dart file. This
+ * method assumes that the data can be produced by scanning the source if it is not already
+ * cached.
+ *
+ * @param source the source representing the Dart file
+ * @param descriptor the descriptor representing the data to be returned
+ * @param defaultValue the value to be returned if the source is not a Dart file
+ * @return the requested data about the given source
+ * @throws AnalysisException if data could not be returned because the source could not be scanned
+ */
+ Object getDartScanData2(Source source, DataDescriptor descriptor, Object defaultValue) {
+ DartEntry dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ return defaultValue;
+ }
+ try {
+ return getDartScanData(source, dartEntry, descriptor);
+ } on ObsoleteSourceAnalysisException catch (exception) {
+ AnalysisEngine.instance.logger.logInformation3("Could not compute ${descriptor.toString()}", exception);
+ return defaultValue;
+ }
}
/**
@@ -4955,7 +5345,12 @@ class AnalysisContextImpl implements InternalAnalysisContext {
if (htmlEntry == null) {
return defaultValue;
}
- return getHtmlResolutionData2(source, htmlEntry, descriptor);
+ try {
+ return getHtmlResolutionData2(source, htmlEntry, descriptor);
+ } on ObsoleteSourceAnalysisException catch (exception) {
+ AnalysisEngine.instance.logger.logInformation3("Could not compute ${descriptor.toString()}", exception);
+ return defaultValue;
+ }
}
/**
@@ -4987,6 +5382,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
AnalysisTask get nextAnalysisTask {
{
bool hintsEnabled = _options.hint;
+ bool sdkErrorsEnabled = _options.generateSdkErrors;
//
// Look for incremental analysis
//
@@ -4999,7 +5395,7 @@ 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);
+ AnalysisTask task = getNextAnalysisTask2(source, _cache.get(source), true, hintsEnabled, sdkErrorsEnabled);
if (task != null) {
return task;
}
@@ -5009,7 +5405,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
//
Source source = _workManager.nextSource;
while (source != null) {
- AnalysisTask task = getNextAnalysisTask2(source, _cache.get(source), false, hintsEnabled);
+ AnalysisTask task = getNextAnalysisTask2(source, _cache.get(source), false, hintsEnabled, sdkErrorsEnabled);
if (task != null) {
return task;
}
@@ -5042,11 +5438,29 @@ class AnalysisContextImpl implements InternalAnalysisContext {
* @param sourceEntry the cache entry associated with the source
* @param isPriority `true` if the source is a priority source
* @param hintsEnabled `true` if hints are currently enabled
+ * @param sdkErrorsEnabled `true` if errors, warnings and hints should be generated for
+ * 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) {
+ AnalysisTask getNextAnalysisTask2(Source source, SourceEntry sourceEntry, bool isPriority, bool hintsEnabled, bool sdkErrorsEnabled) {
if (sourceEntry is DartEntry) {
DartEntry dartEntry = sourceEntry;
+ CacheState scanErrorsState = dartEntry.getState(DartEntry.SCAN_ERRORS);
+ if (identical(scanErrorsState, CacheState.INVALID) || (isPriority && identical(scanErrorsState, CacheState.FLUSHED))) {
+ // TODO(brianwilkerson) Convert this to get the contents from the cache or to asynchronously
+ // request the contents if they are not in the cache.
+ try {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setState(DartEntry.SCAN_ERRORS, CacheState.IN_PROCESS);
+ _cache.put(source, dartCopy);
+ return new ScanDartTask(this, source, getContents(source));
+ } on JavaException catch (exception) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.recordScanError();
+ dartCopy.exception = new AnalysisException.con3(exception);
+ _cache.put(source, dartCopy);
+ }
+ }
CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
if (identical(parseErrorsState, CacheState.INVALID) || (isPriority && identical(parseErrorsState, CacheState.FLUSHED))) {
DartEntryImpl dartCopy = dartEntry.writableCopy;
@@ -5096,25 +5510,27 @@ class AnalysisContextImpl implements InternalAnalysisContext {
//return new ResolveDartUnitTask(this, source, libraryElement);
return new ResolveDartLibraryTask(this, source, librarySource);
}
- CacheState verificationErrorsState = dartEntry.getState2(DartEntry.VERIFICATION_ERRORS, librarySource);
- if (identical(verificationErrorsState, CacheState.INVALID) || (isPriority && identical(verificationErrorsState, CacheState.FLUSHED))) {
- LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
- if (libraryElement != null) {
- DartEntryImpl dartCopy = dartEntry.writableCopy;
- dartCopy.setState2(DartEntry.VERIFICATION_ERRORS, librarySource, CacheState.IN_PROCESS);
- _cache.put(source, dartCopy);
- return new GenerateDartErrorsTask(this, source, libraryElement);
- }
- }
- if (hintsEnabled) {
- CacheState hintsState = dartEntry.getState2(DartEntry.HINTS, librarySource);
- if (identical(hintsState, CacheState.INVALID) || (isPriority && identical(hintsState, CacheState.FLUSHED))) {
+ if (sdkErrorsEnabled || !source.isInSystemLibrary) {
+ CacheState verificationErrorsState = dartEntry.getState2(DartEntry.VERIFICATION_ERRORS, librarySource);
+ if (identical(verificationErrorsState, CacheState.INVALID) || (isPriority && identical(verificationErrorsState, CacheState.FLUSHED))) {
LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
if (libraryElement != null) {
DartEntryImpl dartCopy = dartEntry.writableCopy;
- dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.IN_PROCESS);
+ dartCopy.setState2(DartEntry.VERIFICATION_ERRORS, librarySource, CacheState.IN_PROCESS);
_cache.put(source, dartCopy);
- return new GenerateDartHintsTask(this, libraryElement);
+ return new GenerateDartErrorsTask(this, source, libraryElement);
+ }
+ }
+ if (hintsEnabled) {
+ CacheState hintsState = dartEntry.getState2(DartEntry.HINTS, librarySource);
+ if (identical(hintsState, CacheState.INVALID) || (isPriority && identical(hintsState, CacheState.FLUSHED))) {
+ LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
+ if (libraryElement != null) {
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setState2(DartEntry.HINTS, librarySource, CacheState.IN_PROCESS);
+ _cache.put(source, dartCopy);
+ return new GenerateDartHintsTask(this, libraryElement);
+ }
}
}
}
@@ -5145,29 +5561,26 @@ class AnalysisContextImpl implements InternalAnalysisContext {
_cache.put(source, htmlCopy);
return new ResolveHtmlTask(this, source);
}
+ // Angular support
if (_options.analyzeAngular) {
+ // try to resolve as an Angular entry point
+ CacheState angularEntryState = htmlEntry.getState(HtmlEntry.ANGULAR_ENTRY);
+ if (identical(angularEntryState, CacheState.INVALID)) {
+ HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+ htmlCopy.setState(HtmlEntry.ANGULAR_ENTRY, CacheState.IN_PROCESS);
+ _cache.put(source, htmlCopy);
+ return new ResolveAngularEntryHtmlTask(this, source);
+ }
+ // try to resolve as an Angular application part
CacheState angularErrorsState = htmlEntry.getState(HtmlEntry.ANGULAR_ERRORS);
if (identical(angularErrorsState, CacheState.INVALID)) {
- AngularApplicationInfo entryInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_ENTRY);
- if (entryInfo != null) {
- HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
- htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.IN_PROCESS);
- _cache.put(source, htmlCopy);
- return new ResolveAngularEntryHtmlTask(this, source, entryInfo);
- }
- AngularApplicationInfo applicationInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_APPLICATION);
- if (applicationInfo != null) {
- AngularComponentElement component = htmlEntry.getValue(HtmlEntry.ANGULAR_COMPONENT);
- if (component != null) {
- HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
- htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.IN_PROCESS);
- _cache.put(source, htmlCopy);
- return new ResolveAngularComponentTemplateTask(this, source, component, applicationInfo);
- }
- }
+ AngularApplication application = htmlEntry.getValue(HtmlEntry.ANGULAR_APPLICATION);
+ // try to resolve as an Angular template
+ AngularComponentElement component = htmlEntry.getValue(HtmlEntry.ANGULAR_COMPONENT);
HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
- htmlCopy.setValue(HtmlEntry.ANGULAR_ERRORS, AnalysisError.NO_ERRORS);
+ htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.IN_PROCESS);
_cache.put(source, htmlCopy);
+ return new ResolveAngularComponentTemplateTask(this, source, component, application);
}
}
}
@@ -5282,6 +5695,11 @@ class AnalysisContextImpl implements InternalAnalysisContext {
void getSourcesNeedingProcessing2(Source source, SourceEntry sourceEntry, bool isPriority, bool hintsEnabled, Set<Source> sources) {
if (sourceEntry is DartEntry) {
DartEntry dartEntry = sourceEntry;
+ CacheState scanErrorsState = dartEntry.getState(DartEntry.SCAN_ERRORS);
+ if (identical(scanErrorsState, CacheState.INVALID) || (isPriority && identical(scanErrorsState, CacheState.FLUSHED))) {
+ sources.add(source);
+ return;
+ }
CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
if (identical(parseErrorsState, CacheState.INVALID) || (isPriority && identical(parseErrorsState, CacheState.FLUSHED))) {
sources.add(source);
@@ -5342,15 +5760,16 @@ class AnalysisContextImpl implements InternalAnalysisContext {
sources.add(source);
return;
}
+ // Angular
if (_options.analyzeAngular) {
CacheState angularErrorsState = htmlEntry.getState(HtmlEntry.ANGULAR_ERRORS);
if (identical(angularErrorsState, CacheState.INVALID)) {
- AngularApplicationInfo entryInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_ENTRY);
+ AngularApplication entryInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_ENTRY);
if (entryInfo != null) {
sources.add(source);
return;
}
- AngularApplicationInfo applicationInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_APPLICATION);
+ AngularApplication applicationInfo = htmlEntry.getValue(HtmlEntry.ANGULAR_APPLICATION);
if (applicationInfo != null) {
AngularComponentElement component = htmlEntry.getValue(HtmlEntry.ANGULAR_COMPONENT);
if (component != null) {
@@ -5388,6 +5807,55 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
/**
+ * In response to a change to Angular entry point [HtmlElement], invalidate any results that
+ * depend on it.
+ *
+ * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
+ *
+ * <b>Note:</b> Any cache entries that were accessed before this method was invoked must be
+ * re-accessed after this method returns.
+ *
+ * @param entryCopy the [HtmlEntryImpl] of the (maybe) Angular entry point being invalidated
+ */
+ void invalidateAngularResolution(HtmlEntryImpl entryCopy) {
+ AngularApplication application = entryCopy.getValue(HtmlEntry.ANGULAR_ENTRY);
+ if (application == null) {
+ return;
+ }
+ _angularApplications.remove(application);
+ // invalidate Entry
+ entryCopy.setState(HtmlEntry.ANGULAR_ENTRY, CacheState.INVALID);
+ // reset HTML sources
+ List<AngularElement> oldAngularElements = application.elements;
+ for (AngularElement angularElement in oldAngularElements) {
+ if (angularElement is AngularHasTemplateElement) {
+ AngularHasTemplateElement hasTemplate = angularElement;
+ Source templateSource = hasTemplate.templateSource;
+ if (templateSource != null) {
+ HtmlEntry htmlEntry = getReadableHtmlEntry(templateSource);
+ HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+ htmlCopy.setValue(HtmlEntry.ANGULAR_APPLICATION, null);
+ htmlCopy.setValue(HtmlEntry.ANGULAR_COMPONENT, null);
+ htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.INVALID);
+ _cache.put(templateSource, htmlCopy);
+ _workManager.add(templateSource, SourcePriority.HTML);
+ }
+ }
+ }
+ // reset Dart sources
+ List<Source> oldElementSources = application.elementSources;
+ for (Source elementSource in oldElementSources) {
+ DartEntry dartEntry = getReadableDartEntry(elementSource);
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setValue(DartEntry.ANGULAR_ERRORS, AnalysisError.NO_ERRORS);
+ _cache.put(elementSource, dartCopy);
+ // notify about (disappeared) Angular errors
+ ChangeNoticeImpl notice = getNotice(elementSource);
+ notice.setErrors(dartCopy.allErrors, dartEntry.getValue(SourceEntry.LINE_INFO));
+ }
+ }
+
+ /**
* In response to a change to at least one of the compilation units in the given library,
* invalidate any results that are dependent on the result of resolving that library.
*
@@ -5431,6 +5899,18 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
}
}
+ // invalidate Angular applications
+ List<AngularApplication> angularApplicationsCopy = [];
+ for (AngularApplication application in angularApplicationsCopy) {
+ if (application.dependsOn(librarySource)) {
+ Source entryPointSource = application.entryPoint;
+ HtmlEntry entry = getReadableHtmlEntry(entryPointSource);
+ HtmlEntryImpl entryCopy = entry.writableCopy;
+ invalidateAngularResolution(entryCopy);
+ _cache.put(entryPointSource, entryCopy);
+ _workManager.add(entryPointSource, SourcePriority.HTML);
+ }
+ }
}
/**
@@ -5486,59 +5966,49 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
/**
- * Updates [HtmlEntry]s that correspond to the previously known and new Angular components.
- *
- * @param library the [Library] that was resolved
- * @param dartCopy the [DartEntryImpl] to record new Angular components
+ * Updates [HtmlEntry]s that correspond to the previously known and new Angular application
+ * information.
*/
- void recordAngularComponents(HtmlEntryImpl entry, AngularApplicationInfo app) {
- if (!_options.analyzeAngular) {
- return;
- }
- // reset old Angular errors
- AngularApplicationInfo oldApp = entry.getValue(HtmlEntry.ANGULAR_ENTRY);
- if (oldApp != null) {
- List<AngularElement> oldAngularElements = oldApp.elements;
- for (AngularElement angularElement in oldAngularElements) {
- if (angularElement is AngularComponentElement) {
- AngularComponentElement component = angularElement;
- Source templateSource = component.templateSource;
- if (templateSource != null) {
- HtmlEntry htmlEntry = getReadableHtmlEntry(templateSource);
- HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
- htmlCopy.setValue(HtmlEntry.ANGULAR_APPLICATION, null);
- htmlCopy.setValue(HtmlEntry.ANGULAR_COMPONENT, null);
- htmlCopy.setValue(HtmlEntry.ANGULAR_ERRORS, AnalysisError.NO_ERRORS);
- _cache.put(templateSource, htmlCopy);
- // notify about (disappeared) HTML errors
- ChangeNoticeImpl notice = getNotice(templateSource);
- notice.setErrors(htmlCopy.allErrors, computeLineInfo(templateSource));
- }
- }
- }
- }
- // prepare for new Angular analysis
- if (app != null) {
- List<AngularElement> newAngularElements = app.elements;
+ void recordAngularEntryPoint(HtmlEntryImpl entry, ResolveAngularEntryHtmlTask task) {
+ AngularApplication application = task.application;
+ if (application != null) {
+ _angularApplications.add(application);
+ // if this is an entry point, then we already resolved it
+ entry.setValue(HtmlEntry.ANGULAR_ERRORS, task.entryErrors);
+ // schedule HTML templates analysis
+ List<AngularElement> newAngularElements = application.elements;
for (AngularElement angularElement in newAngularElements) {
- if (angularElement is AngularComponentElement) {
- AngularComponentElement component = angularElement;
- Source templateSource = component.templateSource;
+ if (angularElement is AngularHasTemplateElement) {
+ AngularHasTemplateElement hasTemplate = angularElement;
+ Source templateSource = hasTemplate.templateSource;
if (templateSource != null) {
HtmlEntry htmlEntry = getReadableHtmlEntry(templateSource);
HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
- htmlCopy.setValue(HtmlEntry.ANGULAR_APPLICATION, app);
- htmlCopy.setValue(HtmlEntry.ANGULAR_COMPONENT, component);
+ htmlCopy.setValue(HtmlEntry.ANGULAR_APPLICATION, application);
+ if (hasTemplate is AngularComponentElement) {
+ AngularComponentElement component = hasTemplate;
+ htmlCopy.setValue(HtmlEntry.ANGULAR_COMPONENT, component);
+ }
htmlCopy.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.INVALID);
_cache.put(templateSource, htmlCopy);
_workManager.add(templateSource, SourcePriority.HTML);
}
}
}
+ // update Dart sources errors
+ List<Source> newElementSources = application.elementSources;
+ for (Source elementSource in newElementSources) {
+ DartEntry dartEntry = getReadableDartEntry(elementSource);
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ dartCopy.setValue(DartEntry.ANGULAR_ERRORS, task.getErrors(elementSource));
+ _cache.put(elementSource, dartCopy);
+ // notify about Dart errors
+ ChangeNoticeImpl notice = getNotice(elementSource);
+ notice.setErrors(dartCopy.allErrors, computeLineInfo(elementSource));
+ }
}
- // remember Angular application
- entry.setValue(HtmlEntry.ANGULAR_ENTRY, app);
- entry.setState(HtmlEntry.ANGULAR_ERRORS, CacheState.INVALID);
+ // remember Angular entry point
+ entry.setValue(HtmlEntry.ANGULAR_ENTRY, application);
}
/**
@@ -5591,13 +6061,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
DartEntry dartEntry = null;
{
SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry is! DartEntry) {
+ if (sourceEntry == null) {
+ throw new ObsoleteSourceAnalysisException(source);
+ } else if (sourceEntry is! DartEntry) {
// This shouldn't be possible because we should never have performed the task if the source
// didn't represent a Dart file, but check to be safe.
throw new AnalysisException.con1("Internal error: attempting to verify non-Dart file as a Dart file: ${source.fullName}");
}
dartEntry = sourceEntry as DartEntry;
- int sourceTime = source.modificationStamp;
+ int sourceTime = getModificationStamp(source);
int resultTime = task.modificationTime;
if (sourceTime == resultTime) {
if (dartEntry.modificationTime != sourceTime) {
@@ -5670,7 +6142,9 @@ class AnalysisContextImpl implements InternalAnalysisContext {
// We don't have any information about which sources to mark as invalid other than the library
// source.
SourceEntry sourceEntry = _cache.get(librarySource);
- if (sourceEntry is! DartEntry) {
+ if (sourceEntry == null) {
+ throw new ObsoleteSourceAnalysisException(librarySource);
+ } else if (sourceEntry is! DartEntry) {
// This shouldn't be possible because we should never have performed the task if the source
// didn't represent a Dart file, but check to be safe.
throw new AnalysisException.con1("Internal error: attempting to generate hints for non-Dart file as a Dart file: ${librarySource.fullName}");
@@ -5699,7 +6173,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
if (unitSource == librarySource) {
libraryEntry = dartEntry;
}
- int sourceTime = unitSource.modificationStamp;
+ int sourceTime = getModificationStamp(unitSource);
int resultTime = results.modificationTime;
if (sourceTime == resultTime) {
if (dartEntry.modificationTime != sourceTime) {
@@ -5790,13 +6264,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
DartEntry dartEntry = null;
{
SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry is! DartEntry) {
+ if (sourceEntry == null) {
+ throw new ObsoleteSourceAnalysisException(source);
+ } else if (sourceEntry is! DartEntry) {
// This shouldn't be possible because we should never have performed the task if the source
// didn't represent a Dart file, but check to be safe.
throw new AnalysisException.con1("Internal error: attempting to parse non-Dart file as a Dart file: ${source.fullName}");
}
dartEntry = sourceEntry as DartEntry;
- int sourceTime = source.modificationStamp;
+ int sourceTime = getModificationStamp(source);
int resultTime = task.modificationTime;
if (sourceTime == resultTime) {
if (dartEntry.modificationTime != sourceTime) {
@@ -5809,10 +6285,9 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
DartEntryImpl dartCopy = dartEntry.writableCopy;
if (thrownException == null) {
- LineInfo lineInfo = task.lineInfo;
- dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
if (task.hasPartOfDirective() && !task.hasLibraryDirective()) {
dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.PART);
+ dartCopy.removeContainingLibrary(source);
_workManager.add(source, SourcePriority.NORMAL_PART);
} else {
dartCopy.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
@@ -5823,7 +6298,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
dartCopy.setValue(DartEntry.PARSE_ERRORS, task.errors);
_cache.storedAst(source);
ChangeNoticeImpl notice = getNotice(source);
- notice.setErrors(dartEntry.allErrors, lineInfo);
+ notice.setErrors(dartCopy.allErrors, dartCopy.getValue(SourceEntry.LINE_INFO));
// Verify that the incrementally parsed and resolved unit in the incremental cache
// is structurally equivalent to the fully parsed unit
_incrementalAnalysisCache = IncrementalAnalysisCache.verifyStructure(_incrementalAnalysisCache, source, task.compilationUnit);
@@ -5882,13 +6357,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
HtmlEntry htmlEntry = null;
{
SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry is! HtmlEntry) {
+ if (sourceEntry == null) {
+ throw new ObsoleteSourceAnalysisException(source);
+ } else if (sourceEntry is! HtmlEntry) {
// This shouldn't be possible because we should never have performed the task if the source
// didn't represent an HTML file, but check to be safe.
throw new AnalysisException.con1("Internal error: attempting to parse non-HTML file as a HTML file: ${source.fullName}");
}
htmlEntry = sourceEntry as HtmlEntry;
- int sourceTime = source.modificationStamp;
+ int sourceTime = getModificationStamp(source);
int resultTime = task.modificationTime;
if (sourceTime == resultTime) {
if (htmlEntry.modificationTime != sourceTime) {
@@ -5909,7 +6386,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
htmlCopy.setValue(HtmlEntry.REFERENCED_LIBRARIES, task.referencedLibraries);
_cache.storedAst(source);
ChangeNoticeImpl notice = getNotice(source);
- notice.setErrors(htmlEntry.allErrors, lineInfo);
+ notice.setErrors(htmlCopy.allErrors, lineInfo);
} else {
htmlCopy.recordParseError();
_cache.removedAst(source);
@@ -5972,13 +6449,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
HtmlEntry htmlEntry = null;
{
SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry is! HtmlEntry) {
+ if (sourceEntry == null) {
+ throw new ObsoleteSourceAnalysisException(source);
+ } else if (sourceEntry is! HtmlEntry) {
// This shouldn't be possible because we should never have performed the task if the source
// didn't represent an HTML file, but check to be safe.
throw new AnalysisException.con1("Internal error: attempting to resolve non-HTML file as an HTML file: ${source.fullName}");
}
htmlEntry = sourceEntry as HtmlEntry;
- int sourceTime = source.modificationStamp;
+ int sourceTime = getModificationStamp(source);
int resultTime = task.modificationTime;
if (sourceTime == resultTime) {
if (htmlEntry.modificationTime != sourceTime) {
@@ -5992,6 +6471,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
if (thrownException == null) {
htmlCopy.setValue(HtmlEntry.ANGULAR_ERRORS, task.resolutionErrors);
+ // notify about errors
ChangeNoticeImpl notice = getNotice(source);
notice.htmlUnit = task.resolvedUnit;
notice.setErrors(htmlCopy.allErrors, htmlCopy.getValue(SourceEntry.LINE_INFO));
@@ -6052,13 +6532,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
HtmlEntry htmlEntry = null;
{
SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry is! HtmlEntry) {
+ if (sourceEntry == null) {
+ throw new ObsoleteSourceAnalysisException(source);
+ } else if (sourceEntry is! HtmlEntry) {
// This shouldn't be possible because we should never have performed the task if the source
// didn't represent an HTML file, but check to be safe.
throw new AnalysisException.con1("Internal error: attempting to resolve non-HTML file as an HTML file: ${source.fullName}");
}
htmlEntry = sourceEntry as HtmlEntry;
- int sourceTime = source.modificationStamp;
+ int sourceTime = getModificationStamp(source);
int resultTime = task.modificationTime;
if (sourceTime == resultTime) {
if (htmlEntry.modificationTime != sourceTime) {
@@ -6071,7 +6553,9 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
if (thrownException == null) {
- htmlCopy.setValue(HtmlEntry.ANGULAR_ERRORS, task.resolutionErrors);
+ htmlCopy.setValue(HtmlEntry.RESOLVED_UNIT, task.resolvedUnit);
+ recordAngularEntryPoint(htmlCopy, task);
+ _cache.storedAst(source);
ChangeNoticeImpl notice = getNotice(source);
notice.htmlUnit = task.resolvedUnit;
notice.setErrors(htmlCopy.allErrors, htmlCopy.getValue(SourceEntry.LINE_INFO));
@@ -6133,13 +6617,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
DartEntry dartEntry = null;
{
SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry is! DartEntry) {
+ if (sourceEntry == null) {
+ throw new ObsoleteSourceAnalysisException(source);
+ } else if (sourceEntry is! DartEntry) {
// This shouldn't be possible because we should never have performed the task if the source
// didn't represent a Dart file, but check to be safe.
throw new AnalysisException.con1("Internal error: attempting to resolve Dart dependencies in a non-Dart file: ${source.fullName}");
}
dartEntry = sourceEntry as DartEntry;
- int sourceTime = source.modificationStamp;
+ int sourceTime = getModificationStamp(source);
int resultTime = task.modificationTime;
if (sourceTime == resultTime) {
if (dartEntry.modificationTime != sourceTime) {
@@ -6222,13 +6708,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
DartEntry dartEntry = null;
{
SourceEntry sourceEntry = _cache.get(unitSource);
- if (sourceEntry is! DartEntry) {
+ if (sourceEntry == null) {
+ throw new ObsoleteSourceAnalysisException(unitSource);
+ } else if (sourceEntry is! DartEntry) {
// This shouldn't be possible because we should never have performed the task if the source
// didn't represent a Dart file, but check to be safe.
throw new AnalysisException.con1("Internal error: attempting to resolve non-Dart file as a Dart file: ${unitSource.fullName}");
}
dartEntry = sourceEntry as DartEntry;
- int sourceTime = unitSource.modificationStamp;
+ int sourceTime = getModificationStamp(unitSource);
int resultTime = task.modificationTime;
if (sourceTime == resultTime) {
if (dartEntry.modificationTime != sourceTime) {
@@ -6299,13 +6787,15 @@ class AnalysisContextImpl implements InternalAnalysisContext {
HtmlEntry htmlEntry = null;
{
SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry is! HtmlEntry) {
+ if (sourceEntry == null) {
+ throw new ObsoleteSourceAnalysisException(source);
+ } else if (sourceEntry is! HtmlEntry) {
// This shouldn't be possible because we should never have performed the task if the source
// didn't represent an HTML file, but check to be safe.
throw new AnalysisException.con1("Internal error: attempting to resolve non-HTML file as an HTML file: ${source.fullName}");
}
htmlEntry = sourceEntry as HtmlEntry;
- int sourceTime = source.modificationStamp;
+ int sourceTime = getModificationStamp(source);
int resultTime = task.modificationTime;
if (sourceTime == resultTime) {
if (htmlEntry.modificationTime != sourceTime) {
@@ -6331,7 +6821,6 @@ class AnalysisContextImpl implements InternalAnalysisContext {
_cache.removedAst(source);
}
htmlCopy.exception = thrownException;
- recordAngularComponents(htmlCopy, task.angularApplication);
_cache.put(source, htmlCopy);
htmlEntry = htmlCopy;
} else {
@@ -6371,6 +6860,90 @@ class AnalysisContextImpl implements InternalAnalysisContext {
}
/**
+ * Record the results produced by performing a [ScanDartTask]. If the results were computed
+ * from data that is now out-of-date, then the results will not be recorded.
+ *
+ * @param task the task that was performed
+ * @return an entry containing the computed results
+ * @throws AnalysisException if the results could not be recorded
+ */
+ DartEntry recordScanDartTaskResults(ScanDartTask task) {
+ Source source = task.source;
+ AnalysisException thrownException = task.exception;
+ DartEntry dartEntry = null;
+ {
+ SourceEntry sourceEntry = _cache.get(source);
+ if (sourceEntry == null) {
+ throw new ObsoleteSourceAnalysisException(source);
+ } else if (sourceEntry is! DartEntry) {
+ // This shouldn't be possible because we should never have performed the task if the source
+ // didn't represent a Dart file, but check to be safe.
+ throw new AnalysisException.con1("Internal error: attempting to parse non-Dart file as a Dart file: ${source.fullName}");
+ }
+ dartEntry = sourceEntry as DartEntry;
+ int sourceTime = getModificationStamp(source);
+ int resultTime = task.modificationTime;
+ if (sourceTime == resultTime) {
+ if (dartEntry.modificationTime != sourceTime) {
+ // The source has changed without the context being notified. Simulate notification.
+ sourceChanged(source);
+ dartEntry = getReadableDartEntry(source);
+ if (dartEntry == null) {
+ throw new AnalysisException.con1("A Dart file became a non-Dart file: ${source.fullName}");
+ }
+ }
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null) {
+ LineInfo lineInfo = task.lineInfo;
+ dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
+ dartCopy.setValue(DartEntry.TOKEN_STREAM, task.tokenStream);
+ dartCopy.setValue(DartEntry.SCAN_ERRORS, task.errors);
+ _cache.storedAst(source);
+ _workManager.add(source, SourcePriority.NORMAL_PART);
+ ChangeNoticeImpl notice = getNotice(source);
+ notice.setErrors(dartEntry.allErrors, lineInfo);
+ } else {
+ removeFromParts(source, dartEntry);
+ dartCopy.recordScanError();
+ _cache.removedAst(source);
+ }
+ dartCopy.exception = thrownException;
+ _cache.put(source, dartCopy);
+ dartEntry = dartCopy;
+ } else {
+ logInformation2("Scan results discarded for ${debuggingString(source)}; sourceTime = ${sourceTime}, resultTime = ${resultTime}, cacheTime = ${dartEntry.modificationTime}", thrownException);
+ DartEntryImpl dartCopy = dartEntry.writableCopy;
+ if (thrownException == null || resultTime >= 0) {
+ //
+ // The analysis was performed on out-of-date sources. Mark the cache so that the sources
+ // will be re-analyzed using the up-to-date sources.
+ //
+ // dartCopy.recordScanNotInProcess();
+ removeFromParts(source, dartEntry);
+ dartCopy.invalidateAllInformation();
+ dartCopy.modificationTime = sourceTime;
+ _cache.removedAst(source);
+ _workManager.add(source, SourcePriority.UNKNOWN);
+ } else {
+ //
+ // We could not determine whether the sources were up-to-date or out-of-date. Mark the
+ // cache so that we won't attempt to re-analyze the sources until there's a good chance
+ // that we'll be able to do so without error.
+ //
+ dartCopy.recordScanError();
+ }
+ dartCopy.exception = thrownException;
+ _cache.put(source, dartCopy);
+ dartEntry = dartCopy;
+ }
+ }
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ return dartEntry;
+ }
+
+ /**
* Remove the given library from the list of containing libraries for all of the parts referenced
* by the given entry.
*
@@ -6427,7 +7000,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
} else {
SourceEntryImpl sourceCopy = sourceEntry.writableCopy;
int oldTime = sourceCopy.modificationTime;
- sourceCopy.modificationTime = source.modificationStamp;
+ sourceCopy.modificationTime = getModificationStamp(source);
// TODO(brianwilkerson) Understand why we're not invalidating the cache.
_cache.put(source, sourceCopy);
logInformation("Added new source: ${debuggingString(source)} (previously modified at ${oldTime})");
@@ -6447,7 +7020,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
*/
void sourceChanged(Source source) {
SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry == null || sourceEntry.modificationTime == source.modificationStamp) {
+ if (sourceEntry == null || sourceEntry.modificationTime == getModificationStamp(source)) {
// Either we have removed this source, in which case we don't care that it is changed, or we
// have already invalidated the cache and don't need to invalidate it again.
if (sourceEntry == null) {
@@ -6460,7 +7033,8 @@ class AnalysisContextImpl implements InternalAnalysisContext {
if (sourceEntry is HtmlEntry) {
HtmlEntryImpl htmlCopy = sourceEntry.writableCopy;
int oldTime = htmlCopy.modificationTime;
- htmlCopy.modificationTime = source.modificationStamp;
+ htmlCopy.modificationTime = getModificationStamp(source);
+ invalidateAngularResolution(htmlCopy);
htmlCopy.invalidateAllInformation();
_cache.put(source, htmlCopy);
_cache.removedAst(source);
@@ -6482,9 +7056,9 @@ class AnalysisContextImpl implements InternalAnalysisContext {
// for (Source library : containingLibraries) {
invalidateLibraryResolution(library, writer);
}
- removeFromParts(source, sourceEntry);
- DartEntryImpl dartCopy = sourceEntry.writableCopy;
- dartCopy.modificationTime = source.modificationStamp;
+ removeFromParts(source, _cache.get(source) as DartEntry);
+ DartEntryImpl dartCopy = (_cache.get(source) as DartEntry).writableCopy;
+ dartCopy.modificationTime = getModificationStamp(source);
dartCopy.invalidateAllInformation();
_cache.put(source, dartCopy);
_cache.removedAst(source);
@@ -6502,7 +7076,10 @@ class AnalysisContextImpl implements InternalAnalysisContext {
PrintStringWriter writer = new PrintStringWriter();
writer.println("Removed source: ${debuggingString(source)}");
SourceEntry sourceEntry = _cache.get(source);
- if (sourceEntry is DartEntry) {
+ if (sourceEntry is HtmlEntry) {
+ HtmlEntryImpl htmlCopy = sourceEntry.writableCopy;
+ invalidateAngularResolution(htmlCopy);
+ } else if (sourceEntry is DartEntry) {
Set<Source> libraries = new Set<Source>();
for (Source librarySource in getLibrariesContaining(source)) {
libraries.add(librarySource);
@@ -6537,13 +7114,13 @@ class AnalysisContextImpl implements InternalAnalysisContext {
for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
Source source = entry.getKey();
SourceEntry sourceEntry = entry.getValue();
- int sourceTime = source.modificationStamp;
+ int sourceTime = getModificationStamp(source);
if (sourceTime != sourceEntry.modificationTime) {
sourceChanged(source);
inconsistentCount++;
}
if (sourceEntry.exception != null) {
- if (!source.exists()) {
+ if (!exists(source)) {
missingSources.add(source);
}
}
@@ -6599,6 +7176,8 @@ class AnalysisContextImpl_AnalysisTaskResultRecorder implements AnalysisTaskVisi
SourceEntry visitResolveDartUnitTask(ResolveDartUnitTask task) => AnalysisContextImpl_this.recordResolveDartUnitTaskResults(task);
SourceEntry visitResolveHtmlTask(ResolveHtmlTask task) => AnalysisContextImpl_this.recordResolveHtmlTaskResults(task);
+
+ SourceEntry visitScanDartTask(ScanDartTask task) => AnalysisContextImpl_this.recordScanDartTaskResults(task);
}
class AnalysisContextImpl_ContextRetentionPolicy implements CacheRetentionPolicy {
@@ -6674,6 +7253,12 @@ class AnalysisOptionsImpl implements AnalysisOptions {
bool dart2jsHint = true;
/**
+ * A flag indicating whether errors, warnings and hints should be generated for sources in the
+ * SDK.
+ */
+ bool _generateSdkErrors = false;
+
+ /**
* A flag indicating whether analysis is to generate hint results (e.g. type inference based
* information and pub best practices).
*/
@@ -6690,7 +7275,7 @@ class AnalysisOptionsImpl implements AnalysisOptions {
bool preserveComments = true;
/**
- * A flag indicating whether analysis is to parse comments.
+ * A flag indicating whether analysis is to analyze Angular.
*/
bool analyzeAngular = true;
@@ -6710,7 +7295,19 @@ class AnalysisOptionsImpl implements AnalysisOptions {
dart2jsHint = options.dart2jsHint;
hint = options.hint;
incremental = options.incremental;
- analyzeAngular = options.analyzeAngular;
+ }
+
+ bool get generateSdkErrors => _generateSdkErrors;
+
+ /**
+ * Set whether errors, warnings and hints should be generated for sources in the SDK to match the
+ * given value.
+ *
+ * @param generate `true` if errors, warnings and hints should be generated for sources in
+ * the SDK
+ */
+ void set generateSdkErrors(bool generate) {
+ _generateSdkErrors = generate;
}
}
@@ -6776,7 +7373,7 @@ class ChangeNoticeImpl implements ChangeNotice {
this._errors = errors;
this._lineInfo = lineInfo;
if (lineInfo == null) {
- AnalysisEngine.instance.logger.logError2("No line info: ${source}", new JavaException());
+ AnalysisEngine.instance.logger.logInformation3("No line info: ${source}", new JavaException());
}
}
@@ -7326,15 +7923,7 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext {
}
}
- List<Source> computeExportedLibraries(Source source) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeExportedLibraries");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.computeExportedLibraries(source);
- } finally {
- instrumentation.log();
- }
- }
+ List<Source> computeExportedLibraries(Source source) => _basis.computeExportedLibraries(source);
HtmlElement computeHtmlElement(Source source) {
InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeHtmlElement");
@@ -7349,15 +7938,7 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext {
}
}
- List<Source> computeImportedLibraries(Source source) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeImportedLibraries");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.computeImportedLibraries(source);
- } finally {
- instrumentation.log();
- }
- }
+ List<Source> computeImportedLibraries(Source source) => _basis.computeImportedLibraries(source);
SourceKind computeKindOf(Source source) {
InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-computeKindOf");
@@ -7401,6 +7982,16 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext {
ResolvableHtmlUnit computeResolvableHtmlUnit(Source source) => _basis.computeResolvableHtmlUnit(source);
+ bool exists(Source source) {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-exists");
+ try {
+ instrumentation.metric3("contextId", _contextId);
+ return _basis.exists(source);
+ } finally {
+ instrumentation.log();
+ }
+ }
+
AnalysisContext extractContext(SourceContainer container) {
InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-extractContext");
try {
@@ -7430,6 +8021,22 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext {
*/
AnalysisContext get basis => _basis;
+ CompilationUnitElement getCompilationUnitElement(Source unitSource, Source librarySource) {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getCompilationUnitElement");
+ try {
+ instrumentation.metric3("contextId", _contextId);
+ return _basis.getCompilationUnitElement(unitSource, librarySource);
+ } finally {
+ instrumentation.log();
+ }
+ }
+
+ TimestampedData<String> getContents(Source source) => _basis.getContents(source);
+
+ void getContents2(Source source, Source_ContentReceiver receiver) {
+ _basis.getContents2(source, receiver);
+ }
+
Element getElement(ElementLocation location) {
InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getElement");
try {
@@ -7582,11 +8189,21 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext {
}
}
- LineInfo getLineInfo(Source source) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getLineInfo");
+ LineInfo getLineInfo(Source source) {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getLineInfo");
+ try {
+ instrumentation.metric3("contextId", _contextId);
+ return _basis.getLineInfo(source);
+ } finally {
+ instrumentation.log();
+ }
+ }
+
+ int getModificationStamp(Source source) {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getModificationStamp");
try {
instrumentation.metric3("contextId", _contextId);
- return _basis.getLineInfo(source);
+ return _basis.getModificationStamp(source);
} finally {
instrumentation.log();
}
@@ -7596,7 +8213,15 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext {
Namespace getPublicNamespace2(Source source) => _basis.getPublicNamespace2(source);
- List<Source> get refactoringUnsafeSources => _basis.refactoringUnsafeSources;
+ List<Source> get refactoringUnsafeSources {
+ InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getRefactoringUnsafeSources");
+ try {
+ instrumentation.metric3("contextId", _contextId);
+ return _basis.refactoringUnsafeSources;
+ } finally {
+ instrumentation.log();
+ }
+ }
CompilationUnit getResolvedCompilationUnit(Source unitSource, LibraryElement library) {
InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-getResolvedCompilationUnit");
@@ -7642,8 +8267,12 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext {
TypeProvider get typeProvider => _basis.typeProvider;
+ TimestampedData<CompilationUnit> internalParseCompilationUnit(Source source) => _basis.internalParseCompilationUnit(source);
+
TimestampedData<CompilationUnit> internalResolveCompilationUnit(Source unitSource, LibraryElement libraryElement) => _basis.internalResolveCompilationUnit(unitSource, libraryElement);
+ TimestampedData<Token> internalScanTokenStream(Source source) => _basis.internalScanTokenStream(source);
+
bool isClientLibrary(Source librarySource) {
InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-isClientLibrary");
try {
@@ -7809,16 +8438,6 @@ class InstrumentedAnalysisContextImpl implements InternalAnalysisContext {
instrumentation.log();
}
}
-
- Iterable<Source> sourcesToResolve(List<Source> changedSources) {
- InstrumentationBuilder instrumentation = Instrumentation.builder2("Analysis-sourcesToResolve");
- try {
- instrumentation.metric3("contextId", _contextId);
- return _basis.sourcesToResolve(changedSources);
- } finally {
- instrumentation.log();
- }
- }
}
/**
@@ -7932,6 +8551,15 @@ abstract class InternalAnalysisContext implements AnalysisContext {
TypeProvider get typeProvider;
/**
+ * Return a time-stamped parsed AST for the given source.
+ *
+ * @param source the source of the compilation unit for which an AST is to be returned
+ * @return a time-stamped AST for the source
+ * @throws AnalysisException if the source could not be parsed
+ */
+ TimestampedData<CompilationUnit> internalParseCompilationUnit(Source source);
+
+ /**
* Return a time-stamped fully-resolved compilation unit for the given source in the given
* library.
*
@@ -7945,6 +8573,15 @@ abstract class InternalAnalysisContext implements AnalysisContext {
TimestampedData<CompilationUnit> internalResolveCompilationUnit(Source unitSource, LibraryElement libraryElement);
/**
+ * Return a time-stamped token stream for the given source.
+ *
+ * @param source the source of the compilation unit for which a token stream is to be returned
+ * @return a time-stamped token stream for the source
+ * @throws AnalysisException if the token stream could not be computed
+ */
+ TimestampedData<Token> internalScanTokenStream(Source source);
+
+ /**
* Given a table mapping the source for the libraries represented by the corresponding elements to
* the elements representing the libraries, record those mappings.
*
@@ -8467,21 +9104,6 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
}
/**
- * Returns the array of all top-level Angular elements that could be used in the application with
- * this entry point. Maybe `null` of not an Angular entry point.
- */
- static List<AngularElement> getAngularElements(AnalysisContext context, ht.HtmlUnit unit) {
- if (hasAngularAnnotation(unit)) {
- CompilationUnit dartUnit = getDartUnit(context, unit);
- if (dartUnit != null) {
- LibraryElement libraryElement = dartUnit.element.library;
- return getAngularElements2(libraryElement);
- }
- }
- return null;
- }
-
- /**
* @return `true` if the given [HtmlUnit] has <code>ng-app</code> annotation.
*/
static bool hasAngularAnnotation(ht.HtmlUnit htmlUnit) {
@@ -8519,11 +9141,15 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
* @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) {
+ if (library == null) {
+ return;
+ }
if (!visited.add(library)) {
return;
}
// add Angular elements from current library
for (CompilationUnitElement unit in library.units) {
+ angularElements.addAll(unit.angularViews);
for (ClassElement type in unit.types) {
addAngularElements(angularElements, type);
}
@@ -8543,9 +9169,9 @@ 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 List<AngularElement> getAngularElements2(LibraryElement libraryElement) {
+ static List<AngularElement> getAngularElements(Set<LibraryElement> libraries, LibraryElement libraryElement) {
Set<AngularElement> angularElements = new Set();
- addAngularElements2(angularElements, libraryElement, new Set());
+ addAngularElements2(angularElements, libraryElement, libraries);
return new List.from(angularElements);
}
@@ -8564,11 +9190,19 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
return null;
}
+ static Set<Source> getLibrarySources(Set<LibraryElement> libraries) {
+ Set<Source> sources = new Set();
+ for (LibraryElement library in libraries) {
+ sources.add(library.source);
+ }
+ return sources;
+ }
+
InternalAnalysisContext _context;
TypeProvider _typeProvider;
- AnalysisErrorListener _errorListener;
+ AngularHtmlUnitResolver_FilteringAnalysisErrorListener _errorListener;
Source _source;
@@ -8601,17 +9235,17 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
AngularHtmlUnitResolver(InternalAnalysisContext context, AnalysisErrorListener errorListener, Source source, LineInfo lineInfo, ht.HtmlUnit unit) {
this._context = context;
this._typeProvider = context.typeProvider;
- this._errorListener = errorListener;
+ this._errorListener = new AngularHtmlUnitResolver_FilteringAnalysisErrorListener(errorListener);
this._source = source;
this._lineInfo = lineInfo;
this._unit = unit;
}
/**
- * The [AngularApplicationInfo] for the Web application with this entry point, may be
+ * The [AngularApplication] for the Web application with this entry point, may be
* `null` if not an entry point.
*/
- AngularApplicationInfo calculateAngularApplication() {
+ AngularApplication calculateAngularApplication() {
// check if Angular at all
if (!hasAngularAnnotation(_unit)) {
return null;
@@ -8623,36 +9257,50 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
}
// prepare accessible Angular elements
LibraryElement libraryElement = dartUnit.element.library;
- List<AngularElement> angularElements = getAngularElements2(libraryElement);
- // resolve template URIs
+ Set<LibraryElement> libraries = new Set();
+ List<AngularElement> angularElements = getAngularElements(libraries, libraryElement);
+ // resolve AngularComponentElement template URIs
// TODO(scheglov) resolve to HtmlElement to allow F3 ?
+ Set<Source> angularElementsSources = new Set();
for (AngularElement angularElement in angularElements) {
- if (angularElement is AngularComponentElement) {
- AngularComponentElement component = angularElement;
- String templateUri = component.templateUri;
+ if (angularElement is AngularHasTemplateElement) {
+ AngularHasTemplateElement hasTemplate = angularElement;
+ angularElementsSources.add(angularElement.source);
+ String templateUri = hasTemplate.templateUri;
if (templateUri == null) {
continue;
}
try {
Source templateSource = _source.resolveRelative(parseUriWithException(templateUri));
- if (templateSource == null || !templateSource.exists()) {
+ if (!_context.exists(templateSource)) {
templateSource = _context.sourceFactory.resolveUri(_source, "package:${templateUri}");
- if (templateSource == null || !templateSource.exists()) {
- reportError7(component.templateUriOffset, templateUri.length, AngularCode.URI_DOES_NOT_EXIST, [templateUri]);
+ if (!_context.exists(templateSource)) {
+ _errorListener.onError(new AnalysisError.con2(angularElement.source, hasTemplate.templateUriOffset, templateUri.length, AngularCode.URI_DOES_NOT_EXIST, [templateUri]));
continue;
}
}
if (!AnalysisEngine.isHtmlFileName(templateUri)) {
continue;
}
- (component as AngularComponentElementImpl).templateSource = templateSource;
+ if (hasTemplate is AngularComponentElementImpl) {
+ hasTemplate.templateSource = templateSource;
+ }
+ if (hasTemplate is AngularViewElementImpl) {
+ hasTemplate.templateSource = templateSource;
+ }
} on URISyntaxException catch (exception) {
- reportError7(component.templateUriOffset, templateUri.length, AngularCode.INVALID_URI, [templateUri]);
+ _errorListener.onError(new AnalysisError.con2(angularElement.source, hasTemplate.templateUriOffset, templateUri.length, AngularCode.INVALID_URI, [templateUri]));
}
}
}
+ // create AngularApplication
+ AngularApplication application = new AngularApplication(_source, getLibrarySources(libraries), angularElements, new List.from(angularElementsSources));
+ // set AngularApplication for each AngularElement
+ for (AngularElement angularElement in angularElements) {
+ (angularElement as AngularElementImpl).application = application;
+ }
// done
- return new AngularApplicationInfo(_source, angularElements);
+ return application;
}
/**
@@ -8661,7 +9309,7 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
* @param application the Angular application we are resolving for
* @param component the [AngularComponentElement] to resolve template for, not `null`
*/
- void resolveComponentTemplate(AngularApplicationInfo application, AngularComponentElement component) {
+ void resolveComponentTemplate(AngularApplication application, AngularComponentElement component) {
_isAngular = true;
resolveInternal(application.elements, component);
}
@@ -8669,7 +9317,7 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
/**
* Resolves [source] as an Angular application entry point.
*/
- void resolveEntryPoint(AngularApplicationInfo application) {
+ void resolveEntryPoint(AngularApplication application) {
resolveInternal(application.elements, null);
}
@@ -8935,9 +9583,10 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
}
/**
- * Defines variable for the given [AngularElement].
+ * Defines variable for the given [AngularElement] with type of the enclosing
+ * [ClassElement].
*/
- void defineTopElementVariable(AngularElement element) {
+ void defineTopVariable_forClassElement(AngularElement element) {
ClassElement classElement = element.enclosingElement as ClassElement;
InterfaceType type = classElement.type;
LocalVariableElementImpl variable = createLocalVariable2(type, element.name);
@@ -8946,6 +9595,16 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
}
/**
+ * Defines variable for the given [AngularScopePropertyElement].
+ */
+ void defineTopVariable_forScopeProperty(AngularScopePropertyElement element) {
+ Type2 type = element.type;
+ LocalVariableElementImpl variable = createLocalVariable2(type, element.name);
+ defineTopVariable(variable);
+ variable.toolkitObjects = <AngularElement> [element];
+ }
+
+ /**
* Parse the value of the given token for embedded expressions, and add any embedded expressions
* that are found to the given list of expressions.
*
@@ -9048,13 +9707,6 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
for (AngularElement angularElement in angularElements) {
_injectedLibraries.add(angularElement.library);
}
- // add accessible processors
- for (AngularElement angularElement in angularElements) {
- NgProcessor processor = createProcessor(angularElement);
- if (processor != null) {
- _processors.add(processor);
- }
- }
// prepare Dart library
createLibraryElement();
(_unit.element as HtmlElementImpl).angularCompilationUnit = _unitElement;
@@ -9062,12 +9714,22 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
createResolver();
// maybe resolving component template
if (component != null) {
- defineTopElementVariable(component);
+ defineTopVariable_forClassElement(component);
+ for (AngularScopePropertyElement scopeProperty in component.scopeProperties) {
+ defineTopVariable_forScopeProperty(scopeProperty);
+ }
+ }
+ // add processors
+ for (AngularElement angularElement in angularElements) {
+ NgProcessor processor = createProcessor(angularElement);
+ if (processor != null) {
+ _processors.add(processor);
+ }
}
// define filters
for (AngularElement angularElement in angularElements) {
if (angularElement is AngularFilterElement) {
- defineTopElementVariable(angularElement);
+ defineTopVariable_forClassElement(angularElement);
}
}
// run this HTML visitor
@@ -9112,6 +9774,22 @@ class AngularHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
}
}
+class AngularHtmlUnitResolver_FilteringAnalysisErrorListener implements AnalysisErrorListener {
+ AnalysisErrorListener _listener;
+
+ AngularHtmlUnitResolver_FilteringAnalysisErrorListener(AnalysisErrorListener listener) {
+ this._listener = listener;
+ }
+
+ void onError(AnalysisError error) {
+ ErrorCode errorCode = error.errorCode;
+ if (identical(errorCode, StaticWarningCode.UNDEFINED_GETTER) || identical(errorCode, StaticWarningCode.UNDEFINED_IDENTIFIER) || identical(errorCode, StaticTypeWarningCode.UNDEFINED_GETTER)) {
+ return;
+ }
+ _listener.onError(error);
+ }
+}
+
class AngularHtmlUnitResolver_FoundAppError extends Error {
}
@@ -9345,19 +10023,32 @@ class NgDirectiveElementProcessor extends NgDirectiveProcessor {
}
void apply(AngularHtmlUnitResolver resolver, ht.XmlTagNode node) {
+ String selectorAttributeName = null;
+ {
+ AngularSelectorElement selector = _element.selector;
+ if (selector is HasAttributeSelectorElementImpl) {
+ selectorAttributeName = selector.name;
+ // resolve attribute expression
+ ht.XmlAttributeNode attribute = node.getAttribute(selectorAttributeName);
+ if (attribute != null) {
+ attribute.element = selector;
+ }
+ }
+ }
+ //
for (AngularPropertyElement property in _element.properties) {
// prepare attribute name
String name = property.name;
if (name == ".") {
- AngularSelectorElement selector = _element.selector;
- if (selector is HasAttributeSelectorElementImpl) {
- name = selector.name;
- }
+ name = selectorAttributeName;
}
// resolve attribute expression
ht.XmlAttributeNode attribute = node.getAttribute(name);
if (attribute != null) {
- attribute.element = property;
+ // if not resolved as the selector, resolve as a property
+ if (name != selectorAttributeName) {
+ attribute.element = property;
+ }
// resolve if binding
if (property.propertyKind != AngularPropertyKind.ATTR) {
resolver.pushNameScope();
@@ -9695,6 +10386,15 @@ abstract class AnalysisTaskVisitor<E> {
* @throws AnalysisException if the visitor throws an exception for some reason
*/
E visitResolveHtmlTask(ResolveHtmlTask task);
+
+ /**
+ * Visit a [ScanDartTask].
+ *
+ * @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 visitScanDartTask(ScanDartTask task);
}
/**
@@ -9979,11 +10679,6 @@ class ParseDartTask extends AnalysisTask {
int _modificationTime = -1;
/**
- * The line information that was produced.
- */
- LineInfo _lineInfo;
-
- /**
* The compilation unit that was produced by parsing the source.
*/
CompilationUnit _unit;
@@ -10030,14 +10725,6 @@ class ParseDartTask extends AnalysisTask {
List<AnalysisError> get errors => _errors;
/**
- * Return the line information that was produced, or `null` if the task has not yet been
- * performed or if an exception occurred.
- *
- * @return the line information that was produced
- */
- LineInfo get lineInfo => _lineInfo;
-
- /**
* Return the time at which the contents of the source that was parsed were last modified, or a
* negative value if the task has not yet been performed or if an exception occurred.
*
@@ -10070,19 +10757,12 @@ class ParseDartTask extends AnalysisTask {
void internalPerform() {
RecordingErrorListener errorListener = new RecordingErrorListener();
- List<Token> token = [null];
- //
- // Scan the contents of the file.
- //
- Source_ContentReceiver receiver = new Source_ContentReceiver_ParseDartTask_internalPerform(this, errorListener, token);
- try {
- source.getContents(receiver);
- } on JavaException catch (exception) {
- _modificationTime = source.modificationStamp;
- throw new AnalysisException.con3(exception);
- }
- if (token[0] == null) {
- throw new AnalysisException.con1("Could not get contents for '${source.fullName}'");
+ InternalAnalysisContext context = this.context;
+ TimestampedData<Token> data = context.internalScanTokenStream(source);
+ _modificationTime = data.modificationTime;
+ Token token = data.data;
+ if (token == null) {
+ throw new AnalysisException.con1("Could not get token stream for ${source.fullName}");
}
//
// Then parse the token stream.
@@ -10091,7 +10771,7 @@ class ParseDartTask extends AnalysisTask {
try {
Parser parser = new Parser(source, errorListener);
parser.parseFunctionBodies = context.analysisOptions.analyzeFunctionBodies;
- _unit = parser.parseCompilationUnit(token[0]);
+ _unit = parser.parseCompilationUnit(token);
_errors = errorListener.getErrors2(source);
for (Directive directive in _unit.directives) {
if (directive is LibraryDirective) {
@@ -10100,36 +10780,13 @@ class ParseDartTask extends AnalysisTask {
_hasPartOfDirective2 = true;
}
}
- _unit.lineInfo = _lineInfo;
+ _unit.lineInfo = context.getLineInfo(source);
} finally {
timeCounterParse.stop();
}
}
}
-class Source_ContentReceiver_ParseDartTask_internalPerform implements Source_ContentReceiver {
- final ParseDartTask ParseDartTask_this;
-
- RecordingErrorListener errorListener;
-
- List<Token> token;
-
- Source_ContentReceiver_ParseDartTask_internalPerform(this.ParseDartTask_this, this.errorListener, this.token);
-
- void accept(String contents, int modificationTime) {
- ParseDartTask_this._modificationTime = modificationTime;
- TimeCounter_TimeCounterHandle timeCounterScan = PerformanceStatistics.scan.start();
- try {
- Scanner scanner = new Scanner(ParseDartTask_this.source, new CharSequenceReader(contents), errorListener);
- scanner.preserveComments = ParseDartTask_this.context.analysisOptions.preserveComments;
- token[0] = scanner.tokenize();
- ParseDartTask_this._lineInfo = new LineInfo(scanner.lineStarts);
- } finally {
- timeCounterScan.stop();
- }
- }
-}
-
/**
* Instances of the class `ParseHtmlTask` parse a specific source as an HTML file.
*/
@@ -10170,22 +10827,11 @@ class ParseHtmlTask extends AnalysisTask {
static String _ATTRIBUTE_SRC = "src";
/**
- * The name of the 'type' attribute in a HTML tag.
- */
- static String _ATTRIBUTE_TYPE = "type";
-
- /**
* The name of the 'script' tag in an HTML file.
*/
static String _TAG_SCRIPT = "script";
/**
- * The value of the 'type' attribute of a 'script' tag that indicates that the script is written
- * in Dart.
- */
- static String _TYPE_DART = "application/dart";
-
- /**
* Initialize a newly created task to perform analysis within the given context.
*
* @param context the context in which the task is to be performed
@@ -10241,20 +10887,20 @@ class ParseHtmlTask extends AnalysisTask {
}
void internalPerform() {
- ht.HtmlScanner scanner = new ht.HtmlScanner(source);
try {
- source.getContents(scanner);
+ TimestampedData<String> contents = context.getContents(source);
+ _modificationTime = contents.modificationTime;
+ ht.AbstractScanner scanner = new ht.StringScanner(source, contents.data);
+ scanner.passThroughElements = <String> [_TAG_SCRIPT];
+ ht.Token token = scanner.tokenize();
+ _lineInfo = new LineInfo(scanner.lineStarts);
+ RecordingErrorListener errorListener = new RecordingErrorListener();
+ _unit = new ht.HtmlParser(source, errorListener).parse(token, _lineInfo);
+ _errors = errorListener.getErrors2(source);
+ _referencedLibraries = librarySources;
} on JavaException catch (exception) {
throw new AnalysisException.con3(exception);
}
- ht.HtmlScanResult scannerResult = scanner.result;
- _modificationTime = scannerResult.modificationTime;
- _lineInfo = new LineInfo(scannerResult.lineStarts);
- RecordingErrorListener errorListener = new RecordingErrorListener();
- ht.HtmlParseResult result = new ht.HtmlParser(source, errorListener).parse(scannerResult);
- _unit = result.htmlUnit;
- _errors = errorListener.getErrors2(source);
- _referencedLibraries = librarySources;
}
/**
@@ -10291,7 +10937,7 @@ class RecursiveXmlVisitor_ParseHtmlTask_getLibrarySources extends ht.RecursiveXm
Uri uri = new Uri(path: scriptAttribute.text);
String fileName = uri.path;
Source librarySource = ParseHtmlTask_this.context.sourceFactory.resolveUri(ParseHtmlTask_this.source, fileName);
- if (librarySource != null && librarySource.exists()) {
+ if (ParseHtmlTask_this.context.exists(librarySource)) {
libraries.add(librarySource);
}
} on URISyntaxException catch (e) {
@@ -10314,7 +10960,7 @@ class ResolveAngularComponentTemplateTask extends AnalysisTask {
/**
* The Angular application to resolve in context of.
*/
- AngularApplicationInfo _application;
+ AngularApplication _application;
/**
* The source to be resolved.
@@ -10344,7 +10990,7 @@ class ResolveAngularComponentTemplateTask extends AnalysisTask {
* @param component the component that uses this HTML template, not `null`
* @param application the Angular application to resolve in context of
*/
- ResolveAngularComponentTemplateTask(InternalAnalysisContext context, this.source, AngularComponentElement component, AngularApplicationInfo application) : super(context) {
+ ResolveAngularComponentTemplateTask(InternalAnalysisContext context, this.source, AngularComponentElement component, AngularApplication application) : super(context) {
this._component = component;
this._application = application;
}
@@ -10381,12 +11027,13 @@ class ResolveAngularComponentTemplateTask extends AnalysisTask {
RecordingErrorListener errorListener = new RecordingErrorListener();
LineInfo lineInfo = context.getLineInfo(source);
// do resolve
- AngularHtmlUnitResolver resolver = new AngularHtmlUnitResolver(context, errorListener, source, lineInfo, unit);
- resolver.resolveComponentTemplate(_application, _component);
+ if (_application != null) {
+ AngularHtmlUnitResolver resolver = new AngularHtmlUnitResolver(context, errorListener, source, lineInfo, unit);
+ resolver.resolveComponentTemplate(_application, _component);
+ _resolvedUnit = unit;
+ }
// remember errors
_resolutionErrors = errorListener.getErrors2(source);
- // remember resolved unit
- _resolvedUnit = unit;
}
}
@@ -10401,9 +11048,9 @@ class ResolveAngularEntryHtmlTask extends AnalysisTask {
final Source source;
/**
- * The Angular application to resolve in context of.
+ * The listener to record errors.
*/
- AngularApplicationInfo _application;
+ RecordingErrorListener _errorListener = new RecordingErrorListener();
/**
* The time at which the contents of the source were last modified.
@@ -10421,26 +11068,39 @@ class ResolveAngularEntryHtmlTask extends AnalysisTask {
HtmlElement _element = null;
/**
- * The resolution errors that were discovered while resolving the source.
+ * The Angular application to resolve in context of.
*/
- List<AnalysisError> _resolutionErrors = AnalysisError.NO_ERRORS;
+ AngularApplication _application;
/**
* 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 resolved
- * @param application the Angular application to resolve in context of
*/
- ResolveAngularEntryHtmlTask(InternalAnalysisContext context, this.source, AngularApplicationInfo application) : super(context) {
- this._application = application;
- }
+ ResolveAngularEntryHtmlTask(InternalAnalysisContext context, this.source) : super(context);
accept(AnalysisTaskVisitor visitor) => visitor.visitResolveAngularEntryHtmlTask(this);
+ /**
+ * Returns the [AngularApplication] for the Web application with this Angular entry point,
+ * maybe `null` if not an Angular entry point.
+ */
+ AngularApplication get application => _application;
+
HtmlElement get element => _element;
/**
+ * The resolution errors that were discovered while resolving the source.
+ */
+ List<AnalysisError> get entryErrors => _errorListener.getErrors2(source);
+
+ /**
+ * Returns [AnalysisError]s recorded for the given [Source].
+ */
+ List<AnalysisError> getErrors(Source source) => _errorListener.getErrors2(source);
+
+ /**
* Return the time at which the contents of the source that was parsed were last modified, or a
* negative value if the task has not yet been performed or if an exception occurred.
*
@@ -10448,8 +11108,6 @@ class ResolveAngularEntryHtmlTask extends AnalysisTask {
*/
int get modificationTime => _modificationTime;
- List<AnalysisError> get resolutionErrors => _resolutionErrors;
-
/**
* Return the [HtmlUnit] that was resolved by this task.
*
@@ -10472,12 +11130,13 @@ class ResolveAngularEntryHtmlTask extends AnalysisTask {
}
_modificationTime = resolvableHtmlUnit.modificationTime;
// prepare for resolution
- RecordingErrorListener errorListener = new RecordingErrorListener();
LineInfo lineInfo = context.getLineInfo(source);
+ // try to resolve as an Angular entry point
+ _application = new AngularHtmlUnitResolver(context, _errorListener, source, lineInfo, unit).calculateAngularApplication();
// do resolve
- new AngularHtmlUnitResolver(context, errorListener, source, lineInfo, unit).resolveEntryPoint(_application);
- // remember errors
- _resolutionErrors = errorListener.getErrors2(source);
+ if (_application != null) {
+ new AngularHtmlUnitResolver(context, _errorListener, source, lineInfo, unit).resolveEntryPoint(_application);
+ }
// remember resolved unit
_resolvedUnit = unit;
}
@@ -10563,14 +11222,11 @@ class ResolveDartDependenciesTask extends AnalysisTask {
}
void internalPerform() {
- ResolvableCompilationUnit unit = context.computeResolvableCompilationUnit(source);
+ TimestampedData<CompilationUnit> unit = context.internalParseCompilationUnit(source);
_modificationTime = unit.modificationTime;
- //
- // Then parse the token stream.
- //
TimeCounter_TimeCounterHandle timeCounterParse = PerformanceStatistics.parse.start();
try {
- for (Directive directive in unit.compilationUnit.directives) {
+ for (Directive directive in unit.data.directives) {
if (directive is ExportDirective) {
Source exportSource = resolveSource(source, directive);
if (exportSource != null) {
@@ -10854,16 +11510,6 @@ class ResolveHtmlTask extends AnalysisTask {
List<AnalysisError> _resolutionErrors = AnalysisError.NO_ERRORS;
/**
- * The flag that says is this unit is an Angular application.
- */
- bool _isAngularApplication2 = false;
-
- /**
- * The Angular application information, maybe `null`
- */
- AngularApplicationInfo _angularApplication;
-
- /**
* Initialize a newly created task to perform analysis within the given context.
*
* @param context the context in which the task is to be performed
@@ -10873,12 +11519,6 @@ class ResolveHtmlTask extends AnalysisTask {
accept(AnalysisTaskVisitor visitor) => visitor.visitResolveHtmlTask(this);
- /**
- * Returns the [AngularApplicationInfo] for the Web application with this Angular entry
- * point, maybe `null` if not an Angular entry point.
- */
- AngularApplicationInfo get angularApplication => _angularApplication;
-
HtmlElement get element => _element;
/**
@@ -10898,11 +11538,6 @@ class ResolveHtmlTask extends AnalysisTask {
*/
ht.HtmlUnit get resolvedUnit => _resolvedUnit;
- /**
- * Returns `true` if analyzed unit is an Angular application.
- */
- bool get isAngularApplication => _isAngularApplication2;
-
String get taskDescription {
if (source == null) {
return "resolve as html null source";
@@ -10921,12 +11556,6 @@ class ResolveHtmlTask extends AnalysisTask {
HtmlUnitBuilder builder = new HtmlUnitBuilder(context);
_element = builder.buildHtmlElement2(source, _modificationTime, unit);
RecordingErrorListener errorListener = builder.errorListener;
- LineInfo lineInfo = context.getLineInfo(source);
- // try to resolve as an Angular entry point
- if (context.analysisOptions.analyzeAngular) {
- _isAngularApplication2 = AngularHtmlUnitResolver.hasAngularAnnotation(unit);
- _angularApplication = new AngularHtmlUnitResolver(context, errorListener, source, lineInfo, unit).calculateAngularApplication();
- }
// record all resolution errors
_resolutionErrors = errorListener.getErrors2(source);
// remember resolved unit
@@ -10935,6 +11564,110 @@ class ResolveHtmlTask extends AnalysisTask {
}
/**
+ * Instances of the class `ScanDartTask` scan a specific source as a Dart file.
+ */
+class ScanDartTask extends AnalysisTask {
+ /**
+ * The source to be scanned.
+ */
+ final Source source;
+
+ /**
+ * The contents of the source.
+ */
+ String _content;
+
+ /**
+ * The time at which the contents of the source were last modified.
+ */
+ int _modificationTime = 0;
+
+ /**
+ * The token stream that was produced by scanning the source.
+ */
+ Token _tokenStream;
+
+ /**
+ * The line information that was produced.
+ */
+ LineInfo _lineInfo;
+
+ /**
+ * The errors that were produced by scanning the source.
+ */
+ List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
+
+ /**
+ * 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
+ */
+ ScanDartTask(InternalAnalysisContext context, this.source, TimestampedData<String> contentData) : super(context) {
+ this._content = contentData.data;
+ this._modificationTime = contentData.modificationTime;
+ }
+
+ accept(AnalysisTaskVisitor visitor) => visitor.visitScanDartTask(this);
+
+ /**
+ * Return the errors that were produced by scanning the source, or `null` if the task has
+ * not yet been performed or if an exception occurred.
+ *
+ * @return the errors that were produced by scanning the source
+ */
+ List<AnalysisError> get errors => _errors;
+
+ /**
+ * Return the line information that was produced, or `null` if the task has not yet been
+ * performed or if an exception occurred.
+ *
+ * @return the line information that was produced
+ */
+ LineInfo get lineInfo => _lineInfo;
+
+ /**
+ * Return the time at which the contents of the source that was parsed were last modified, or a
+ * negative value if the task has not yet been performed or if an exception occurred.
+ *
+ * @return the time at which the contents of the source that was parsed were last modified
+ */
+ int get modificationTime => _modificationTime;
+
+ /**
+ * Return the token stream that was produced by scanning the source, or `null` if the task
+ * has not yet been performed or if an exception occurred.
+ *
+ * @return the token stream that was produced by scanning the source
+ */
+ Token get tokenStream => _tokenStream;
+
+ String get taskDescription {
+ if (source == null) {
+ return "scan as dart null source";
+ }
+ return "scan as dart ${source.fullName}";
+ }
+
+ void internalPerform() {
+ RecordingErrorListener errorListener = new RecordingErrorListener();
+ TimeCounter_TimeCounterHandle timeCounterScan = PerformanceStatistics.scan.start();
+ try {
+ Scanner scanner = new Scanner(source, new CharSequenceReader(_content), errorListener);
+ scanner.preserveComments = context.analysisOptions.preserveComments;
+ _tokenStream = scanner.tokenize();
+ _lineInfo = new LineInfo(scanner.lineStarts);
+ _errors = errorListener.getErrors2(source);
+ } on JavaException catch (exception) {
+ throw new AnalysisException.con3(exception);
+ } finally {
+ timeCounterScan.stop();
+ }
+ }
+}
+
+/**
* 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)

Powered by Google App Engine
This is Rietveld 408576698