Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Side by Side Diff: lib/src/checker/rules.dart

Issue 1024073003: Treat Object and dynamic similarly (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/runtime/dart/convert.js ('k') | test/checker/checker_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 _nonnullableTypes.addAll(types.map(_typeFromName)); 107 _nonnullableTypes.addAll(types.map(_typeFromName));
108 } 108 }
109 109
110 DartType getStaticType(Expression expr) { 110 DartType getStaticType(Expression expr) {
111 var type = expr.staticType; 111 var type = expr.staticType;
112 if (type != null) return type; 112 if (type != null) return type;
113 _reporter.log(new MissingTypeError(expr)); 113 _reporter.log(new MissingTypeError(expr));
114 return provider.dynamicType; 114 return provider.dynamicType;
115 } 115 }
116 116
117 bool _isBottom(DartType t, {bool dynamicIsBottom: false}) {
118 if (t.isDynamic && dynamicIsBottom) return true;
119 // TODO(vsm): We need direct support for non-nullability in DartType.
120 // This should check on "true/nonnullable" Bottom
121 if (t.isBottom && _nonnullableTypes.isEmpty) return true;
122 return false;
123 }
124
125 bool _isTop(DartType t, {bool dynamicIsBottom: false}) {
126 if (t.isDynamic && !dynamicIsBottom) return true;
127 if (t.isObject) return true;
128 return false;
129 }
130
117 bool isNonNullableType(DartType t) => _nonnullableTypes.contains(t); 131 bool isNonNullableType(DartType t) => _nonnullableTypes.contains(t);
118 132
119 bool maybeNonNullableType(DartType t) { 133 bool maybeNonNullableType(DartType t) {
120 // Return true iff t *may* be a primitive type. 134 // Return true iff t *may* be a primitive type.
121 // If t is a generic type parameter, return true if it may be 135 // If t is a generic type parameter, return true if it may be
122 // instantiated as a primitive. 136 // instantiated as a primitive.
123 if (isNonNullableType(t)) { 137 if (isNonNullableType(t)) {
124 return true; 138 return true;
125 } else if (t is TypeParameterType) { 139 } else if (t is TypeParameterType) {
126 var bound = t.element.bound; 140 var bound = t.element.bound;
127 if (bound == null) { 141 if (bound == null) {
128 bound = provider.dynamicType; 142 bound = provider.dynamicType;
129 } 143 }
130 return _nonnullableTypes.any((DartType p) => isSubTypeOf(p, bound)); 144 return _nonnullableTypes.any((DartType p) => isSubTypeOf(p, bound));
131 } else { 145 } else {
132 return false; 146 return false;
133 } 147 }
134 } 148 }
135 149
136 bool _anyParameterType(FunctionType ft, bool predicate(DartType t)) { 150 bool _anyParameterType(FunctionType ft, bool predicate(DartType t)) {
137 return ft.normalParameterTypes.any(predicate) || 151 return ft.normalParameterTypes.any(predicate) ||
138 ft.optionalParameterTypes.any(predicate) || 152 ft.optionalParameterTypes.any(predicate) ||
139 ft.namedParameterTypes.values.any(predicate); 153 ft.namedParameterTypes.values.any(predicate);
140 } 154 }
141 155
142 // TODO(leafp): Revisit this. 156 // TODO(leafp): Revisit this.
143 bool isGroundType(DartType t) { 157 bool isGroundType(DartType t) {
144 if (t is TypeParameterType) return false; 158 if (t is TypeParameterType) return false;
145 if (t.isDynamic) return true; 159 if (_isTop(t)) return true;
146 160
147 if (t is FunctionType) { 161 if (t is FunctionType) {
148 if (!t.returnType.isDynamic || 162 if (!_isTop(t.returnType) ||
149 _anyParameterType(t, (pt) => !pt.isDynamic)) { 163 _anyParameterType(t, (pt) => !_isBottom(pt, dynamicIsBottom: true))) {
150 return false; 164 return false;
151 } else { 165 } else {
152 return true; 166 return true;
153 } 167 }
154 } 168 }
155 169
156 if (t is InterfaceType) { 170 if (t is InterfaceType) {
157 var typeArguments = t.typeArguments; 171 var typeArguments = t.typeArguments;
158 for (var typeArgument in typeArguments) { 172 for (var typeArgument in typeArguments) {
159 if (!typeArgument.isDynamic && !typeArgument.isObject) return false; 173 if (!_isTop(typeArgument)) return false;
160 } 174 }
161 return true; 175 return true;
162 } 176 }
163 177
164 throw new StateError("Unexpected type"); 178 throw new StateError("Unexpected type");
165 } 179 }
166 180
167 FunctionType getCallMethodType(DartType t) { 181 FunctionType getCallMethodType(DartType t) {
168 if (t is InterfaceType) { 182 if (t is InterfaceType) {
169 ClassElement element = t.element; 183 ClassElement element = t.element;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 for (final parent in i1.mixins) { 286 for (final parent in i1.mixins) {
273 if (_isInterfaceSubTypeOf(parent, i2)) return true; 287 if (_isInterfaceSubTypeOf(parent, i2)) return true;
274 } 288 }
275 289
276 return false; 290 return false;
277 } 291 }
278 292
279 bool isSubTypeOf(DartType t1, DartType t2, {bool dynamicIsBottom: false}) { 293 bool isSubTypeOf(DartType t1, DartType t2, {bool dynamicIsBottom: false}) {
280 if (t1 == t2) return true; 294 if (t1 == t2) return true;
281 295
282 if (t2.isDynamic) return !dynamicIsBottom; 296 // Trivially true.
283 if (t1.isDynamic) return dynamicIsBottom; 297 if (_isTop(t2, dynamicIsBottom: dynamicIsBottom) ||
298 _isBottom(t1, dynamicIsBottom: dynamicIsBottom)) {
299 return true;
300 }
284 301
285 // Null can be assigned to anything non-primitive. 302 // Trivially false.
286 // FIXME: Can this be anything besides null? 303 if (_isTop(t1, dynamicIsBottom: dynamicIsBottom) ||
304 _isBottom(t2, dynamicIsBottom: dynamicIsBottom)) {
305 return false;
306 }
307
308 // The null type is a subtype of any nonnullable type.
309 // TODO(vsm): Note, t1.isBottom still allows for null confusingly.
310 // _isBottom(t1) does not necessarily imply t1.isBottom if there are
311 // nonnullable types in the system.
287 if (t1.isBottom) { 312 if (t1.isBottom) {
288 // Return false iff t2 *may* be a primitive type. 313 // Return false iff t2 *may* be a primitive type.
289 return !maybeNonNullableType(t2); 314 return !maybeNonNullableType(t2);
290 } 315 }
291 if (t2.isBottom) return false;
292
293 // Trivially true for non-primitives.
294 if (t2 == provider.objectType) return true;
295 if (t1 == provider.objectType) return false;
296 316
297 // S <: T where S is a type variable 317 // S <: T where S is a type variable
298 // T is not dynamic or object (handled above) 318 // T is not dynamic or object (handled above)
299 // S != T (handled above) 319 // S != T (handled above)
300 // So only true if bound of S is S' and 320 // So only true if bound of S is S' and
301 // S' <: T 321 // S' <: T
302 if (t1 is TypeParameterType) { 322 if (t1 is TypeParameterType) {
303 DartType bound = t1.element.bound; 323 DartType bound = t1.element.bound;
304 if (bound == null) return false; 324 if (bound == null) return false;
305 return isSubTypeOf(bound, t2); 325 return isSubTypeOf(bound, t2);
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 if (element is FunctionElement || element is MethodElement) { 544 if (element is FunctionElement || element is MethodElement) {
525 // An original declaration. 545 // An original declaration.
526 return false; 546 return false;
527 } 547 }
528 } 548 }
529 549
530 var ft = t as FunctionType; 550 var ft = t as FunctionType;
531 return _anyParameterType(ft, (pt) => pt.isDynamic); 551 return _anyParameterType(ft, (pt) => pt.isDynamic);
532 } 552 }
533 } 553 }
OLDNEW
« no previous file with comments | « lib/runtime/dart/convert.js ('k') | test/checker/checker_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698