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

Side by Side Diff: lib/runtime/dart_runtime.js

Issue 1050723002: partially implement instance of checks and some codegen fixes (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 8 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/math.js ('k') | lib/src/codegen/js_codegen.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 var dart, _js_helper; 5 var dart, _js_helper;
6 (function (dart) { 6 (function (dart) {
7 'use strict'; 7 'use strict';
8 8
9 var defineProperty = Object.defineProperty; 9 let defineProperty = Object.defineProperty;
10 var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; 10 let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
11 var getOwnPropertyNames = Object.getOwnPropertyNames; 11 let getOwnPropertyNames = Object.getOwnPropertyNames;
12 12
13 // Adapted from Angular.js 13 // Adapted from Angular.js
14 var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; 14 let FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
15 var FN_ARG_SPLIT = /,/; 15 let FN_ARG_SPLIT = /,/;
16 var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/; 16 let FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
17 var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; 17 let STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
18 18
19 function formalParameterList(fn) { 19 function formalParameterList(fn) {
20 var fnText,argDecl; 20 let fnText,argDecl;
21 var args=[]; 21 let args=[];
22 fnText = fn.toString().replace(STRIP_COMMENTS, ''); 22 fnText = fn.toString().replace(STRIP_COMMENTS, '');
23 argDecl = fnText.match(FN_ARGS); 23 argDecl = fnText.match(FN_ARGS);
24 24
25 var r = argDecl[1].split(FN_ARG_SPLIT); 25 let r = argDecl[1].split(FN_ARG_SPLIT);
26 for(var a in r) { 26 for(let a in r) {
27 var arg = r[a]; 27 let arg = r[a];
28 arg.replace(FN_ARG, function(all, underscore, name){ 28 arg.replace(FN_ARG, function(all, underscore, name){
29 args.push(name); 29 args.push(name);
30 }); 30 });
31 } 31 }
32 return args; 32 return args;
33 } 33 }
34 34
35 function dload(obj, field) { 35 function dload(obj, field) {
36 if (!(field in obj)) { 36 if (!(field in obj)) {
37 throw new core.NoSuchMethodError(obj, field); 37 throw new core.NoSuchMethodError(obj, field);
38 } 38 }
39 return obj[field]; 39 return obj[field];
40 } 40 }
41 dart.dload = dload; 41 dart.dload = dload;
42 42
43 // TODO(jmesserly): this should call noSuchMethod, not throw. 43 // TODO(jmesserly): this should call noSuchMethod, not throw.
44 function throwNoSuchMethod(obj, name, args, opt_func) { 44 function throwNoSuchMethod(obj, name, args, opt_func) {
45 if (obj === void 0) obj = opt_func; 45 if (obj === void 0) obj = opt_func;
46 throw new core.NoSuchMethodError(obj, name, args); 46 throw new core.NoSuchMethodError(obj, name, args);
47 } 47 }
48 48
49 function checkAndCall(f, obj, args, name) { 49 function checkAndCall(f, obj, args, name) {
50 if (!(f instanceof Function)) { 50 if (!(f instanceof Function)) {
51 // Grab the `call` method if it's not a function. 51 // Grab the `call` method if it's not a function.
52 if (f !== null) f = f.call; 52 if (f !== null) f = f.call;
53 if (!(f instanceof Function)) { 53 if (!(f instanceof Function)) {
54 throwNoSuchMethod(obj, method, args); 54 throwNoSuchMethod(obj, method, args);
55 } 55 }
56 } 56 }
57 var formals = formalParameterList(f); 57 let formals = formalParameterList(f);
58 // TODO(vsm): Type check args! We need to encode sufficient type info on f. 58 // TODO(vsm): Type check args! We need to encode sufficient type info on f.
59 if (formals.length < args.length) { 59 if (formals.length < args.length) {
60 throwNoSuchMethod(obj, name, args, f); 60 throwNoSuchMethod(obj, name, args, f);
61 } else if (formals.length > args.length) { 61 } else if (formals.length > args.length) {
62 for (var i = args.length; i < formals.length; ++i) { 62 for (let i = args.length; i < formals.length; ++i) {
63 if (formals[i].indexOf("opt$") != 0) { 63 if (formals[i].indexOf("opt$") != 0) {
64 throwNoSuchMethod(obj, name, args, f); 64 throwNoSuchMethod(obj, name, args, f);
65 } 65 }
66 } 66 }
67 } 67 }
68 return f.apply(obj, args); 68 return f.apply(obj, args);
69 } 69 }
70 70
71 function dinvokef(f/*, ...args*/) { 71 function dinvokef(f/*, ...args*/) {
72 var args = Array.prototype.slice.call(arguments, 1); 72 let args = Array.prototype.slice.call(arguments, 1);
73 return checkAndCall(f, void 0, args, 'call'); 73 return checkAndCall(f, void 0, args, 'call');
74 } 74 }
75 dart.dinvokef = dinvokef; 75 dart.dinvokef = dinvokef;
76 76
77 function dinvoke(obj, method/*, ...args*/) { 77 function dinvoke(obj, method/*, ...args*/) {
78 var args = Array.prototype.slice.call(arguments, 2); 78 let args = Array.prototype.slice.call(arguments, 2);
79 return checkAndCall(obj[method], obj, args, method); 79 return checkAndCall(obj[method], obj, args, method);
80 } 80 }
81 dart.dinvoke = dinvoke; 81 dart.dinvoke = dinvoke;
82 82
83 function dindex(obj, index) { 83 function dindex(obj, index) {
84 return checkAndCall(obj.get, obj, [index], '[]'); 84 return checkAndCall(obj.get, obj, [index], '[]');
85 } 85 }
86 dart.dindex = dindex; 86 dart.dindex = dindex;
87 87
88 function dsetindex(obj, index, value) { 88 function dsetindex(obj, index, value) {
89 return checkAndCall(obj.set, obj, [index, value], '[]='); 89 return checkAndCall(obj.set, obj, [index, value], '[]=');
90 } 90 }
91 dart.dsetindex = dindex; 91 dart.dsetindex = dindex;
92 92
93 function dbinary(left, op, right) { 93 function dbinary(left, op, right) {
94 return checkAndCall(left[op], left, [right], op); 94 return checkAndCall(left[op], left, [right], op);
95 } 95 }
96 dart.dbinary = dbinary; 96 dart.dbinary = dbinary;
97 97
98 function as_(obj, type) { 98 function cast(obj, type) {
99 // TODO(vsm): Implement. 99 //TODO(vsm): handle non-nullable types
100 // if (obj == null || is(obj, type)) return obj; 100 if (obj == null) return obj;
101 // throw new core.CastError(); 101 let actual = getRuntimeType(obj);
102 return obj; 102 if (isSubtype(actual, type)) return obj;
103 throw new _js_helper.CastErrorImplementation(actual, type);
103 } 104 }
104 dart.as = as_; 105 dart.as = cast;
105 106
106 function is(obj, type) { 107 /**
107 // TODO(vsm): Implement. 108 * Returns the runtime type of obj. This is the same as `obj.runtimeType`
108 throw new core.UnimplementedError(); 109 * but will not call an overridden getter.
110 *
111 * Currently this will return null for non-Dart objects.
112 */
113 function getRuntimeType(obj) {
114 switch (typeof obj) {
115 case "undefined":
116 return core.Null;
117 case "number":
118 return Math.floor(obj) == obj ? core.int : core.double;
119 case "boolean":
120 return core.bool;
121 case "string":
122 return core.String;
123 case "symbol":
124 return Symbol;
125 }
126 // Undefined is handled above. For historical reasons,
127 // typeof null == "object" in JS.
128 if (obj === null) return core.Null;
129 return obj.constructor;
109 } 130 }
110 dart.is = is; 131 dart.getRuntimeType = getRuntimeType;
132
133 function instanceOf(obj, type) {
134 return isSubtype(getRuntimeType(obj), type);
135 }
136 dart.is = instanceOf;
137
138 /**
139 * Computes the canonical type.
140 * This maps JS types onto their corresponding Dart Type.
141 */
142 // TODO(jmesserly): lots more needs to be done here.
143 function canonicalType(t) {
144 if (t === Object) return core.Object;
145 if (t === Function) return core.Function;
146 if (t === Array) return core.List;
147
148 // We shouldn't normally get here with these types, unless something strange
149 // happens like subclassing Number in JS and passing it to Dart.
150 if (t === String) return core.String;
151 if (t === Number) return core.double;
152 if (t === Boolean) return core.bool;
153 return t;
154 }
155
156 let subtypeMap = new Map();
157 function isSubtype(t1, t2) {
158 // See if we already know the answer
159 // TODO(jmesserly): general purpose memoize function?
160 let map = subtypeMap.get(t1);
161 let result;
162 if (map) {
163 result = map.get(t2);
164 if (result !== void 0) return result;
165 } else {
166 subtypeMap.set(t1, map = new Map());
167 }
168 map.set(t2, result = isSubtype_(t1, t2));
169 return result;
170 }
171 dart.isSubtype = isSubtype;
172
173 function isSubtype_(t1, t2) {
174 t1 = canonicalType(t1);
175 t2 = canonicalType(t2);
176 if (t1 == t2) return true;
177
178 // In Dart, dynamic is effectively both top and bottom.
179 // Here, we treat dynamic as top - the base type of everything.
180 if (t1 == dart.dynamic) return false;
181 if (t2 == dart.dynamic) return true;
182
183 if (t2 == core.Object) return true;
184 if (t1 == core.Object) return false;
185
186 // "Traditional" name-based subtype check.
187 if (isClassSubType(t1, t2)) {
188 return true;
189 }
190
191 // Function subtyping.
192 // TODO(jmesserly): implement.
193 return false;
194 }
195
196 function safeGetOwnProperty(obj, name) {
197 var desc = getOwnPropertyDescriptor(obj, name);
198 if (desc) return desc.value;
199 }
200
201 function isClassSubType(t1, t2) {
202 // We support Dart's covariant generics with the caveat that we do not
203 // substitute bottom for dynamic in subtyping rules.
204 // I.e., given T1, ..., Tn where at least one Ti != dynamic we disallow:
205 // - S !<: S<T1, ..., Tn>
206 // - S<dynamic, ..., dynamic> !<: S<T1, ..., Tn>
207 if (t1 == t2) return true;
208
209 if (t1 == core.Object) return false;
210
211 // Check if t1 and t2 have the same raw type. If so, check covariance on
212 // type parameters.
213 let raw1 = safeGetOwnProperty(t1, dart.originalDeclaration);
214 let raw2 = safeGetOwnProperty(t2, dart.originalDeclaration);
215 if (raw1 != null && raw1 == raw2) {
216 let typeArguments1 = safeGetOwnProperty(t1, dart.typeArguments);
217 let typeArguments2 = safeGetOwnProperty(t2, dart.typeArguments);
218 let length = typeArguments1.length;
219 if (typeArguments2.length == 0) {
220 // t2 is the raw form of t1
221 return true;
222 } else if (length == 0) {
223 // t1 is raw, but t2 is not
224 return false;
225 }
226 assert(length == typeArguments2.length);
227 for (let i = 0; i < length; ++i) {
228 if (!isSubtype(typeArguments1[i], typeArguments2[i])) {
229 return false;
230 }
231 }
232 return true;
233 }
234
235 // Check superclass.
236 if (isClassSubType(t1.__proto__, t2)) return true;
237
238 // Check interfaces.
239 let getInterfaces = safeGetOwnProperty(t1, dart.implements);
240 if (getInterfaces) {
241 for (let i1 of getInterfaces()) {
242 // TODO(jmesserly): remove the != null check once we can load core libs.
243 if (i1 != null && isClassSubType(i1, t2)) return true;
244 }
245 }
246
247 return false;
248 }
111 249
112 function closureWrap(obj, type) { 250 function closureWrap(obj, type) {
113 // TODO(vsm): Remove this once we handle in the checker. 251 // TODO(vsm): Remove this once we handle in the checker.
114 return obj; 252 return obj;
115 } 253 }
116 dart.closureWrap = closureWrap; 254 dart.closureWrap = closureWrap;
117 255
256
257 // TODO(jmesserly): this isn't currently used, but it could be if we want
258 // `obj is NonGroundType<T,S>` to be rejected at runtime instead of compile
259 // time. Also TODO: update this to handle functions.
118 function isGroundType(type) { 260 function isGroundType(type) {
119 // TODO(vsm): Implement. 261 let typeArgs = safeGetOwnProperty(type, dart.typeArguments);
120 throw new core.UnimplementedError(); 262 if (!typeArgs) return true;
263 for (let t of typeArgs) {
264 if (t != core.Object && t != dart.dynamic) return false;
265 }
266 return true;
121 } 267 }
122 dart.isGroundType = isGroundType; 268 dart.isGroundType = isGroundType;
123 269
124 function arity(f) { 270 function arity(f) {
125 // TODO(vsm): Implement. 271 // TODO(jmesserly): need to parse optional params.
126 throw new core.UnimplementedError(); 272 // In ES6, length is the number of required arguments.
273 return { min: f.length, max: f.length };
127 } 274 }
128 dart.arity = arity; 275 dart.arity = arity;
129 276
130 function equals(x, y) { 277 function equals(x, y) {
131 if (x == null || y == null) return x == y; 278 if (x == null || y == null) return x == y;
132 var eq = x['==']; 279 let eq = x['=='];
133 return eq ? eq.call(x, y) : x == y; 280 return eq ? eq.call(x, y) : x == y;
134 } 281 }
135 dart.equals = equals; 282 dart.equals = equals;
136 283
137 /** Checks that `x` is not null or undefined. */ 284 /** Checks that `x` is not null or undefined. */
138 function notNull(x) { 285 function notNull(x) {
139 if (x == null) throw 'expected not-null value'; 286 if (x == null) throw 'expected not-null value';
140 return x; 287 return x;
141 } 288 }
142 dart.notNull = notNull; 289 dart.notNull = notNull;
143 290
144 /** 291 /**
145 * Defines a lazy property. 292 * Defines a lazy property.
146 * After initial get or set, it will replace itself with a value property. 293 * After initial get or set, it will replace itself with a value property.
147 */ 294 */
148 // TODO(jmesserly): is this the best implementation for JS engines? 295 // TODO(jmesserly): is this the best implementation for JS engines?
149 // TODO(jmesserly): reusing descriptor objects has been shown to improve 296 // TODO(jmesserly): reusing descriptor objects has been shown to improve
150 // performance in other projects (e.g. webcomponents.js ShadowDOM polyfill). 297 // performance in other projects (e.g. webcomponents.js ShadowDOM polyfill).
151 function defineLazyProperty(to, name, desc) { 298 function defineLazyProperty(to, name, desc) {
152 var init = desc.get; 299 let init = desc.get;
153 var writable = !!desc.set; 300 let writable = !!desc.set;
154 function lazySetter(value) { 301 function lazySetter(value) {
155 defineProperty(to, name, { value: value, writable: writable }); 302 defineProperty(to, name, { value: value, writable: writable });
156 } 303 }
157 function lazyGetter() { 304 function lazyGetter() {
158 // Clear the init function to detect circular initialization. 305 // Clear the init function to detect circular initialization.
159 var f = init; 306 let f = init;
160 if (f === null) throw 'circular initialization for field ' + name; 307 if (f === null) throw 'circular initialization for field ' + name;
161 init = null; 308 init = null;
162 309
163 // Compute and store the value. 310 // Compute and store the value.
164 var value = f(); 311 let value = f();
165 lazySetter(value); 312 lazySetter(value);
166 return value; 313 return value;
167 } 314 }
168 desc.get = lazyGetter; 315 desc.get = lazyGetter;
169 desc.configurable = true; 316 desc.configurable = true;
170 if (writable) desc.set = lazySetter; 317 if (writable) desc.set = lazySetter;
171 defineProperty(to, name, desc); 318 defineProperty(to, name, desc);
172 } 319 }
173 320
174 function defineLazy(to, from) { 321 function defineLazy(to, from) {
175 var names = getOwnPropertyNames(from); 322 let names = getOwnPropertyNames(from);
176 for (var i = 0; i < names.length; i++) { 323 for (let i = 0; i < names.length; i++) {
177 var name = names[i]; 324 let name = names[i];
178 defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name)); 325 defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name));
179 } 326 }
180 } 327 }
181 // TODO(jmesserly): these are identical, but this makes it easier to grep for. 328 // TODO(jmesserly): these are identical, but this makes it easier to grep for.
182 dart.defineLazyClass = defineLazy; 329 dart.defineLazyClass = defineLazy;
183 dart.defineLazyProperties = defineLazy; 330 dart.defineLazyProperties = defineLazy;
184 dart.defineLazyClassGeneric = defineLazyProperty; 331 dart.defineLazyClassGeneric = defineLazyProperty;
185 332
186 /** 333 /**
187 * Copy properties from source to destination object. 334 * Copy properties from source to destination object.
188 * This operation is commonly called `mixin` in JS. 335 * This operation is commonly called `mixin` in JS.
189 */ 336 */
190 function copyProperties(to, from) { 337 function copyProperties(to, from) {
191 var names = getOwnPropertyNames(from); 338 let names = getOwnPropertyNames(from);
192 for (var i = 0; i < names.length; i++) { 339 for (let i = 0; i < names.length; i++) {
193 var name = names[i]; 340 let name = names[i];
194 defineProperty(to, name, getOwnPropertyDescriptor(from, name)); 341 defineProperty(to, name, getOwnPropertyDescriptor(from, name));
195 } 342 }
196 return to; 343 return to;
197 } 344 }
198 dart.copyProperties = copyProperties; 345 dart.copyProperties = copyProperties;
199 346
200 347
201 /** The Symbol for storing type arguments on a specialized generic type. */ 348 /** The Symbol for storing type arguments on a specialized generic type. */
202 dart.mixins = Symbol('mixins'); 349 dart.mixins = Symbol('mixins');
203 dart.implements = Symbol('implements') 350 dart.implements = Symbol('implements');
204 351
205 /** 352 /**
206 * Returns a new type that mixes members from base and all mixins. 353 * Returns a new type that mixes members from base and all mixins.
207 * 354 *
208 * Each mixin applies in sequence, with further to the right ones overriding 355 * Each mixin applies in sequence, with further to the right ones overriding
209 * previous entries. 356 * previous entries.
210 * 357 *
211 * For each mixin, we only take its own properties, not anything from its 358 * For each mixin, we only take its own properties, not anything from its
212 * superclass (prototype). 359 * superclass (prototype).
213 */ 360 */
214 function mixin(base/*, ...mixins*/) { 361 function mixin(base/*, ...mixins*/) {
215 // Create an initializer for the mixin, so when derived constructor calls 362 // Create an initializer for the mixin, so when derived constructor calls
216 // super, we can correctly initialize base and mixins. 363 // super, we can correctly initialize base and mixins.
217 var mixins = Array.prototype.slice.call(arguments, 1); 364 let mixins = Array.prototype.slice.call(arguments, 1);
218 365
219 // Create a class that will hold all of the mixin methods. 366 // Create a class that will hold all of the mixin methods.
220 class Mixin extends base { 367 class Mixin extends base {
221 // Initializer method: run mixin initializers, then the base. 368 // Initializer method: run mixin initializers, then the base.
222 [base.name](/*...args*/) { 369 [base.name](/*...args*/) {
223 // Run mixin initializers. They cannot have arguments. 370 // Run mixin initializers. They cannot have arguments.
224 // Run them backwards so most-derived mixin is initialized first. 371 // Run them backwards so most-derived mixin is initialized first.
225 for (var i = mixins.length - 1; i >= 0; i--) { 372 for (let i = mixins.length - 1; i >= 0; i--) {
226 var mixin = mixins[i]; 373 let mixin = mixins[i];
227 mixin.prototype[mixin.name].call(this); 374 mixin.prototype[mixin.name].call(this);
228 } 375 }
229 // Run base initializer. 376 // Run base initializer.
230 base.prototype[base.name].apply(this, arguments); 377 base.prototype[base.name].apply(this, arguments);
231 } 378 }
232 } 379 }
233 // Copy each mixin's methods, with later ones overwriting earlier entries. 380 // Copy each mixin's methods, with later ones overwriting earlier entries.
234 for (var i = 0; i < mixins.length; i++) { 381 for (let m of mixins) {
235 copyProperties(Mixin.prototype, mixins[i].prototype); 382 copyProperties(Mixin.prototype, m.prototype);
236 } 383 }
237 // Save mixins for reflection 384 // Save mixins for reflection
238 Mixin[dart.mixins] = mixins; 385 Mixin[dart.mixins] = mixins;
239 return Mixin; 386 return Mixin;
240 } 387 }
241 dart.mixin = mixin; 388 dart.mixin = mixin;
242 389
243 /** 390 /**
244 * Creates a dart:collection LinkedHashMap. 391 * Creates a dart:collection LinkedHashMap.
245 * 392 *
246 * For a map with string keys an object literal can be used, for example 393 * For a map with string keys an object literal can be used, for example
247 * `map({'hi': 1, 'there': 2})`. 394 * `map({'hi': 1, 'there': 2})`.
248 * 395 *
249 * Otherwise an array should be used, for example `map([1, 2, 3, 4])` will 396 * Otherwise an array should be used, for example `map([1, 2, 3, 4])` will
250 * create a map with keys [1, 3] and values [2, 4]. Each key-value pair 397 * create a map with keys [1, 3] and values [2, 4]. Each key-value pair
251 * should be adjacent entries in the array. 398 * should be adjacent entries in the array.
252 * 399 *
253 * For a map with no keys the function can be called with no arguments, for 400 * For a map with no keys the function can be called with no arguments, for
254 * example `map()`. 401 * example `map()`.
255 */ 402 */
256 // TODO(jmesserly): this could be faster 403 // TODO(jmesserly): this could be faster
257 function map(values) { 404 function map(values) {
258 var map = new collection.LinkedHashMap(); 405 let map = new collection.LinkedHashMap();
259 if (Array.isArray(values)) { 406 if (Array.isArray(values)) {
260 for (var i = 0, end = values.length - 1; i < end; i += 2) { 407 for (let i = 0, end = values.length - 1; i < end; i += 2) {
261 var key = values[i]; 408 let key = values[i];
262 var value = values[i + 1]; 409 let value = values[i + 1];
263 map.set(key, value); 410 map.set(key, value);
264 } 411 }
265 } else if (typeof values === 'object') { 412 } else if (typeof values === 'object') {
266 var keys = Object.getOwnPropertyNames(values); 413 for (let key of Object.getOwnPropertyNames(values)) {
267 for (var i = 0; i < keys.length; i++) { 414 map.set(key, values[key]);
268 var key = keys[i];
269 var value = values[key];
270 map.set(key, value);
271 } 415 }
272 } 416 }
273 return map; 417 return map;
274 } 418 }
275 dart.map = map; 419 dart.map = map;
276 420
277 function assert(condition) { 421 function assert(condition) {
278 // TODO(jmesserly): throw assertion error. 422 // TODO(jmesserly): throw assertion error.
279 if (!condition) throw 'assertion failed'; 423 if (!condition) throw 'assertion failed';
280 } 424 }
281 dart.assert = assert; 425 dart.assert = assert;
282 426
283 function throw_(obj) { throw obj; } 427 function throw_(obj) { throw obj; }
284 dart.throw_ = throw_; 428 dart.throw_ = throw_;
285 429
286 /** 430 /**
287 * Given a class and an initializer method name, creates a constructor 431 * Given a class and an initializer method name, creates a constructor
288 * function with the same name. For example `new SomeClass.name(args)`. 432 * function with the same name. For example `new SomeClass.name(args)`.
289 */ 433 */
290 function defineNamedConstructor(clazz, name) { 434 function defineNamedConstructor(clazz, name) {
291 var proto = clazz.prototype; 435 let proto = clazz.prototype;
292 var initMethod = proto[name]; 436 let initMethod = proto[name];
293 var ctor = function() { return initMethod.apply(this, arguments); } 437 let ctor = function() { return initMethod.apply(this, arguments); }
294 ctor.prototype = proto; 438 ctor.prototype = proto;
295 clazz[name] = ctor; 439 clazz[name] = ctor;
296 } 440 }
297 dart.defineNamedConstructor = defineNamedConstructor; 441 dart.defineNamedConstructor = defineNamedConstructor;
298 442
299 function stackTrace(exception) { 443 function stackTrace(exception) {
300 throw new core.UnimplementedError(); 444 throw new core.UnimplementedError();
301 } 445 }
302 dart.stackTrace = stackTrace; 446 dart.stackTrace = stackTrace;
303 447
304 /** The Symbol for storing type arguments on a specialized generic type. */ 448 /** The Symbol for storing type arguments on a specialized generic type. */
305 dart.typeSignature = Symbol('typeSignature'); 449 dart.typeArguments = Symbol('typeArguments');
450 dart.originalDeclaration = Symbol('originalDeclaration');
306 451
307 /** Memoize a generic type constructor function. */ 452 /** Memoize a generic type constructor function. */
308 function generic(typeConstructor) { 453 function generic(typeConstructor) {
309 var length = typeConstructor.length; 454 let length = typeConstructor.length;
310 if (length < 1) throw 'must have at least one generic type argument'; 455 if (length < 1) throw Error('must have at least one generic type argument');
311 456
312 var resultMap = new Map(); 457 let resultMap = new Map();
313 function makeGenericType(/*...arguments*/) { 458 function makeGenericType(/*...arguments*/) {
314 if (arguments.length != length && arguments.length != 0) { 459 if (arguments.length != length && arguments.length != 0) {
315 throw 'requires ' + length + ' or 0 type arguments'; 460 throw Error('requires ' + length + ' or 0 type arguments');
316 } 461 }
462 let args = Array.prototype.slice.call(arguments);
463 while (args.length < length) args.push(dart.dynamic);
317 464
318 var value = resultMap; 465 let value = resultMap;
319 for (var i = 0; i < length; i++) { 466 for (let i = 0; i < length; i++) {
320 var arg = arguments[i]; 467 let arg = args[i];
321 if (arg === void 0) arg = dart.dynamic; 468 if (arg == null) {
322 469 throw Error('type arguments should not be null: ' + typeConstructor);
323 var map = value; 470 }
471 let map = value;
324 value = map.get(arg); 472 value = map.get(arg);
325 if (value === void 0) { 473 if (value === void 0) {
326 if (i + 1 == length) { 474 if (i + 1 == length) {
327 value = typeConstructor.apply(null, arguments); 475 value = typeConstructor.apply(null, args);
328 // Save the type constructor and arguments for reflection. 476 // Save the type constructor and arguments for reflection.
329 if (value) { 477 if (value) {
330 var args = Array.prototype.slice.call(arguments); 478 value[dart.typeArguments] = args;
331 value[dart.typeSignature] = [makeGenericType].concat(args); 479 value[dart.originalDeclaration] = makeGenericType;
332 } 480 }
333 } else { 481 } else {
334 value = new Map(); 482 value = new Map();
335 } 483 }
336 map.set(arg, value); 484 map.set(arg, value);
337 } 485 }
338 } 486 }
339 return value; 487 return value;
340 } 488 }
341 return makeGenericType; 489 return makeGenericType;
342 } 490 }
343 dart.generic = generic; 491 dart.generic = generic;
344 492
345 // TODO(jmesserly): right now this is a sentinel. It should be a type object 493 // TODO(jmesserly): right now this is a sentinel. It should be a type object
346 // of some sort, assuming we keep around `dynamic` at runtime. 494 // of some sort, assuming we keep around `dynamic` at runtime.
347 dart.dynamic = Object.create(null); 495 dart.dynamic = { toString() { return 'dynamic'; } };
348 496
349 dart.JsSymbol = Symbol; 497 dart.JsSymbol = Symbol;
350 498
351 // TODO(jmesserly): hack to bootstrap the SDK 499 // TODO(jmesserly): hack to bootstrap the SDK
352 _js_helper = _js_helper || {}; 500 _js_helper = _js_helper || {};
353 _js_helper.checkNum = notNull; 501 _js_helper.checkNum = notNull;
354 502
355 })(dart || (dart = {})); 503 })(dart || (dart = {}));
OLDNEW
« no previous file with comments | « lib/runtime/dart/math.js ('k') | lib/src/codegen/js_codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698