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

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: Reverted to new .dart files in input_sdk: please compare them against previous patchset 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
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) return this._stringValue;
86
87 let buffer = '('; 50 let buffer = '(';
88 for (let i = 0; i < this.args.length; ++i) { 51 for (let i = 0; i < this.args.length; ++i) {
89 if (i > 0) { 52 if (i > 0) {
90 buffer += ', '; 53 buffer += ', ';
91 } 54 }
92 buffer += typeName(this.args[i]); 55 buffer += typeName(this.args[i]);
93 } 56 }
94 if (this.optionals.length > 0) { 57 if (this.optionals.length > 0) {
95 if (this.args.length > 0) buffer += ', '; 58 if (this.args.length > 0) buffer += ', ';
96 buffer += '['; 59 buffer += '[';
97 for (let i = 0; i < this.optionals.length; ++i) { 60 for (let i = 0; i < this.optionals.length; ++i) {
98 if (i > 0) { 61 if (i > 0) {
99 buffer += ', '; 62 buffer += ', ';
100 } 63 }
101 buffer += typeName(this.optionals[i]); 64 buffer += typeName(this.optionals[i]);
102 } 65 }
103 buffer += ']'; 66 buffer += ']';
104 } else if (Object.keys(this.named).length > 0) { 67 } else if (Object.keys(this.named).length > 0) {
105 if (this.args.length > 0) buffer += ', '; 68 if (this.args.length > 0) buffer += ', ';
106 buffer += '{'; 69 buffer += '{';
107 let names = getOwnPropertyNames(this.named).sort(); 70 let names = getOwnPropertyNames(this.named).sort();
108 for (let i = 0; i < names.length; ++i) { 71 for (let i = 0; i < names.length; ++i) {
109 if (i > 0) { 72 if (i > 0) {
110 buffer += ', '; 73 buffer += ', ';
111 } 74 }
112 buffer += names[i] + ': ' + typeName(this.named[names[i]]); 75 buffer += names[i] + ': ' + typeName(this.named[names[i]]);
113 } 76 }
114 buffer += '}'; 77 buffer += '}';
115 } 78 }
116
117 buffer += ') -> ' + typeName(this.returnType); 79 buffer += ') -> ' + typeName(this.returnType);
118 this._stringValue = buffer; 80 this._stringValue = buffer;
119 return buffer; 81 return buffer;
120 } 82 }
121 } 83 };
122 84 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) { 85 constructor(definite, returnType, args, optionals, named) {
141 super(); 86 super();
142 this.definite = definite; 87 this.definite = definite;
143 this.returnType = returnType; 88 this.returnType = returnType;
144 this.args = args; 89 this.args = args;
145 this.optionals = optionals; 90 this.optionals = optionals;
146 this.named = named; 91 this.named = named;
147
148 // TODO(vsm): This is just parameter metadata for now.
149 this.metadata = []; 92 this.metadata = [];
150 function process(array, metadata) { 93 function process(array, metadata) {
151 var result = []; 94 var result = [];
152 for (var i = 0; i < array.length; ++i) { 95 for (var i = 0; i < array.length; ++i) {
153 var arg = array[i]; 96 var arg = array[i];
154 if (arg instanceof Array) { 97 if (arg instanceof Array) {
155 metadata.push(arg.slice(1)); 98 metadata.push(arg.slice(1));
156 result.push(arg[0]); 99 result.push(arg[0]);
157 } else { 100 } else {
158 metadata.push([]); 101 metadata.push([]);
159 result.push(arg); 102 result.push(arg);
160 } 103 }
161 } 104 }
162 return result; 105 return result;
163 } 106 }
164 this.args = process(this.args, this.metadata); 107 this.args = process(this.args, this.metadata);
165 this.optionals = process(this.optionals, this.metadata); 108 this.optionals = process(this.optionals, this.metadata);
166 // TODO(vsm): Add named arguments.
167 this._canonize(); 109 this._canonize();
168 } 110 }
169 _canonize() { 111 _canonize() {
170 if (this.definite) return; 112 if (this.definite) return;
171
172 function replace(a) { 113 function replace(a) {
173 return (a == dynamicR) ? bottomR : a; 114 return a == dynamic ? bottom : a;
174 } 115 }
175
176 this.args = this.args.map(replace); 116 this.args = this.args.map(replace);
177
178 if (this.optionals.length > 0) { 117 if (this.optionals.length > 0) {
179 this.optionals = this.optionals.map(replace); 118 this.optionals = this.optionals.map(replace);
180 } 119 }
181
182 if (Object.keys(this.named).length > 0) { 120 if (Object.keys(this.named).length > 0) {
183 let r = {}; 121 let r = {};
184 for (let name of getOwnPropertyNames(this.named)) { 122 for (let name of getOwnPropertyNames(this.named)) {
185 r[name] = replace(this.named[name]); 123 r[name] = replace(this.named[name]);
186 } 124 }
187 this.named = r; 125 this.named = r;
188 } 126 }
189 } 127 }
190 } 128 };
191 129 const Typedef = class Typedef extends AbstractFunctionType {
192 class Typedef extends AbstractFunctionType {
193 constructor(name, closure) { 130 constructor(name, closure) {
194 super(); 131 super();
195 this._name = name; 132 this._name = name;
196 this._closure = closure; 133 this._closure = closure;
197 this._functionType = null; 134 this._functionType = null;
198 } 135 }
199
200 get definite() { 136 get definite() {
201 return this._functionType.definite; 137 return this._functionType.definite;
202 } 138 }
203
204 get name() { 139 get name() {
205 return this._name; 140 return this._name;
206 } 141 }
207
208 get functionType() { 142 get functionType() {
209 if (!this._functionType) { 143 if (!this._functionType) {
210 this._functionType = this._closure(); 144 this._functionType = this._closure();
211 } 145 }
212 return this._functionType; 146 return this._functionType;
213 } 147 }
214
215 get returnType() { 148 get returnType() {
216 return this.functionType.returnType; 149 return this.functionType.returnType;
217 } 150 }
218
219 get args() { 151 get args() {
220 return this.functionType.args; 152 return this.functionType.args;
221 } 153 }
222
223 get optionals() { 154 get optionals() {
224 return this.functionType.optionals; 155 return this.functionType.optionals;
225 } 156 }
226
227 get named() { 157 get named() {
228 return this.functionType.named; 158 return this.functionType.named;
229 } 159 }
230
231 get metadata() { 160 get metadata() {
232 return this.functionType.metadata; 161 return this.functionType.metadata;
233 } 162 }
234 } 163 };
235
236 function _functionType(definite, returnType, args, extra) { 164 function _functionType(definite, returnType, args, extra) {
237 // TODO(vsm): Cache / memomize?
238 let optionals; 165 let optionals;
239 let named; 166 let named;
240 if (extra === void 0) { 167 if (extra === void 0) {
241 optionals = []; 168 optionals = [];
242 named = {}; 169 named = {};
243 } else if (extra instanceof Array) { 170 } else if (extra instanceof Array) {
244 optionals = extra; 171 optionals = extra;
245 named = {}; 172 named = {};
246 } else { 173 } else {
247 optionals = []; 174 optionals = [];
248 named = extra; 175 named = extra;
249 } 176 }
250 return new FunctionType(definite, returnType, args, optionals, named); 177 return new FunctionType(definite, returnType, args, optionals, named);
251 } 178 }
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) { 179 function functionType(returnType, args, extra) {
258 return _functionType(false, returnType, args, extra); 180 return _functionType(false, returnType, args, extra);
259 } 181 }
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) { 182 function definiteFunctionType(returnType, args, extra) {
267 return _functionType(true, returnType, args, extra); 183 return _functionType(true, returnType, args, extra);
268 } 184 }
269 exports.definiteFunctionType = definiteFunctionType;
270
271 function typedef(name, closure) { 185 function typedef(name, closure) {
272 return new Typedef(name, closure); 186 return new Typedef(name, closure);
273 } 187 }
274 exports.typedef = typedef;
275
276 function isDartType(type) { 188 function isDartType(type) {
277 return rtti.read(type) === core.Type; 189 return rtti.read(type) === core.Type;
278 } 190 }
279 exports.isDartType = isDartType;
280
281 function typeName(type) { 191 function typeName(type) {
282 // Non-instance types
283 if (type instanceof TypeRep) return type.toString(); 192 if (type instanceof TypeRep) return type.toString();
284 // Instance types
285 let tag = rtti.read(type); 193 let tag = rtti.read(type);
286 if (tag === core.Type) { 194 if (tag === core.Type) {
287 let name = type.name; 195 let name = type.name;
288 let args = classes.getGenericArgs(type); 196 let args = classes.getGenericArgs(type);
289 if (args) { 197 if (args) {
290 name += '<'; 198 name += '<';
291 for (let i = 0; i < args.length; ++i) { 199 for (let i = 0; i < args.length; ++i) {
292 if (i > 0) name += ', '; 200 if (i > 0) name += ', ';
293 name += typeName(args[i]); 201 name += typeName(args[i]);
294 } 202 }
295 name += '>'; 203 name += '>';
296 } 204 }
297 return name; 205 return name;
298 } 206 }
299 if (tag) return "Not a type: " + tag.name; 207 if (tag) return "Not a type: " + tag.name;
300 return "JSObject<" + type.name + ">"; 208 return "JSObject<" + type.name + ">";
301 } 209 }
302 exports.typeName = typeName;
303
304 function isFunctionType(type) { 210 function isFunctionType(type) {
305 return type instanceof AbstractFunctionType || type == core.Function; 211 return type instanceof AbstractFunctionType || type == core.Function;
306 } 212 }
307
308 function isFunctionSubType(ft1, ft2) { 213 function isFunctionSubType(ft1, ft2) {
309 if (ft2 == core.Function) { 214 if (ft2 == core.Function) {
310 return true; 215 return true;
311 } 216 }
312
313 let ret1 = ft1.returnType; 217 let ret1 = ft1.returnType;
314 let ret2 = ft2.returnType; 218 let ret2 = ft2.returnType;
315
316 if (!isSubtype_(ret1, ret2)) { 219 if (!isSubtype_(ret1, ret2)) {
317 // Covariant return types 220 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; 221 return false;
325 } 222 }
326 } 223 }
327
328 let args1 = ft1.args; 224 let args1 = ft1.args;
329 let args2 = ft2.args; 225 let args2 = ft2.args;
330
331 if (args1.length > args2.length) { 226 if (args1.length > args2.length) {
332 return false; 227 return false;
333 } 228 }
334
335 for (let i = 0; i < args1.length; ++i) { 229 for (let i = 0; i < args1.length; ++i) {
336 if (!isSubtype_(args2[i], args1[i])) { 230 if (!isSubtype_(args2[i], args1[i])) {
337 return false; 231 return false;
338 } 232 }
339 } 233 }
340
341 let optionals1 = ft1.optionals; 234 let optionals1 = ft1.optionals;
342 let optionals2 = ft2.optionals; 235 let optionals2 = ft2.optionals;
343
344 if (args1.length + optionals1.length < args2.length + optionals2.length) { 236 if (args1.length + optionals1.length < args2.length + optionals2.length) {
345 return false; 237 return false;
346 } 238 }
347
348 let j = 0; 239 let j = 0;
349 for (let i = args1.length; i < args2.length; ++i, ++j) { 240 for (let i = args1.length; i < args2.length; ++i, ++j) {
350 if (!isSubtype_(args2[i], optionals1[j])) { 241 if (!isSubtype_(args2[i], optionals1[j])) {
351 return false; 242 return false;
352 } 243 }
353 } 244 }
354
355 for (let i = 0; i < optionals2.length; ++i, ++j) { 245 for (let i = 0; i < optionals2.length; ++i, ++j) {
356 if (!isSubtype_(optionals2[i], optionals1[j])) { 246 if (!isSubtype_(optionals2[i], optionals1[j])) {
357 return false; 247 return false;
358 } 248 }
359 } 249 }
360
361 let named1 = ft1.named; 250 let named1 = ft1.named;
362 let named2 = ft2.named; 251 let named2 = ft2.named;
363
364 let names = getOwnPropertyNames(named2); 252 let names = getOwnPropertyNames(named2);
365 for (let i = 0; i < names.length; ++i) { 253 for (let i = 0; i < names.length; ++i) {
366 let name = names[i]; 254 let name = names[i];
367 let n1 = named1[name]; 255 let n1 = named1[name];
368 let n2 = named2[name]; 256 let n2 = named2[name];
369 if (n1 === void 0) { 257 if (n1 === void 0) {
370 return false; 258 return false;
371 } 259 }
372 if (!isSubtype_(n2, n1)) { 260 if (!isSubtype_(n2, n1)) {
373 return false; 261 return false;
374 } 262 }
375 } 263 }
376
377 return true; 264 return true;
378 } 265 }
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) { 266 function canonicalType(t) {
386 if (t === Object) return core.Object; 267 if (t === Object) return core.Object;
387 if (t === Function) return core.Function; 268 if (t === Function) return core.Function;
388 if (t === Array) return core.List; 269 if (t === Array) return core.List;
389
390 // We shouldn't normally get here with these types, unless something strange
391 // happens like subclassing Number in JS and passing it to Dart.
392 if (t === String) return core.String; 270 if (t === String) return core.String;
393 if (t === Number) return core.double; 271 if (t === Number) return core.double;
394 if (t === Boolean) return core.bool; 272 if (t === Boolean) return core.bool;
395 return t; 273 return t;
396 } 274 }
397
398 const subtypeMap = new Map(); 275 const subtypeMap = new Map();
399 function isSubtype(t1, t2) { 276 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); 277 let map = subtypeMap.get(t1);
403 let result; 278 let result;
404 if (map) { 279 if (map) {
405 result = map.get(t2); 280 result = map.get(t2);
406 if (result !== void 0) return result; 281 if (result !== void 0) return result;
407 } else { 282 } else {
408 subtypeMap.set(t1, map = new Map()); 283 subtypeMap.set(t1, map = new Map());
409 } 284 }
410 result = isSubtype_(t1, t2) 285 result = isSubtype_(t1, t2);
411 map.set(t2, result); 286 map.set(t2, result);
412 return result; 287 return result;
413 } 288 }
414 exports.isSubtype = isSubtype;
415
416 function _isBottom(type) { 289 function _isBottom(type) {
417 return type == bottomR; 290 return type == bottom;
418 } 291 }
419
420 function _isTop(type) { 292 function _isTop(type) {
421 return type == core.Object || (type == dynamicR); 293 return type == core.Object || type == dynamic;
422 } 294 }
423
424 function isSubtype_(t1, t2) { 295 function isSubtype_(t1, t2) {
425 t1 = canonicalType(t1); 296 t1 = canonicalType(t1);
426 t2 = canonicalType(t2); 297 t2 = canonicalType(t2);
427 if (t1 == t2) return true; 298 if (t1 == t2) return true;
428
429 // Trivially true.
430 if (_isTop(t2) || _isBottom(t1)) { 299 if (_isTop(t2) || _isBottom(t1)) {
431 return true; 300 return true;
432 } 301 }
433
434 // Trivially false.
435 if (_isTop(t1) || _isBottom(t2)) { 302 if (_isTop(t1) || _isBottom(t2)) {
436 return false; 303 return false;
437 } 304 }
438
439 // "Traditional" name-based subtype check.
440 if (isClassSubType(t1, t2)) { 305 if (isClassSubType(t1, t2)) {
441 return true; 306 return true;
442 } 307 }
443 308 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); 309 return isFunctionSubType(t1, t2);
450 } 310 }
451 return false; 311 return false;
452 } 312 }
453
454 function isClassSubType(t1, t2) { 313 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); 314 t1 = canonicalType(t1);
461 assert(t2 == canonicalType(t2)); 315 assert(t2 == canonicalType(t2));
462 if (t1 == t2) return true; 316 if (t1 == t2) return true;
463
464 if (t1 == core.Object) return false; 317 if (t1 == core.Object) return false;
465 318 if (t1 == null) return t2 == core.Object || t2 == dynamic;
466 // If t1 is a JS Object, we may not hit core.Object.
467 if (t1 == null) return t2 == core.Object || t2 == dynamicR;
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); 319 let raw1 = classes.getGenericClass(t1);
472 let raw2 = classes.getGenericClass(t2); 320 let raw2 = classes.getGenericClass(t2);
473 if (raw1 != null && raw1 == raw2) { 321 if (raw1 != null && raw1 == raw2) {
474 let typeArguments1 = classes.getGenericArgs(t1); 322 let typeArguments1 = classes.getGenericArgs(t1);
475 let typeArguments2 = classes.getGenericArgs(t2); 323 let typeArguments2 = classes.getGenericArgs(t2);
476 let length = typeArguments1.length; 324 let length = typeArguments1.length;
477 if (typeArguments2.length == 0) { 325 if (typeArguments2.length == 0) {
478 // t2 is the raw form of t1
479 return true; 326 return true;
480 } else if (length == 0) { 327 } else if (length == 0) {
481 // t1 is raw, but t2 is not
482 return false; 328 return false;
483 } 329 }
484 assert(length == typeArguments2.length); 330 assert(length == typeArguments2.length);
485 for (let i = 0; i < length; ++i) { 331 for (let i = 0; i < length; ++i) {
486 if (!isSubtype(typeArguments1[i], typeArguments2[i])) { 332 if (!isSubtype(typeArguments1[i], typeArguments2[i])) {
487 return false; 333 return false;
488 } 334 }
489 } 335 }
490 return true; 336 return true;
491 } 337 }
492
493 // Check superclass.
494 if (isClassSubType(t1.__proto__, t2)) return true; 338 if (isClassSubType(t1.__proto__, t2)) return true;
495
496 // Check mixins.
497 let mixins = classes.getMixins(t1); 339 let mixins = classes.getMixins(t1);
498 if (mixins) { 340 if (mixins) {
499 for (let m1 of mixins) { 341 for (let m1 of mixins) {
500 // TODO(jmesserly): remove the != null check once we can load core libs.
501 if (m1 != null && isClassSubType(m1, t2)) return true; 342 if (m1 != null && isClassSubType(m1, t2)) return true;
502 } 343 }
503 } 344 }
504
505 // Check interfaces.
506 let getInterfaces = classes.getImplements(t1); 345 let getInterfaces = classes.getImplements(t1);
507 if (getInterfaces) { 346 if (getInterfaces) {
508 for (let i1 of getInterfaces()) { 347 for (let i1 of getInterfaces()) {
509 // TODO(jmesserly): remove the != null check once we can load core libs.
510 if (i1 != null && isClassSubType(i1, t2)) return true; 348 if (i1 != null && isClassSubType(i1, t2)) return true;
511 } 349 }
512 } 350 }
513
514 return false; 351 return false;
515 } 352 }
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) { 353 function isGroundType(type) {
521 // TODO(vsm): Cache this if we start using it at runtime.
522
523 if (type instanceof AbstractFunctionType) { 354 if (type instanceof AbstractFunctionType) {
524 if (!_isTop(type.returnType)) return false; 355 if (!_isTop(type.returnType)) return false;
525 for (let i = 0; i < type.args.length; ++i) { 356 for (let i = 0; i < type.args.length; ++i) {
526 if (!_isBottom(type.args[i])) return false; 357 if (!_isBottom(type.args[i])) return false;
527 } 358 }
528 for (let i = 0; i < type.optionals.length; ++i) { 359 for (let i = 0; i < type.optionals.length; ++i) {
529 if (!_isBottom(type.optionals[i])) return false; 360 if (!_isBottom(type.optionals[i])) return false;
530 } 361 }
531 let names = getOwnPropertyNames(type.named); 362 let names = getOwnPropertyNames(type.named);
532 for (let i = 0; i < names.length; ++i) { 363 for (let i = 0; i < names.length; ++i) {
533 if (!_isBottom(type.named[names[i]])) return false; 364 if (!_isBottom(type.named[names[i]])) return false;
534 } 365 }
535 return true; 366 return true;
536 } 367 }
537
538 let typeArgs = classes.getGenericArgs(type); 368 let typeArgs = classes.getGenericArgs(type);
539 if (!typeArgs) return true; 369 if (!typeArgs) return true;
540 for (let t of typeArgs) { 370 for (let t of typeArgs) {
541 if (t != core.Object && t != dynamicR) return false; 371 if (t != core.Object && t != dynamic) return false;
542 } 372 }
543 return true; 373 return true;
544 } 374 }
375 // Exports:
376 exports.assert = assert;
377 exports.getOwnPropertyNames = getOwnPropertyNames;
378 exports.TypeRep = TypeRep;
379 exports.Dynamic = Dynamic;
380 exports.dynamic = dynamic;
381 exports.Void = Void;
382 exports.void = void$;
383 exports.Bottom = Bottom;
384 exports.bottom = bottom;
385 exports.JSObject = JSObject;
386 exports.jsobject = jsobject;
387 exports.AbstractFunctionType = AbstractFunctionType;
388 exports.FunctionType = FunctionType;
389 exports.Typedef = Typedef;
390 exports.functionType = functionType;
391 exports.definiteFunctionType = definiteFunctionType;
392 exports.typedef = typedef;
393 exports.isDartType = isDartType;
394 exports.typeName = typeName;
395 exports.isFunctionType = isFunctionType;
396 exports.isFunctionSubType = isFunctionSubType;
397 exports.canonicalType = canonicalType;
398 exports.subtypeMap = subtypeMap;
399 exports.isSubtype = isSubtype;
400 exports.isSubtype_ = isSubtype_;
401 exports.isClassSubType = isClassSubType;
545 exports.isGroundType = isGroundType; 402 exports.isGroundType = isGroundType;
546
547 }); 403 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698