| 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 dev_compiler.src.checker.rules; | 5 library dev_compiler.src.checker.rules; |
| 6 | 6 |
| 7 import 'package:analyzer/src/generated/ast.dart'; | 7 import 'package:analyzer/src/generated/ast.dart'; |
| 8 import 'package:analyzer/src/generated/element.dart'; | 8 import 'package:analyzer/src/generated/element.dart'; |
| 9 import 'package:analyzer/src/generated/resolver.dart'; | 9 import 'package:analyzer/src/generated/resolver.dart'; |
| 10 | 10 |
| (...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 void annotateMapLiteral(MapLiteral e, List<DartType> targs) {} | 563 void annotateMapLiteral(MapLiteral e, List<DartType> targs) {} |
| 564 | 564 |
| 565 /// Called for each new/const which gets inferred | 565 /// Called for each new/const which gets inferred |
| 566 void annotateInstanceCreationExpression( | 566 void annotateInstanceCreationExpression( |
| 567 InstanceCreationExpression e, List<DartType> targs) {} | 567 InstanceCreationExpression e, List<DartType> targs) {} |
| 568 | 568 |
| 569 /// Downward inference | 569 /// Downward inference |
| 570 bool inferExpression(Expression e, DartType t) { | 570 bool inferExpression(Expression e, DartType t) { |
| 571 if (e is Conversion) return inferExpression(e.node, t); | 571 if (e is Conversion) return inferExpression(e.node, t); |
| 572 if (rules.isSubTypeOf(rules.getStaticType(e), t)) return true; | 572 if (rules.isSubTypeOf(rules.getStaticType(e), t)) return true; |
| 573 if (e is FunctionExpression) return _inferFunctionExpression(e, t); |
| 573 if (e is ListLiteral) return _inferListLiteral(e, t); | 574 if (e is ListLiteral) return _inferListLiteral(e, t); |
| 574 if (e is MapLiteral) return _inferMapLiteral(e, t); | 575 if (e is MapLiteral) return _inferMapLiteral(e, t); |
| 575 if (e is NamedExpression) return _inferNamedExpression(e, t); | 576 if (e is NamedExpression) return _inferNamedExpression(e, t); |
| 576 if (e is InstanceCreationExpression) return _inferInstanceCreationExpression
( | 577 if (e is InstanceCreationExpression) return _inferInstanceCreationExpression
( |
| 577 e, t); | 578 e, t); |
| 578 return false; | 579 return false; |
| 579 } | 580 } |
| 580 | 581 |
| 581 /// If t1 = I<dynamic, ..., dynamic>, then look for a supertype | 582 /// If t1 = I<dynamic, ..., dynamic>, then look for a supertype |
| 582 /// of t1 of the form K<S0, ..., Sm> where t2 = K<S0', ..., Sm'> | 583 /// of t1 of the form K<S0, ..., Sm> where t2 = K<S0', ..., Sm'> |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 } | 717 } |
| 717 } | 718 } |
| 718 annotateInstanceCreationExpression(e, targs); | 719 annotateInstanceCreationExpression(e, targs); |
| 719 return true; | 720 return true; |
| 720 } | 721 } |
| 721 | 722 |
| 722 bool _inferNamedExpression(NamedExpression e, DartType t) { | 723 bool _inferNamedExpression(NamedExpression e, DartType t) { |
| 723 return inferExpression(e.expression, t); | 724 return inferExpression(e.expression, t); |
| 724 } | 725 } |
| 725 | 726 |
| 727 bool _inferFunctionExpression(FunctionExpression e, DartType t) { |
| 728 if (t is! FunctionType) return false; |
| 729 var returnT = (t as FunctionType).returnType; |
| 730 if (returnT.isDynamic) return false; |
| 731 var eType = e.staticType; |
| 732 if (eType is! FunctionType) return false; |
| 733 if (e.body is! ExpressionFunctionBody) return false; |
| 734 var body = (e.body as ExpressionFunctionBody).expression; |
| 735 if (!inferExpression(body, returnT)) return false; |
| 736 // TODO(leafp): Try narrowing the argument types if possible |
| 737 // to get better code in the function body. This requires checking |
| 738 // that the body is well-typed at the more specific type. |
| 739 var element = (e.element as ExecutableElementImpl); |
| 740 var oldReturnT = element.returnType; |
| 741 element.returnType = returnT; |
| 742 // Work around dynamic as bottom for now by handling function literals |
| 743 // with dynamic arguments specially. We already know the body is typable |
| 744 // at the chosen type, and if all args are dynamic, then function must be |
| 745 // typeable. |
| 746 if ((eType as FunctionType).parameters.every((x) => x.type.isDynamic)) { |
| 747 return true; |
| 748 } |
| 749 if (rules.isSubTypeOf(e.staticType, t)) return true; |
| 750 element.returnType = oldReturnT; |
| 751 return false; |
| 752 } |
| 753 |
| 726 bool _inferListLiteral(ListLiteral e, DartType t) { | 754 bool _inferListLiteral(ListLiteral e, DartType t) { |
| 727 var dyn = rules.provider.dynamicType; | 755 var dyn = rules.provider.dynamicType; |
| 728 var listT = rules.provider.listType.substitute4([dyn]); | 756 var listT = rules.provider.listType.substitute4([dyn]); |
| 729 // List <: t (using dart rules) must be true | 757 // List <: t (using dart rules) must be true |
| 730 if (!listT.isSubtypeOf(t)) return false; | 758 if (!listT.isSubtypeOf(t)) return false; |
| 731 // The list literal must have no type arguments | 759 // The list literal must have no type arguments |
| 732 if (e.typeArguments != null) return false; | 760 if (e.typeArguments != null) return false; |
| 733 if (t is! InterfaceType) return false; | 761 if (t is! InterfaceType) return false; |
| 734 var targs = _matchTypes(listT, t); | 762 var targs = _matchTypes(listT, t); |
| 735 if (targs == null) return false; | 763 if (targs == null) return false; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 759 var entries = e.entries; | 787 var entries = e.entries; |
| 760 bool inferEntry(MapLiteralEntry entry) { | 788 bool inferEntry(MapLiteralEntry entry) { |
| 761 return inferExpression(entry.key, kType) && | 789 return inferExpression(entry.key, kType) && |
| 762 inferExpression(entry.value, vType); | 790 inferExpression(entry.value, vType); |
| 763 } | 791 } |
| 764 var b = entries.every(inferEntry); | 792 var b = entries.every(inferEntry); |
| 765 if (b) annotateMapLiteral(e, targs); | 793 if (b) annotateMapLiteral(e, targs); |
| 766 return b; | 794 return b; |
| 767 } | 795 } |
| 768 } | 796 } |
| OLD | NEW |