Chromium Code Reviews| Index: pkg/analyzer/lib/src/generated/engine.dart |
| =================================================================== |
| --- pkg/analyzer/lib/src/generated/engine.dart (revision 42670) |
| +++ pkg/analyzer/lib/src/generated/engine.dart (working copy) |
| @@ -1192,6 +1192,7 @@ |
| */ |
| AnalysisTask get nextAnalysisTask { |
| bool hintsEnabled = _options.hint; |
| + bool lintsEnabled = _options.lint; |
| bool hasBlockedTask = false; |
| // |
| // Look for incremental analysis |
| @@ -1224,8 +1225,12 @@ |
| sourcesToRemove.add(source); |
| continue; |
| } |
| - AnalysisContextImpl_TaskData taskData = |
| - _getNextAnalysisTaskForSource(source, sourceEntry, true, hintsEnabled); |
| + AnalysisContextImpl_TaskData taskData = _getNextAnalysisTaskForSource( |
| + source, |
| + sourceEntry, |
| + true, |
| + hintsEnabled, |
| + lintsEnabled); |
| task = taskData.task; |
| if (task != null) { |
| break; |
| @@ -1253,8 +1258,12 @@ |
| int priorityCount = _priorityOrder.length; |
| for (int i = 0; i < priorityCount; i++) { |
| Source source = _priorityOrder[i]; |
| - AnalysisContextImpl_TaskData taskData = |
| - _getNextAnalysisTaskForSource(source, _cache.get(source), true, hintsEnabled); |
| + AnalysisContextImpl_TaskData taskData = _getNextAnalysisTaskForSource( |
| + source, |
| + _cache.get(source), |
| + true, |
| + hintsEnabled, |
| + lintsEnabled); |
| AnalysisTask task = taskData.task; |
| if (task != null) { |
| return task; |
| @@ -1297,8 +1306,12 @@ |
| try { |
| while (sources.hasNext) { |
| Source source = sources.next(); |
| - AnalysisContextImpl_TaskData taskData = |
| - _getNextAnalysisTaskForSource(source, _cache.get(source), false, hintsEnabled); |
| + AnalysisContextImpl_TaskData taskData = _getNextAnalysisTaskForSource( |
| + source, |
| + _cache.get(source), |
| + false, |
| + hintsEnabled, |
| + lintsEnabled); |
| AnalysisTask task = taskData.task; |
| if (task != null) { |
| return task; |
| @@ -1382,6 +1395,8 @@ |
| List<Source> get sourcesNeedingProcessing { |
| HashSet<Source> sources = new HashSet<Source>(); |
| bool hintsEnabled = _options.hint; |
| + bool lintsEnabled = _options.lint; |
| + |
| // |
| // Look for priority sources that need to be analyzed. |
| // |
| @@ -1391,6 +1406,7 @@ |
| _cache.get(source), |
| true, |
| hintsEnabled, |
| + lintsEnabled, |
| sources); |
| } |
| // |
| @@ -1404,6 +1420,7 @@ |
| _cache.get(source), |
| false, |
| hintsEnabled, |
| + lintsEnabled, |
| sources); |
| } |
| return new List<Source>.from(sources); |
| @@ -1590,6 +1607,8 @@ |
| @override |
| List<AnalysisError> computeErrors(Source source) { |
| bool enableHints = _options.hint; |
| + bool enableLints = _options.lint; |
| + |
| SourceEntry sourceEntry = _getReadableSourceEntry(source); |
| if (sourceEntry is DartEntry) { |
| List<AnalysisError> errors = new List<AnalysisError>(); |
| @@ -1621,6 +1640,12 @@ |
| errors, |
| _getDartHintData(source, source, dartEntry, DartEntry.HINTS)); |
| } |
| + if (enableLints) { |
| + dartEntry = _getReadableDartEntry(source); |
| + ListUtilities.addAll( |
| + errors, |
| + _getDartLintData(source, source, dartEntry, DartEntry.LINTS)); |
| + } |
| } else { |
| List<Source> libraries = getLibrariesContaining(source); |
| for (Source librarySource in libraries) { |
| @@ -1645,6 +1670,12 @@ |
| errors, |
| _getDartHintData(source, librarySource, dartEntry, DartEntry.HINTS)); |
| } |
| + if (enableLints) { |
| + dartEntry = _getReadableDartEntry(source); |
| + ListUtilities.addAll( |
| + errors, |
| + _getDartLintData(source, librarySource, dartEntry, DartEntry.LINTS)); |
| + } |
| } |
| } |
| } on ObsoleteSourceAnalysisException catch (exception, stackTrace) { |
| @@ -2248,6 +2279,10 @@ |
| DartEntry.HINTS, |
| librarySource, |
| AnalysisError.NO_ERRORS); |
| + dartEntry.setValueInLibrary( |
| + DartEntry.LINTS, |
| + librarySource, |
| + AnalysisError.NO_ERRORS); |
| } |
| }); |
| } |
| @@ -2474,6 +2509,7 @@ |
| void visitCacheItems(void callback(Source source, SourceEntry dartEntry, |
| DataDescriptor rowDesc, CacheState state)) { |
| bool hintsEnabled = _options.hint; |
| + bool lintsEnabled = _options.lint; |
| MapIterator<Source, SourceEntry> iterator = _cache.iterator(); |
| while (iterator.moveNext()) { |
| Source source = iterator.key; |
| @@ -2523,10 +2559,13 @@ |
| } else if (source.isInSystemLibrary && |
| !_generateSdkErrors && |
| (descriptor == DartEntry.VERIFICATION_ERRORS || |
| - descriptor == DartEntry.HINTS)) { |
| + descriptor == DartEntry.HINTS || |
| + descriptor == DartEntry.LINTS)) { |
| continue; |
| } else if (!hintsEnabled && descriptor == DartEntry.HINTS) { |
| continue; |
| + } else if (!lintsEnabled && descriptor == DartEntry.LINTS) { |
| + continue; |
| } |
| callback( |
| librarySource, |
| @@ -2633,6 +2672,72 @@ |
| } |
| /** |
| + * 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 |
| + * [CacheStateERROR]. This method assumes that the data can be produced by generating hints |
|
danrubel
2015/01/07 20:17:57
hints -> lints
pquitslund
2015/01/08 00:29:52
Done.
|
| + * for the library if the data is not already cached. |
| + * |
| + * <b>Note:</b> This method cannot be used in an async environment. |
| + * |
| + * @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 _cacheDartLintData(Source unitSource, Source librarySource, |
| + DartEntry dartEntry, DataDescriptor descriptor) { |
| + // |
| + // Check to see whether we already have the information being requested. |
| + // |
| + CacheState state = dartEntry.getStateInLibrary(descriptor, librarySource); |
| + 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. |
| + // |
| + DartEntry libraryEntry = _getReadableDartEntry(librarySource); |
| + libraryEntry = _cacheDartResolutionData( |
| + librarySource, |
| + librarySource, |
| + libraryEntry, |
| + DartEntry.ELEMENT); |
| + LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT); |
| + CompilationUnitElement definingUnit = |
| + libraryElement.definingCompilationUnit; |
| + List<CompilationUnitElement> parts = libraryElement.parts; |
| + List<TimestampedData<CompilationUnit>> units = |
| + new List<TimestampedData>(parts.length + 1); |
| + units[0] = _getResolvedUnit(definingUnit, librarySource); |
| + if (units[0] == null) { |
| + Source source = definingUnit.source; |
| + units[0] = new TimestampedData<CompilationUnit>( |
| + getModificationStamp(source), |
| + resolveCompilationUnit(source, libraryElement)); |
| + } |
| + for (int i = 0; i < parts.length; i++) { |
| + units[i + 1] = _getResolvedUnit(parts[i], librarySource); |
| + if (units[i + 1] == null) { |
| + Source source = parts[i].source; |
| + units[i + |
| + 1] = new TimestampedData<CompilationUnit>( |
| + getModificationStamp(source), |
| + resolveCompilationUnit(source, libraryElement)); |
| + } |
| + } |
| + dartEntry = new GenerateDartLintsTask( |
|
Brian Wilkerson
2015/01/07 23:57:54
This is fine for now, but unless you're going to h
pquitslund
2015/01/08 00:29:52
Konstantin and I chatted about this and thought it
|
| + this, |
| + units, |
| + getLibraryElement(librarySource)).perform(_resultRecorder) as DartEntry; |
| + state = dartEntry.getStateInLibrary(descriptor, librarySource); |
| + } |
| + return dartEntry; |
| + } |
| + |
| + |
| + /** |
| * 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 parsing the source if it is not already cached. |
| @@ -3175,6 +3280,52 @@ |
| } |
| /** |
| + * Create a [GenerateDartHintsTask] for the given source, marking the hints as being |
|
danrubel
2015/01/07 20:17:57
hint -> lint in 2 places
pquitslund
2015/01/08 00:29:52
Done.
|
| + * in-process. |
| + * |
| + * @param source the source whose content is to be verified |
| + * @param dartEntry the entry for the source |
| + * @param librarySource the source for the library containing the source |
| + * @param libraryEntry the entry for the library |
| + * @return task data representing the created task |
| + */ |
| + AnalysisContextImpl_TaskData _createGenerateDartLintsTask(Source source, |
| + DartEntry dartEntry, Source librarySource, DartEntry libraryEntry) { |
| + if (libraryEntry.getState(DartEntry.ELEMENT) != CacheState.VALID) { |
| + return _createResolveDartLibraryTask(librarySource, libraryEntry); |
| + } |
| + LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT); |
| + CompilationUnitElement definingUnit = |
| + libraryElement.definingCompilationUnit; |
| + List<CompilationUnitElement> parts = libraryElement.parts; |
| + List<TimestampedData<CompilationUnit>> units = |
| + new List<TimestampedData>(parts.length + 1); |
| + units[0] = _getResolvedUnit(definingUnit, librarySource); |
| + if (units[0] == null) { |
| + // TODO(brianwilkerson) We should return a ResolveDartUnitTask |
| + // (unless there are multiple ASTs that need to be resolved). |
| + return _createResolveDartLibraryTask(librarySource, libraryEntry); |
| + } |
| + for (int i = 0; i < parts.length; i++) { |
| + units[i + 1] = _getResolvedUnit(parts[i], librarySource); |
| + if (units[i + 1] == null) { |
| + // TODO(brianwilkerson) We should return a ResolveDartUnitTask |
| + // (unless there are multiple ASTs that need to be resolved). |
| + return _createResolveDartLibraryTask(librarySource, libraryEntry); |
| + } |
| + } |
| + dartEntry.setStateInLibrary( |
| + DartEntry.LINTS, |
| + librarySource, |
| + CacheState.IN_PROCESS); |
| + return new AnalysisContextImpl_TaskData( |
| + new GenerateDartLintsTask(this, units, libraryElement), |
|
Brian Wilkerson
2015/01/07 23:57:54
Ditto
pquitslund
2015/01/08 00:29:52
Done.
|
| + false); |
| + } |
| + |
| + |
| + |
| + /** |
| * Create a [GetContentTask] for the given source, marking the content as being in-process. |
| * |
| * @param source the source whose content is to be accessed |
| @@ -3469,6 +3620,31 @@ |
| } |
| /** |
| + * Given a source for a Dart file and the library that contains it, return the data represented by |
| + * the given descriptor that is associated with that source. This method assumes that the data can |
| + * be produced by generating hints for the library if it is not already cached. |
|
danrubel
2015/01/07 20:17:57
hint -> lint
pquitslund
2015/01/08 00:29:52
Done.
|
| + * |
| + * <b>Note:</b> This method cannot be used in an async environment. |
| + * |
| + * @param unitSource the source representing the Dart file |
| + * @param librarySource the source representing the library containing the Dart file |
| + * @param dartEntry the entry representing the Dart file |
| + * @param descriptor the descriptor representing the data to be returned |
| + * @return the requested data about the given source |
| + * @throws AnalysisException if data could not be returned because the source could not be |
| + * resolved |
| + */ |
| + Object _getDartLintData(Source unitSource, Source librarySource, |
| + DartEntry dartEntry, DataDescriptor descriptor) { |
| + dartEntry = |
| + _cacheDartLintData(unitSource, librarySource, dartEntry, descriptor); |
| + if (identical(descriptor, DartEntry.ELEMENT)) { |
| + return dartEntry.getValue(descriptor); |
| + } |
| + return dartEntry.getValueInLibrary(descriptor, librarySource); |
| + } |
| + |
| + /** |
| * Given a source for a Dart file, return the data represented by the given descriptor that is |
| * associated with that source. This method assumes that the data can be produced by parsing the |
| * source if it is not already cached. |
| @@ -3746,10 +3922,12 @@ |
| * @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 lintsEnabled `true` if lints are currently enabled |
| * @return the next task that needs to be performed for the given source |
| */ |
| AnalysisContextImpl_TaskData _getNextAnalysisTaskForSource(Source source, |
| - SourceEntry sourceEntry, bool isPriority, bool hintsEnabled) { |
| + SourceEntry sourceEntry, bool isPriority, bool hintsEnabled, |
| + bool lintsEnabled) { |
| // Refuse to generate tasks for html based files that are above 1500 KB |
| if (_isTooBigHtmlSourceEntry(source, sourceEntry)) { |
| // TODO (jwren) we still need to report an error of some kind back to the |
| @@ -3859,6 +4037,18 @@ |
| libraryEntry); |
| } |
| } |
| + if (lintsEnabled) { |
| + CacheState lintsState = |
| + dartEntry.getStateInLibrary(DartEntry.LINTS, librarySource); |
| + if (lintsState == CacheState.INVALID || |
| + (isPriority && lintsState == CacheState.FLUSHED)) { |
| + return _createGenerateDartLintsTask( |
| + source, |
| + dartEntry, |
| + librarySource, |
| + libraryEntry); |
| + } |
| + } |
| } |
| } |
| } |
| @@ -4041,10 +4231,12 @@ |
| * @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 lintsEnabled `true` if lints are currently enabled |
| * @param sources the set to which sources should be added |
| */ |
| void _getSourcesNeedingProcessing(Source source, SourceEntry sourceEntry, |
| - bool isPriority, bool hintsEnabled, HashSet<Source> sources) { |
| + bool isPriority, bool hintsEnabled, bool lintsEnabled, |
| + HashSet<Source> sources) { |
| if (sourceEntry is DartEntry) { |
| DartEntry dartEntry = sourceEntry; |
| CacheState scanErrorsState = dartEntry.getState(DartEntry.SCAN_ERRORS); |
| @@ -4110,6 +4302,19 @@ |
| } |
| } |
| } |
| + if (lintsEnabled) { |
| + CacheState lintsState = |
| + dartEntry.getStateInLibrary(DartEntry.LINTS, librarySource); |
| + if (lintsState == CacheState.INVALID || |
| + (isPriority && lintsState == CacheState.FLUSHED)) { |
| + LibraryElement libraryElement = |
| + libraryEntry.getValue(DartEntry.ELEMENT); |
| + if (libraryElement != null) { |
| + sources.add(source); |
| + return; |
| + } |
| + } |
| + } |
| } |
| } |
| } |
| @@ -4599,6 +4804,50 @@ |
| * Record the results produced by performing a [task] and return the cache |
| * entry associated with the results. |
| */ |
| + DartEntry _recordGenerateDartLintsTask(GenerateDartLintsTask task) { |
| + Source librarySource = task.libraryElement.source; |
| + CaughtException thrownException = task.exception; |
| + DartEntry libraryEntry = null; |
| + HashMap<Source, List<AnalysisError>> lintMap = task.lintMap; |
| + if (lintMap == null) { |
| + // We don't have any information about which sources to mark as invalid |
| + // other than the library source. |
| + DartEntry libraryEntry = _cache.get(librarySource); |
| + if (thrownException == null) { |
| + String message = |
| + "GenerateDartHintsTask returned a null lint map " |
|
danrubel
2015/01/07 20:17:57
Hint -> Lint
pquitslund
2015/01/08 00:29:51
Done.
|
| + "without throwing an exception: ${librarySource.fullName}"; |
| + thrownException = |
| + new CaughtException(new AnalysisException(message), null); |
| + } |
| + libraryEntry.recordLintErrorInLibrary(librarySource, thrownException); |
| + throw new AnalysisException('<rethrow>', thrownException); |
| + } |
| + lintMap.forEach((Source unitSource, List<AnalysisError> lints) { |
| + DartEntry dartEntry = _cache.get(unitSource); |
| + if (unitSource == librarySource) { |
| + libraryEntry = dartEntry; |
| + } |
| + if (thrownException == null) { |
| + dartEntry.setValueInLibrary(DartEntry.LINTS, librarySource, lints); |
| + ChangeNoticeImpl notice = _getNotice(unitSource); |
| + LineInfo lineInfo = dartEntry.getValue(SourceEntry.LINE_INFO); |
| + notice.setErrors(dartEntry.allErrors, lineInfo); |
| + } else { |
| + dartEntry.recordLintErrorInLibrary(librarySource, thrownException); |
| + } |
| + }); |
| + if (thrownException != null) { |
| + throw new AnalysisException('<rethrow>', thrownException); |
| + } |
| + return libraryEntry; |
| + } |
| + |
| + |
| + /** |
| + * Record the results produced by performing a [task] and return the cache |
| + * entry associated with the results. |
| + */ |
| SourceEntry _recordGetContentsTask(GetContentTask task) { |
| if (!task.isComplete) { |
| return null; |
| @@ -5194,6 +5443,10 @@ |
| AnalysisContextImpl_this._recordGenerateDartHintsTask(task); |
| @override |
| + DartEntry visitGenerateDartLintsTask(GenerateDartLintsTask task) => |
| + AnalysisContextImpl_this._recordGenerateDartLintsTask(task); |
| + |
| + @override |
| SourceEntry visitGetContentTask(GetContentTask task) => |
| AnalysisContextImpl_this._recordGetContentsTask(task); |
| @@ -5279,6 +5532,7 @@ |
| bool _astIsNeeded(DartEntry dartEntry) => |
| dartEntry.hasInvalidData(DartEntry.HINTS) || |
| + dartEntry.hasInvalidData(DartEntry.HINTS) || |
|
danrubel
2015/01/07 20:17:57
HINTS -> LINTS
Plus perhaps a test?
pquitslund
2015/01/08 00:29:52
Great catch. Thanks!
Tests to follow in the next
|
| dartEntry.hasInvalidData(DartEntry.VERIFICATION_ERRORS) || |
| dartEntry.hasInvalidData(DartEntry.RESOLUTION_ERRORS); |
| } |
| @@ -6546,6 +6800,13 @@ |
| bool get incrementalValidation; |
| /** |
| + * Return `true` if analysis is to generate lint warnings. |
| + * |
| + * @return `true` if analysis is to generate lint warnings |
| + */ |
| + bool get lint; |
| + |
| + /** |
| * Return `true` if analysis is to parse comments. |
| * |
| * @return `true` if analysis is to parse comments |
| @@ -6647,6 +6908,11 @@ |
| bool incrementalValidation = false; |
| /** |
| + * A flag indicating whether analysis is to generate lint warnings. |
| + */ |
| + bool lint = false; |
| + |
| + /** |
| * A flag indicating whether analysis is to parse comments. |
| */ |
| bool preserveComments = true; |
| @@ -6675,6 +6941,7 @@ |
| incremental = options.incremental; |
| incrementalApi = options.incrementalApi; |
| incrementalValidation = options.incrementalValidation; |
| + lint = options.lint; |
| preserveComments = options.preserveComments; |
| } |
| @@ -6868,6 +7135,12 @@ |
| * Visit the given [task], returning the result of the visit. This method will |
| * throw an AnalysisException if the visitor throws an exception. |
| */ |
| + E visitGenerateDartLintsTask(GenerateDartLintsTask task); |
| + |
| + /** |
| + * Visit the given [task], returning the result of the visit. This method will |
| + * throw an AnalysisException if the visitor throws an exception. |
| + */ |
| E visitGetContentTask(GetContentTask task); |
| /** |
| @@ -8833,6 +9106,15 @@ |
| new DataDescriptor<bool>("DartEntry.IS_LAUNCHABLE", false); |
| /** |
| + * The data descriptor representing lint warnings resulting from auditing the |
| + * source. |
| + */ |
| + static final DataDescriptor<List<AnalysisError>> LINTS = |
| + new DataDescriptor<List<AnalysisError>>( |
| + "DartEntry.LINTS", |
| + AnalysisError.NO_ERRORS); |
| + |
| + /** |
| * The data descriptor representing the errors resulting from parsing the |
| * source. |
| */ |
| @@ -8925,6 +9207,7 @@ |
| errors.addAll(state.getValue(RESOLUTION_ERRORS)); |
| errors.addAll(state.getValue(VERIFICATION_ERRORS)); |
| errors.addAll(state.getValue(HINTS)); |
| + errors.addAll(state.getValue(LINTS)); |
| state = state._nextState; |
| } |
| errors.addAll(getValue(ANGULAR_ERRORS)); |
| @@ -9080,7 +9363,8 @@ |
| DartEntry.RESOLUTION_ERRORS, |
| DartEntry.RESOLVED_UNIT, |
| DartEntry.VERIFICATION_ERRORS, |
| - DartEntry.HINTS]; |
| + DartEntry.HINTS, |
| + DartEntry.LINTS]; |
| } |
| /** |
| @@ -9255,6 +9539,21 @@ |
| } |
| /** |
| + * Record that an error occurred while attempting to generate lints for the |
| + * source represented by this entry. This will set the state of all |
| + * verification information as being in error. |
| + * |
| + * @param librarySource the source of the library in which hints were being generated |
|
danrubel
2015/01/07 20:17:57
hint -> lint
pquitslund
2015/01/08 00:29:52
Done.
|
| + * @param exception the exception that shows where the error occurred |
| + */ |
| + void recordLintErrorInLibrary(Source librarySource, |
| + CaughtException exception) { |
| + this.exception = exception; |
| + ResolutionState state = _getOrCreateResolutionState(librarySource); |
| + state.recordLintError(); |
| + } |
| + |
| + /** |
| * Record that an [exception] 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. |
| @@ -9478,6 +9777,7 @@ |
| descriptor == BUILT_ELEMENT || |
| descriptor == BUILT_UNIT || |
| descriptor == HINTS || |
| + descriptor == LINTS || |
| descriptor == RESOLUTION_ERRORS || |
| descriptor == RESOLVED_UNIT || |
| descriptor == VERIFICATION_ERRORS; |
| @@ -9689,6 +9989,7 @@ |
| */ |
| bool astIsNeeded(DartEntry dartEntry) => |
| dartEntry.hasInvalidData(DartEntry.HINTS) || |
| + dartEntry.hasInvalidData(DartEntry.LINTS) || |
| dartEntry.hasInvalidData(DartEntry.VERIFICATION_ERRORS) || |
| dartEntry.hasInvalidData(DartEntry.RESOLUTION_ERRORS); |
| @@ -9980,6 +10281,57 @@ |
| } |
| } |
| +/// Generates lint feedback for a single Dart library. |
| +class GenerateDartLintsTask extends AnalysisTask { |
| + |
| + ///The compilation units that comprise the library, with the defining |
| + ///compilation unit appearing first in the array. |
| + final List<TimestampedData<CompilationUnit>> _units; |
| + |
| + /// The element model for the library being analyzed. |
| + final LibraryElement libraryElement; |
| + |
| + /// Initialize a newly created task to perform lint checking over these |
| + /// [_units] belonging to this [libraryElement] within the given [context]. |
| + GenerateDartLintsTask(context, this._units, this.libraryElement) |
| + : super(context); |
| + |
| + /// A mapping of analyzed sources to their associated lint warnings. |
| + /// May be [null] if the task has not been performed or if analysis did not |
| + /// complete normally. |
| + HashMap<Source, List<AnalysisError>> lintMap; |
| + |
| + @override |
| + String get taskDescription { |
| + Source librarySource = libraryElement.source; |
| + return (librarySource == null) ? |
| + "generate Dart lints for library without source" : |
| + "generate Dart lints for ${librarySource.fullName}"; |
| + } |
| + |
| + @override |
| + accept(AnalysisTaskVisitor visitor) => |
| + visitor.visitGenerateDartLintsTask(this); |
| + |
| + @override |
| + void internalPerform() { |
| + |
| + List<CompilationUnit> compilationUnits = |
| + _units.map((TimestampedData<CompilationUnit> unit) => unit.data); |
| + RecordingErrorListener errorListener = new RecordingErrorListener(); |
| + LintGenerator lintGenerator = |
| + new LintGenerator(compilationUnits, errorListener); |
| + lintGenerator.generate(); |
| + |
| + lintMap = new HashMap<Source, List<AnalysisError>>(); |
| + compilationUnits.forEach((CompilationUnit unit) { |
| + Source source = unit.element.source; |
| + lintMap[source] = errorListener.getErrorsForSource(source); |
| + }); |
| + } |
| +} |
| + |
| + |
| /** |
| * Instances of the class `GetContentTask` get the contents of a source. |
| */ |
| @@ -11798,6 +12150,11 @@ |
| static TimeCounter hints = new TimeCounter(); |
| /** |
| + * The [TimeCounter] for time spent in linting. |
| + */ |
| + static TimeCounter lint = new TimeCounter(); |
| + |
| + /** |
| * Reset all of the time counters to zero. |
| */ |
| static void reset() { |
| @@ -11809,6 +12166,7 @@ |
| polymer = new TimeCounter(); |
| errors = new TimeCounter(); |
| hints = new TimeCounter(); |
| + lint = new TimeCounter(); |
| } |
| } |
| @@ -12667,6 +13025,7 @@ |
| setState(DartEntry.BUILT_UNIT, CacheState.INVALID); |
| setState(DartEntry.BUILT_ELEMENT, CacheState.INVALID); |
| setState(DartEntry.HINTS, CacheState.INVALID); |
| + setState(DartEntry.LINTS, CacheState.INVALID); |
| setState(DartEntry.RESOLVED_UNIT, CacheState.INVALID); |
| setState(DartEntry.RESOLUTION_ERRORS, CacheState.INVALID); |
| setState(DartEntry.VERIFICATION_ERRORS, CacheState.INVALID); |
| @@ -12692,6 +13051,15 @@ |
| } |
| /** |
| + * Record that an exception occurred while attempting to generate lints for |
| + * the source associated with this entry. This will set the state of all |
| + * verification information as being in error. |
| + */ |
| + void recordLintError() { |
| + setState(DartEntry.LINTS, CacheState.ERROR); |
| + } |
| + |
| + /** |
| * Record that an exception occurred while attempting to resolve the source |
| * associated with this state. |
| */ |
| @@ -12800,6 +13168,8 @@ |
| oldEntry); |
| needsSeparator = |
| _writeStateDiffOn(buffer, needsSeparator, "hints", DartEntry.HINTS, oldEntry); |
| + needsSeparator = |
| + _writeStateDiffOn(buffer, needsSeparator, "lints", DartEntry.LINTS, oldEntry); |
| return needsSeparator; |
| } |
| @@ -12820,6 +13190,7 @@ |
| "verificationErrors", |
| DartEntry.VERIFICATION_ERRORS); |
| _writeStateOn(buffer, "hints", DartEntry.HINTS); |
| + _writeStateOn(buffer, "lints", DartEntry.LINTS); |
| if (_nextState != null) { |
| _nextState._writeOn(buffer); |
| } |