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

Side by Side Diff: pkg/analyzer/lib/src/task/dart.dart

Issue 2754423002: Fail inference when an instance field is referenced. (Closed)
Patch Set: Created 3 years, 9 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 unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698