| 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 |
| 11 import 'package:dev_compiler/src/info.dart'; | 11 import 'package:dev_compiler/src/info.dart'; |
| 12 import 'package:dev_compiler/src/options.dart'; | 12 import 'package:dev_compiler/src/options.dart'; |
| 13 import 'package:dev_compiler/src/report.dart' show CheckerReporter; | |
| 14 | 13 |
| 15 abstract class TypeRules { | 14 abstract class TypeRules { |
| 16 final TypeProvider provider; | 15 final TypeProvider provider; |
| 17 LibraryInfo currentLibraryInfo = null; | 16 LibraryInfo currentLibraryInfo = null; |
| 18 | 17 |
| 19 TypeRules(TypeProvider this.provider); | 18 TypeRules(TypeProvider this.provider); |
| 20 | 19 |
| 20 MissingTypeReporter reportMissingType; |
| 21 |
| 21 bool isSubTypeOf(DartType t1, DartType t2); | 22 bool isSubTypeOf(DartType t1, DartType t2); |
| 22 bool isAssignable(DartType t1, DartType t2); | 23 bool isAssignable(DartType t1, DartType t2); |
| 23 | 24 |
| 24 bool isGroundType(DartType t) => true; | 25 bool isGroundType(DartType t) => true; |
| 25 // TODO(vsm): The default implementation is not ignoring the return type, | 26 // TODO(vsm): The default implementation is not ignoring the return type, |
| 26 // only the restricted override is. | 27 // only the restricted override is. |
| 27 bool isFunctionSubTypeOf(FunctionType f1, FunctionType f2, | 28 bool isFunctionSubTypeOf(FunctionType f1, FunctionType f2, |
| 28 {bool fuzzyArrows: true, bool ignoreReturn: false}) => | 29 {bool fuzzyArrows: true, bool ignoreReturn: false}) => |
| 29 isSubTypeOf(f1, f2); | 30 isSubTypeOf(f1, f2); |
| 30 | 31 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 44 | 45 |
| 45 bool isDynamic(DartType t); | 46 bool isDynamic(DartType t); |
| 46 bool isDynamicTarget(Expression expr); | 47 bool isDynamicTarget(Expression expr); |
| 47 bool isDynamicGet(Expression expr); | 48 bool isDynamicGet(Expression expr); |
| 48 bool isDynamicCall(Expression call); | 49 bool isDynamicCall(Expression call); |
| 49 } | 50 } |
| 50 | 51 |
| 51 class DartRules extends TypeRules { | 52 class DartRules extends TypeRules { |
| 52 DartRules(TypeProvider provider) : super(provider); | 53 DartRules(TypeProvider provider) : super(provider); |
| 53 | 54 |
| 55 MissingTypeReporter reportMissingType = null; |
| 56 |
| 54 bool isSubTypeOf(DartType t1, DartType t2) { | 57 bool isSubTypeOf(DartType t1, DartType t2) { |
| 55 return t1.isSubtypeOf(t2); | 58 return t1.isSubtypeOf(t2); |
| 56 } | 59 } |
| 57 | 60 |
| 58 bool isAssignable(DartType t1, DartType t2) { | 61 bool isAssignable(DartType t1, DartType t2) { |
| 59 return t1.isAssignableTo(t2); | 62 return t1.isAssignableTo(t2); |
| 60 } | 63 } |
| 61 | 64 |
| 62 StaticInfo checkAssignment( | 65 StaticInfo checkAssignment( |
| 63 Expression expr, DartType toType, bool constContext) { | 66 Expression expr, DartType toType, bool constContext) { |
| 64 final fromType = getStaticType(expr); | 67 final fromType = getStaticType(expr); |
| 65 if (!isAssignable(fromType, toType)) { | 68 if (!isAssignable(fromType, toType)) { |
| 66 return new StaticTypeError(this, expr, toType); | 69 return new StaticTypeError(this, expr, toType); |
| 67 } | 70 } |
| 68 return null; | 71 return null; |
| 69 } | 72 } |
| 70 | 73 |
| 71 DartType elementType(Element e) { | 74 DartType elementType(Element e) { |
| 72 return (e as dynamic).type; | 75 return (e as dynamic).type; |
| 73 } | 76 } |
| 74 | 77 |
| 75 /// By default, all invocations are dynamic in Dart. | 78 /// By default, all invocations are dynamic in Dart. |
| 76 bool isDynamic(DartType t) => true; | 79 bool isDynamic(DartType t) => true; |
| 77 bool isDynamicTarget(Expression expr) => true; | 80 bool isDynamicTarget(Expression expr) => true; |
| 78 bool isDynamicGet(Expression expr) => true; | 81 bool isDynamicGet(Expression expr) => true; |
| 79 bool isDynamicCall(Expression call) => true; | 82 bool isDynamicCall(Expression call) => true; |
| 80 } | 83 } |
| 81 | 84 |
| 85 typedef void MissingTypeReporter(Expression expr); |
| 86 |
| 82 class RestrictedRules extends TypeRules { | 87 class RestrictedRules extends TypeRules { |
| 83 final CheckerReporter _reporter; | 88 MissingTypeReporter reportMissingType = null; |
| 84 final RulesOptions options; | 89 final RulesOptions options; |
| 85 final List<DartType> _nonnullableTypes; | 90 final List<DartType> _nonnullableTypes; |
| 86 DownwardsInference inferrer; | 91 DownwardsInference inferrer; |
| 87 | 92 |
| 88 DartType _typeFromName(String name) { | 93 DartType _typeFromName(String name) { |
| 89 switch (name) { | 94 switch (name) { |
| 90 case 'int': | 95 case 'int': |
| 91 return provider.intType; | 96 return provider.intType; |
| 92 case 'double': | 97 case 'double': |
| 93 return provider.doubleType; | 98 return provider.doubleType; |
| 94 case 'num': | 99 case 'num': |
| 95 return provider.numType; | 100 return provider.numType; |
| 96 case 'bool': | 101 case 'bool': |
| 97 return provider.boolType; | 102 return provider.boolType; |
| 98 case 'String': | 103 case 'String': |
| 99 return provider.stringType; | 104 return provider.stringType; |
| 100 default: | 105 default: |
| 101 throw new UnsupportedError('Unsupported non-nullable type $name'); | 106 throw new UnsupportedError('Unsupported non-nullable type $name'); |
| 102 } | 107 } |
| 103 } | 108 } |
| 104 | 109 |
| 105 RestrictedRules(TypeProvider provider, this._reporter, {this.options}) | 110 RestrictedRules(TypeProvider provider, {this.options}) |
| 106 : _nonnullableTypes = <DartType>[], | 111 : _nonnullableTypes = <DartType>[], |
| 107 super(provider) { | 112 super(provider) { |
| 108 var types = options.nonnullableTypes; | 113 var types = options.nonnullableTypes; |
| 109 _nonnullableTypes.addAll(types.map(_typeFromName)); | 114 _nonnullableTypes.addAll(types.map(_typeFromName)); |
| 110 inferrer = new DownwardsInference(this); | 115 inferrer = new DownwardsInference(this); |
| 111 } | 116 } |
| 112 | 117 |
| 113 DartType getStaticType(Expression expr) { | 118 DartType getStaticType(Expression expr) { |
| 114 var type = expr.staticType; | 119 var type = expr.staticType; |
| 115 if (type != null) return type; | 120 if (type != null) return type; |
| 116 _reporter.log(new MissingTypeError(expr)); | 121 if (reportMissingType != null) reportMissingType(expr); |
| 117 return provider.dynamicType; | 122 return provider.dynamicType; |
| 118 } | 123 } |
| 119 | 124 |
| 120 bool _isBottom(DartType t, {bool dynamicIsBottom: false}) { | 125 bool _isBottom(DartType t, {bool dynamicIsBottom: false}) { |
| 121 if (t.isDynamic && dynamicIsBottom) return true; | 126 if (t.isDynamic && dynamicIsBottom) return true; |
| 122 // TODO(vsm): We need direct support for non-nullability in DartType. | 127 // TODO(vsm): We need direct support for non-nullability in DartType. |
| 123 // This should check on "true/nonnullable" Bottom | 128 // This should check on "true/nonnullable" Bottom |
| 124 if (t.isBottom && _nonnullableTypes.isEmpty) return true; | 129 if (t.isBottom && _nonnullableTypes.isEmpty) return true; |
| 125 return false; | 130 return false; |
| 126 } | 131 } |
| (...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 var entries = e.entries; | 833 var entries = e.entries; |
| 829 bool inferEntry(MapLiteralEntry entry) { | 834 bool inferEntry(MapLiteralEntry entry) { |
| 830 return _inferExpression(entry.key, kType, errors) && | 835 return _inferExpression(entry.key, kType, errors) && |
| 831 _inferExpression(entry.value, vType, errors); | 836 _inferExpression(entry.value, vType, errors); |
| 832 } | 837 } |
| 833 var b = entries.every(inferEntry); | 838 var b = entries.every(inferEntry); |
| 834 if (b) annotateMapLiteral(e, targs); | 839 if (b) annotateMapLiteral(e, targs); |
| 835 return b; | 840 return b; |
| 836 } | 841 } |
| 837 } | 842 } |
| OLD | NEW |