| 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 |