| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer.src.task.dart; | 5 library analyzer.src.task.dart; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; | 10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 new ListResultDescriptor<AnalysisError>( | 380 new ListResultDescriptor<AnalysisError>( |
| 381 'HINT_ERRORS', AnalysisError.NO_ERRORS); | 381 'HINT_ERRORS', AnalysisError.NO_ERRORS); |
| 382 | 382 |
| 383 /** | 383 /** |
| 384 * The ignore information for a [Source]. | 384 * The ignore information for a [Source]. |
| 385 */ | 385 */ |
| 386 final ResultDescriptor<IgnoreInfo> IGNORE_INFO = | 386 final ResultDescriptor<IgnoreInfo> IGNORE_INFO = |
| 387 new ResultDescriptor<IgnoreInfo>('IGNORE_INFO', null); | 387 new ResultDescriptor<IgnoreInfo>('IGNORE_INFO', null); |
| 388 | 388 |
| 389 /** | 389 /** |
| 390 * This result is `true` if the variable references an instance field or |
| 391 * an instance getter. |
| 392 * |
| 393 * The result is only available for [VariableElement]s, and only when strong |
| 394 * mode is enabled. |
| 395 */ |
| 396 final ResultDescriptor<bool> INFERABLE_VARIABLE_REFERENCES_INSTANCE_FIELD = |
| 397 new ResultDescriptor<bool>( |
| 398 'INFERABLE_VARIABLE_REFERENCES_INSTANCE_FIELD', false); |
| 399 |
| 400 /** |
| 390 * A list of the [VariableElement]s whose type should be inferred that another | 401 * A list of the [VariableElement]s whose type should be inferred that another |
| 391 * inferable static variable (the target) depends on. | 402 * inferable static variable (the target) depends on. |
| 392 * | 403 * |
| 393 * The result is only available for [VariableElement]s, and only when strong | 404 * The result is only available for [VariableElement]s, and only when strong |
| 394 * mode is enabled. | 405 * mode is enabled. |
| 395 */ | 406 */ |
| 396 final ListResultDescriptor<VariableElement> | 407 final ListResultDescriptor<VariableElement> |
| 397 INFERABLE_STATIC_VARIABLE_DEPENDENCIES = | 408 INFERABLE_STATIC_VARIABLE_DEPENDENCIES = |
| 398 new ListResultDescriptor<VariableElement>( | 409 new ListResultDescriptor<VariableElement>( |
| 399 'INFERABLE_STATIC_VARIABLE_DEPENDENCIES', null); | 410 'INFERABLE_STATIC_VARIABLE_DEPENDENCIES', null); |
| (...skipping 1731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2131 class ComputeInferableStaticVariableDependenciesTask | 2142 class ComputeInferableStaticVariableDependenciesTask |
| 2132 extends InferStaticVariableTask { | 2143 extends InferStaticVariableTask { |
| 2133 /** | 2144 /** |
| 2134 * The name of the [RESOLVED_UNIT7] input. | 2145 * The name of the [RESOLVED_UNIT7] input. |
| 2135 */ | 2146 */ |
| 2136 static const String UNIT_INPUT = 'UNIT_INPUT'; | 2147 static const String UNIT_INPUT = 'UNIT_INPUT'; |
| 2137 | 2148 |
| 2138 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( | 2149 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
| 2139 'ComputeInferableStaticVariableDependenciesTask', | 2150 'ComputeInferableStaticVariableDependenciesTask', |
| 2140 createTask, | 2151 createTask, |
| 2141 buildInputs, | 2152 buildInputs, <ResultDescriptor>[ |
| 2142 <ResultDescriptor>[INFERABLE_STATIC_VARIABLE_DEPENDENCIES]); | 2153 INFERABLE_STATIC_VARIABLE_DEPENDENCIES, |
| 2154 INFERABLE_VARIABLE_REFERENCES_INSTANCE_FIELD |
| 2155 ]); |
| 2143 | 2156 |
| 2144 ComputeInferableStaticVariableDependenciesTask( | 2157 ComputeInferableStaticVariableDependenciesTask( |
| 2145 InternalAnalysisContext context, VariableElement variable) | 2158 InternalAnalysisContext context, VariableElement variable) |
| 2146 : super(context, variable); | 2159 : super(context, variable); |
| 2147 | 2160 |
| 2148 @override | 2161 @override |
| 2149 TaskDescriptor get descriptor => DESCRIPTOR; | 2162 TaskDescriptor get descriptor => DESCRIPTOR; |
| 2150 | 2163 |
| 2151 @override | 2164 @override |
| 2152 void internalPerform() { | 2165 void internalPerform() { |
| 2153 // | 2166 // |
| 2154 // Prepare inputs. | 2167 // Prepare inputs. |
| 2155 // | 2168 // |
| 2156 CompilationUnit unit = getRequiredInput(UNIT_INPUT); | 2169 CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
| 2157 // | 2170 // |
| 2158 // Compute dependencies. | 2171 // Compute dependencies. |
| 2159 // | 2172 // |
| 2160 VariableDeclaration declaration = getDeclaration(unit); | 2173 VariableDeclaration declaration = getDeclaration(unit); |
| 2161 VariableGatherer gatherer = new VariableGatherer(_isInferableStatic); | 2174 VariableGatherer gatherer = new VariableGatherer(_isInferableStatic); |
| 2162 declaration.initializer.accept(gatherer); | 2175 declaration.initializer.accept(gatherer); |
| 2176 // print('[INFERABLE_STATIC_VARIABLE_DEPENDENCIES][$declaration] ${gatherer.h
asInstanceFieldOrGetterReference}'); |
| 2163 // | 2177 // |
| 2164 // Record outputs. | 2178 // Record outputs. |
| 2165 // | 2179 // |
| 2166 outputs[INFERABLE_STATIC_VARIABLE_DEPENDENCIES] = gatherer.results.toList(); | 2180 outputs[INFERABLE_STATIC_VARIABLE_DEPENDENCIES] = gatherer.results.toList(); |
| 2181 outputs[INFERABLE_VARIABLE_REFERENCES_INSTANCE_FIELD] = |
| 2182 gatherer.hasInstanceFieldOrGetterReference; |
| 2167 } | 2183 } |
| 2168 | 2184 |
| 2169 /** | 2185 /** |
| 2170 * Return `true` if the given [variable] is a static variable whose type | 2186 * Return `true` if the given [variable] is a static variable whose type |
| 2171 * should be inferred. | 2187 * should be inferred. |
| 2172 */ | 2188 */ |
| 2173 bool _isInferableStatic(VariableElement variable) => | 2189 bool _isInferableStatic(VariableElement variable) => |
| 2174 variable.isStatic && | 2190 variable.isStatic && |
| 2175 variable.hasImplicitType && | 2191 variable.hasImplicitType && |
| 2176 variable.initializer != null; | 2192 variable.initializer != null; |
| (...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3671 * stores it in the element model. | 3687 * stores it in the element model. |
| 3672 */ | 3688 */ |
| 3673 class InferStaticVariableTypeTask extends InferStaticVariableTask { | 3689 class InferStaticVariableTypeTask extends InferStaticVariableTask { |
| 3674 /** | 3690 /** |
| 3675 * The name of the input which ensures that dependent values have their type | 3691 * The name of the input which ensures that dependent values have their type |
| 3676 * inferred before the target. | 3692 * inferred before the target. |
| 3677 */ | 3693 */ |
| 3678 static const String DEPENDENCIES_INPUT = 'DEPENDENCIES_INPUT'; | 3694 static const String DEPENDENCIES_INPUT = 'DEPENDENCIES_INPUT'; |
| 3679 | 3695 |
| 3680 /** | 3696 /** |
| 3697 * The [INFERABLE_VARIABLE_REFERENCES_INSTANCE_FIELD] input. |
| 3698 */ |
| 3699 static const String REFERENCES_INSTANCE_FIELD_INPUT = |
| 3700 'REFERENCES_INSTANCE_FIELD_INPUT'; |
| 3701 |
| 3702 /** |
| 3681 * The name of the [TYPE_PROVIDER] input. | 3703 * The name of the [TYPE_PROVIDER] input. |
| 3682 */ | 3704 */ |
| 3683 static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT'; | 3705 static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT'; |
| 3684 | 3706 |
| 3685 /** | 3707 /** |
| 3686 * The name of the [RESOLVED_UNIT8] input. | 3708 * The name of the [RESOLVED_UNIT8] input. |
| 3687 */ | 3709 */ |
| 3688 static const String UNIT_INPUT = 'UNIT_INPUT'; | 3710 static const String UNIT_INPUT = 'UNIT_INPUT'; |
| 3689 | 3711 |
| 3690 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( | 3712 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3709 void internalPerform() { | 3731 void internalPerform() { |
| 3710 // | 3732 // |
| 3711 // Prepare inputs. | 3733 // Prepare inputs. |
| 3712 // | 3734 // |
| 3713 // Note: DEPENDENCIES_INPUT is not needed. It is merely a bookkeeping | 3735 // Note: DEPENDENCIES_INPUT is not needed. It is merely a bookkeeping |
| 3714 // dependency to ensure that the variables that this variable references | 3736 // dependency to ensure that the variables that this variable references |
| 3715 // have types inferred before inferring the type of this variable. | 3737 // have types inferred before inferring the type of this variable. |
| 3716 // | 3738 // |
| 3717 VariableElementImpl variable = target; | 3739 VariableElementImpl variable = target; |
| 3718 | 3740 |
| 3741 bool referencesInstanceField = |
| 3742 getRequiredInput(REFERENCES_INSTANCE_FIELD_INPUT); |
| 3719 CompilationUnit unit = getRequiredInput(UNIT_INPUT); | 3743 CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
| 3720 TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); | 3744 TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); |
| 3721 | 3745 |
| 3722 // If we're not in a dependency cycle, and we have no type annotation, | 3746 // If we're not in a dependency cycle, and we have no type annotation, |
| 3723 // re-resolve the right hand side and do inference. | 3747 // re-resolve the right hand side and do inference. |
| 3724 List<AnalysisError> errors = AnalysisError.NO_ERRORS; | 3748 List<AnalysisError> errors = AnalysisError.NO_ERRORS; |
| 3725 if (dependencyCycle == null && variable.hasImplicitType) { | 3749 if (dependencyCycle == null && variable.hasImplicitType) { |
| 3726 VariableDeclaration declaration = getDeclaration(unit); | 3750 VariableDeclaration declaration = getDeclaration(unit); |
| 3751 Expression initializer = declaration.initializer; |
| 3727 // | 3752 // |
| 3728 // Re-resolve the variable's initializer so that the inferred types | 3753 // Re-resolve the variable's initializer so that the inferred types |
| 3729 // of other variables will be propagated. | 3754 // of other variables will be propagated. |
| 3730 // | 3755 // |
| 3731 RecordingErrorListener errorListener = new RecordingErrorListener(); | 3756 RecordingErrorListener errorListener = new RecordingErrorListener(); |
| 3732 Expression initializer = declaration.initializer; | |
| 3733 ResolutionContext resolutionContext = | 3757 ResolutionContext resolutionContext = |
| 3734 ResolutionContextBuilder.contextFor(initializer); | 3758 ResolutionContextBuilder.contextFor(initializer); |
| 3735 ResolverVisitor visitor = new ResolverVisitor( | 3759 ResolverVisitor visitor = new ResolverVisitor( |
| 3736 variable.library, variable.source, typeProvider, errorListener, | 3760 variable.library, variable.source, typeProvider, errorListener, |
| 3737 nameScope: resolutionContext.scope); | 3761 nameScope: resolutionContext.scope); |
| 3738 if (resolutionContext.enclosingClassDeclaration != null) { | 3762 if (resolutionContext.enclosingClassDeclaration != null) { |
| 3739 visitor.prepareToResolveMembersInClass( | 3763 visitor.prepareToResolveMembersInClass( |
| 3740 resolutionContext.enclosingClassDeclaration); | 3764 resolutionContext.enclosingClassDeclaration); |
| 3741 } | 3765 } |
| 3742 visitor.initForIncrementalResolution(); | 3766 visitor.initForIncrementalResolution(); |
| 3743 initializer.accept(visitor); | 3767 initializer.accept(visitor); |
| 3744 | 3768 |
| 3769 DartType newType; |
| 3770 if (hasInstanceGetterReference(initializer)) { |
| 3771 // Instance getters cannot be used for top-level type inference. |
| 3772 newType = typeProvider.dynamicType; |
| 3773 } else { |
| 3774 newType = initializer.staticType; |
| 3775 if (newType == null || newType.isBottom || newType.isDartCoreNull) { |
| 3776 newType = typeProvider.dynamicType; |
| 3777 } |
| 3778 } |
| 3779 |
| 3745 // | 3780 // |
| 3746 // Record the type of the variable. | 3781 // Record the type of the variable. |
| 3747 // | 3782 // |
| 3748 DartType newType = initializer.staticType; | |
| 3749 if (newType == null || newType.isBottom || newType.isDartCoreNull) { | |
| 3750 newType = typeProvider.dynamicType; | |
| 3751 } | |
| 3752 setFieldType(variable, newType); | 3783 setFieldType(variable, newType); |
| 3753 errors = getUniqueErrors(errorListener.errors); | 3784 errors = getUniqueErrors(errorListener.errors); |
| 3754 } else { | 3785 } else { |
| 3755 // TODO(brianwilkerson) For now we simply don't infer any type for | 3786 // TODO(brianwilkerson) For now we simply don't infer any type for |
| 3756 // variables or fields involved in a cycle. We could try to be smarter | 3787 // variables or fields involved in a cycle. We could try to be smarter |
| 3757 // by re-resolving the initializer in a context in which the types of all | 3788 // by re-resolving the initializer in a context in which the types of all |
| 3758 // of the variables in the cycle are assumed to be `null`, but it isn't | 3789 // of the variables in the cycle are assumed to be `null`, but it isn't |
| 3759 // clear to me that this would produce better results often enough to | 3790 // clear to me that this would produce better results often enough to |
| 3760 // warrant the extra effort. | 3791 // warrant the extra effort. |
| 3761 } | 3792 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3772 * [target]. | 3803 * [target]. |
| 3773 */ | 3804 */ |
| 3774 static Map<String, TaskInput> buildInputs(AnalysisTarget target) { | 3805 static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
| 3775 VariableElement variable = target; | 3806 VariableElement variable = target; |
| 3776 LibrarySpecificUnit unit = | 3807 LibrarySpecificUnit unit = |
| 3777 new LibrarySpecificUnit(variable.library.source, variable.source); | 3808 new LibrarySpecificUnit(variable.library.source, variable.source); |
| 3778 return <String, TaskInput>{ | 3809 return <String, TaskInput>{ |
| 3779 DEPENDENCIES_INPUT: INFERABLE_STATIC_VARIABLE_DEPENDENCIES | 3810 DEPENDENCIES_INPUT: INFERABLE_STATIC_VARIABLE_DEPENDENCIES |
| 3780 .of(variable) | 3811 .of(variable) |
| 3781 .toListOf(INFERRED_STATIC_VARIABLE), | 3812 .toListOf(INFERRED_STATIC_VARIABLE), |
| 3813 REFERENCES_INSTANCE_FIELD_INPUT: |
| 3814 INFERABLE_VARIABLE_REFERENCES_INSTANCE_FIELD.of(variable), |
| 3782 TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request), | 3815 TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request), |
| 3783 UNIT_INPUT: RESOLVED_UNIT7.of(unit), | 3816 UNIT_INPUT: RESOLVED_UNIT7.of(unit), |
| 3784 // In strong mode, add additional dependencies to enforce inference | 3817 // In strong mode, add additional dependencies to enforce inference |
| 3785 // ordering. | 3818 // ordering. |
| 3786 | 3819 |
| 3787 // Require that full inference be complete for all dependencies of the | 3820 // Require that full inference be complete for all dependencies of the |
| 3788 // current library cycle. | 3821 // current library cycle. |
| 3789 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES | 3822 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES |
| 3790 .of(unit.library) | 3823 .of(unit.library) |
| 3791 .toListOf(CREATED_RESOLVED_UNIT10) | 3824 .toListOf(CREATED_RESOLVED_UNIT10) |
| (...skipping 2764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6556 | 6589 |
| 6557 @override | 6590 @override |
| 6558 bool moveNext() { | 6591 bool moveNext() { |
| 6559 if (_newSources.isEmpty) { | 6592 if (_newSources.isEmpty) { |
| 6560 return false; | 6593 return false; |
| 6561 } | 6594 } |
| 6562 currentTarget = _newSources.removeLast(); | 6595 currentTarget = _newSources.removeLast(); |
| 6563 return true; | 6596 return true; |
| 6564 } | 6597 } |
| 6565 } | 6598 } |
| OLD | NEW |