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