Index: packages/analyzer/lib/src/task/dart.dart |
diff --git a/analyzer/lib/src/task/dart.dart b/packages/analyzer/lib/src/task/dart.dart |
similarity index 73% |
rename from analyzer/lib/src/task/dart.dart |
rename to packages/analyzer/lib/src/task/dart.dart |
index fa8daec4119a889465b5a188a541d190e7cf371b..81745f737c392878715fe203cd8f0b4b8a3f55b9 100644 |
--- a/analyzer/lib/src/task/dart.dart |
+++ b/packages/analyzer/lib/src/task/dart.dart |
@@ -14,17 +14,22 @@ import 'package:analyzer/src/generated/engine.dart' |
hide AnalysisCache, AnalysisTask; |
import 'package:analyzer/src/generated/error.dart'; |
import 'package:analyzer/src/generated/error_verifier.dart'; |
+import 'package:analyzer/src/generated/incremental_resolver.dart'; |
import 'package:analyzer/src/generated/java_engine.dart'; |
import 'package:analyzer/src/generated/parser.dart'; |
import 'package:analyzer/src/generated/resolver.dart'; |
import 'package:analyzer/src/generated/scanner.dart'; |
import 'package:analyzer/src/generated/sdk.dart'; |
import 'package:analyzer/src/generated/source.dart'; |
+import 'package:analyzer/src/generated/visitors.dart'; |
+import 'package:analyzer/src/plugin/engine_plugin.dart'; |
+import 'package:analyzer/src/services/lint.dart'; |
import 'package:analyzer/src/task/driver.dart'; |
import 'package:analyzer/src/task/general.dart'; |
import 'package:analyzer/src/task/html.dart'; |
import 'package:analyzer/src/task/inputs.dart'; |
import 'package:analyzer/src/task/model.dart'; |
+import 'package:analyzer/src/task/strong_mode.dart'; |
import 'package:analyzer/task/dart.dart'; |
import 'package:analyzer/task/general.dart'; |
import 'package:analyzer/task/model.dart'; |
@@ -36,6 +41,18 @@ const ResultCachingPolicy AST_CACHING_POLICY = |
const SimpleResultCachingPolicy(8192, 8192); |
/** |
+ * The [ResultCachingPolicy] for [Element]s. |
+ */ |
+const ResultCachingPolicy ELEMENT_CACHING_POLICY = |
+ const SimpleResultCachingPolicy(-1, -1); |
+ |
+/** |
+ * The [ResultCachingPolicy] for [TOKEN_STREAM]. |
+ */ |
+const ResultCachingPolicy TOKEN_STREAM_CACHING_POLICY = |
+ const SimpleResultCachingPolicy(1, 1); |
+ |
+/** |
* The errors produced while resolving a library directives. |
* |
* The list will be empty if there were no errors, but will not be `null`. |
@@ -62,8 +79,11 @@ final ListResultDescriptor<AnalysisError> BUILD_LIBRARY_ERRORS = |
* constants defined at top level, statically inside classes, and local to |
* functions, as well as constant constructors, annotations, and default values |
* of parameters to constant constructors. |
+ * |
+ * The result is only available for [LibrarySpecificUnit]s. |
*/ |
-final ListResultDescriptor<ConstantEvaluationTarget> COMPILATION_UNIT_CONSTANTS = |
+final ListResultDescriptor< |
+ ConstantEvaluationTarget> COMPILATION_UNIT_CONSTANTS = |
new ListResultDescriptor<ConstantEvaluationTarget>( |
'COMPILATION_UNIT_CONSTANTS', null, |
cachingPolicy: ELEMENT_CACHING_POLICY); |
@@ -94,6 +114,9 @@ final ListResultDescriptor<ConstantEvaluationTarget> CONSTANT_DEPENDENCIES = |
* A [ConstantEvaluationTarget] that has been successfully constant-evaluated. |
* |
* TODO(paulberry): is ELEMENT_CACHING_POLICY the correct caching policy? |
+ * |
+ * The result is only available for [ConstantEvaluationTarget]s. |
+ * |
*/ |
final ResultDescriptor<ConstantEvaluationTarget> CONSTANT_VALUE = |
new ResultDescriptor<ConstantEvaluationTarget>('CONSTANT_VALUE', null, |
@@ -108,12 +131,6 @@ final ListResultDescriptor<Source> CONTAINING_LIBRARIES = |
new ListResultDescriptor<Source>('CONTAINING_LIBRARIES', Source.EMPTY_LIST); |
/** |
- * The [ResultCachingPolicy] for [Element]s. |
- */ |
-const ResultCachingPolicy ELEMENT_CACHING_POLICY = |
- const SimpleResultCachingPolicy(-1, -1); |
- |
-/** |
* The sources representing the export closure of a library. |
* The [Source]s include only library sources, not their units. |
* |
@@ -143,6 +160,78 @@ final ListResultDescriptor<Source> IMPORT_EXPORT_SOURCE_CLOSURE = |
new ListResultDescriptor<Source>('IMPORT_EXPORT_SOURCE_CLOSURE', null); |
/** |
+ * A list of the [LibraryElement]s that make up the strongly connected |
+ * component in the import/export graph in which the target resides. |
+ * |
+ * Only non-empty in strongMode |
+ * |
+ * The result is only available for [LibrarySpecificUnit]s. |
+ */ |
+final ListResultDescriptor<LibraryElement> LIBRARY_CYCLE = |
+ new ListResultDescriptor<LibraryElement>('LIBRARY_CYCLE', null); |
+ |
+/** |
+ * A list of the [CompilationUnitElement]s (including all parts) that make up |
+ * the strongly connected component in the import/export graph in which the |
+ * target resides. |
+ * |
+ * Only non-empty in strongMode |
+ * |
+ * The result is only available for [LibrarySpecificUnit]s. |
+ */ |
+final ListResultDescriptor<CompilationUnitElement> LIBRARY_CYCLE_UNITS = |
+ new ListResultDescriptor<CompilationUnitElement>( |
+ 'LIBRARY_CYCLE_UNITS', null); |
+ |
+/** |
+ * A list of the [CompilationUnitElement]s that comprise all of the parts and |
+ * libraries in the direct import/export dependencies of the library cycle |
+ * of the target, with the intra-component dependencies excluded. |
+ * |
+ * Only non-empty in strongMode |
+ * |
+ * The result is only available for [LibrarySpecificUnit]s. |
+ */ |
+final ListResultDescriptor<CompilationUnitElement> LIBRARY_CYCLE_DEPENDENCIES = |
+ new ListResultDescriptor<CompilationUnitElement>( |
+ 'LIBRARY_CYCLE_DEPENDENCIES', null); |
+ |
+/** |
+ * A list of the [VariableElement]s whose type should be inferred that another |
+ * inferable static variable (the target) depends on. |
+ * |
+ * The result is only available for [VariableElement]s, and only when strong |
+ * mode is enabled. |
+ */ |
+final ListResultDescriptor< |
+ VariableElement> INFERABLE_STATIC_VARIABLE_DEPENDENCIES = |
+ new ListResultDescriptor<VariableElement>( |
+ 'INFERABLE_STATIC_VARIABLE_DEPENDENCIES', null); |
+ |
+/** |
+ * A list of the [VariableElement]s defined in a unit whose type should be |
+ * inferred. This includes variables defined at the library level as well as |
+ * static members inside classes. |
+ * |
+ * The result is only available for [LibrarySpecificUnit]s, and only when strong |
+ * mode is enabled. |
+ */ |
+final ListResultDescriptor<VariableElement> INFERABLE_STATIC_VARIABLES_IN_UNIT = |
+ new ListResultDescriptor<VariableElement>( |
+ 'INFERABLE_STATIC_VARIABLES_IN_UNIT', null); |
+ |
+/** |
+ * 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, |
+ cachingPolicy: ELEMENT_CACHING_POLICY); |
+ |
+/** |
* The partial [LibraryElement] associated with a library. |
* |
* The [LibraryElement] and its [CompilationUnitElement]s are attached to each |
@@ -222,6 +311,17 @@ final ListResultDescriptor<AnalysisError> LIBRARY_UNIT_ERRORS = |
'LIBRARY_UNIT_ERRORS', AnalysisError.NO_ERRORS); |
/** |
+ * The errors produced while generating lints for 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> LINTS = |
+ new ListResultDescriptor<AnalysisError>( |
+ 'LINT_ERRORS', AnalysisError.NO_ERRORS); |
+ |
+/** |
* The errors produced while parsing a compilation unit. |
* |
* The list will be empty if there were no errors, but will not be `null`. |
@@ -241,15 +341,15 @@ final ResultDescriptor<ReferencedNames> REFERENCED_NAMES = |
new ResultDescriptor<ReferencedNames>('REFERENCED_NAMES', null); |
/** |
- * The errors produced while resolving references. |
+ * The errors produced while resolving a full 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_REFERENCES_ERRORS = |
+final ListResultDescriptor<AnalysisError> RESOLVE_UNIT_ERRORS = |
new ListResultDescriptor<AnalysisError>( |
- 'RESOLVE_REFERENCES_ERRORS', AnalysisError.NO_ERRORS); |
+ 'RESOLVE_UNIT_ERRORS', AnalysisError.NO_ERRORS); |
/** |
* The errors produced while resolving type names. |
@@ -307,8 +407,9 @@ final ResultDescriptor<CompilationUnit> RESOLVED_UNIT4 = |
cachingPolicy: AST_CACHING_POLICY); |
/** |
- * The resolved [CompilationUnit] associated with a compilation unit, with |
- * constants not yet resolved. |
+ * The resolved [CompilationUnit] associated with a compilation unit in which |
+ * elements and types have been initially resolved outside of method bodies in |
+ * addition to everything that is true of a [RESOLVED_UNIT4]. |
* |
* The result is only available for [LibrarySpecificUnit]s. |
*/ |
@@ -317,6 +418,49 @@ final ResultDescriptor<CompilationUnit> RESOLVED_UNIT5 = |
cachingPolicy: AST_CACHING_POLICY); |
/** |
+ * The resolved [CompilationUnit] associated with a compilation unit in which |
+ * the types of static variables have been inferred in addition to everything |
+ * that is true of a [RESOLVED_UNIT5]. |
+ * |
+ * The result is only available for [LibrarySpecificUnit]s. |
+ */ |
+final ResultDescriptor<CompilationUnit> RESOLVED_UNIT6 = |
+ new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT6', null, |
+ cachingPolicy: AST_CACHING_POLICY); |
+ |
+/** |
+ * The resolved [CompilationUnit] associated with a compilation unit in which |
+ * the right hand sides of instance variables have been re-resolved in addition |
+ * to everything that is true of a [RESOLVED_UNIT6]. |
+ * |
+ * The result is only available for [LibrarySpecificUnit]s. |
+ */ |
+final ResultDescriptor<CompilationUnit> RESOLVED_UNIT7 = |
+ new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT7', null, |
+ cachingPolicy: AST_CACHING_POLICY); |
+ |
+/** |
+ * The resolved [CompilationUnit] associated with a compilation unit in which |
+ * the types of class members have been inferred in addition to everything that |
+ * is true of a [RESOLVED_UNIT7]. |
+ * |
+ * The result is only available for [LibrarySpecificUnit]s. |
+ */ |
+final ResultDescriptor<CompilationUnit> RESOLVED_UNIT8 = |
+ new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT8', null, |
+ cachingPolicy: AST_CACHING_POLICY); |
+ |
+/** |
+ * The resolved [CompilationUnit] associated with a compilation unit, with |
+ * constants not yet resolved. |
+ * |
+ * The result is only available for [LibrarySpecificUnit]s. |
+ */ |
+final ResultDescriptor<CompilationUnit> RESOLVED_UNIT9 = |
+ new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT9', null, |
+ cachingPolicy: AST_CACHING_POLICY); |
+ |
+/** |
* The errors produced while scanning a compilation unit. |
* |
* The list will be empty if there were no errors, but will not be `null`. |
@@ -328,12 +472,6 @@ final ListResultDescriptor<AnalysisError> SCAN_ERRORS = |
'SCAN_ERRORS', AnalysisError.NO_ERRORS); |
/** |
- * The [ResultCachingPolicy] for [TOKEN_STREAM]. |
- */ |
-const ResultCachingPolicy TOKEN_STREAM_CACHING_POLICY = |
- const SimpleResultCachingPolicy(1, 1); |
- |
-/** |
* The [TypeProvider] of the [AnalysisContext]. |
*/ |
final ResultDescriptor<TypeProvider> TYPE_PROVIDER = |
@@ -399,11 +537,12 @@ class BuildCompilationUnitElementTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'BuildCompilationUnitElementTask', createTask, buildInputs, |
- <ResultDescriptor>[ |
+ 'BuildCompilationUnitElementTask', |
+ createTask, |
+ buildInputs, <ResultDescriptor>[ |
+ COMPILATION_UNIT_CONSTANTS, |
COMPILATION_UNIT_ELEMENT, |
- RESOLVED_UNIT1, |
- COMPILATION_UNIT_CONSTANTS |
+ RESOLVED_UNIT1 |
]); |
/** |
@@ -428,7 +567,7 @@ class BuildCompilationUnitElementTask extends SourceBasedAnalysisTask { |
// |
// Build or reuse CompilationUnitElement. |
// |
- unit = AstCloner.clone(unit); |
+// unit = AstCloner.clone(unit); |
AnalysisCache analysisCache = |
(context as InternalAnalysisContext).analysisCache; |
CompilationUnitElement element = |
@@ -446,15 +585,14 @@ class BuildCompilationUnitElementTask extends SourceBasedAnalysisTask { |
ConstantFinder constantFinder = |
new ConstantFinder(context, source, librarySpecificUnit.library); |
unit.accept(constantFinder); |
- List<ConstantEvaluationTarget> constants = |
- new List<ConstantEvaluationTarget>.from( |
- constantFinder.constantsToCompute); |
+ List<ConstantEvaluationTarget> constants = new List< |
+ ConstantEvaluationTarget>.from(constantFinder.constantsToCompute); |
// |
// Record outputs. |
// |
+ outputs[COMPILATION_UNIT_CONSTANTS] = constants; |
outputs[COMPILATION_UNIT_ELEMENT] = element; |
outputs[RESOLVED_UNIT1] = unit; |
- outputs[COMPILATION_UNIT_CONSTANTS] = constants; |
} |
/** |
@@ -465,7 +603,7 @@ class BuildCompilationUnitElementTask extends SourceBasedAnalysisTask { |
static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
LibrarySpecificUnit unit = target; |
return <String, TaskInput>{ |
- PARSED_UNIT_INPUT_NAME: PARSED_UNIT.of(unit.unit) |
+ PARSED_UNIT_INPUT_NAME: PARSED_UNIT.of(unit.unit, flushOnAccess: true) |
}; |
} |
@@ -521,10 +659,10 @@ class BuildDirectiveElementsTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'BuildDirectiveElementsTask', createTask, buildInputs, <ResultDescriptor>[ |
- LIBRARY_ELEMENT2, |
- BUILD_DIRECTIVES_ERRORS |
- ]); |
+ 'BuildDirectiveElementsTask', |
+ createTask, |
+ buildInputs, |
+ <ResultDescriptor>[LIBRARY_ELEMENT2, BUILD_DIRECTIVES_ERRORS]); |
BuildDirectiveElementsTask( |
InternalAnalysisContext context, AnalysisTarget target) |
@@ -629,8 +767,11 @@ class BuildDirectiveElementsTask extends SourceBasedAnalysisTask { |
directive.element = exportElement; |
exports.add(exportElement); |
if (exportSourceKindMap[exportedSource] != SourceKind.LIBRARY) { |
- errors.add(new AnalysisError(exportedSource, uriLiteral.offset, |
- uriLiteral.length, CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, |
+ errors.add(new AnalysisError( |
+ exportedSource, |
+ uriLiteral.offset, |
+ uriLiteral.length, |
+ CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, |
[uriLiteral.toSource()])); |
} |
} |
@@ -740,7 +881,9 @@ class BuildEnumMemberElementsTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'BuildEnumMemberElementsTask', createTask, buildInputs, |
+ 'BuildEnumMemberElementsTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[RESOLVED_UNIT2]); |
BuildEnumMemberElementsTask( |
@@ -801,7 +944,9 @@ class BuildExportNamespaceTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'BuildExportNamespaceTask', createTask, buildInputs, |
+ 'BuildExportNamespaceTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[LIBRARY_ELEMENT4]); |
BuildExportNamespaceTask( |
@@ -957,8 +1102,11 @@ class BuildLibraryElementTask extends SourceBasedAnalysisTask { |
String partLibraryName = |
_getPartLibraryName(partSource, partUnit, directivesToResolve); |
if (partLibraryName == null) { |
- errors.add(new AnalysisError(librarySource, partUri.offset, |
- partUri.length, CompileTimeErrorCode.PART_OF_NON_PART, |
+ errors.add(new AnalysisError( |
+ librarySource, |
+ partUri.offset, |
+ partUri.length, |
+ CompileTimeErrorCode.PART_OF_NON_PART, |
[partUri.toSource()])); |
} else if (libraryNameNode == null) { |
if (partsLibraryName == _UNKNOWN_LIBRARY_NAME) { |
@@ -967,11 +1115,12 @@ class BuildLibraryElementTask extends SourceBasedAnalysisTask { |
partsLibraryName = null; |
} |
} else if (libraryNameNode.name != partLibraryName) { |
- errors.add(new AnalysisError(librarySource, partUri.offset, |
- partUri.length, StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [ |
- libraryNameNode.name, |
- partLibraryName |
- ])); |
+ errors.add(new AnalysisError( |
+ librarySource, |
+ partUri.offset, |
+ partUri.length, |
+ StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, |
+ [libraryNameNode.name, partLibraryName])); |
} |
} |
if (entryPoint == null) { |
@@ -1138,7 +1287,9 @@ class BuildPublicNamespaceTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'BuildPublicNamespaceTask', createTask, buildInputs, |
+ 'BuildPublicNamespaceTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[LIBRARY_ELEMENT3]); |
BuildPublicNamespaceTask( |
@@ -1188,7 +1339,9 @@ class BuildSourceExportClosureTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'BuildSourceExportClosureTask', createTask, buildInputs, |
+ 'BuildSourceExportClosureTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[EXPORT_SOURCE_CLOSURE]); |
BuildSourceExportClosureTask( |
@@ -1243,7 +1396,9 @@ class BuildSourceImportExportClosureTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'BuildSourceImportExportClosureTask', createTask, buildInputs, |
+ 'BuildSourceImportExportClosureTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[IMPORT_EXPORT_SOURCE_CLOSURE, IS_CLIENT]); |
BuildSourceImportExportClosureTask( |
@@ -1305,7 +1460,9 @@ class BuildTypeProviderTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'BuildTypeProviderTask', createTask, buildInputs, |
+ 'BuildTypeProviderTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[TYPE_PROVIDER]); |
BuildTypeProviderTask( |
@@ -1355,7 +1512,7 @@ class BuildTypeProviderTask extends SourceBasedAnalysisTask { |
*/ |
class ComputeConstantDependenciesTask extends ConstantEvaluationAnalysisTask { |
/** |
- * The name of the [RESOLVED_UNIT5] input. |
+ * The name of the [RESOLVED_UNIT9] input. |
*/ |
static const String UNIT_INPUT = 'UNIT_INPUT'; |
@@ -1365,7 +1522,9 @@ class ComputeConstantDependenciesTask extends ConstantEvaluationAnalysisTask { |
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT'; |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'ComputeConstantDependenciesTask', createTask, buildInputs, |
+ 'ComputeConstantDependenciesTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[CONSTANT_DEPENDENCIES]); |
ComputeConstantDependenciesTask( |
@@ -1385,13 +1544,13 @@ class ComputeConstantDependenciesTask extends ConstantEvaluationAnalysisTask { |
// constant dependencies. |
// |
ConstantEvaluationTarget constant = target; |
- AnalysisContext context = constant.context; |
TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); |
// |
// Compute dependencies. |
// |
List<ConstantEvaluationTarget> dependencies = <ConstantEvaluationTarget>[]; |
- new ConstantEvaluationEngine(typeProvider, context.declaredVariables) |
+ new ConstantEvaluationEngine(typeProvider, context.declaredVariables, |
+ typeSystem: context.typeSystem) |
.computeDependencies(constant, dependencies.add); |
// |
// Record outputs. |
@@ -1409,13 +1568,13 @@ class ComputeConstantDependenciesTask extends ConstantEvaluationAnalysisTask { |
CompilationUnitElementImpl unit = target |
.getAncestor((Element element) => element is CompilationUnitElement); |
return <String, TaskInput>{ |
- UNIT_INPUT: RESOLVED_UNIT5 |
+ UNIT_INPUT: RESOLVED_UNIT9 |
.of(new LibrarySpecificUnit(unit.librarySource, target.source)), |
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request) |
}; |
} else if (target is ConstantEvaluationTarget_Annotation) { |
return <String, TaskInput>{ |
- UNIT_INPUT: RESOLVED_UNIT5 |
+ UNIT_INPUT: RESOLVED_UNIT9 |
.of(new LibrarySpecificUnit(target.librarySource, target.source)), |
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request) |
}; |
@@ -1425,7 +1584,7 @@ class ComputeConstantDependenciesTask extends ConstantEvaluationAnalysisTask { |
} |
/** |
- * Create a [ResolveUnitReferencesTask] based on the given [target] in |
+ * Create a [ComputeConstantDependenciesTask] based on the given [target] in |
* the given [context]. |
*/ |
static ComputeConstantDependenciesTask createTask( |
@@ -1451,7 +1610,9 @@ class ComputeConstantValueTask extends ConstantEvaluationAnalysisTask { |
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT'; |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'ComputeConstantValueTask', createTask, buildInputs, |
+ 'ComputeConstantValueTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[CONSTANT_VALUE]); |
ComputeConstantValueTask( |
@@ -1480,7 +1641,8 @@ class ComputeConstantValueTask extends ConstantEvaluationAnalysisTask { |
// cycle. |
// |
ConstantEvaluationEngine constantEvaluationEngine = |
- new ConstantEvaluationEngine(typeProvider, context.declaredVariables); |
+ new ConstantEvaluationEngine(typeProvider, context.declaredVariables, |
+ typeSystem: context.typeSystem); |
if (dependencyCycle == null) { |
constantEvaluationEngine.computeConstantValue(constant); |
} else { |
@@ -1525,6 +1687,174 @@ class ComputeConstantValueTask extends ConstantEvaluationAnalysisTask { |
} |
/** |
+ * A task that computes the [INFERABLE_STATIC_VARIABLE_DEPENDENCIES] for a |
+ * static variable whose type should be inferred. |
+ */ |
+class ComputeInferableStaticVariableDependenciesTask |
+ extends ConstantEvaluationAnalysisTask { |
+ /** |
+ * The name of the [RESOLVED_UNIT5] input. |
+ */ |
+ static const String UNIT_INPUT = 'UNIT_INPUT'; |
+ |
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
+ 'ComputeInferableStaticVariableDependenciesTask', |
+ createTask, |
+ buildInputs, |
+ <ResultDescriptor>[INFERABLE_STATIC_VARIABLE_DEPENDENCIES]); |
+ |
+ ComputeInferableStaticVariableDependenciesTask( |
+ InternalAnalysisContext context, VariableElement variable) |
+ : super(context, variable); |
+ |
+ @override |
+ TaskDescriptor get descriptor => DESCRIPTOR; |
+ |
+ @override |
+ void internalPerform() { |
+ // |
+ // Prepare inputs. |
+ // |
+ VariableElement variable = target; |
+ CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
+ // |
+ // Compute dependencies. |
+ // |
+ NodeLocator locator = new NodeLocator(variable.nameOffset); |
+ AstNode node = locator.searchWithin(unit); |
+ VariableDeclaration declaration = |
+ node.getAncestor((AstNode ancestor) => ancestor is VariableDeclaration); |
+ if (declaration == null || declaration.name != node) { |
+ throw new AnalysisException( |
+ "NodeLocator failed to find a variable's declaration"); |
+ } |
+ VariableGatherer gatherer = new VariableGatherer(_isInferableStatic); |
+ declaration.initializer.accept(gatherer); |
+ // |
+ // Record outputs. |
+ // |
+ outputs[INFERABLE_STATIC_VARIABLE_DEPENDENCIES] = gatherer.results.toList(); |
+ } |
+ |
+ /** |
+ * Return `true` if the given [variable] is a static variable whose type |
+ * should be inferred. |
+ */ |
+ bool _isInferableStatic(VariableElement variable) => variable.isStatic && |
+ variable.hasImplicitType && |
+ variable.initializer != null; |
+ |
+ /** |
+ * 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) { |
+ if (target is VariableElement) { |
+ CompilationUnitElementImpl unit = target |
+ .getAncestor((Element element) => element is CompilationUnitElement); |
+ return <String, TaskInput>{ |
+ UNIT_INPUT: RESOLVED_UNIT5 |
+ .of(new LibrarySpecificUnit(unit.librarySource, unit.source)) |
+ }; |
+ } |
+ throw new AnalysisException( |
+ 'Cannot build inputs for a ${target.runtimeType}'); |
+ } |
+ |
+ /** |
+ * Create a [ComputeInferableStaticVariableDependenciesTask] based on the |
+ * given [target] in the given [context]. |
+ */ |
+ static ComputeInferableStaticVariableDependenciesTask createTask( |
+ AnalysisContext context, AnalysisTarget target) { |
+ return new ComputeInferableStaticVariableDependenciesTask(context, target); |
+ } |
+} |
+ |
+/** |
+ * A task that computes the [LIBRARY_CYCLE] for a |
+ * library element. Also computes the [LIBRARY_CYCLE_UNITS] and the |
+ * [LIBRARY_CYCLE_DEPENDENCIES]. |
+ */ |
+class ComputeLibraryCycleTask extends SourceBasedAnalysisTask { |
+ /** |
+ * The name of the [LIBRARY_ELEMENT2] input. |
+ */ |
+ static const String LIBRARY_ELEMENT_INPUT = 'LIBRARY_ELEMENT_INPUT'; |
+ |
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
+ 'ComputeLibraryCycleForUnitTask', |
+ createTask, |
+ buildInputs, <ResultDescriptor>[ |
+ LIBRARY_CYCLE, |
+ LIBRARY_CYCLE_UNITS, |
+ LIBRARY_CYCLE_DEPENDENCIES |
+ ]); |
+ |
+ ComputeLibraryCycleTask( |
+ InternalAnalysisContext context, AnalysisTarget target) |
+ : super(context, target); |
+ |
+ @override |
+ TaskDescriptor get descriptor => DESCRIPTOR; |
+ |
+ @override |
+ void internalPerform() { |
+ if (context.analysisOptions.strongMode) { |
+ LibraryElementImpl library = getRequiredInput(LIBRARY_ELEMENT_INPUT); |
+ List<LibraryElement> component = library.libraryCycle; |
+ Set<LibraryElement> filter = new Set<LibraryElement>.from(component); |
+ Set<CompilationUnitElement> deps = new Set<CompilationUnitElement>(); |
+ void addLibrary(l) { |
+ if (!filter.contains(l)) { |
+ deps.addAll(l.units); |
+ } |
+ } |
+ for (LibraryElement l in component) { |
+ l.importedLibraries.forEach(addLibrary); |
+ l.exportedLibraries.forEach(addLibrary); |
+ } |
+ |
+ // |
+ // Record outputs. |
+ // |
+ outputs[LIBRARY_CYCLE] = component; |
+ outputs[LIBRARY_CYCLE_UNITS] = component.expand((l) => l.units).toList(); |
+ outputs[LIBRARY_CYCLE_DEPENDENCIES] = deps.toList(); |
+ } else { |
+ outputs[LIBRARY_CYCLE] = []; |
+ outputs[LIBRARY_CYCLE_UNITS] = []; |
+ outputs[LIBRARY_CYCLE_DEPENDENCIES] = []; |
+ } |
+ } |
+ |
+ /** |
+ * 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>{ |
+ 'resolveReachableLibraries': IMPORT_EXPORT_SOURCE_CLOSURE |
+ .of(unit.library) |
+ .toListOf(LIBRARY_ELEMENT2), |
+ LIBRARY_ELEMENT_INPUT: LIBRARY_ELEMENT2.of(unit.library) |
+ }; |
+ } |
+ |
+ /** |
+ * Create a [ComputeLibraryCycleTask] based on the |
+ * given [target] in the given [context]. |
+ */ |
+ static ComputeLibraryCycleTask createTask( |
+ AnalysisContext context, AnalysisTarget target) { |
+ return new ComputeLibraryCycleTask(context, target); |
+ } |
+} |
+ |
+/** |
* A base class for analysis tasks whose target is expected to be a |
* [ConstantEvaluationTarget]. |
*/ |
@@ -1565,7 +1895,9 @@ class ContainingLibrariesTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'ContainingLibrariesTask', createTask, buildInputs, |
+ 'ContainingLibrariesTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[CONTAINING_LIBRARIES]); |
ContainingLibrariesTask( |
@@ -1705,31 +2037,6 @@ class DartDelta extends Delta { |
*/ |
class DartErrorsTask extends SourceBasedAnalysisTask { |
/** |
- * The name of the [BUILD_DIRECTIVES_ERRORS] input. |
- */ |
- static const String BUILD_DIRECTIVES_ERRORS_INPUT = 'BUILD_DIRECTIVES_ERRORS'; |
- |
- /** |
- * The name of the [BUILD_LIBRARY_ERRORS] input. |
- */ |
- static const String BUILD_LIBRARY_ERRORS_INPUT = 'BUILD_LIBRARY_ERRORS'; |
- |
- /** |
- * The name of the [LIBRARY_UNIT_ERRORS] input. |
- */ |
- static const String LIBRARY_UNIT_ERRORS_INPUT = 'LIBRARY_UNIT_ERRORS'; |
- |
- /** |
- * The name of the [PARSE_ERRORS] input. |
- */ |
- static const String PARSE_ERRORS_INPUT = 'PARSE_ERRORS'; |
- |
- /** |
- * The name of the [SCAN_ERRORS] input. |
- */ |
- static const String SCAN_ERRORS_INPUT = 'SCAN_ERRORS'; |
- |
- /** |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor('DartErrorsTask', |
@@ -1743,18 +2050,21 @@ class DartErrorsTask extends SourceBasedAnalysisTask { |
@override |
void internalPerform() { |
+ List<List<AnalysisError>> errorLists = <List<AnalysisError>>[]; |
// |
// Prepare inputs. |
// |
- List<List<AnalysisError>> errorLists = <List<AnalysisError>>[]; |
- errorLists.add(getRequiredInput(BUILD_DIRECTIVES_ERRORS_INPUT)); |
- errorLists.add(getRequiredInput(BUILD_LIBRARY_ERRORS_INPUT)); |
- errorLists.add(getRequiredInput(PARSE_ERRORS_INPUT)); |
- errorLists.add(getRequiredInput(SCAN_ERRORS_INPUT)); |
- Map<Source, List<AnalysisError>> unitErrors = |
- getRequiredInput(LIBRARY_UNIT_ERRORS_INPUT); |
- for (List<AnalysisError> errors in unitErrors.values) { |
- errorLists.add(errors); |
+ EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin; |
+ for (ResultDescriptor result in enginePlugin.dartErrorsForSource) { |
+ String inputName = result.name + '_input'; |
+ errorLists.add(getRequiredInput(inputName)); |
+ } |
+ for (ResultDescriptor result in enginePlugin.dartErrorsForUnit) { |
+ String inputName = result.name + '_input'; |
+ Map<Source, List<AnalysisError>> errorMap = getRequiredInput(inputName); |
+ for (List<AnalysisError> errors in errorMap.values) { |
+ errorLists.add(errors); |
+ } |
} |
// |
// Record outputs. |
@@ -1769,18 +2079,23 @@ class DartErrorsTask extends SourceBasedAnalysisTask { |
*/ |
static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
Source source = target; |
- return <String, TaskInput>{ |
- BUILD_DIRECTIVES_ERRORS_INPUT: BUILD_DIRECTIVES_ERRORS.of(source), |
- BUILD_LIBRARY_ERRORS_INPUT: BUILD_LIBRARY_ERRORS.of(source), |
- PARSE_ERRORS_INPUT: PARSE_ERRORS.of(source), |
- SCAN_ERRORS_INPUT: SCAN_ERRORS.of(source), |
- LIBRARY_UNIT_ERRORS_INPUT: CONTAINING_LIBRARIES |
- .of(source) |
- .toMap((Source library) { |
+ Map<String, TaskInput> inputs = <String, TaskInput>{}; |
+ EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin; |
+ // for Source |
+ for (ResultDescriptor result in enginePlugin.dartErrorsForSource) { |
+ String inputName = result.name + '_input'; |
+ inputs[inputName] = result.of(source); |
+ } |
+ // for LibrarySpecificUnit |
+ for (ResultDescriptor result in enginePlugin.dartErrorsForUnit) { |
+ String inputName = result.name + '_input'; |
+ inputs[inputName] = |
+ CONTAINING_LIBRARIES.of(source).toMap((Source library) { |
LibrarySpecificUnit unit = new LibrarySpecificUnit(library, source); |
- return LIBRARY_UNIT_ERRORS.of(unit); |
- }) |
- }; |
+ return result.of(unit); |
+ }); |
+ } |
+ return inputs; |
} |
/** |
@@ -1798,7 +2113,7 @@ class DartErrorsTask extends SourceBasedAnalysisTask { |
*/ |
class EvaluateUnitConstantsTask extends SourceBasedAnalysisTask { |
/** |
- * The name of the [RESOLVED_UNIT5] input. |
+ * The name of the [RESOLVED_UNIT9] input. |
*/ |
static const String UNIT_INPUT = 'UNIT_INPUT'; |
@@ -1811,7 +2126,9 @@ class EvaluateUnitConstantsTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'EvaluateUnitConstantsTask', createTask, buildInputs, |
+ 'EvaluateUnitConstantsTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[RESOLVED_UNIT]); |
EvaluateUnitConstantsTask(AnalysisContext context, LibrarySpecificUnit target) |
@@ -1837,7 +2154,7 @@ class EvaluateUnitConstantsTask extends SourceBasedAnalysisTask { |
LibrarySpecificUnit unit = target; |
return <String, TaskInput>{ |
'libraryElement': LIBRARY_ELEMENT.of(unit.library), |
- UNIT_INPUT: RESOLVED_UNIT5.of(unit), |
+ UNIT_INPUT: RESOLVED_UNIT9.of(unit), |
CONSTANT_VALUES: |
COMPILATION_UNIT_CONSTANTS.of(unit).toListOf(CONSTANT_VALUE) |
}; |
@@ -1961,7 +2278,7 @@ class ExportNamespaceBuilder { |
*/ |
class GatherUsedImportedElementsTask extends SourceBasedAnalysisTask { |
/** |
- * The name of the [RESOLVED_UNIT5] input. |
+ * The name of the [RESOLVED_UNIT9] input. |
*/ |
static const String UNIT_INPUT = 'UNIT_INPUT'; |
@@ -1969,7 +2286,9 @@ class GatherUsedImportedElementsTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'GatherUsedImportedElementsTask', createTask, buildInputs, |
+ 'GatherUsedImportedElementsTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[USED_IMPORTED_ELEMENTS]); |
GatherUsedImportedElementsTask( |
@@ -2003,7 +2322,7 @@ class GatherUsedImportedElementsTask extends SourceBasedAnalysisTask { |
*/ |
static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
LibrarySpecificUnit unit = target; |
- return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT5.of(unit)}; |
+ return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT9.of(unit)}; |
} |
/** |
@@ -2021,7 +2340,7 @@ class GatherUsedImportedElementsTask extends SourceBasedAnalysisTask { |
*/ |
class GatherUsedLocalElementsTask extends SourceBasedAnalysisTask { |
/** |
- * The name of the [RESOLVED_UNIT5] input. |
+ * The name of the [RESOLVED_UNIT9] input. |
*/ |
static const String UNIT_INPUT = 'UNIT_INPUT'; |
@@ -2029,7 +2348,9 @@ class GatherUsedLocalElementsTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'GatherUsedLocalElementsTask', createTask, buildInputs, |
+ 'GatherUsedLocalElementsTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[USED_LOCAL_ELEMENTS]); |
GatherUsedLocalElementsTask( |
@@ -2063,7 +2384,7 @@ class GatherUsedLocalElementsTask extends SourceBasedAnalysisTask { |
*/ |
static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
LibrarySpecificUnit unit = target; |
- return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT5.of(unit)}; |
+ return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT9.of(unit)}; |
} |
/** |
@@ -2081,7 +2402,7 @@ class GatherUsedLocalElementsTask extends SourceBasedAnalysisTask { |
*/ |
class GenerateHintsTask extends SourceBasedAnalysisTask { |
/** |
- * The name of the [RESOLVED_UNIT5] input. |
+ * The name of the [RESOLVED_UNIT9] input. |
*/ |
static const String RESOLVED_UNIT_INPUT = 'RESOLVED_UNIT'; |
@@ -2135,10 +2456,12 @@ class GenerateHintsTask extends SourceBasedAnalysisTask { |
getRequiredInput(USED_LOCAL_ELEMENTS_INPUT); |
CompilationUnitElement unitElement = unit.element; |
LibraryElement libraryElement = unitElement.library; |
+ TypeSystem typeSystem = context.typeSystem; |
+ |
// |
// Generate errors. |
// |
- unit.accept(new DeadCodeVerifier(errorReporter)); |
+ unit.accept(new DeadCodeVerifier(errorReporter, typeSystem: typeSystem)); |
// Verify imports. |
{ |
ImportsVerifier verifier = new ImportsVerifier(); |
@@ -2163,7 +2486,9 @@ class GenerateHintsTask extends SourceBasedAnalysisTask { |
InheritanceManager inheritanceManager = |
new InheritanceManager(libraryElement); |
TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); |
- unit.accept(new BestPracticesVerifier(errorReporter, typeProvider)); |
+ |
+ unit.accept(new BestPracticesVerifier(errorReporter, typeProvider, |
+ typeSystem: typeSystem)); |
unit.accept(new OverrideVerifier(errorReporter, inheritanceManager)); |
// Find to-do comments. |
new ToDoFinder(errorReporter).findIn(unit); |
@@ -2206,22 +2531,559 @@ class GenerateHintsTask extends SourceBasedAnalysisTask { |
} |
/** |
- * A task computes all of the errors of all of the units for a single |
- * library source and sets the [LIBRARY_ERRORS_READY] flag. |
+ * A task that generates [LINTS] for a unit. |
*/ |
-class LibraryErrorsReadyTask extends SourceBasedAnalysisTask { |
+class GenerateLintsTask extends SourceBasedAnalysisTask { |
/** |
- * The task descriptor describing this kind of task. |
+ * The name of the [RESOLVED_UNIT8] input. |
*/ |
- static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'LibraryErrorsReadyTask', createTask, buildInputs, |
- <ResultDescriptor>[LIBRARY_ERRORS_READY]); |
+ static const String RESOLVED_UNIT_INPUT = 'RESOLVED_UNIT'; |
- LibraryErrorsReadyTask(InternalAnalysisContext context, AnalysisTarget target) |
- : super(context, target); |
+ /** |
+ * The name of a list of [USED_LOCAL_ELEMENTS] for each library unit input. |
+ */ |
+ static const String USED_LOCAL_ELEMENTS_INPUT = 'USED_LOCAL_ELEMENTS'; |
- @override |
- TaskDescriptor get descriptor => DESCRIPTOR; |
+ /** |
+ * The name of a list of [USED_IMPORTED_ELEMENTS] for each library unit input. |
+ */ |
+ static const String USED_IMPORTED_ELEMENTS_INPUT = 'USED_IMPORTED_ELEMENTS'; |
+ |
+ /** |
+ * The name of the [TYPE_PROVIDER] input. |
+ */ |
+ static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT'; |
+ |
+ /** |
+ * The task descriptor describing this kind of task. |
+ */ |
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
+ 'GenerateLintsTask', createTask, buildInputs, <ResultDescriptor>[LINTS]); |
+ |
+ GenerateLintsTask(InternalAnalysisContext context, AnalysisTarget target) |
+ : super(context, target); |
+ |
+ @override |
+ TaskDescriptor get descriptor => DESCRIPTOR; |
+ |
+ @override |
+ void internalPerform() { |
+ AnalysisOptions analysisOptions = context.analysisOptions; |
+ if (!analysisOptions.lint) { |
+ outputs[LINTS] = AnalysisError.NO_ERRORS; |
+ return; |
+ } |
+ // |
+ // Prepare collectors. |
+ // |
+ RecordingErrorListener errorListener = new RecordingErrorListener(); |
+ Source source = getRequiredSource(); |
+ ErrorReporter errorReporter = new ErrorReporter(errorListener, source); |
+ // |
+ // Prepare inputs. |
+ // |
+ CompilationUnit unit = getRequiredInput(RESOLVED_UNIT_INPUT); |
+ |
+ // |
+ // Generate lints. |
+ // |
+ LintGenerator.LINTERS.forEach((l) => l.reporter = errorReporter); |
+ Iterable<AstVisitor> visitors = |
+ LintGenerator.LINTERS.map((l) => l.getVisitor()).toList(); |
+ unit.accept(new DelegatingAstVisitor(visitors.where((v) => v != null))); |
+ |
+ // |
+ // Record outputs. |
+ // |
+ outputs[LINTS] = errorListener.errors; |
+ } |
+ |
+ /** |
+ * 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) => |
+ <String, TaskInput>{RESOLVED_UNIT_INPUT: RESOLVED_UNIT.of(target)}; |
+ |
+ /** |
+ * Create a [GenerateLintsTask] based on the given [target] in |
+ * the given [context]. |
+ */ |
+ static GenerateLintsTask createTask( |
+ AnalysisContext context, AnalysisTarget target) { |
+ return new GenerateLintsTask(context, target); |
+ } |
+} |
+ |
+/** |
+ * A task that ensures that all of the inferrable instance members in a |
+ * compilation unit have had their type inferred. |
+ */ |
+class InferInstanceMembersInUnitTask extends SourceBasedAnalysisTask { |
+ /** |
+ * The name of the [TYPE_PROVIDER] input. |
+ */ |
+ static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT'; |
+ |
+ /** |
+ * The name of the input whose value is the [RESOLVED_UNIT6] for the |
+ * compilation unit. |
+ */ |
+ static const String UNIT_INPUT = 'UNIT_INPUT'; |
+ |
+ /** |
+ * The task descriptor describing this kind of task. |
+ */ |
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
+ 'InferInstanceMembersInUnitTask', |
+ createTask, |
+ buildInputs, |
+ <ResultDescriptor>[RESOLVED_UNIT8]); |
+ |
+ /** |
+ * Initialize a newly created task to build a library element for the given |
+ * [unit] in the given [context]. |
+ */ |
+ InferInstanceMembersInUnitTask( |
+ InternalAnalysisContext context, LibrarySpecificUnit unit) |
+ : super(context, unit); |
+ |
+ @override |
+ TaskDescriptor get descriptor => DESCRIPTOR; |
+ |
+ @override |
+ void internalPerform() { |
+ // |
+ // Prepare inputs. |
+ // |
+ CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
+ TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); |
+ // |
+ // Infer instance members. |
+ // |
+ if (context.analysisOptions.strongMode) { |
+ InstanceMemberInferrer inferrer = new InstanceMemberInferrer(typeProvider, |
+ typeSystem: context.typeSystem); |
+ inferrer.inferCompilationUnit(unit.element); |
+ } |
+ // |
+ // Record outputs. |
+ // |
+ outputs[RESOLVED_UNIT8] = unit; |
+ } |
+ |
+ /** |
+ * 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 |
+ * [libSource]. |
+ */ |
+ static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
+ LibrarySpecificUnit unit = target; |
+ return <String, TaskInput>{ |
+ UNIT_INPUT: RESOLVED_UNIT7.of(unit), |
+ TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request), |
+ // In strong mode, add additional dependencies to enforce inference |
+ // ordering. |
+ |
+ // Require that field re-resolution be complete for all units in the |
+ // current library cycle. |
+ 'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList( |
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT7 |
+ .of(new LibrarySpecificUnit(unit.librarySource, unit.source))), |
+ // Require that full inference be complete for all dependencies of the |
+ // current library cycle. |
+ 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList( |
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT8 |
+ .of(new LibrarySpecificUnit(unit.librarySource, unit.source))) |
+ }; |
+ } |
+ |
+ /** |
+ * Create a [InferInstanceMembersInUnitTask] based on the given [target] in |
+ * the given [context]. |
+ */ |
+ static InferInstanceMembersInUnitTask createTask( |
+ AnalysisContext context, AnalysisTarget target) { |
+ return new InferInstanceMembersInUnitTask(context, target); |
+ } |
+} |
+ |
+/** |
+ * A task that ensures that all of the inferrable instance members in a |
+ * compilation unit have had their right hand sides re-resolved |
+ */ |
+class ResolveInstanceFieldsInUnitTask extends SourceBasedAnalysisTask { |
+ /** |
+ * The name of the [LIBRARY_ELEMENT5] input. |
+ */ |
+ static const String LIBRARY_INPUT = 'LIBRARY_INPUT'; |
+ |
+ /** |
+ * The name of the [TYPE_PROVIDER] input. |
+ */ |
+ static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT'; |
+ |
+ /** |
+ * The name of the input whose value is the [RESOLVED_UNIT6] for the |
+ * compilation unit. |
+ */ |
+ static const String UNIT_INPUT = 'UNIT_INPUT'; |
+ |
+ /** |
+ * The task descriptor describing this kind of task. |
+ */ |
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
+ 'ResolveInstanceFieldsInUnitTask', |
+ createTask, |
+ buildInputs, |
+ <ResultDescriptor>[RESOLVED_UNIT7]); |
+ |
+ /** |
+ * Initialize a newly created task to build a library element for the given |
+ * [unit] in the given [context]. |
+ */ |
+ ResolveInstanceFieldsInUnitTask( |
+ InternalAnalysisContext context, LibrarySpecificUnit unit) |
+ : super(context, unit); |
+ |
+ @override |
+ TaskDescriptor get descriptor => DESCRIPTOR; |
+ |
+ @override |
+ void internalPerform() { |
+ // |
+ // Prepare inputs. |
+ // |
+ LibraryElement libraryElement = getRequiredInput(LIBRARY_INPUT); |
+ CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
+ TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); |
+ |
+ CompilationUnitElement unitElement = unit.element; |
+ if (context.analysisOptions.strongMode) { |
+ // |
+ // Resolve references. |
+ // |
+ // TODO(leafp): This code only needs to re-resolve the right hand sides of |
+ // instance fields. We could do incremental resolution on each field |
+ // only using the incremental resolver. However, this caused a massive |
+ // performance degredation on the large_class_declaration_test.dart test. |
+ // I would hypothesize that incremental resolution of field is linear in |
+ // the size of the enclosing class, and hence incrementally resolving each |
+ // field was quadratic. We may wish to revisit this if we can resolve |
+ // this performance issue. |
+ InheritanceManager inheritanceManager = |
+ new InheritanceManager(libraryElement); |
+ PartialResolverVisitor visitor = new PartialResolverVisitor( |
+ libraryElement, |
+ unitElement.source, |
+ typeProvider, |
+ AnalysisErrorListener.NULL_LISTENER, |
+ inheritanceManager: inheritanceManager); |
+ unit.accept(visitor); |
+ } |
+ // |
+ // Record outputs. |
+ // |
+ outputs[RESOLVED_UNIT7] = unit; |
+ } |
+ |
+ /** |
+ * 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 |
+ * [libSource]. |
+ */ |
+ static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
+ LibrarySpecificUnit unit = target; |
+ return <String, TaskInput>{ |
+ UNIT_INPUT: RESOLVED_UNIT6.of(unit), |
+ LIBRARY_INPUT: LIBRARY_ELEMENT5.of(unit.library), |
+ TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request), |
+ // In strong mode, add additional dependencies to enforce inference |
+ // ordering. |
+ |
+ // Require that static variable inference be complete for all units in |
+ // the current library cycle. |
+ 'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList( |
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT6 |
+ .of(new LibrarySpecificUnit(unit.librarySource, unit.source))), |
+ // Require that full inference be complete for all dependencies of the |
+ // current library cycle. |
+ 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList( |
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT8 |
+ .of(new LibrarySpecificUnit(unit.librarySource, unit.source))) |
+ }; |
+ } |
+ |
+ /** |
+ * Create a [ResolveInstanceFieldsInUnitTask] based on the given [target] in |
+ * the given [context]. |
+ */ |
+ static ResolveInstanceFieldsInUnitTask createTask( |
+ AnalysisContext context, AnalysisTarget target) { |
+ return new ResolveInstanceFieldsInUnitTask(context, target); |
+ } |
+} |
+ |
+/** |
+ * An abstract class that defines utility methods that are useful for tasks |
+ * operating on static variables. |
+ */ |
+abstract class InferStaticVariableTask extends ConstantEvaluationAnalysisTask { |
+ InferStaticVariableTask( |
+ InternalAnalysisContext context, VariableElement variable) |
+ : super(context, variable); |
+ |
+ /** |
+ * Return the declaration of the target within the given compilation [unit]. |
+ * Throw an exception if the declaration cannot be found. |
+ */ |
+ VariableDeclaration getDeclaration(CompilationUnit unit) { |
+ VariableElement variable = target; |
+ NodeLocator locator = new NodeLocator(variable.nameOffset); |
+ AstNode node = locator.searchWithin(unit); |
+ VariableDeclaration declaration = |
+ node.getAncestor((AstNode ancestor) => ancestor is VariableDeclaration); |
+ if (declaration == null || declaration.name != node) { |
+ throw new AnalysisException( |
+ "Failed to find the declaration of the variable ${variable.displayName} in ${variable.source}"); |
+ } |
+ return declaration; |
+ } |
+} |
+ |
+/** |
+ * A task that ensures that all of the inferrable static variables in a |
+ * compilation unit have had their type inferred. |
+ */ |
+class InferStaticVariableTypesInUnitTask extends SourceBasedAnalysisTask { |
+ /** |
+ * The name of the input whose value is the [RESOLVED_UNIT5] for the |
+ * compilation unit. |
+ */ |
+ static const String UNIT_INPUT = 'UNIT_INPUT'; |
+ |
+ /** |
+ * The name of the input whose value is a list of the inferrable static |
+ * variables whose types have been computed. |
+ */ |
+ static const String INFERRED_VARIABLES_INPUT = 'INFERRED_VARIABLES_INPUT'; |
+ |
+ /** |
+ * The task descriptor describing this kind of task. |
+ */ |
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
+ 'InferStaticVariableTypesInUnitTask', |
+ createTask, |
+ buildInputs, |
+ <ResultDescriptor>[RESOLVED_UNIT6]); |
+ |
+ /** |
+ * Initialize a newly created task to build a library element for the given |
+ * [unit] in the given [context]. |
+ */ |
+ InferStaticVariableTypesInUnitTask( |
+ InternalAnalysisContext context, LibrarySpecificUnit unit) |
+ : super(context, unit); |
+ |
+ @override |
+ TaskDescriptor get descriptor => DESCRIPTOR; |
+ |
+ @override |
+ void internalPerform() { |
+ // |
+ // Prepare inputs. |
+ // |
+ CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
+ // |
+ // 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[RESOLVED_UNIT6] = unit; |
+ } |
+ |
+ /** |
+ * 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 |
+ * [libSource]. |
+ */ |
+ static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
+ LibrarySpecificUnit unit = target; |
+ return <String, TaskInput>{ |
+ INFERRED_VARIABLES_INPUT: INFERABLE_STATIC_VARIABLES_IN_UNIT |
+ .of(unit) |
+ .toListOf(INFERRED_STATIC_VARIABLE), |
+ UNIT_INPUT: RESOLVED_UNIT5.of(unit) |
+ }; |
+ } |
+ |
+ /** |
+ * Create a [InferStaticVariableTypesInUnitTask] based on the given [target] |
+ * in the given [context]. |
+ */ |
+ static InferStaticVariableTypesInUnitTask createTask( |
+ AnalysisContext context, AnalysisTarget target) { |
+ return new InferStaticVariableTypesInUnitTask(context, target); |
+ } |
+} |
+ |
+/** |
+ * A task that computes the type of an inferrable static variable and |
+ * stores it in the element model. |
+ */ |
+class InferStaticVariableTypeTask extends InferStaticVariableTask { |
+ /** |
+ * The name of the input which ensures that dependent values have their type |
+ * inferred before the target. |
+ */ |
+ static const String DEPENDENCIES_INPUT = 'DEPENDENCIES_INPUT'; |
+ |
+ /** |
+ * The name of the [TYPE_PROVIDER] input. |
+ */ |
+ static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT'; |
+ |
+ /** |
+ * The name of the [RESOLVED_UNIT5] input. |
+ */ |
+ static const String UNIT_INPUT = 'UNIT_INPUT'; |
+ |
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
+ 'InferStaticVariableTypeTask', |
+ createTask, |
+ buildInputs, |
+ <ResultDescriptor>[INFERRED_STATIC_VARIABLE]); |
+ |
+ InferStaticVariableTypeTask( |
+ InternalAnalysisContext context, VariableElement variable) |
+ : super(context, variable); |
+ |
+ @override |
+ TaskDescriptor get descriptor => DESCRIPTOR; |
+ |
+ @override |
+ bool get handlesDependencyCycles => true; |
+ |
+ @override |
+ void internalPerform() { |
+ // |
+ // Prepare inputs. |
+ // |
+ // Note: DEPENDENCIES_INPUT is not needed. It is merely a bookkeeping |
+ // dependency to ensure that the variables that this variable references |
+ // have types inferred before inferring the type of this variable. |
+ // |
+ VariableElementImpl variable = target; |
+ |
+ CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
+ TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); |
+ |
+ // If we're not in a dependency cycle, and we have no type annotation, |
+ // re-resolve the right hand side and do inference. |
+ if (dependencyCycle == null && variable.hasImplicitType) { |
+ VariableDeclaration declaration = getDeclaration(unit); |
+ // |
+ // Re-resolve the variable's initializer so that the inferred types |
+ // of other variables will be propagated. |
+ // |
+ Expression initializer = declaration.initializer; |
+ ResolutionContext resolutionContext = ResolutionContextBuilder.contextFor( |
+ initializer, AnalysisErrorListener.NULL_LISTENER); |
+ ResolverVisitor visitor = new ResolverVisitor(variable.library, |
+ variable.source, typeProvider, AnalysisErrorListener.NULL_LISTENER, |
+ nameScope: resolutionContext.scope); |
+ if (resolutionContext.enclosingClassDeclaration != null) { |
+ visitor.prepareToResolveMembersInClass( |
+ resolutionContext.enclosingClassDeclaration); |
+ } |
+ visitor.initForIncrementalResolution(); |
+ initializer.accept(visitor); |
+ |
+ // |
+ // Record the type of the variable. |
+ // |
+ DartType newType = initializer.staticType; |
+ if (newType == null || newType.isBottom) { |
+ newType = typeProvider.dynamicType; |
+ } |
+ variable.type = newType; |
+ (variable.initializer as ExecutableElementImpl).returnType = newType; |
+ if (variable is PropertyInducingElementImpl) { |
+ setReturnType(variable.getter, newType); |
+ if (!variable.isFinal && !variable.isConst) { |
+ setParameterType(variable.setter, newType); |
+ } |
+ } |
+ } else { |
+ // TODO(brianwilkerson) For now we simply don't infer any type for |
+ // variables or fields involved in a cycle. We could try to be smarter |
+ // by re-resolving the initializer in a context in which the types of all |
+ // of the variables in the cycle are assumed to be `null`, but it isn't |
+ // clear to me that this would produce better results often enough to |
+ // warrant the extra effort. |
+ } |
+ // |
+ // Record outputs. |
+ // |
+ outputs[INFERRED_STATIC_VARIABLE] = variable; |
+ } |
+ |
+ /** |
+ * 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) { |
+ VariableElement variable = target; |
+ LibrarySpecificUnit unit = |
+ new LibrarySpecificUnit(variable.library.source, variable.source); |
+ return <String, TaskInput>{ |
+ DEPENDENCIES_INPUT: INFERABLE_STATIC_VARIABLE_DEPENDENCIES |
+ .of(variable) |
+ .toListOf(INFERRED_STATIC_VARIABLE), |
+ TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request), |
+ UNIT_INPUT: RESOLVED_UNIT5.of(unit), |
+ // In strong mode, add additional dependencies to enforce inference |
+ // ordering. |
+ |
+ // Require that full inference be complete for all dependencies of the |
+ // current library cycle. |
+ 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList( |
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT8 |
+ .of(new LibrarySpecificUnit(unit.librarySource, unit.source))) |
+ }; |
+ } |
+ |
+ /** |
+ * Create a [InferStaticVariableTypeTask] based on the given [target] in the |
+ * given [context]. |
+ */ |
+ static InferStaticVariableTypeTask createTask( |
+ AnalysisContext context, AnalysisTarget target) { |
+ return new InferStaticVariableTypeTask(context, target); |
+ } |
+} |
+ |
+/** |
+ * A task computes all of the errors of all of the units for a single |
+ * library source and sets the [LIBRARY_ERRORS_READY] flag. |
+ */ |
+class LibraryErrorsReadyTask extends SourceBasedAnalysisTask { |
+ /** |
+ * The task descriptor describing this kind of task. |
+ */ |
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
+ 'LibraryErrorsReadyTask', |
+ createTask, |
+ buildInputs, |
+ <ResultDescriptor>[LIBRARY_ERRORS_READY]); |
+ |
+ LibraryErrorsReadyTask(InternalAnalysisContext context, AnalysisTarget target) |
+ : super(context, target); |
+ |
+ @override |
+ TaskDescriptor get descriptor => DESCRIPTOR; |
@override |
void internalPerform() { |
@@ -2256,15 +3118,24 @@ class LibraryErrorsReadyTask extends SourceBasedAnalysisTask { |
*/ |
class LibraryUnitErrorsTask extends SourceBasedAnalysisTask { |
/** |
+ * The name of the [BUILD_DIRECTIVES_ERRORS] input. |
+ */ |
+ static const String BUILD_DIRECTIVES_ERRORS_INPUT = 'BUILD_DIRECTIVES_ERRORS'; |
+ |
+ /** |
+ * The name of the [BUILD_LIBRARY_ERRORS] input. |
+ */ |
+ static const String BUILD_LIBRARY_ERRORS_INPUT = 'BUILD_LIBRARY_ERRORS'; |
+ |
+ /** |
* The name of the [HINTS] input. |
*/ |
static const String HINTS_INPUT = 'HINTS'; |
/** |
- * The name of the [RESOLVE_REFERENCES_ERRORS] input. |
+ * The name of the [LINTS] input. |
*/ |
- static const String RESOLVE_REFERENCES_ERRORS_INPUT = |
- 'RESOLVE_REFERENCES_ERRORS'; |
+ static const String LINTS_INPUT = 'LINTS'; |
/** |
* The name of the [RESOLVE_TYPE_NAMES_ERRORS] input. |
@@ -2273,6 +3144,11 @@ class LibraryUnitErrorsTask extends SourceBasedAnalysisTask { |
'RESOLVE_TYPE_NAMES_ERRORS'; |
/** |
+ * The name of the [RESOLVE_UNIT_ERRORS] input. |
+ */ |
+ static const String RESOLVE_UNIT_ERRORS_INPUT = 'RESOLVE_UNIT_ERRORS'; |
+ |
+ /** |
* The name of the [VARIABLE_REFERENCE_ERRORS] input. |
*/ |
static const String VARIABLE_REFERENCE_ERRORS_INPUT = |
@@ -2287,7 +3163,9 @@ class LibraryUnitErrorsTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'LibraryUnitErrorsTask', createTask, buildInputs, |
+ 'LibraryUnitErrorsTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[LIBRARY_UNIT_ERRORS]); |
LibraryUnitErrorsTask(InternalAnalysisContext context, AnalysisTarget target) |
@@ -2302,9 +3180,12 @@ class LibraryUnitErrorsTask extends SourceBasedAnalysisTask { |
// Prepare inputs. |
// |
List<List<AnalysisError>> errorLists = <List<AnalysisError>>[]; |
+ errorLists.add(getRequiredInput(BUILD_DIRECTIVES_ERRORS_INPUT)); |
+ errorLists.add(getRequiredInput(BUILD_LIBRARY_ERRORS_INPUT)); |
errorLists.add(getRequiredInput(HINTS_INPUT)); |
- errorLists.add(getRequiredInput(RESOLVE_REFERENCES_ERRORS_INPUT)); |
+ errorLists.add(getRequiredInput(LINTS_INPUT)); |
errorLists.add(getRequiredInput(RESOLVE_TYPE_NAMES_ERRORS_INPUT)); |
+ errorLists.add(getRequiredInput(RESOLVE_UNIT_ERRORS_INPUT)); |
errorLists.add(getRequiredInput(VARIABLE_REFERENCE_ERRORS_INPUT)); |
errorLists.add(getRequiredInput(VERIFY_ERRORS_INPUT)); |
// |
@@ -2320,13 +3201,26 @@ class LibraryUnitErrorsTask extends SourceBasedAnalysisTask { |
*/ |
static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
LibrarySpecificUnit unit = target; |
- return <String, TaskInput>{ |
+ Map<String, TaskInput> inputs = <String, TaskInput>{ |
HINTS_INPUT: HINTS.of(unit), |
- RESOLVE_REFERENCES_ERRORS_INPUT: RESOLVE_REFERENCES_ERRORS.of(unit), |
+ LINTS_INPUT: LINTS.of(unit), |
RESOLVE_TYPE_NAMES_ERRORS_INPUT: RESOLVE_TYPE_NAMES_ERRORS.of(unit), |
+ RESOLVE_UNIT_ERRORS_INPUT: RESOLVE_UNIT_ERRORS.of(unit), |
VARIABLE_REFERENCE_ERRORS_INPUT: VARIABLE_REFERENCE_ERRORS.of(unit), |
VERIFY_ERRORS_INPUT: VERIFY_ERRORS.of(unit) |
}; |
+ Source source = unit.source; |
+ if (unit.library == source) { |
+ inputs[BUILD_DIRECTIVES_ERRORS_INPUT] = |
+ BUILD_DIRECTIVES_ERRORS.of(source); |
+ inputs[BUILD_LIBRARY_ERRORS_INPUT] = BUILD_LIBRARY_ERRORS.of(source); |
+ } else { |
+ inputs[BUILD_DIRECTIVES_ERRORS_INPUT] = |
+ new ConstantTaskInput(AnalysisError.NO_ERRORS); |
+ inputs[BUILD_LIBRARY_ERRORS_INPUT] = |
+ new ConstantTaskInput(AnalysisError.NO_ERRORS); |
+ } |
+ return inputs; |
} |
/** |
@@ -2363,8 +3257,8 @@ class ParseDartTask extends SourceBasedAnalysisTask { |
/** |
* The task descriptor describing this kind of task. |
*/ |
- static final TaskDescriptor DESCRIPTOR = new TaskDescriptor('ParseDartTask', |
- createTask, buildInputs, <ResultDescriptor>[ |
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
+ 'ParseDartTask', createTask, buildInputs, <ResultDescriptor>[ |
EXPLICITLY_IMPORTED_LIBRARIES, |
EXPORTED_LIBRARIES, |
IMPORTED_LIBRARIES, |
@@ -2528,6 +3422,108 @@ class ParseDartTask extends SourceBasedAnalysisTask { |
} |
/** |
+ * A task that builds [RESOLVED_UNIT5] for a unit. |
+ */ |
+class PartiallyResolveUnitReferencesTask extends SourceBasedAnalysisTask { |
+ /** |
+ * The name of the [LIBRARY_ELEMENT5] input. |
+ */ |
+ static const String LIBRARY_INPUT = 'LIBRARY_INPUT'; |
+ |
+ /** |
+ * The name of the [RESOLVED_UNIT4] input. |
+ */ |
+ static const String UNIT_INPUT = 'UNIT_INPUT'; |
+ |
+ /** |
+ * The name of the [TYPE_PROVIDER] input. |
+ */ |
+ static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT'; |
+ |
+ /** |
+ * The task descriptor describing this kind of task. |
+ */ |
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
+ 'PartiallyResolveUnitReferencesTask', |
+ createTask, |
+ buildInputs, |
+ <ResultDescriptor>[INFERABLE_STATIC_VARIABLES_IN_UNIT, RESOLVED_UNIT5]); |
+ |
+ PartiallyResolveUnitReferencesTask( |
+ InternalAnalysisContext context, AnalysisTarget target) |
+ : super(context, target); |
+ |
+ @override |
+ TaskDescriptor get descriptor => DESCRIPTOR; |
+ |
+ @override |
+ void internalPerform() { |
+ // |
+ // Prepare inputs. |
+ // |
+ LibraryElement libraryElement = getRequiredInput(LIBRARY_INPUT); |
+ CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
+ CompilationUnitElement unitElement = unit.element; |
+ TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); |
+ if (context.analysisOptions.strongMode) { |
+ // |
+ // Resolve references. |
+ // |
+ InheritanceManager inheritanceManager = |
+ new InheritanceManager(libraryElement); |
+ PartialResolverVisitor visitor = new PartialResolverVisitor( |
+ libraryElement, |
+ unitElement.source, |
+ typeProvider, |
+ AnalysisErrorListener.NULL_LISTENER, |
+ inheritanceManager: inheritanceManager); |
+ unit.accept(visitor); |
+ // |
+ // Record outputs. |
+ // |
+ outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = visitor.variablesAndFields; |
+ } else { |
+ outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = []; |
+ } |
+ outputs[RESOLVED_UNIT5] = unit; |
+ } |
+ |
+ /** |
+ * 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>{ |
+ 'fullyBuiltLibraryElements': IMPORT_EXPORT_SOURCE_CLOSURE |
+ .of(unit.library) |
+ .toListOf(LIBRARY_ELEMENT5), |
+ LIBRARY_INPUT: LIBRARY_ELEMENT5.of(unit.library), |
+ UNIT_INPUT: RESOLVED_UNIT4.of(unit), |
+ TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request), |
+ // In strong mode, add additional dependencies to enforce inference |
+ // ordering. |
+ |
+ // Require that full inference be complete for all dependencies of the |
+ // current library cycle. |
+ 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList( |
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT8 |
+ .of(new LibrarySpecificUnit(unit.librarySource, unit.source))) |
+ }; |
+ } |
+ |
+ /** |
+ * Create a [PartiallyResolveUnitReferencesTask] based on the given [target] |
+ * in the given [context]. |
+ */ |
+ static PartiallyResolveUnitReferencesTask createTask( |
+ AnalysisContext context, AnalysisTarget target) { |
+ return new PartiallyResolveUnitReferencesTask(context, target); |
+ } |
+} |
+ |
+/** |
* The helper for building the public [Namespace] of a [LibraryElement]. |
*/ |
class PublicNamespaceBuilder { |
@@ -2665,6 +3661,94 @@ class ReferencedNamesBuilder extends RecursiveAstVisitor { |
} |
/** |
+ * A task that resolves the bodies of top-level functions, constructors, and |
+ * methods within a single compilation unit. |
+ */ |
+class ResolveUnitTask extends SourceBasedAnalysisTask { |
+ /** |
+ * The name of the input whose value is the defining [LIBRARY_ELEMENT5]. |
+ */ |
+ static const String LIBRARY_INPUT = 'LIBRARY_INPUT'; |
+ |
+ /** |
+ * The name of the [TYPE_PROVIDER] input. |
+ */ |
+ static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT'; |
+ |
+ /** |
+ * The name of the [RESOLVED_UNIT8] input. |
+ */ |
+ static const String UNIT_INPUT = 'UNIT_INPUT'; |
+ |
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
+ 'ResolveUnitTask', |
+ createTask, |
+ buildInputs, |
+ <ResultDescriptor>[RESOLVE_UNIT_ERRORS, RESOLVED_UNIT9]); |
+ |
+ ResolveUnitTask( |
+ InternalAnalysisContext context, LibrarySpecificUnit compilationUnit) |
+ : super(context, compilationUnit); |
+ |
+ @override |
+ TaskDescriptor get descriptor => DESCRIPTOR; |
+ |
+ @override |
+ void internalPerform() { |
+ // |
+ // Prepare inputs. |
+ // |
+ LibraryElement libraryElement = getRequiredInput(LIBRARY_INPUT); |
+ CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
+ TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); |
+ // |
+ // Resolve everything |
+ // |
+ CompilationUnitElement unitElement = unit.element; |
+ RecordingErrorListener errorListener = new RecordingErrorListener(); |
+ ResolverVisitor visitor = new ResolverVisitor( |
+ libraryElement, unitElement.source, typeProvider, errorListener); |
+ unit.accept(visitor); |
+ // |
+ // Record outputs. |
+ // |
+ outputs[RESOLVE_UNIT_ERRORS] = errorListener.errors; |
+ outputs[RESOLVED_UNIT9] = unit; |
+ } |
+ |
+ /** |
+ * 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>{ |
+ LIBRARY_INPUT: LIBRARY_ELEMENT5.of(unit.library), |
+ TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request), |
+ UNIT_INPUT: RESOLVED_UNIT8.of(unit), |
+ // In strong mode, add additional dependencies to enforce inference |
+ // ordering. |
+ |
+ // Require that inference be complete for all units in the |
+ // current library cycle. |
+ 'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList( |
+ (CompilationUnitElementImpl unit) => RESOLVED_UNIT8 |
+ .of(new LibrarySpecificUnit(unit.librarySource, unit.source))) |
+ }; |
+ } |
+ |
+ /** |
+ * Create a [ResolveUnitTask] based on the given [target] in |
+ * the given [context]. |
+ */ |
+ static ResolveUnitTask createTask( |
+ AnalysisContext context, AnalysisTarget target) { |
+ return new ResolveUnitTask(context, target); |
+ } |
+} |
+ |
+/** |
* A task that finishes resolution by requesting [RESOLVED_UNIT_NO_CONSTANTS] for every |
* unit in the libraries closure and produces [LIBRARY_ELEMENT]. |
*/ |
@@ -2675,7 +3759,7 @@ class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask { |
static const String LIBRARY_INPUT = 'LIBRARY_INPUT'; |
/** |
- * The name of the list of [RESOLVED_UNIT5] input. |
+ * The name of the list of [RESOLVED_UNIT9] input. |
*/ |
static const String UNITS_INPUT = 'UNITS_INPUT'; |
@@ -2683,7 +3767,9 @@ class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'ResolveLibraryReferencesTask', createTask, buildInputs, |
+ 'ResolveLibraryReferencesTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[LIBRARY_ELEMENT, REFERENCED_NAMES]); |
ResolveLibraryReferencesTask( |
@@ -2722,12 +3808,12 @@ class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask { |
return <String, TaskInput>{ |
LIBRARY_INPUT: LIBRARY_ELEMENT5.of(source), |
UNITS_INPUT: UNITS.of(source).toList((Source unit) => |
- RESOLVED_UNIT5.of(new LibrarySpecificUnit(source, unit))), |
+ RESOLVED_UNIT9.of(new LibrarySpecificUnit(source, unit))), |
'resolvedUnits': IMPORT_EXPORT_SOURCE_CLOSURE |
.of(source) |
.toMapOf(UNITS) |
.toFlattenList((Source library, Source unit) => |
- RESOLVED_UNIT5.of(new LibrarySpecificUnit(library, unit))), |
+ RESOLVED_UNIT9.of(new LibrarySpecificUnit(library, unit))), |
}; |
} |
@@ -2755,7 +3841,9 @@ class ResolveLibraryTypeNamesTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'ResolveLibraryTypeNamesTask', createTask, buildInputs, |
+ 'ResolveLibraryTypeNamesTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[LIBRARY_ELEMENT5]); |
ResolveLibraryTypeNamesTask( |
@@ -2796,95 +3884,6 @@ class ResolveLibraryTypeNamesTask extends SourceBasedAnalysisTask { |
} |
/** |
- * A task that builds [RESOLVED_UNIT5] for a unit. |
- */ |
-class ResolveUnitReferencesTask extends SourceBasedAnalysisTask { |
- /** |
- * The name of the [LIBRARY_ELEMENT5] input. |
- */ |
- static const String LIBRARY_INPUT = 'LIBRARY_INPUT'; |
- |
- /** |
- * The name of the [RESOLVED_UNIT4] input. |
- */ |
- static const String UNIT_INPUT = 'UNIT_INPUT'; |
- |
- /** |
- * The name of the [TYPE_PROVIDER] input. |
- */ |
- static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT'; |
- |
- /** |
- * The task descriptor describing this kind of task. |
- */ |
- static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'ResolveUnitReferencesTask', createTask, buildInputs, <ResultDescriptor>[ |
- RESOLVE_REFERENCES_ERRORS, |
- RESOLVED_UNIT5 |
- ]); |
- |
- ResolveUnitReferencesTask( |
- InternalAnalysisContext context, AnalysisTarget target) |
- : super(context, target); |
- |
- @override |
- TaskDescriptor get descriptor => DESCRIPTOR; |
- |
- @override |
- void internalPerform() { |
- RecordingErrorListener errorListener = new RecordingErrorListener(); |
- // |
- // Prepare inputs. |
- // |
- LibraryElement libraryElement = getRequiredInput(LIBRARY_INPUT); |
- CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
- CompilationUnitElement unitElement = unit.element; |
- TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); |
- // |
- // Resolve references. |
- // |
- InheritanceManager inheritanceManager = |
- new InheritanceManager(libraryElement); |
- AstVisitor visitor = new ResolverVisitor( |
- libraryElement, unitElement.source, typeProvider, errorListener, |
- inheritanceManager: inheritanceManager); |
- unit.accept(visitor); |
- // |
- // Record outputs. |
- // |
- outputs[RESOLVE_REFERENCES_ERRORS] = |
- removeDuplicateErrors(errorListener.errors); |
- outputs[RESOLVED_UNIT5] = unit; |
- } |
- |
- /** |
- * 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>{ |
- 'fullyBuiltLibraryElements': IMPORT_EXPORT_SOURCE_CLOSURE |
- .of(unit.library) |
- .toListOf(LIBRARY_ELEMENT5), |
- LIBRARY_INPUT: LIBRARY_ELEMENT5.of(unit.library), |
- UNIT_INPUT: RESOLVED_UNIT4.of(unit), |
- TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request) |
- }; |
- } |
- |
- /** |
- * Create a [ResolveUnitReferencesTask] based on the given [target] in |
- * the given [context]. |
- */ |
- static ResolveUnitReferencesTask createTask( |
- AnalysisContext context, AnalysisTarget target) { |
- return new ResolveUnitReferencesTask(context, target); |
- } |
-} |
- |
-/** |
* A task that builds [RESOLVED_UNIT3] for a unit. |
*/ |
class ResolveUnitTypeNamesTask extends SourceBasedAnalysisTask { |
@@ -2907,10 +3906,10 @@ class ResolveUnitTypeNamesTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'ResolveUnitTypeNamesTask', createTask, buildInputs, <ResultDescriptor>[ |
- RESOLVE_TYPE_NAMES_ERRORS, |
- RESOLVED_UNIT3 |
- ]); |
+ 'ResolveUnitTypeNamesTask', |
+ createTask, |
+ buildInputs, |
+ <ResultDescriptor>[RESOLVE_TYPE_NAMES_ERRORS, RESOLVED_UNIT3]); |
ResolveUnitTypeNamesTask( |
InternalAnalysisContext context, AnalysisTarget target) |
@@ -2992,7 +3991,9 @@ class ResolveVariableReferencesTask extends SourceBasedAnalysisTask { |
* The task descriptor describing this kind of task. |
*/ |
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
- 'ResolveVariableReferencesTask', createTask, buildInputs, |
+ 'ResolveVariableReferencesTask', |
+ createTask, |
+ buildInputs, |
<ResultDescriptor>[RESOLVED_UNIT4, VARIABLE_REFERENCE_ERRORS]); |
ResolveVariableReferencesTask( |
@@ -3037,7 +4038,7 @@ class ResolveVariableReferencesTask extends SourceBasedAnalysisTask { |
LibrarySpecificUnit unit = target; |
return <String, TaskInput>{ |
LIBRARY_INPUT: LIBRARY_ELEMENT1.of(unit.library), |
- UNIT_INPUT: RESOLVED_UNIT1.of(unit), |
+ UNIT_INPUT: RESOLVED_UNIT3.of(unit), |
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request) |
}; |
} |
@@ -3064,12 +4065,11 @@ class ScanDartTask extends SourceBasedAnalysisTask { |
/** |
* The task descriptor describing this kind of task. |
*/ |
- static final TaskDescriptor DESCRIPTOR = new TaskDescriptor('ScanDartTask', |
- createTask, buildInputs, <ResultDescriptor>[ |
- LINE_INFO, |
- SCAN_ERRORS, |
- TOKEN_STREAM |
- ]); |
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
+ 'ScanDartTask', |
+ createTask, |
+ buildInputs, |
+ <ResultDescriptor>[LINE_INFO, SCAN_ERRORS, TOKEN_STREAM]); |
/** |
* Initialize a newly created task to access the content of the source |
@@ -3096,8 +4096,10 @@ class ScanDartTask extends SourceBasedAnalysisTask { |
message = exception.toString(); |
} |
} |
- errorListener.onError(new AnalysisError( |
- source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT, [message])); |
+ if (source.exists()) { |
+ errorListener.onError(new AnalysisError( |
+ source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT, [message])); |
+ } |
} |
if (target is DartScript) { |
DartScript script = target; |
@@ -3110,7 +4112,8 @@ class ScanDartTask extends SourceBasedAnalysisTask { |
} |
ScriptFragment fragment = fragments[0]; |
- Scanner scanner = new Scanner(source, |
+ Scanner scanner = new Scanner( |
+ source, |
new SubSequenceReader(fragment.content, fragment.offset), |
errorListener); |
scanner.setSourceStart(fragment.line, fragment.column); |
@@ -3218,8 +4221,12 @@ class VerifyUnitTask extends SourceBasedAnalysisTask { |
// |
// Use the ErrorVerifier to compute errors. |
// |
- ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, |
- libraryElement, typeProvider, new InheritanceManager(libraryElement)); |
+ ErrorVerifier errorVerifier = new ErrorVerifier( |
+ errorReporter, |
+ libraryElement, |
+ typeProvider, |
+ new InheritanceManager(libraryElement), |
+ context.analysisOptions.enableSuperMixins); |
unit.accept(errorVerifier); |
// |
// Record outputs. |
@@ -3390,6 +4397,9 @@ class _SourceClosureTaskInputBuilder implements TaskInputBuilder<List<Source>> { |
} |
@override |
+ bool get flushOnAccess => false; |
+ |
+ @override |
List<Source> get inputValue { |
return _libraries.map((LibraryElement library) => library.source).toList(); |
} |