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

Side by Side Diff: pkg/analyzer/lib/src/summary/link.dart

Issue 1894263003: Clean up handling of declared/inferred types in VariableElementForLink (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/linker_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 /** 5 /**
6 * This library is capable of producing linked summaries from unlinked 6 * This library is capable of producing linked summaries from unlinked
7 * ones (or prelinked ones). It functions by building a miniature 7 * ones (or prelinked ones). It functions by building a miniature
8 * element model to represent the contents of the summaries, and then 8 * element model to represent the contents of the summaries, and then
9 * scanning the element model to gather linked information and adding 9 * scanning the element model to gather linked information and adding
10 * it to the summary data structures. 10 * it to the summary data structures.
(...skipping 2396 matching lines...) Expand 10 before | Expand all | Expand 10 after
2407 /** 2407 /**
2408 * Specialization of [FieldElementForLink] for class fields. 2408 * Specialization of [FieldElementForLink] for class fields.
2409 */ 2409 */
2410 class FieldElementForLink_ClassField extends VariableElementForLink 2410 class FieldElementForLink_ClassField extends VariableElementForLink
2411 implements FieldElementForLink { 2411 implements FieldElementForLink {
2412 @override 2412 @override
2413 final ClassElementForLink_Class enclosingElement; 2413 final ClassElementForLink_Class enclosingElement;
2414 2414
2415 /** 2415 /**
2416 * If this is an instance field, the type that was computed by 2416 * If this is an instance field, the type that was computed by
2417 * [InstanceMemberInferrer]. 2417 * [InstanceMemberInferrer] (if any). Otherwise `null`.
2418 */ 2418 */
2419 DartType _inferredInstanceType; 2419 DartType _inferredInstanceType;
2420 2420
2421 DartType _declaredType;
2422
2423 FieldElementForLink_ClassField(ClassElementForLink_Class enclosingElement, 2421 FieldElementForLink_ClassField(ClassElementForLink_Class enclosingElement,
2424 UnlinkedVariable unlinkedVariable) 2422 UnlinkedVariable unlinkedVariable)
2425 : enclosingElement = enclosingElement, 2423 : enclosingElement = enclosingElement,
2426 super(unlinkedVariable, enclosingElement.enclosingElement); 2424 super(unlinkedVariable, enclosingElement.enclosingElement);
2427 2425
2428 @override 2426 @override
2429 bool get isStatic => unlinkedVariable.isStatic; 2427 bool get isStatic => unlinkedVariable.isStatic;
2430 2428
2431 @override 2429 @override
2432 DartType get type {
2433 // TODO(paulberry): can this be unified with
2434 // [VariableElementForLink.asStaticType]?
2435 assert(!isStatic);
2436 if (_inferredInstanceType != null) {
2437 return _inferredInstanceType;
2438 } else if (_declaredType == null) {
2439 if (unlinkedVariable.type == null) {
2440 if (!compilationUnit.isInBuildUnit) {
2441 _inferredInstanceType = compilationUnit.getLinkedType(
2442 unlinkedVariable.inferredTypeSlot, enclosingElement);
2443 return _inferredInstanceType;
2444 }
2445 _declaredType = DynamicTypeImpl.instance;
2446 } else {
2447 _declaredType = compilationUnit._resolveTypeRef(
2448 unlinkedVariable.type, enclosingElement);
2449 }
2450 }
2451 return _declaredType;
2452 }
2453
2454 @override
2455 void set type(DartType inferredType) { 2430 void set type(DartType inferredType) {
2456 assert(!isStatic); 2431 assert(!isStatic);
2457 assert(_inferredInstanceType == null); 2432 assert(_inferredInstanceType == null);
2458 _inferredInstanceType = inferredType; 2433 _inferredInstanceType = inferredType;
2459 } 2434 }
2460 2435
2461 @override 2436 @override
2462 TypeParameterizedElementForLink get _typeParameterContext => enclosingElement; 2437 TypeParameterizedElementForLink get _typeParameterContext => enclosingElement;
2463 2438
2464 /** 2439 /**
2465 * Store the results of type inference for this field in 2440 * Store the results of type inference for this field in
2466 * [compilationUnit]. 2441 * [compilationUnit].
2467 */ 2442 */
2468 void link(CompilationUnitElementInBuildUnit compilationUnit) { 2443 void link(CompilationUnitElementInBuildUnit compilationUnit) {
2469 if (hasImplicitType) { 2444 if (hasImplicitType) {
2470 if (isStatic) { 2445 compilationUnit._storeLinkedType(
2471 TypeInferenceNode typeInferenceNode = this.asTypeInferenceNode; 2446 unlinkedVariable.inferredTypeSlot,
2472 if (typeInferenceNode != null) { 2447 isStatic ? inferredType : _inferredInstanceType,
2473 compilationUnit._storeLinkedType(unlinkedVariable.inferredTypeSlot, 2448 _typeParameterContext);
2474 typeInferenceNode.inferredType, enclosingElement);
2475 }
2476 } else {
2477 compilationUnit._storeLinkedType(unlinkedVariable.inferredTypeSlot,
2478 _inferredInstanceType, enclosingElement);
2479 }
2480 } 2449 }
2481 } 2450 }
2482 2451
2483 @override 2452 @override
2484 String toString() => '$enclosingElement.$name'; 2453 String toString() => '$enclosingElement.$name';
2485 } 2454 }
2486 2455
2487 /** 2456 /**
2488 * Specialization of [FieldElementForLink] for enum fields. 2457 * Specialization of [FieldElementForLink] for enum fields.
2489 */ 2458 */
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
2596 /** 2565 /**
2597 * The variable for which this element is the initializer. 2566 * The variable for which this element is the initializer.
2598 */ 2567 */
2599 final VariableElementForLink _variable; 2568 final VariableElementForLink _variable;
2600 2569
2601 FunctionElementForLink_Initializer(this._variable); 2570 FunctionElementForLink_Initializer(this._variable);
2602 2571
2603 @override 2572 @override
2604 DartType get returnType { 2573 DartType get returnType {
2605 // If this is a variable whose type needs inferring, infer it. 2574 // If this is a variable whose type needs inferring, infer it.
2606 TypeInferenceNode typeInferenceNode = _variable._typeInferenceNode; 2575 if (_variable.hasImplicitType) {
2607 if (typeInferenceNode != null) { 2576 return _variable.inferredType;
2608 return typeInferenceNode.inferredType;
2609 } else { 2577 } else {
2610 // There's no reason linking should need to access the type of 2578 // There's no reason linking should need to access the type of
2611 // this FunctionElement, since the variable doesn't need its 2579 // this FunctionElement, since the variable doesn't need its
2612 // type inferred. 2580 // type inferred.
2613 assert(false); 2581 assert(false);
2614 // But for robustness, return the dynamic type. 2582 // But for robustness, return the dynamic type.
2615 return DynamicTypeImpl.instance; 2583 return DynamicTypeImpl.instance;
2616 } 2584 }
2617 } 2585 }
2618 2586
2619 @override 2587 @override
2620 void set returnType(DartType newType) { 2588 void set returnType(DartType newType) {
2621 // TODO(paulberry): store inferred type. 2589 // InstanceMemberInferrer stores the new type both here and on the variable
2590 // element. We don't need to record both values, so we ignore it here.
2622 } 2591 }
2623 2592
2624 @override 2593 @override
2625 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 2594 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
2626 } 2595 }
2627 2596
2628 /** 2597 /**
2629 * Specialization of [DependencyWalker] for linking library cycles. 2598 * Specialization of [DependencyWalker] for linking library cycles.
2630 */ 2599 */
2631 class LibraryCycleDependencyWalker extends DependencyWalker<LibraryCycleNode> { 2600 class LibraryCycleDependencyWalker extends DependencyWalker<LibraryCycleNode> {
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after
3736 TypeParameterizedElementForLink get _typeParameterContext => null; 3705 TypeParameterizedElementForLink get _typeParameterContext => null;
3737 3706
3738 /** 3707 /**
3739 * Store the results of type inference for this variable in 3708 * Store the results of type inference for this variable in
3740 * [compilationUnit]. 3709 * [compilationUnit].
3741 */ 3710 */
3742 void link(CompilationUnitElementInBuildUnit compilationUnit) { 3711 void link(CompilationUnitElementInBuildUnit compilationUnit) {
3743 if (hasImplicitType) { 3712 if (hasImplicitType) {
3744 TypeInferenceNode typeInferenceNode = this.asTypeInferenceNode; 3713 TypeInferenceNode typeInferenceNode = this.asTypeInferenceNode;
3745 if (typeInferenceNode != null) { 3714 if (typeInferenceNode != null) {
3746 compilationUnit._storeLinkedType(unlinkedVariable.inferredTypeSlot, 3715 compilationUnit._storeLinkedType(
3747 typeInferenceNode.inferredType, null); 3716 unlinkedVariable.inferredTypeSlot, inferredType, null);
3748 } 3717 }
3749 } 3718 }
3750 } 3719 }
3751 } 3720 }
3752 3721
3753 /** 3722 /**
3754 * Specialization of [DependencyWalker] for performing type inferrence 3723 * Specialization of [DependencyWalker] for performing type inferrence
3755 * on static and top level variables. 3724 * on static and top level variables.
3756 */ 3725 */
3757 class TypeInferenceDependencyWalker 3726 class TypeInferenceDependencyWalker
(...skipping 15 matching lines...) Expand all
3773 * Specialization of [Node] used to construct the type inference dependency 3742 * Specialization of [Node] used to construct the type inference dependency
3774 * graph. 3743 * graph.
3775 */ 3744 */
3776 class TypeInferenceNode extends Node<TypeInferenceNode> { 3745 class TypeInferenceNode extends Node<TypeInferenceNode> {
3777 /** 3746 /**
3778 * The [FieldElement] or [TopLevelVariableElement] to which this 3747 * The [FieldElement] or [TopLevelVariableElement] to which this
3779 * node refers. 3748 * node refers.
3780 */ 3749 */
3781 final VariableElementForLink variableElement; 3750 final VariableElementForLink variableElement;
3782 3751
3783 /**
3784 * If a type has been inferred for this node, the inferred type (may be
3785 * `dynamic`). Otherwise `null`.
3786 */
3787 DartType _inferredType;
3788
3789 TypeInferenceNode(this.variableElement); 3752 TypeInferenceNode(this.variableElement);
3790 3753
3791 /**
3792 * Infer a type for this node if necessary, and return it.
3793 */
3794 DartType get inferredType {
3795 if (_inferredType == null) {
3796 Linker._initializerTypeInferenceCycle =
3797 variableElement.compilationUnit.library.libraryCycleForLink;
3798 new TypeInferenceDependencyWalker().walk(this);
3799 assert(_inferredType != null);
3800 Linker._initializerTypeInferenceCycle = null;
3801 }
3802 return _inferredType;
3803 }
3804
3805 @override 3754 @override
3806 bool get isEvaluated => _inferredType != null; 3755 bool get isEvaluated => variableElement._inferredType != null;
3807 3756
3808 /** 3757 /**
3809 * Collect the type inference dependencies in [unlinkedConst] (which should be 3758 * Collect the type inference dependencies in [unlinkedConst] (which should be
3810 * interpreted relative to [compilationUnit]) and store them in 3759 * interpreted relative to [compilationUnit]) and store them in
3811 * [dependencies]. 3760 * [dependencies].
3812 */ 3761 */
3813 void collectDependencies( 3762 void collectDependencies(
3814 List<TypeInferenceNode> dependencies, 3763 List<TypeInferenceNode> dependencies,
3815 UnlinkedConst unlinkedConst, 3764 UnlinkedConst unlinkedConst,
3816 CompilationUnitElementForLink compilationUnit) { 3765 CompilationUnitElementForLink compilationUnit) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3864 List<TypeInferenceNode> dependencies = <TypeInferenceNode>[]; 3813 List<TypeInferenceNode> dependencies = <TypeInferenceNode>[];
3865 collectDependencies( 3814 collectDependencies(
3866 dependencies, 3815 dependencies,
3867 variableElement.unlinkedVariable.constExpr, 3816 variableElement.unlinkedVariable.constExpr,
3868 variableElement.compilationUnit); 3817 variableElement.compilationUnit);
3869 return dependencies; 3818 return dependencies;
3870 } 3819 }
3871 3820
3872 void evaluate(bool inCycle) { 3821 void evaluate(bool inCycle) {
3873 if (inCycle) { 3822 if (inCycle) {
3874 _inferredType = DynamicTypeImpl.instance; 3823 variableElement._inferredType = DynamicTypeImpl.instance;
3875 } else { 3824 } else {
3876 _inferredType = new ExprTypeComputer(variableElement).compute(); 3825 variableElement._inferredType =
3826 new ExprTypeComputer(variableElement).compute();
3877 } 3827 }
3878 } 3828 }
3879 } 3829 }
3880 3830
3881 /** 3831 /**
3882 * Element representing a type parameter resynthesized from a summary during 3832 * Element representing a type parameter resynthesized from a summary during
3883 * linking. 3833 * linking.
3884 */ 3834 */
3885 class TypeParameterElementForLink implements TypeParameterElementImpl { 3835 class TypeParameterElementForLink implements TypeParameterElementImpl {
3886 /** 3836 /**
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
4203 ConstNode _constNode; 4153 ConstNode _constNode;
4204 4154
4205 /** 4155 /**
4206 * If this variable has an initializer and an implicit type, and the enclosing 4156 * If this variable has an initializer and an implicit type, and the enclosing
4207 * library is part of the build unit being linked, the variable's node in the 4157 * library is part of the build unit being linked, the variable's node in the
4208 * type inference dependency graph. Otherwise `null`. 4158 * type inference dependency graph. Otherwise `null`.
4209 */ 4159 */
4210 TypeInferenceNode _typeInferenceNode; 4160 TypeInferenceNode _typeInferenceNode;
4211 4161
4212 FunctionElementForLink_Initializer _initializer; 4162 FunctionElementForLink_Initializer _initializer;
4213 DartType _staticType; 4163 DartType _inferredType;
4164 DartType _declaredType;
4214 4165
4215 /** 4166 /**
4216 * The compilation unit in which this variable appears. 4167 * The compilation unit in which this variable appears.
4217 */ 4168 */
4218 final CompilationUnitElementForLink compilationUnit; 4169 final CompilationUnitElementForLink compilationUnit;
4219 4170
4220 VariableElementForLink(this.unlinkedVariable, this.compilationUnit) { 4171 VariableElementForLink(this.unlinkedVariable, this.compilationUnit) {
4221 if (compilationUnit.isInBuildUnit && unlinkedVariable.constExpr != null) { 4172 if (compilationUnit.isInBuildUnit && unlinkedVariable.constExpr != null) {
4222 _constNode = new ConstVariableNode(this); 4173 _constNode = new ConstVariableNode(this);
4223 if (unlinkedVariable.type == null) { 4174 if (unlinkedVariable.type == null) {
4224 _typeInferenceNode = new TypeInferenceNode(this); 4175 _typeInferenceNode = new TypeInferenceNode(this);
4225 } 4176 }
4226 } 4177 }
4227 } 4178 }
4228 4179
4229 @override 4180 @override
4230 ConstructorElementForLink get asConstructor => null; 4181 ConstructorElementForLink get asConstructor => null;
4231 4182
4232 @override 4183 @override
4233 ConstVariableNode get asConstVariable => _constNode; 4184 ConstVariableNode get asConstVariable => _constNode;
4234 4185
4235 @override 4186 @override
4236 DartType get asStaticType { 4187 DartType get asStaticType => type;
4237 if (_staticType == null) {
4238 if (_typeInferenceNode != null) {
4239 assert(_typeInferenceNode.isEvaluated);
4240 _staticType = _typeInferenceNode.inferredType;
4241 } else if (hasImplicitType) {
4242 if (!compilationUnit.isInBuildUnit) {
4243 _staticType = compilationUnit.getLinkedType(
4244 unlinkedVariable.inferredTypeSlot, _typeParameterContext);
4245 } else {
4246 _staticType = DynamicTypeImpl.instance;
4247 }
4248 } else {
4249 _staticType = compilationUnit._resolveTypeRef(
4250 unlinkedVariable.type, _typeParameterContext);
4251 }
4252 }
4253 return _staticType;
4254 }
4255 4188
4256 @override 4189 @override
4257 TypeInferenceNode get asTypeInferenceNode => _typeInferenceNode; 4190 TypeInferenceNode get asTypeInferenceNode => _typeInferenceNode;
4258 4191
4192 /**
4193 * If the variable has an explicitly declared return type, return it.
4194 * Otherwise return `null`.
4195 */
4196 DartType get declaredType {
4197 if (unlinkedVariable.type == null) {
4198 return null;
4199 } else {
4200 return _declaredType ??= compilationUnit._resolveTypeRef(
4201 unlinkedVariable.type, _typeParameterContext);
4202 }
4203 }
4204
4259 @override 4205 @override
4260 bool get hasImplicitType => unlinkedVariable.type == null; 4206 bool get hasImplicitType => unlinkedVariable.type == null;
4261 4207
4208 /**
4209 * Return the inferred type of the variable element. Should only be called if
4210 * no type was explicitly declared.
4211 */
4212 DartType get inferredType {
4213 // We should only try to infer a type when none is explicitly declared.
4214 assert(unlinkedVariable.type == null);
4215 if (_inferredType == null) {
4216 if (_typeInferenceNode != null) {
4217 assert(Linker._initializerTypeInferenceCycle == null);
4218 Linker._initializerTypeInferenceCycle =
4219 compilationUnit.library.libraryCycleForLink;
4220 try {
4221 new TypeInferenceDependencyWalker().walk(_typeInferenceNode);
4222 assert(_inferredType != null);
4223 } finally {
4224 Linker._initializerTypeInferenceCycle = null;
4225 }
4226 } else if (compilationUnit.isInBuildUnit) {
4227 _inferredType = DynamicTypeImpl.instance;
4228 } else {
4229 _inferredType = compilationUnit.getLinkedType(
4230 unlinkedVariable.inferredTypeSlot, _typeParameterContext);
4231 }
4232 }
4233 return _inferredType;
4234 }
4235
4262 @override 4236 @override
4263 FunctionElementForLink_Initializer get initializer { 4237 FunctionElementForLink_Initializer get initializer {
4264 if (unlinkedVariable.constExpr == null) { 4238 if (unlinkedVariable.constExpr == null) {
4265 return null; 4239 return null;
4266 } else { 4240 } else {
4267 return _initializer ??= new FunctionElementForLink_Initializer(this); 4241 return _initializer ??= new FunctionElementForLink_Initializer(this);
4268 } 4242 }
4269 } 4243 }
4270 4244
4271 @override 4245 @override
(...skipping 11 matching lines...) Expand all
4283 @override 4257 @override
4284 String get name => unlinkedVariable.name; 4258 String get name => unlinkedVariable.name;
4285 4259
4286 @override 4260 @override
4287 DartType get propagatedType { 4261 DartType get propagatedType {
4288 // TODO(paulberry): implement propagated types in the linker. 4262 // TODO(paulberry): implement propagated types in the linker.
4289 return DynamicTypeImpl.instance; 4263 return DynamicTypeImpl.instance;
4290 } 4264 }
4291 4265
4292 @override 4266 @override
4267 DartType get type => declaredType ?? inferredType;
4268
4269 @override
4293 void set type(DartType newType) { 4270 void set type(DartType newType) {
4294 // TODO(paulberry): store inferred type. 4271 // TODO(paulberry): store inferred type.
4295 } 4272 }
4296 4273
4297 /** 4274 /**
4298 * The context in which type parameters should be interpreted, or `null` if 4275 * The context in which type parameters should be interpreted, or `null` if
4299 * there are no type parameters in scope. 4276 * there are no type parameters in scope.
4300 */ 4277 */
4301 TypeParameterizedElementForLink get _typeParameterContext; 4278 TypeParameterizedElementForLink get _typeParameterContext;
4302 4279
(...skipping 22 matching lines...) Expand all
4325 if (type is InterfaceType) { 4302 if (type is InterfaceType) {
4326 Element result = type.lookUpGetter(name, compilationUnit.library); 4303 Element result = type.lookUpGetter(name, compilationUnit.library);
4327 result ??= type.lookUpMethod(name, compilationUnit.library); 4304 result ??= type.lookUpMethod(name, compilationUnit.library);
4328 return result; 4305 return result;
4329 } 4306 }
4330 } 4307 }
4331 // TODO(scheglov): implement for propagated types 4308 // TODO(scheglov): implement for propagated types
4332 return null; 4309 return null;
4333 } 4310 }
4334 } 4311 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/linker_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698