| Index: pkg/analyzer/lib/src/task/dart.dart
|
| diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
|
| index 4ff2448fed81fd5929db03745844d9fc6cb73db6..88bcc99d218883c1f9a06130fc53ec649107cc5e 100644
|
| --- a/pkg/analyzer/lib/src/task/dart.dart
|
| +++ b/pkg/analyzer/lib/src/task/dart.dart
|
| @@ -334,6 +334,7 @@ final List<ListResultDescriptor<AnalysisError>> ERROR_SOURCE_RESULTS =
|
| BUILD_DIRECTIVES_ERRORS,
|
| BUILD_LIBRARY_ERRORS,
|
| PARSE_ERRORS,
|
| + RESOLVE_DIRECTIVES_ERRORS,
|
| SCAN_ERRORS,
|
| ];
|
|
|
| @@ -626,6 +627,17 @@ final ListResultDescriptor<AnalysisError> PARSE_ERRORS =
|
| 'PARSE_ERRORS', AnalysisError.NO_ERRORS);
|
|
|
| /**
|
| + * The compilation unit AST produced while parsing a compilation unit.
|
| + *
|
| + * The AST structure will not have resolution information associated with it.
|
| + *
|
| + * The result is only available for [Source]s representing a compilation unit.
|
| + */
|
| +final ResultDescriptor<CompilationUnit> PARSED_UNIT1 =
|
| + new ResultDescriptor<CompilationUnit>('PARSED_UNIT1', null,
|
| + cachingPolicy: AST_CACHING_POLICY);
|
| +
|
| +/**
|
| * The list of [PendingError]s for a compilation unit.
|
| *
|
| * The result is only available for [LibrarySpecificUnit]s.
|
| @@ -729,6 +741,17 @@ final ListResultDescriptor<ConstantEvaluationTarget> REQUIRED_CONSTANTS =
|
| 'REQUIRED_CONSTANTS', const <ConstantEvaluationTarget>[]);
|
|
|
| /**
|
| + * The errors produced while resolving [UriBasedDirective]s in a unit.
|
| + *
|
| + * The list will be empty if there were no errors, but will not be `null`.
|
| + *
|
| + * The result is only available for [Source]s representing a compilation unit.
|
| + */
|
| +final ListResultDescriptor<AnalysisError> RESOLVE_DIRECTIVES_ERRORS =
|
| + new ListResultDescriptor<AnalysisError>(
|
| + 'PARSE_ERRORS2', AnalysisError.NO_ERRORS);
|
| +
|
| +/**
|
| * The errors produced while resolving bounds of type parameters of classes,
|
| * class and function aliases.
|
| *
|
| @@ -2757,6 +2780,7 @@ class DartDelta extends Delta {
|
| // Keep results that don't change: any library.
|
| if (_isTaskResult(ScanDartTask.DESCRIPTOR, descriptor) ||
|
| _isTaskResult(ParseDartTask.DESCRIPTOR, descriptor) ||
|
| + _isTaskResult(ResolveDirectivesTask.DESCRIPTOR, descriptor) ||
|
| _isTaskResult(BuildCompilationUnitElementTask.DESCRIPTOR, descriptor) ||
|
| _isTaskResult(BuildLibraryElementTask.DESCRIPTOR, descriptor) ||
|
| _isTaskResult(BuildDirectiveElementsTask.DESCRIPTOR, descriptor) ||
|
| @@ -4035,17 +4059,10 @@ class ParseDartTask extends SourceBasedAnalysisTask {
|
| */
|
| static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
|
| 'ParseDartTask', createTask, buildInputs, <ResultDescriptor>[
|
| - EXPLICITLY_IMPORTED_LIBRARIES,
|
| - EXPORTED_LIBRARIES,
|
| - IMPORTED_LIBRARIES,
|
| - INCLUDED_PARTS,
|
| - LIBRARY_SPECIFIC_UNITS,
|
| PARSE_ERRORS,
|
| - PARSED_UNIT,
|
| + PARSED_UNIT1,
|
| REFERENCED_NAMES,
|
| - REFERENCED_SOURCES,
|
| SOURCE_KIND,
|
| - UNITS,
|
| ]);
|
|
|
| /**
|
| @@ -4077,10 +4094,7 @@ class ParseDartTask extends SourceBasedAnalysisTask {
|
|
|
| bool hasNonPartOfDirective = false;
|
| bool hasPartOfDirective = false;
|
| - HashSet<Source> explicitlyImportedSourceSet = new HashSet<Source>();
|
| - HashSet<Source> exportedSourceSet = new HashSet<Source>();
|
| - HashSet<Source> includedSourceSet = new HashSet<Source>();
|
| - NodeList<Directive> directives = unit.directives;
|
| + List<Directive> directives = unit.directives;
|
| int length = directives.length;
|
| for (int i = 0; i < length; i++) {
|
| Directive directive = directives[i];
|
| @@ -4088,42 +4102,9 @@ class ParseDartTask extends SourceBasedAnalysisTask {
|
| hasPartOfDirective = true;
|
| } else {
|
| hasNonPartOfDirective = true;
|
| - if (directive is UriBasedDirective) {
|
| - Source referencedSource =
|
| - resolveDirective(context, source, directive, errorListener);
|
| - if (referencedSource != null) {
|
| - if (directive is ExportDirective) {
|
| - exportedSourceSet.add(referencedSource);
|
| - } else if (directive is ImportDirective) {
|
| - explicitlyImportedSourceSet.add(referencedSource);
|
| - } else if (directive is PartDirective) {
|
| - includedSourceSet.add(referencedSource);
|
| - } else {
|
| - throw new AnalysisException(
|
| - '$runtimeType failed to handle a ${directive.runtimeType}');
|
| - }
|
| - }
|
| - }
|
| }
|
| }
|
| //
|
| - // Always include "dart:core" source.
|
| - //
|
| - HashSet<Source> importedSourceSet =
|
| - new HashSet.from(explicitlyImportedSourceSet);
|
| - Source coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE);
|
| - if (coreLibrarySource == null) {
|
| - String message;
|
| - DartSdk sdk = context.sourceFactory.dartSdk;
|
| - if (sdk == null) {
|
| - message = 'Could not resolve "dart:core": SDK not defined';
|
| - } else {
|
| - message = 'Could not resolve "dart:core": SDK incorrectly configured';
|
| - }
|
| - throw new AnalysisException(message);
|
| - }
|
| - importedSourceSet.add(coreLibrarySource);
|
| - //
|
| // Compute kind.
|
| //
|
| SourceKind sourceKind = SourceKind.LIBRARY;
|
| @@ -4140,31 +4121,11 @@ class ParseDartTask extends SourceBasedAnalysisTask {
|
| //
|
| // Record outputs.
|
| //
|
| - List<Source> explicitlyImportedSources =
|
| - explicitlyImportedSourceSet.toList();
|
| - List<Source> exportedSources = exportedSourceSet.toList();
|
| - List<Source> importedSources = importedSourceSet.toList();
|
| - List<Source> includedSources = includedSourceSet.toList();
|
| List<AnalysisError> parseErrors = getUniqueErrors(errorListener.errors);
|
| - List<Source> unitSources = <Source>[source]..addAll(includedSourceSet);
|
| - List<Source> referencedSources = (new Set<Source>()
|
| - ..addAll(importedSources)
|
| - ..addAll(exportedSources)
|
| - ..addAll(unitSources))
|
| - .toList();
|
| - List<LibrarySpecificUnit> librarySpecificUnits =
|
| - unitSources.map((s) => new LibrarySpecificUnit(source, s)).toList();
|
| - outputs[EXPLICITLY_IMPORTED_LIBRARIES] = explicitlyImportedSources;
|
| - outputs[EXPORTED_LIBRARIES] = exportedSources;
|
| - outputs[IMPORTED_LIBRARIES] = importedSources;
|
| - outputs[INCLUDED_PARTS] = includedSources;
|
| - outputs[LIBRARY_SPECIFIC_UNITS] = librarySpecificUnits;
|
| outputs[PARSE_ERRORS] = parseErrors;
|
| - outputs[PARSED_UNIT] = unit;
|
| + outputs[PARSED_UNIT1] = unit;
|
| outputs[REFERENCED_NAMES] = referencedNames;
|
| - outputs[REFERENCED_SOURCES] = referencedSources;
|
| outputs[SOURCE_KIND] = sourceKind;
|
| - outputs[UNITS] = unitSources;
|
| }
|
|
|
| /**
|
| @@ -4188,45 +4149,6 @@ class ParseDartTask extends SourceBasedAnalysisTask {
|
| AnalysisContext context, AnalysisTarget target) {
|
| return new ParseDartTask(context, target);
|
| }
|
| -
|
| - /**
|
| - * Return the result of resolving the URI of the given URI-based [directive]
|
| - * against the URI of the given library, or `null` if the URI is not valid.
|
| - *
|
| - * Resolution is to be performed in the given [context]. Errors should be
|
| - * reported to the [errorListener].
|
| - */
|
| - static Source resolveDirective(AnalysisContext context, Source librarySource,
|
| - UriBasedDirective directive, AnalysisErrorListener errorListener) {
|
| - StringLiteral uriLiteral = directive.uri;
|
| - String uriContent = uriLiteral.stringValue;
|
| - if (uriContent != null) {
|
| - uriContent = uriContent.trim();
|
| - directive.uriContent = uriContent;
|
| - }
|
| - UriValidationCode code = directive.validate();
|
| - if (code == null) {
|
| - String encodedUriContent = Uri.encodeFull(uriContent);
|
| - Source source =
|
| - context.sourceFactory.resolveUri(librarySource, encodedUriContent);
|
| - directive.source = source;
|
| - return source;
|
| - }
|
| - if (code == UriValidationCode.URI_WITH_DART_EXT_SCHEME) {
|
| - return null;
|
| - }
|
| - if (code == UriValidationCode.URI_WITH_INTERPOLATION) {
|
| - errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
|
| - uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION));
|
| - return null;
|
| - }
|
| - if (code == UriValidationCode.INVALID_URI) {
|
| - errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
|
| - uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent]));
|
| - return null;
|
| - }
|
| - throw new AnalysisException('Failed to handle validation code: $code');
|
| - }
|
| }
|
|
|
| /**
|
| @@ -5324,6 +5246,176 @@ class ResolveDirectiveElementsTask extends SourceBasedAnalysisTask {
|
| }
|
|
|
| /**
|
| + * A task that resolves URIs of [UriBasedDirective]s and reports errors.
|
| + */
|
| +class ResolveDirectivesTask extends SourceBasedAnalysisTask {
|
| + /**
|
| + * The name of the input whose value is the [PARSED_UNIT1] for the file.
|
| + */
|
| + static const String PARSED_UNIT_INPUT = 'PARSED_UNIT_INPUT';
|
| +
|
| + /**
|
| + * The task descriptor describing this kind of task.
|
| + */
|
| + static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
|
| + 'ResolveDirectivesTask', createTask, buildInputs, <ResultDescriptor>[
|
| + EXPLICITLY_IMPORTED_LIBRARIES,
|
| + EXPORTED_LIBRARIES,
|
| + IMPORTED_LIBRARIES,
|
| + INCLUDED_PARTS,
|
| + LIBRARY_SPECIFIC_UNITS,
|
| + PARSED_UNIT,
|
| + RESOLVE_DIRECTIVES_ERRORS,
|
| + REFERENCED_SOURCES,
|
| + UNITS,
|
| + ]);
|
| +
|
| + /**
|
| + * Initialize a newly created task to parse the content of the Dart file
|
| + * associated with the given [target] in the given [context].
|
| + */
|
| + ResolveDirectivesTask(InternalAnalysisContext context, AnalysisTarget target)
|
| + : super(context, target);
|
| +
|
| + @override
|
| + TaskDescriptor get descriptor => DESCRIPTOR;
|
| +
|
| + @override
|
| + void internalPerform() {
|
| + Source source = getRequiredSource();
|
| + CompilationUnit unit = getRequiredInput(PARSED_UNIT_INPUT);
|
| +
|
| + RecordingErrorListener errorListener = new RecordingErrorListener();
|
| + HashSet<Source> explicitlyImportedSourceSet = new HashSet<Source>();
|
| + HashSet<Source> exportedSourceSet = new HashSet<Source>();
|
| + HashSet<Source> includedSourceSet = new HashSet<Source>();
|
| + NodeList<Directive> directives = unit.directives;
|
| + int length = directives.length;
|
| + for (int i = 0; i < length; i++) {
|
| + Directive directive = directives[i];
|
| + if (directive is UriBasedDirective) {
|
| + Source referencedSource =
|
| + resolveDirective(context, source, directive, errorListener);
|
| + if (referencedSource != null) {
|
| + if (directive is ExportDirective) {
|
| + exportedSourceSet.add(referencedSource);
|
| + } else if (directive is ImportDirective) {
|
| + explicitlyImportedSourceSet.add(referencedSource);
|
| + } else if (directive is PartDirective) {
|
| + includedSourceSet.add(referencedSource);
|
| + } else {
|
| + throw new AnalysisException(
|
| + '$runtimeType failed to handle a ${directive.runtimeType}');
|
| + }
|
| + }
|
| + }
|
| + }
|
| + //
|
| + // Always include "dart:core" source.
|
| + //
|
| + HashSet<Source> importedSourceSet =
|
| + new HashSet.from(explicitlyImportedSourceSet);
|
| + Source coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE);
|
| + if (coreLibrarySource == null) {
|
| + String message;
|
| + DartSdk sdk = context.sourceFactory.dartSdk;
|
| + if (sdk == null) {
|
| + message = 'Could not resolve "dart:core": SDK not defined';
|
| + } else {
|
| + message = 'Could not resolve "dart:core": SDK incorrectly configured';
|
| + }
|
| + throw new AnalysisException(message);
|
| + }
|
| + importedSourceSet.add(coreLibrarySource);
|
| + //
|
| + // Record outputs.
|
| + //
|
| + List<Source> explicitlyImportedSources =
|
| + explicitlyImportedSourceSet.toList();
|
| + List<Source> exportedSources = exportedSourceSet.toList();
|
| + List<Source> importedSources = importedSourceSet.toList();
|
| + List<Source> includedSources = includedSourceSet.toList();
|
| + List<AnalysisError> errors = getUniqueErrors(errorListener.errors);
|
| + List<Source> unitSources = <Source>[source]..addAll(includedSourceSet);
|
| + List<Source> referencedSources = (new Set<Source>()
|
| + ..addAll(importedSources)
|
| + ..addAll(exportedSources)
|
| + ..addAll(unitSources))
|
| + .toList();
|
| + List<LibrarySpecificUnit> librarySpecificUnits =
|
| + unitSources.map((s) => new LibrarySpecificUnit(source, s)).toList();
|
| + outputs[EXPLICITLY_IMPORTED_LIBRARIES] = explicitlyImportedSources;
|
| + outputs[EXPORTED_LIBRARIES] = exportedSources;
|
| + outputs[IMPORTED_LIBRARIES] = importedSources;
|
| + outputs[INCLUDED_PARTS] = includedSources;
|
| + outputs[LIBRARY_SPECIFIC_UNITS] = librarySpecificUnits;
|
| + outputs[PARSED_UNIT] = unit;
|
| + outputs[RESOLVE_DIRECTIVES_ERRORS] = errors;
|
| + outputs[REFERENCED_SOURCES] = referencedSources;
|
| + outputs[UNITS] = unitSources;
|
| + }
|
| +
|
| + /**
|
| + * Return a map from the names of the inputs of this kind of task to the task
|
| + * input descriptors describing those inputs for a task with the given
|
| + * [target].
|
| + */
|
| + static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
|
| + return <String, TaskInput>{
|
| + PARSED_UNIT_INPUT: PARSED_UNIT1.of(target, flushOnAccess: true)
|
| + };
|
| + }
|
| +
|
| + /**
|
| + * Create a [ResolveDirectivesTask] based on the given [target] in the given
|
| + * [context].
|
| + */
|
| + static ResolveDirectivesTask createTask(
|
| + AnalysisContext context, AnalysisTarget target) {
|
| + return new ResolveDirectivesTask(context, target);
|
| + }
|
| +
|
| + /**
|
| + * Return the result of resolving the URI of the given URI-based [directive]
|
| + * against the URI of the given library, or `null` if the URI is not valid.
|
| + *
|
| + * Resolution is to be performed in the given [context]. Errors should be
|
| + * reported to the [errorListener].
|
| + */
|
| + static Source resolveDirective(AnalysisContext context, Source librarySource,
|
| + UriBasedDirective directive, AnalysisErrorListener errorListener) {
|
| + StringLiteral uriLiteral = directive.uri;
|
| + String uriContent = uriLiteral.stringValue;
|
| + if (uriContent != null) {
|
| + uriContent = uriContent.trim();
|
| + directive.uriContent = uriContent;
|
| + }
|
| + UriValidationCode code = directive.validate();
|
| + if (code == null) {
|
| + String encodedUriContent = Uri.encodeFull(uriContent);
|
| + Source source =
|
| + context.sourceFactory.resolveUri(librarySource, encodedUriContent);
|
| + directive.source = source;
|
| + return source;
|
| + }
|
| + if (code == UriValidationCode.URI_WITH_DART_EXT_SCHEME) {
|
| + return null;
|
| + }
|
| + if (code == UriValidationCode.URI_WITH_INTERPOLATION) {
|
| + errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
|
| + uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION));
|
| + return null;
|
| + }
|
| + if (code == UriValidationCode.INVALID_URI) {
|
| + errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
|
| + uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent]));
|
| + return null;
|
| + }
|
| + throw new AnalysisException('Failed to handle validation code: $code');
|
| + }
|
| +}
|
| +
|
| +/**
|
| * A task that ensures that all of the inferable instance members in a
|
| * compilation unit have had their right hand sides re-resolved
|
| */
|
|
|