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 /// Encapsulates how to invoke the analyzer resolver and overrides how it | 5 /// Encapsulates how to invoke the analyzer resolver and overrides how it |
6 /// computes types on expressions to use our restricted set of types. | 6 /// computes types on expressions to use our restricted set of types. |
7 library dev_compiler.src.checker.resolver; | 7 library dev_compiler.src.checker.resolver; |
8 | 8 |
9 import 'package:analyzer/analyzer.dart'; | 9 import 'package:analyzer/analyzer.dart'; |
10 import 'package:analyzer/src/generated/ast.dart'; | 10 import 'package:analyzer/src/generated/ast.dart'; |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 | 147 |
148 // Track types in this strongly connected component, ensure we visit | 148 // Track types in this strongly connected component, ensure we visit |
149 // supertypes before subtypes. | 149 // supertypes before subtypes. |
150 var typeToDeclaration = <InterfaceType, ClassDeclaration>{}; | 150 var typeToDeclaration = <InterfaceType, ClassDeclaration>{}; |
151 classes.forEach((c) => typeToDeclaration[c.element.type] = c); | 151 classes.forEach((c) => typeToDeclaration[c.element.type] = c); |
152 var seen = new Set<InterfaceType>(); | 152 var seen = new Set<InterfaceType>(); |
153 visit(ClassDeclaration cls) { | 153 visit(ClassDeclaration cls) { |
154 var element = cls.element; | 154 var element = cls.element; |
155 var type = element.type; | 155 var type = element.type; |
156 if (seen.contains(type)) return; | 156 if (seen.contains(type)) return; |
| 157 seen.add(type); |
157 for (var supertype in element.allSupertypes) { | 158 for (var supertype in element.allSupertypes) { |
158 var supertypeClass = typeToDeclaration[supertype]; | 159 var supertypeClass = typeToDeclaration[supertype]; |
159 if (supertypeClass != null) visit(supertypeClass); | 160 if (supertypeClass != null) visit(supertypeClass); |
160 } | 161 } |
161 seen.add(type); | |
162 | 162 |
163 if (_options.inferFromOverrides) { | 163 if (_options.inferFromOverrides) { |
164 // Infer field types from overrides first, otherwise from initializers. | 164 // Infer field types from overrides first, otherwise from initializers. |
165 var pending = new Set<VariableDeclaration>(); | 165 var pending = new Set<VariableDeclaration>(); |
166 cls.members | 166 cls.members |
167 .where(_isInstanceField) | 167 .where(_isInstanceField) |
168 .forEach((f) => _inferFieldTypeFromOverride(f, pending)); | 168 .forEach((f) => _inferFieldTypeFromOverride(f, pending)); |
169 if (pending.isNotEmpty) _inferVariableFromInitializer(pending); | 169 if (pending.isNotEmpty) _inferVariableFromInitializer(pending); |
170 | 170 |
171 // Infer return-types from overrides | 171 // Infer return-types from overrides |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 } | 459 } |
460 | 460 |
461 @override | 461 @override |
462 visitFieldFormalParameter(FieldFormalParameter node) { | 462 visitFieldFormalParameter(FieldFormalParameter node) { |
463 // Ensure the field formal parameter's type is updated after inference. | 463 // Ensure the field formal parameter's type is updated after inference. |
464 // Normally this happens during TypeResolver, but that's before we've done | 464 // Normally this happens during TypeResolver, but that's before we've done |
465 // inference on the field type. | 465 // inference on the field type. |
466 var element = node.element; | 466 var element = node.element; |
467 if (element is FieldFormalParameterElement) { | 467 if (element is FieldFormalParameterElement) { |
468 if (element.type.isDynamic) { | 468 if (element.type.isDynamic) { |
469 element.type = element.field.type; | 469 // In malformed code, there may be no actual field. |
| 470 if (element.field != null) { |
| 471 element.type = element.field.type; |
| 472 } |
470 } | 473 } |
471 } | 474 } |
472 super.visitFieldFormalParameter(node); | 475 super.visitFieldFormalParameter(node); |
473 } | 476 } |
474 } | 477 } |
475 | 478 |
476 /// Internal state of the resolver, stored so we can reanalyze portions of the | 479 /// Internal state of the resolver, stored so we can reanalyze portions of the |
477 /// AST quickly, without recomputing everything from the top. | 480 /// AST quickly, without recomputing everything from the top. |
478 class _ResolverState { | 481 class _ResolverState { |
479 final TypePromotionManager_TypePromoteScope promotionScope; | 482 final TypePromotionManager_TypePromoteScope promotionScope; |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 } | 716 } |
714 } | 717 } |
715 | 718 |
716 // Review note: no longer need to override visitFunctionExpression, this is | 719 // Review note: no longer need to override visitFunctionExpression, this is |
717 // handled by the analyzer internally. | 720 // handled by the analyzer internally. |
718 // TODO(vsm): in visitbinaryExpression: check computeStaticReturnType result? | 721 // TODO(vsm): in visitbinaryExpression: check computeStaticReturnType result? |
719 // TODO(vsm): in visitFunctionDeclaration: Should we ever use the expression | 722 // TODO(vsm): in visitFunctionDeclaration: Should we ever use the expression |
720 // type in a (...) => expr or just the written type? | 723 // type in a (...) => expr or just the written type? |
721 | 724 |
722 } | 725 } |
OLD | NEW |