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

Side by Side Diff: lib/runtime/dart/_types.js

Issue 1530563003: Generate all runtime files from dart. (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years 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/_runtime.js ('k') | lib/runtime/dart/_utils.js » ('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
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.
4
5 /* This library defines the representation of runtime types.
6 */
7
8 dart_library.library('dart/_types', null, /* Imports */[ 1 dart_library.library('dart/_types', null, /* Imports */[
9 ], /* Lazy Imports */[
10 'dart/_utils', 2 'dart/_utils',
3 'dart/_rtti'
4 ], /* Lazy imports */[
11 'dart/core', 5 'dart/core',
12 'dart/_classes', 6 'dart/_classes'
13 'dart/_rtti' 7 ], function(exports, utils, rtti, core, classes) {
14 ], function(exports, dart_utils, core, classes, rtti) {
15 'use strict'; 8 'use strict';
16 9 const assert = utils.assert;
17 const getOwnPropertyNames = Object.getOwnPropertyNames; 10 const getOwnPropertyNames = Object.getOwnPropertyNames;
18 11 const TypeRep = class TypeRep extends rtti.LazyTagged(() => core.Type) {
19 const assert = dart_utils.assert_; 12 get name() {
20 13 return this.toString();
21 /** 14 }
22 * Types in dart are represented at runtime as follows. 15 };
23 * - Normal nominal types, produced from classes, are represented 16 const Dynamic = class Dynamic extends TypeRep {
24 * at runtime by the JS class of which they are an instance. 17 toString() {
25 * If the type is the result of instantiating a generic class, 18 return "dynamic";
26 * then the "classes" module manages the association between the 19 }
27 * instantiated class and the original class declaration 20 };
28 * and the type arguments with which it was instantiated. This 21 const dynamic = new Dynamic();
29 * assocation can be queried via the "classes" module". 22 const Void = class Void extends TypeRep {
30 * 23 toString() {
31 * - All other types are represented as instances of class TypeRep, 24 return "void";
32 * defined in this module. 25 }
33 * - Dynamic, Void, and Bottom are singleton instances of sentinal 26 };
34 * classes. 27 const void$ = new Void();
35 * - Function types are instances of subclasses of AbstractFunctionType. 28 const Bottom = class Bottom extends TypeRep {
36 * 29 toString() {
37 * Function types are represented in one of two ways: 30 return "bottom";
38 * - As an instance of FunctionType. These are eagerly computed. 31 }
39 * - As an instance of TypeDef. The TypeDef representation lazily 32 };
40 * computes an instance of FunctionType, and delegates to that instance. 33 const bottom = new Bottom();
41 * 34 const JSObject = class JSObject extends TypeRep {
42 * All types satisfy the following interface: 35 toString() {
43 * get String name; 36 return "NativeJavaScriptObject";
44 * String toString(); 37 }
45 * 38 };
46 */ 39 const jsobject = new JSObject();
47 class TypeRep extends rtti.LazyTagged(() => core.Type) { 40 const AbstractFunctionType = class AbstractFunctionType extends TypeRep {
48 get name() {return this.toString();}
49 }
50
51 class Dynamic extends TypeRep {
52 toString() { return "dynamic"; }
53 }
54 let dynamicR = new Dynamic();
55 exports.dynamic = dynamicR;
56
57 class Void extends TypeRep {
58 toString() { return "void"; }
59 }
60
61 let voidR = new Void();
62 exports.void = voidR;
63
64 class Bottom extends TypeRep {
65 toString() { return "bottom"; }
66 }
67 let bottomR = new Bottom();
68 exports.bottom = bottomR;
69
70 class JSObject extends TypeRep {
71 toString() { return "NativeJavaScriptObject"; }
72 }
73 let jsobjectR = new JSObject();
74 exports.jsobject = jsobjectR;
75
76 class AbstractFunctionType extends TypeRep {
77 constructor() { 41 constructor() {
78 super(); 42 super();
79 this._stringValue = null; 43 this._stringValue = null;
80 } 44 }
81 45 toString() {
82 toString() { return this.name; } 46 return this.name;
83 47 }
84 get name() { 48 get name() {
85 if (this._stringValue) return this._stringValue; 49 if (this._stringValue)
86 50 return this._stringValue;
87 let buffer = '('; 51 let buffer = '(';
88 for (let i = 0; i < this.args.length; ++i) { 52 for (let i = 0; i < this.args.length; ++i) {
89 if (i > 0) { 53 if (i > 0) {
90 buffer += ', '; 54 buffer += ', ';
91 } 55 }
92 buffer += typeName(this.args[i]); 56 buffer += typeName(this.args[i]);
93 } 57 }
94 if (this.optionals.length > 0) { 58 if (this.optionals.length > 0) {
95 if (this.args.length > 0) buffer += ', '; 59 if (this.args.length > 0)
60 buffer += ', ';
96 buffer += '['; 61 buffer += '[';
97 for (let i = 0; i < this.optionals.length; ++i) { 62 for (let i = 0; i < this.optionals.length; ++i) {
98 if (i > 0) { 63 if (i > 0) {
99 buffer += ', '; 64 buffer += ', ';
100 } 65 }
101 buffer += typeName(this.optionals[i]); 66 buffer += typeName(this.optionals[i]);
102 } 67 }
103 buffer += ']'; 68 buffer += ']';
104 } else if (Object.keys(this.named).length > 0) { 69 } else if (Object.keys(this.named).length > 0) {
105 if (this.args.length > 0) buffer += ', '; 70 if (this.args.length > 0)
71 buffer += ', ';
106 buffer += '{'; 72 buffer += '{';
107 let names = getOwnPropertyNames(this.named).sort(); 73 let names = getOwnPropertyNames(this.named).sort();
108 for (let i = 0; i < names.length; ++i) { 74 for (let i = 0; i < names.length; ++i) {
109 if (i > 0) { 75 if (i > 0) {
110 buffer += ', '; 76 buffer += ', ';
111 } 77 }
112 buffer += names[i] + ': ' + typeName(this.named[names[i]]); 78 buffer += names[i] + ': ' + typeName(this.named[names[i]]);
113 } 79 }
114 buffer += '}'; 80 buffer += '}';
115 } 81 }
116
117 buffer += ') -> ' + typeName(this.returnType); 82 buffer += ') -> ' + typeName(this.returnType);
118 this._stringValue = buffer; 83 this._stringValue = buffer;
119 return buffer; 84 return buffer;
120 } 85 }
121 } 86 };
122 87 const FunctionType = class FunctionType extends AbstractFunctionType {
123 class FunctionType extends AbstractFunctionType {
124 /**
125 * Construct a function type. There are two arrow constructors,
126 * distinguished by the "definite" flag.
127 *
128 * The fuzzy arrow (definite is false) treats any arguments
129 * of type dynamic as having type bottom, and will always be
130 * called with a dynamic invoke.
131 *
132 * The definite arrow (definite is true) leaves arguments unchanged.
133 *
134 * We eagerly canonize the argument types to avoid having to deal with
135 * this logic in multiple places.
136 *
137 * TODO(leafp): Figure out how to present this to the user. How
138 * should these be printed out?
139 */
140 constructor(definite, returnType, args, optionals, named) { 88 constructor(definite, returnType, args, optionals, named) {
141 super(); 89 super();
90 if (!returnType || args.indexOf(void 0) >= 0) {
91 throw new Error('Found undefined return type or arg type!');
92 }
142 this.definite = definite; 93 this.definite = definite;
143 this.returnType = returnType; 94 this.returnType = returnType;
144 this.args = args; 95 this.args = args;
145 this.optionals = optionals; 96 this.optionals = optionals;
146 this.named = named; 97 this.named = named;
147
148 // TODO(vsm): This is just parameter metadata for now.
149 this.metadata = []; 98 this.metadata = [];
150 function process(array, metadata) { 99 function process(array, metadata) {
151 var result = []; 100 var result = [];
152 for (var i = 0; i < array.length; ++i) { 101 for (var i = 0; i < array.length; ++i) {
153 var arg = array[i]; 102 var arg = array[i];
154 if (arg instanceof Array) { 103 if (arg instanceof Array) {
155 metadata.push(arg.slice(1)); 104 metadata.push(arg.slice(1));
156 result.push(arg[0]); 105 result.push(arg[0]);
157 } else { 106 } else {
158 metadata.push([]); 107 metadata.push([]);
159 result.push(arg); 108 result.push(arg);
160 } 109 }
161 } 110 }
162 return result; 111 return result;
163 } 112 }
164 this.args = process(this.args, this.metadata); 113 this.args = process(this.args, this.metadata);
165 this.optionals = process(this.optionals, this.metadata); 114 this.optionals = process(this.optionals, this.metadata);
166 // TODO(vsm): Add named arguments.
167 this._canonize(); 115 this._canonize();
168 } 116 }
169 _canonize() { 117 _canonize() {
170 if (this.definite) return; 118 if (this.definite)
171 119 return;
172 function replace(a) { 120 function replace(a) {
173 return (a == dynamicR) ? bottomR : a; 121 return a == dynamic ? bottom : a;
174 } 122 }
175
176 this.args = this.args.map(replace); 123 this.args = this.args.map(replace);
177
178 if (this.optionals.length > 0) { 124 if (this.optionals.length > 0) {
179 this.optionals = this.optionals.map(replace); 125 this.optionals = this.optionals.map(replace);
180 } 126 }
181
182 if (Object.keys(this.named).length > 0) { 127 if (Object.keys(this.named).length > 0) {
183 let r = {}; 128 let r = {};
184 for (let name of getOwnPropertyNames(this.named)) { 129 for (let name of getOwnPropertyNames(this.named)) {
185 r[name] = replace(this.named[name]); 130 r[name] = replace(this.named[name]);
186 } 131 }
187 this.named = r; 132 this.named = r;
188 } 133 }
189 } 134 }
190 } 135 };
191 136 const Typedef = class Typedef extends AbstractFunctionType {
192 class Typedef extends AbstractFunctionType {
193 constructor(name, closure) { 137 constructor(name, closure) {
194 super(); 138 super();
195 this._name = name; 139 this._name = name;
196 this._closure = closure; 140 this._closure = closure;
197 this._functionType = null; 141 this._functionType = null;
198 } 142 }
199
200 get definite() { 143 get definite() {
201 return this._functionType.definite; 144 return this._functionType.definite;
202 } 145 }
203
204 get name() { 146 get name() {
205 return this._name; 147 return this._name;
206 } 148 }
207
208 get functionType() { 149 get functionType() {
209 if (!this._functionType) { 150 if (!this._functionType) {
210 this._functionType = this._closure(); 151 this._functionType = this._closure();
211 } 152 }
212 return this._functionType; 153 return this._functionType;
213 } 154 }
214
215 get returnType() { 155 get returnType() {
216 return this.functionType.returnType; 156 return this.functionType.returnType;
217 } 157 }
218
219 get args() { 158 get args() {
220 return this.functionType.args; 159 return this.functionType.args;
221 } 160 }
222
223 get optionals() { 161 get optionals() {
224 return this.functionType.optionals; 162 return this.functionType.optionals;
225 } 163 }
226
227 get named() { 164 get named() {
228 return this.functionType.named; 165 return this.functionType.named;
229 } 166 }
230
231 get metadata() { 167 get metadata() {
232 return this.functionType.metadata; 168 return this.functionType.metadata;
233 } 169 }
234 } 170 };
235
236 function _functionType(definite, returnType, args, extra) { 171 function _functionType(definite, returnType, args, extra) {
237 // TODO(vsm): Cache / memomize?
238 let optionals; 172 let optionals;
239 let named; 173 let named;
240 if (extra === void 0) { 174 if (extra === void 0) {
241 optionals = []; 175 optionals = [];
242 named = {}; 176 named = {};
243 } else if (extra instanceof Array) { 177 } else if (extra instanceof Array) {
244 optionals = extra; 178 optionals = extra;
245 named = {}; 179 named = {};
246 } else { 180 } else {
247 optionals = []; 181 optionals = [];
248 named = extra; 182 named = extra;
249 } 183 }
250 return new FunctionType(definite, returnType, args, optionals, named); 184 return new FunctionType(definite, returnType, args, optionals, named);
251 } 185 }
252
253 /**
254 * Create a "fuzzy" function type. If any arguments are dynamic
255 * they will be replaced with bottom.
256 */
257 function functionType(returnType, args, extra) { 186 function functionType(returnType, args, extra) {
258 return _functionType(false, returnType, args, extra); 187 return _functionType(false, returnType, args, extra);
259 } 188 }
260 exports.functionType = functionType;
261
262 /**
263 * Create a definite function type. No substitution of dynamic for
264 * bottom occurs.
265 */
266 function definiteFunctionType(returnType, args, extra) { 189 function definiteFunctionType(returnType, args, extra) {
267 return _functionType(true, returnType, args, extra); 190 return _functionType(true, returnType, args, extra);
268 } 191 }
269 exports.definiteFunctionType = definiteFunctionType;
270
271 function typedef(name, closure) { 192 function typedef(name, closure) {
272 return new Typedef(name, closure); 193 return new Typedef(name, closure);
273 } 194 }
274 exports.typedef = typedef;
275
276 function isDartType(type) { 195 function isDartType(type) {
277 return rtti.read(type) === core.Type; 196 return rtti.read(type) === core.Type;
278 } 197 }
279 exports.isDartType = isDartType;
280
281 function typeName(type) { 198 function typeName(type) {
282 // Non-instance types 199 if (type instanceof TypeRep)
283 if (type instanceof TypeRep) return type.toString(); 200 return type.toString();
284 // Instance types
285 let tag = rtti.read(type); 201 let tag = rtti.read(type);
286 if (tag === core.Type) { 202 if (tag === core.Type) {
287 let name = type.name; 203 let name = type.name;
288 let args = classes.getGenericArgs(type); 204 let args = classes.getGenericArgs(type);
289 if (args) { 205 if (args) {
290 name += '<'; 206 name += '<';
291 for (let i = 0; i < args.length; ++i) { 207 for (let i = 0; i < args.length; ++i) {
292 if (i > 0) name += ', '; 208 if (i > 0)
209 name += ', ';
293 name += typeName(args[i]); 210 name += typeName(args[i]);
294 } 211 }
295 name += '>'; 212 name += '>';
296 } 213 }
297 return name; 214 return name;
298 } 215 }
299 if (tag) return "Not a type: " + tag.name; 216 if (tag)
217 return "Not a type: " + tag.name;
300 return "JSObject<" + type.name + ">"; 218 return "JSObject<" + type.name + ">";
301 } 219 }
302 exports.typeName = typeName;
303
304 function isFunctionType(type) { 220 function isFunctionType(type) {
305 return type instanceof AbstractFunctionType || type == core.Function; 221 return type instanceof AbstractFunctionType || type == core.Function;
306 } 222 }
307
308 function isFunctionSubType(ft1, ft2) { 223 function isFunctionSubType(ft1, ft2) {
309 if (ft2 == core.Function) { 224 if (ft2 == core.Function) {
310 return true; 225 return true;
311 } 226 }
312
313 let ret1 = ft1.returnType; 227 let ret1 = ft1.returnType;
314 let ret2 = ft2.returnType; 228 let ret2 = ft2.returnType;
315
316 if (!isSubtype_(ret1, ret2)) { 229 if (!isSubtype_(ret1, ret2)) {
317 // Covariant return types 230 if (ret2 != void$) {
318 // Note, void (which can only appear as a return type) is effectively
319 // treated as dynamic. If the base return type is void, we allow any
320 // subtype return type.
321 // E.g., we allow:
322 // () -> int <: () -> void
323 if (ret2 != voidR) {
324 return false; 231 return false;
325 } 232 }
326 } 233 }
327
328 let args1 = ft1.args; 234 let args1 = ft1.args;
329 let args2 = ft2.args; 235 let args2 = ft2.args;
330
331 if (args1.length > args2.length) { 236 if (args1.length > args2.length) {
332 return false; 237 return false;
333 } 238 }
334
335 for (let i = 0; i < args1.length; ++i) { 239 for (let i = 0; i < args1.length; ++i) {
336 if (!isSubtype_(args2[i], args1[i])) { 240 if (!isSubtype_(args2[i], args1[i])) {
337 return false; 241 return false;
338 } 242 }
339 } 243 }
340
341 let optionals1 = ft1.optionals; 244 let optionals1 = ft1.optionals;
342 let optionals2 = ft2.optionals; 245 let optionals2 = ft2.optionals;
343
344 if (args1.length + optionals1.length < args2.length + optionals2.length) { 246 if (args1.length + optionals1.length < args2.length + optionals2.length) {
345 return false; 247 return false;
346 } 248 }
347
348 let j = 0; 249 let j = 0;
349 for (let i = args1.length; i < args2.length; ++i, ++j) { 250 for (let i = args1.length; i < args2.length; ++i, ++j) {
350 if (!isSubtype_(args2[i], optionals1[j])) { 251 if (!isSubtype_(args2[i], optionals1[j])) {
351 return false; 252 return false;
352 } 253 }
353 } 254 }
354
355 for (let i = 0; i < optionals2.length; ++i, ++j) { 255 for (let i = 0; i < optionals2.length; ++i, ++j) {
356 if (!isSubtype_(optionals2[i], optionals1[j])) { 256 if (!isSubtype_(optionals2[i], optionals1[j])) {
357 return false; 257 return false;
358 } 258 }
359 } 259 }
360
361 let named1 = ft1.named; 260 let named1 = ft1.named;
362 let named2 = ft2.named; 261 let named2 = ft2.named;
363
364 let names = getOwnPropertyNames(named2); 262 let names = getOwnPropertyNames(named2);
365 for (let i = 0; i < names.length; ++i) { 263 for (let i = 0; i < names.length; ++i) {
366 let name = names[i]; 264 let name = names[i];
367 let n1 = named1[name]; 265 let n1 = named1[name];
368 let n2 = named2[name]; 266 let n2 = named2[name];
369 if (n1 === void 0) { 267 if (n1 === void 0) {
370 return false; 268 return false;
371 } 269 }
372 if (!isSubtype_(n2, n1)) { 270 if (!isSubtype_(n2, n1)) {
373 return false; 271 return false;
374 } 272 }
375 } 273 }
376
377 return true; 274 return true;
378 } 275 }
379
380 /**
381 * Computes the canonical type.
382 * This maps JS types onto their corresponding Dart Type.
383 */
384 // TODO(jmesserly): lots more needs to be done here.
385 function canonicalType(t) { 276 function canonicalType(t) {
386 if (t === Object) return core.Object; 277 if (t === Object)
387 if (t === Function) return core.Function; 278 return core.Object;
388 if (t === Array) return core.List; 279 if (t === Function)
389 280 return core.Function;
390 // We shouldn't normally get here with these types, unless something strange 281 if (t === Array)
391 // happens like subclassing Number in JS and passing it to Dart. 282 return core.List;
392 if (t === String) return core.String; 283 if (t === String)
393 if (t === Number) return core.double; 284 return core.String;
394 if (t === Boolean) return core.bool; 285 if (t === Number)
286 return core.double;
287 if (t === Boolean)
288 return core.bool;
395 return t; 289 return t;
396 } 290 }
397
398 const subtypeMap = new Map(); 291 const subtypeMap = new Map();
399 function isSubtype(t1, t2) { 292 function isSubtype(t1, t2) {
400 // See if we already know the answer
401 // TODO(jmesserly): general purpose memoize function?
402 let map = subtypeMap.get(t1); 293 let map = subtypeMap.get(t1);
403 let result; 294 let result;
404 if (map) { 295 if (map) {
405 result = map.get(t2); 296 result = map.get(t2);
406 if (result !== void 0) return result; 297 if (result !== void 0)
298 return result;
407 } else { 299 } else {
408 subtypeMap.set(t1, map = new Map()); 300 subtypeMap.set(t1, map = new Map());
409 } 301 }
410 result = isSubtype_(t1, t2) 302 result = isSubtype_(t1, t2);
411 map.set(t2, result); 303 map.set(t2, result);
412 return result; 304 return result;
413 } 305 }
414 exports.isSubtype = isSubtype;
415
416 function _isBottom(type) { 306 function _isBottom(type) {
417 return type == bottomR; 307 return type == bottom;
418 } 308 }
419
420 function _isTop(type) { 309 function _isTop(type) {
421 return type == core.Object || (type == dynamicR); 310 return type == core.Object || type == dynamic;
422 } 311 }
423
424 function isSubtype_(t1, t2) { 312 function isSubtype_(t1, t2) {
425 t1 = canonicalType(t1); 313 t1 = canonicalType(t1);
426 t2 = canonicalType(t2); 314 t2 = canonicalType(t2);
427 if (t1 == t2) return true; 315 if (t1 == t2)
428 316 return true;
429 // Trivially true.
430 if (_isTop(t2) || _isBottom(t1)) { 317 if (_isTop(t2) || _isBottom(t1)) {
431 return true; 318 return true;
432 } 319 }
433
434 // Trivially false.
435 if (_isTop(t1) || _isBottom(t2)) { 320 if (_isTop(t1) || _isBottom(t2)) {
436 return false; 321 return false;
437 } 322 }
438
439 // "Traditional" name-based subtype check.
440 if (isClassSubType(t1, t2)) { 323 if (isClassSubType(t1, t2)) {
441 return true; 324 return true;
442 } 325 }
443 326 if (isFunctionType(t1) && isFunctionType(t2)) {
444 // Function subtyping.
445 // TODO(vsm): Handle Objects with call methods. Those are functions
446 // even if they do not *nominally* subtype core.Function.
447 if (isFunctionType(t1) &&
448 isFunctionType(t2)) {
449 return isFunctionSubType(t1, t2); 327 return isFunctionSubType(t1, t2);
450 } 328 }
451 return false; 329 return false;
452 } 330 }
453
454 function isClassSubType(t1, t2) { 331 function isClassSubType(t1, t2) {
455 // We support Dart's covariant generics with the caveat that we do not
456 // substitute bottom for dynamic in subtyping rules.
457 // I.e., given T1, ..., Tn where at least one Ti != dynamic we disallow:
458 // - S !<: S<T1, ..., Tn>
459 // - S<dynamic, ..., dynamic> !<: S<T1, ..., Tn>
460 t1 = canonicalType(t1); 332 t1 = canonicalType(t1);
461 assert(t2 == canonicalType(t2)); 333 assert(t2 == canonicalType(t2));
462 if (t1 == t2) return true; 334 if (t1 == t2)
463 335 return true;
464 if (t1 == core.Object) return false; 336 if (t1 == core.Object)
465 337 return false;
466 // If t1 is a JS Object, we may not hit core.Object. 338 if (t1 == null)
467 if (t1 == null) return t2 == core.Object || t2 == dynamicR; 339 return t2 == core.Object || t2 == dynamic;
468
469 // Check if t1 and t2 have the same raw type. If so, check covariance on
470 // type parameters.
471 let raw1 = classes.getGenericClass(t1); 340 let raw1 = classes.getGenericClass(t1);
472 let raw2 = classes.getGenericClass(t2); 341 let raw2 = classes.getGenericClass(t2);
473 if (raw1 != null && raw1 == raw2) { 342 if (raw1 != null && raw1 == raw2) {
474 let typeArguments1 = classes.getGenericArgs(t1); 343 let typeArguments1 = classes.getGenericArgs(t1);
475 let typeArguments2 = classes.getGenericArgs(t2); 344 let typeArguments2 = classes.getGenericArgs(t2);
476 let length = typeArguments1.length; 345 let length = typeArguments1.length;
477 if (typeArguments2.length == 0) { 346 if (typeArguments2.length == 0) {
478 // t2 is the raw form of t1
479 return true; 347 return true;
480 } else if (length == 0) { 348 } else if (length == 0) {
481 // t1 is raw, but t2 is not
482 return false; 349 return false;
483 } 350 }
484 assert(length == typeArguments2.length); 351 assert(length == typeArguments2.length);
485 for (let i = 0; i < length; ++i) { 352 for (let i = 0; i < length; ++i) {
486 if (!isSubtype(typeArguments1[i], typeArguments2[i])) { 353 if (!isSubtype(typeArguments1[i], typeArguments2[i])) {
487 return false; 354 return false;
488 } 355 }
489 } 356 }
490 return true; 357 return true;
491 } 358 }
492 359 if (isClassSubType(t1.__proto__, t2))
493 // Check superclass. 360 return true;
494 if (isClassSubType(t1.__proto__, t2)) return true;
495
496 // Check mixins.
497 let mixins = classes.getMixins(t1); 361 let mixins = classes.getMixins(t1);
498 if (mixins) { 362 if (mixins) {
499 for (let m1 of mixins) { 363 for (let m1 of mixins) {
500 // TODO(jmesserly): remove the != null check once we can load core libs. 364 if (m1 != null && isClassSubType(m1, t2))
501 if (m1 != null && isClassSubType(m1, t2)) return true; 365 return true;
502 } 366 }
503 } 367 }
504
505 // Check interfaces.
506 let getInterfaces = classes.getImplements(t1); 368 let getInterfaces = classes.getImplements(t1);
507 if (getInterfaces) { 369 if (getInterfaces) {
508 for (let i1 of getInterfaces()) { 370 for (let i1 of getInterfaces()) {
509 // TODO(jmesserly): remove the != null check once we can load core libs. 371 if (i1 != null && isClassSubType(i1, t2))
510 if (i1 != null && isClassSubType(i1, t2)) return true; 372 return true;
511 } 373 }
512 } 374 }
513
514 return false; 375 return false;
515 } 376 }
516
517 // TODO(jmesserly): this isn't currently used, but it could be if we want
518 // `obj is NonGroundType<T,S>` to be rejected at runtime instead of compile
519 // time.
520 function isGroundType(type) { 377 function isGroundType(type) {
521 // TODO(vsm): Cache this if we start using it at runtime.
522
523 if (type instanceof AbstractFunctionType) { 378 if (type instanceof AbstractFunctionType) {
524 if (!_isTop(type.returnType)) return false; 379 if (!_isTop(type.returnType))
380 return false;
525 for (let i = 0; i < type.args.length; ++i) { 381 for (let i = 0; i < type.args.length; ++i) {
526 if (!_isBottom(type.args[i])) return false; 382 if (!_isBottom(type.args[i]))
383 return false;
527 } 384 }
528 for (let i = 0; i < type.optionals.length; ++i) { 385 for (let i = 0; i < type.optionals.length; ++i) {
529 if (!_isBottom(type.optionals[i])) return false; 386 if (!_isBottom(type.optionals[i]))
387 return false;
530 } 388 }
531 let names = getOwnPropertyNames(type.named); 389 let names = getOwnPropertyNames(type.named);
532 for (let i = 0; i < names.length; ++i) { 390 for (let i = 0; i < names.length; ++i) {
533 if (!_isBottom(type.named[names[i]])) return false; 391 if (!_isBottom(type.named[names[i]]))
392 return false;
534 } 393 }
535 return true; 394 return true;
536 } 395 }
537
538 let typeArgs = classes.getGenericArgs(type); 396 let typeArgs = classes.getGenericArgs(type);
539 if (!typeArgs) return true; 397 if (!typeArgs)
398 return true;
540 for (let t of typeArgs) { 399 for (let t of typeArgs) {
541 if (t != core.Object && t != dynamicR) return false; 400 if (t != core.Object && t != dynamic)
401 return false;
542 } 402 }
543 return true; 403 return true;
544 } 404 }
405 // Exports:
406 exports.assert = assert;
407 exports.getOwnPropertyNames = getOwnPropertyNames;
408 exports.TypeRep = TypeRep;
409 exports.Dynamic = Dynamic;
410 exports.dynamic = dynamic;
411 exports.Void = Void;
412 exports.void = void$;
413 exports.Bottom = Bottom;
414 exports.bottom = bottom;
415 exports.JSObject = JSObject;
416 exports.jsobject = jsobject;
417 exports.AbstractFunctionType = AbstractFunctionType;
418 exports.FunctionType = FunctionType;
419 exports.Typedef = Typedef;
420 exports.functionType = functionType;
421 exports.definiteFunctionType = definiteFunctionType;
422 exports.typedef = typedef;
423 exports.isDartType = isDartType;
424 exports.typeName = typeName;
425 exports.isFunctionType = isFunctionType;
426 exports.isFunctionSubType = isFunctionSubType;
427 exports.canonicalType = canonicalType;
428 exports.subtypeMap = subtypeMap;
429 exports.isSubtype = isSubtype;
430 exports.isSubtype_ = isSubtype_;
431 exports.isClassSubType = isClassSubType;
545 exports.isGroundType = isGroundType; 432 exports.isGroundType = isGroundType;
546
547 }); 433 });
OLDNEW
« no previous file with comments | « lib/runtime/dart/_runtime.js ('k') | lib/runtime/dart/_utils.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698