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

Unified Diff: pkg/analyzer/lib/src/task/dart.dart

Issue 1326553003: Add the task to resolve function bodies (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 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/task/dart.dart
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 65e391f5ec652faed36e1df01e57402d1ce9f200..1623a04365ac4f7de4190388b9ff4493cd8bda89 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -162,6 +162,30 @@ final ListResultDescriptor<Source> IMPORT_EXPORT_SOURCE_CLOSURE =
new ListResultDescriptor<Source>('IMPORT_EXPORT_SOURCE_CLOSURE', null);
/**
+ * The errors produced while inferring the type of a static variable.
+ *
+ * The list will be empty if there were no errors, but will not be `null`.
+ *
+ * The result is only available for [VariableElement]s, and only when strong
+ * mode is enabled.
+ */
+final ListResultDescriptor<AnalysisError> INFER_STATIC_VARIABLE_ERRORS =
+ new ListResultDescriptor<AnalysisError>(
+ 'INFER_STATIC_VARIABLE_ERRORS', AnalysisError.NO_ERRORS);
+
+/**
+ * The errors produced while inferring the types of all of the static variables
+ * in a compilation unit.
+ *
+ * The list will be empty if there were no errors, but will not be `null`.
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ListResultDescriptor<AnalysisError> INFER_STATIC_VARIABLE_TYPES_ERRORS =
+new ListResultDescriptor<AnalysisError>(
+ 'INFER_STATIC_VARIABLE_TYPES_ERRORS', AnalysisError.NO_ERRORS);
+
+/**
* A list of the [VariableElement]s whose type should be inferred that another
* inferable static variable (the target) depends on.
*
@@ -188,6 +212,9 @@ final ListResultDescriptor<VariableElement> INFERABLE_STATIC_VARIABLES_IN_UNIT =
/**
* An inferrable static variable ([VariableElement]) whose type has been
* inferred.
+ *
+ * The result is only available for [VariableElement]s, and only when strong
+ * mode is enabled.
*/
final ResultDescriptor<VariableElement> INFERRED_STATIC_VARIABLE =
new ResultDescriptor<VariableElement>('INFERRED_STATIC_VARIABLE', null,
@@ -303,6 +330,18 @@ final ResultDescriptor<ReferencedNames> REFERENCED_NAMES =
new ResultDescriptor<ReferencedNames>('REFERENCED_NAMES', null);
/**
+ * The errors produced while resolving the function bodies within a compilation
+ * unit.
+ *
+ * The list will be empty if there were no errors, but will not be `null`.
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ListResultDescriptor<AnalysisError> RESOLVE_FUNCTION_BODIES_ERRORS =
+ new ListResultDescriptor<AnalysisError>(
+ 'RESOLVE_FUNCTION_BODIES_ERRORS', AnalysisError.NO_ERRORS);
+
+/**
* The errors produced while resolving references.
*
* The list will be empty if there were no errors, but will not be `null`.
@@ -2534,13 +2573,19 @@ class InferStaticVariableTypesInUnitTask extends SourceBasedAnalysisTask {
static const String INFERRED_VARIABLES_INPUT = 'INFERRED_VARIABLES_INPUT';
/**
+ * The name of the input whose value is a list of the errors produced while
+ * inferring types for static variables.
+ */
+ static const String INFER_STATIC_VARIABLE_ERRORS_INPUT = 'INFER_STATIC_VARIABLE_ERRORS';
+
+ /**
* The task descriptor describing this kind of task.
*/
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
'InferStaticVariableTypesInUnitTask',
createTask,
buildInputs,
- <ResultDescriptor>[RESOLVED_UNIT6]);
+ <ResultDescriptor>[INFER_STATIC_VARIABLE_TYPES_ERRORS, RESOLVED_UNIT6]);
/**
* Initialize a newly created task to build a library element for the given
@@ -2559,11 +2604,17 @@ class InferStaticVariableTypesInUnitTask extends SourceBasedAnalysisTask {
// Prepare inputs.
//
CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+ List<List<AnalysisError>> perVariableErrors = getRequiredInput(INFER_STATIC_VARIABLE_ERRORS_INPUT);
Paul Berry 2015/09/02 17:10:08 Long line. Did you forget to run the formatter?
Brian Wilkerson 2015/09/03 15:08:37 It appears so, yes.
+ List<AnalysisError> errors = <AnalysisError>[];
+ for (List<AnalysisError> variableErrors in perVariableErrors) {
+ errors.addAll(variableErrors);
+ }
//
// Record outputs. There is no additional work to be done at this time
// because the work has implicitly been done by virtue of the task model
// preparing all of the inputs.
//
+ outputs[INFER_STATIC_VARIABLE_TYPES_ERRORS] = errors;
outputs[RESOLVED_UNIT6] = unit;
}
@@ -2578,6 +2629,9 @@ class InferStaticVariableTypesInUnitTask extends SourceBasedAnalysisTask {
INFERRED_VARIABLES_INPUT: INFERABLE_STATIC_VARIABLES_IN_UNIT
.of(unit)
.toListOf(INFERRED_STATIC_VARIABLE),
+ INFER_STATIC_VARIABLE_ERRORS_INPUT: INFERABLE_STATIC_VARIABLES_IN_UNIT
+ .of(unit)
+ .toListOf(INFER_STATIC_VARIABLE_ERRORS),
UNIT_INPUT: RESOLVED_UNIT5.of(unit)
};
}
@@ -2616,8 +2670,10 @@ class InferStaticVariableTypeTask extends InferStaticVariableTask {
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
'InferStaticVariableTypeTask',
createTask,
- buildInputs,
- <ResultDescriptor>[INFERRED_STATIC_VARIABLE]);
+ buildInputs, <ResultDescriptor>[
+ INFER_STATIC_VARIABLE_ERRORS,
+ INFERRED_STATIC_VARIABLE
+ ]);
InferStaticVariableTypeTask(
InternalAnalysisContext context, VariableElement variable)
@@ -2641,6 +2697,7 @@ class InferStaticVariableTypeTask extends InferStaticVariableTask {
VariableElementImpl variable = target;
CompilationUnit unit = getRequiredInput(UNIT_INPUT);
TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
+ RecordingErrorListener errorListener = new RecordingErrorListener();
if (dependencyCycle == null) {
//
// Re-resolve the variable's initializer so that the inferred types of other
@@ -2654,7 +2711,6 @@ class InferStaticVariableTypeTask extends InferStaticVariableTask {
throw new AnalysisException(
"NodeLocator failed to find a variable's declaration");
}
- RecordingErrorListener errorListener = new RecordingErrorListener();
Expression initializer = declaration.initializer;
ResolutionContext resolutionContext =
ResolutionContextBuilder.contextFor(initializer, errorListener);
@@ -2692,6 +2748,7 @@ class InferStaticVariableTypeTask extends InferStaticVariableTask {
// Record outputs.
//
outputs[INFERRED_STATIC_VARIABLE] = variable;
+ outputs[INFER_STATIC_VARIABLE_ERRORS] = errorListener.errors;
}
/**
@@ -2780,10 +2837,22 @@ class LibraryUnitErrorsTask extends SourceBasedAnalysisTask {
static const String HINTS_INPUT = 'HINTS';
/**
- * The name of the [RESOLVE_REFERENCES_ERRORS] input.
+ * The name of the [INFER_STATIC_VARIABLE_TYPES_ERRORS] input.
+ */
+ static const String INFER_STATIC_VARIABLE_TYPES_ERRORS_INPUT =
+ 'INFER_STATIC_VARIABLE_TYPES_ERRORS';
+
+ /**
+ * The name of the [PARTIALLY_RESOLVE_REFERENCES_ERRORS] input.
*/
- static const String RESOLVE_REFERENCES_ERRORS_INPUT =
- 'RESOLVE_REFERENCES_ERRORS';
+ static const String PARTIALLY_RESOLVE_REFERENCES_ERRORS_INPUT =
+ 'PARTIALLY_RESOLVE_REFERENCES_ERRORS';
+
+ /**
+ * The name of the [RESOLVE_FUNCTION_BODIES_ERRORS] input.
+ */
+ static const String RESOLVE_FUNCTION_BODIES_ERRORS_INPUT =
+ 'RESOLVE_FUNCTION_BODIES_ERRORS';
/**
* The name of the [RESOLVE_TYPE_NAMES_ERRORS] input.
@@ -2824,7 +2893,9 @@ class LibraryUnitErrorsTask extends SourceBasedAnalysisTask {
//
List<List<AnalysisError>> errorLists = <List<AnalysisError>>[];
errorLists.add(getRequiredInput(HINTS_INPUT));
- errorLists.add(getRequiredInput(RESOLVE_REFERENCES_ERRORS_INPUT));
+ errorLists.add(getRequiredInput(INFER_STATIC_VARIABLE_TYPES_ERRORS_INPUT));
+ errorLists.add(getRequiredInput(PARTIALLY_RESOLVE_REFERENCES_ERRORS_INPUT));
+ errorLists.add(getRequiredInput(RESOLVE_FUNCTION_BODIES_ERRORS_INPUT));
errorLists.add(getRequiredInput(RESOLVE_TYPE_NAMES_ERRORS_INPUT));
errorLists.add(getRequiredInput(VARIABLE_REFERENCE_ERRORS_INPUT));
errorLists.add(getRequiredInput(VERIFY_ERRORS_INPUT));
@@ -2843,7 +2914,9 @@ class LibraryUnitErrorsTask extends SourceBasedAnalysisTask {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
HINTS_INPUT: HINTS.of(unit),
- RESOLVE_REFERENCES_ERRORS_INPUT: RESOLVE_REFERENCES_ERRORS.of(unit),
+ INFER_STATIC_VARIABLE_TYPES_ERRORS_INPUT: INFER_STATIC_VARIABLE_TYPES_ERRORS.of(unit),
+ PARTIALLY_RESOLVE_REFERENCES_ERRORS_INPUT: PARTIALLY_RESOLVE_REFERENCES_ERRORS.of(unit),
+ RESOLVE_FUNCTION_BODIES_ERRORS_INPUT: RESOLVE_FUNCTION_BODIES_ERRORS.of(unit),
RESOLVE_TYPE_NAMES_ERRORS_INPUT: RESOLVE_TYPE_NAMES_ERRORS.of(unit),
VARIABLE_REFERENCE_ERRORS_INPUT: VARIABLE_REFERENCE_ERRORS.of(unit),
VERIFY_ERRORS_INPUT: VERIFY_ERRORS.of(unit)
@@ -3295,6 +3368,110 @@ class ReferencedNamesBuilder extends RecursiveAstVisitor {
}
/**
+ * A task that resolves the bodies of top-level functions, constructors, and
+ * methods within a single compilation unit.
+ */
+class ResolveFunctionBodiesInUnitTask extends SourceBasedAnalysisTask {
+ /**
+ * The name of the [TYPE_PROVIDER] input.
+ */
+ static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
+
+ /**
+ * The name of the [RESOLVED_UNIT7] input.
+ */
+ static const String UNIT_INPUT = 'UNIT_INPUT';
+
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+ 'ResolveFunctionBodiesInUnitTask',
+ createTask,
+ buildInputs,
+ <ResultDescriptor>[RESOLVE_FUNCTION_BODIES_ERRORS, RESOLVED_UNIT8]);
+
+ ResolveFunctionBodiesInUnitTask(
+ InternalAnalysisContext context, LibrarySpecificUnit compilationUnit)
+ : super(context, compilationUnit);
+
+ @override
+ TaskDescriptor get descriptor => DESCRIPTOR;
+
+ @override
+ void internalPerform() {
+ //
+ // Prepare inputs.
+ //
+ CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+ TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
+ //
+ // Resolve function bodies.
+ //
+ CompilationUnitElement unitElement = unit.element;
+ RecordingErrorListener errorListener = new RecordingErrorListener();
+ for (CompilationUnitMember unitMember in unit.declarations) {
+ if (unitMember is FunctionDeclaration) {
+ _resolveFunctionBody(unitMember.functionExpression.body, unitElement,
+ typeProvider, errorListener);
+ } else if (unitMember is ClassDeclaration) {
+ for (ClassMember classMember in unitMember.members) {
+ if (classMember is ConstructorDeclaration) {
+ _resolveFunctionBody(
+ classMember.body, unitElement, typeProvider, errorListener);
+ } else if (classMember is MethodDeclaration) {
+ _resolveFunctionBody(
+ classMember.body, unitElement, typeProvider, errorListener);
+ }
+ }
+ }
+ }
+ //
+ // Record outputs.
+ //
+ outputs[RESOLVE_FUNCTION_BODIES_ERRORS] = errorListener.errors;
+ outputs[RESOLVED_UNIT8] = unit;
+ }
+
+ void _resolveFunctionBody(
+ FunctionBody functionBody,
+ CompilationUnitElement unitElement,
+ TypeProvider typeProvider,
+ RecordingErrorListener errorListener) {
+ ResolutionContext resolutionContext =
+ ResolutionContextBuilder.contextFor(functionBody, errorListener);
+ ResolverVisitor visitor = new ResolverVisitor(
+ unitElement.library, unitElement.source, typeProvider, errorListener,
+ nameScope: resolutionContext.scope);
+ if (resolutionContext.enclosingClassDeclaration != null) {
+ visitor.prepareToResolveMembersInClass(
+ resolutionContext.enclosingClassDeclaration);
+ }
+ visitor.initForIncrementalResolution();
+ functionBody.accept(visitor);
+ }
+
+ /**
+ * 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) {
+ LibrarySpecificUnit unit = target;
+ return <String, TaskInput>{
+ TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
+ UNIT_INPUT: RESOLVED_UNIT7.of(unit)
+ };
+ }
+
+ /**
+ * Create a [ResolveFunctionBodiesInUnitTask] based on the given [target] in
+ * the given [context].
+ */
+ static ResolveFunctionBodiesInUnitTask createTask(
+ AnalysisContext context, AnalysisTarget target) {
+ return new ResolveFunctionBodiesInUnitTask(context, target);
+ }
+}
+
+/**
* A task that finishes resolution by requesting [RESOLVED_UNIT_NO_CONSTANTS] for every
* unit in the libraries closure and produces [LIBRARY_ELEMENT].
*/

Powered by Google App Engine
This is Rietveld 408576698