| 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 var dart; | 5 var dart; |
| 6 (function (dart) { | 6 (function (dart) { |
| 7 'use strict'; |
| 8 |
| 7 var defineProperty = Object.defineProperty; | 9 var defineProperty = Object.defineProperty; |
| 8 var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; | 10 var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; |
| 9 var getOwnPropertyNames = Object.getOwnPropertyNames; | 11 var getOwnPropertyNames = Object.getOwnPropertyNames; |
| 10 | 12 |
| 11 // Adapted from Angular.js | 13 // Adapted from Angular.js |
| 12 var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; | 14 var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; |
| 13 var FN_ARG_SPLIT = /,/; | 15 var FN_ARG_SPLIT = /,/; |
| 14 var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/; | 16 var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/; |
| 15 var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; | 17 var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; |
| 16 | 18 |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 var value = f(); | 158 var value = f(); |
| 157 lazySetter(value); | 159 lazySetter(value); |
| 158 return value; | 160 return value; |
| 159 } | 161 } |
| 160 desc.get = lazyGetter; | 162 desc.get = lazyGetter; |
| 161 desc.configurable = true; | 163 desc.configurable = true; |
| 162 if (writable) desc.set = lazySetter; | 164 if (writable) desc.set = lazySetter; |
| 163 defineProperty(to, name, desc); | 165 defineProperty(to, name, desc); |
| 164 } | 166 } |
| 165 | 167 |
| 166 function defineLazyProperties(to, from) { | 168 function defineLazy(to, from) { |
| 167 var names = getOwnPropertyNames(from); | 169 var names = getOwnPropertyNames(from); |
| 168 for (var i = 0; i < names.length; i++) { | 170 for (var i = 0; i < names.length; i++) { |
| 169 var name = names[i]; | 171 var name = names[i]; |
| 170 defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name)); | 172 defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name)); |
| 171 } | 173 } |
| 172 } | 174 } |
| 173 dart.defineLazyProperties = defineLazyProperties; | 175 // TODO(jmesserly): these are identical, but this makes it easier to grep for. |
| 176 dart.defineLazyClass = defineLazy; |
| 177 dart.defineLazyProperties = defineLazy; |
| 178 dart.defineLazyClassGeneric = defineLazyProperty; |
| 174 | 179 |
| 175 /** | 180 /** |
| 176 * Copy properties from source to destination object. | 181 * Copy properties from source to destination object. |
| 177 * This operation is commonly called `mixin` in JS. | 182 * This operation is commonly called `mixin` in JS. |
| 178 */ | 183 */ |
| 179 function copyProperties(to, from) { | 184 function copyProperties(to, from) { |
| 180 var names = getOwnPropertyNames(from); | 185 var names = getOwnPropertyNames(from); |
| 181 for (var i = 0; i < names.length; i++) { | 186 for (var i = 0; i < names.length; i++) { |
| 182 var name = names[i]; | 187 var name = names[i]; |
| 183 defineProperty(to, name, getOwnPropertyDescriptor(from, name)); | 188 defineProperty(to, name, getOwnPropertyDescriptor(from, name)); |
| 184 } | 189 } |
| 185 return to; | 190 return to; |
| 186 } | 191 } |
| 187 dart.copyProperties = copyProperties; | 192 dart.copyProperties = copyProperties; |
| 188 | 193 |
| 189 /** | 194 /** |
| 190 * Returns a new type that mixes members from base and all mixins. | 195 * Returns a new type that mixes members from base and all mixins. |
| 191 * | 196 * |
| 192 * Each mixin applies in sequence, with further to the right ones overriding | 197 * Each mixin applies in sequence, with further to the right ones overriding |
| 193 * previous entries. | 198 * previous entries. |
| 194 * | 199 * |
| 195 * For each mixin, we only take its own properties, not anything from its | 200 * For each mixin, we only take its own properties, not anything from its |
| 196 * superclass (prototype). | 201 * superclass (prototype). |
| 197 */ | 202 */ |
| 198 function mixin(base/*, ...mixins*/) { | 203 function mixin(base/*, ...mixins*/) { |
| 199 // Inherit statics from Base to simulate ES6 class inheritance | 204 // Create an initializer for the mixin, so when derived constructor calls |
| 200 // Conceptually this is: `class Mixin extends base {}` | 205 // super, we can correctly initialize base and mixins. |
| 201 function Mixin() { | 206 var mixins = Array.prototype.slice.call(arguments, 1); |
| 202 // TODO(jmesserly): since we're using initializers and not constructors, | 207 |
| 203 // we can just skip directly to core.Object. | 208 // Create a class that will hold all of the mixin methods. |
| 204 core.Object.apply(this, arguments); | 209 class Mixin extends base { |
| 210 // Initializer method: run mixin initializers, then the base. |
| 211 [base.name](/*...args*/) { |
| 212 // Run mixin initializers. They cannot have arguments. |
| 213 // Run them backwards so most-derived mixin is initialized first. |
| 214 for (var i = mixins.length - 1; i >= 0; i--) { |
| 215 var mixin = mixins[i]; |
| 216 mixin.prototype[mixin.name].call(this); |
| 217 } |
| 218 // Run base initializer. |
| 219 base.prototype[base.name].apply(this, arguments); |
| 220 } |
| 205 } | 221 } |
| 206 Mixin.__proto__ = base; | 222 // Copy each mixin's methods, with later ones overwriting earlier entries. |
| 207 Mixin.prototype = Object.create(base.prototype); | |
| 208 Mixin.prototype.constructor = Mixin; | |
| 209 // Copy each mixin, with later ones overwriting earlier entries. | |
| 210 var mixins = Array.prototype.slice.call(arguments, 1); | |
| 211 for (var i = 0; i < mixins.length; i++) { | 223 for (var i = 0; i < mixins.length; i++) { |
| 212 copyProperties(Mixin.prototype, mixins[i].prototype); | 224 copyProperties(Mixin.prototype, mixins[i].prototype); |
| 213 } | 225 } |
| 214 // Create an initializer for the mixin, so when derived constructor calls | |
| 215 // super, we can correctly initialize base and mixins. | |
| 216 var baseCtor = base.prototype[base.name]; | |
| 217 Mixin.prototype[base.name] = function() { | |
| 218 // Run mixin initializers. They cannot have arguments. | |
| 219 // Run them backwards so most-derived mixin is initialized first. | |
| 220 for (var i = mixins.length - 1; i >= 0; i--) { | |
| 221 var mixin = mixins[i]; | |
| 222 mixin.prototype[mixin.name].call(this); | |
| 223 } | |
| 224 // Run base initializer. | |
| 225 baseCtor.apply(this, arguments); | |
| 226 } | |
| 227 return Mixin; | 226 return Mixin; |
| 228 } | 227 } |
| 229 dart.mixin = mixin; | 228 dart.mixin = mixin; |
| 230 | 229 |
| 231 /** | 230 /** |
| 232 * Creates a dart:collection LinkedHashMap. | 231 * Creates a dart:collection LinkedHashMap. |
| 233 * | 232 * |
| 234 * For a map with string keys an object literal can be used, for example | 233 * For a map with string keys an object literal can be used, for example |
| 235 * `map({'hi': 1, 'there': 2})`. | 234 * `map({'hi': 1, 'there': 2})`. |
| 236 * | 235 * |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 | 297 |
| 299 var resultMap = new Map(); | 298 var resultMap = new Map(); |
| 300 function makeGenericType(/*...arguments*/) { | 299 function makeGenericType(/*...arguments*/) { |
| 301 if (arguments.length != length) { | 300 if (arguments.length != length) { |
| 302 throw 'requires ' + length + ' type arguments'; | 301 throw 'requires ' + length + ' type arguments'; |
| 303 } | 302 } |
| 304 | 303 |
| 305 var value = resultMap; | 304 var value = resultMap; |
| 306 for (var i = 0; i < length; i++) { | 305 for (var i = 0; i < length; i++) { |
| 307 var arg = arguments[i]; | 306 var arg = arguments[i]; |
| 308 // TODO(jmesserly): assume `dynamic` here? | 307 if (arg === void 0) arg = dart.dynamic; |
| 309 if (arg === void 0) throw 'undefined is not allowed as a type argument'; | |
| 310 | 308 |
| 311 var map = value; | 309 var map = value; |
| 312 value = map.get(arg); | 310 value = map.get(arg); |
| 313 if (value === void 0) { | 311 if (value === void 0) { |
| 314 if (i + 1 == length) { | 312 if (i + 1 == length) { |
| 315 value = typeConstructor.apply(null, arguments); | 313 value = typeConstructor.apply(null, arguments); |
| 316 // Save the type constructor and arguments for reflection. | 314 // Save the type constructor and arguments for reflection. |
| 317 if (value) { | 315 if (value) { |
| 318 var args = Array.prototype.slice.call(arguments); | 316 var args = Array.prototype.slice.call(arguments); |
| 319 value[dart.typeSignature] = [makeGenericType].concat(args); | 317 value[dart.typeSignature] = [makeGenericType].concat(args); |
| 320 } | 318 } |
| 321 } else { | 319 } else { |
| 322 value = new Map(); | 320 value = new Map(); |
| 323 } | 321 } |
| 324 map.set(arg, value); | 322 map.set(arg, value); |
| 325 } | 323 } |
| 326 } | 324 } |
| 327 return value; | 325 return value; |
| 328 } | 326 } |
| 329 return makeGenericType; | 327 return makeGenericType; |
| 330 } | 328 } |
| 331 dart.generic = generic; | 329 dart.generic = generic; |
| 332 | 330 |
| 333 | 331 // TODO(jmesserly): this is just a placeholder. |
| 334 /** | 332 dart.dynamic = Object.create(null); |
| 335 * Implements Dart constructor behavior. Because of V8 `super` [constructor | |
| 336 * restrictions](https://code.google.com/p/v8/issues/detail?id=3330#c65) we | |
| 337 * cannot currently emit actual ES6 constructors with super calls. Instead | |
| 338 * we use the same trick as named constructors, and do them as instance | |
| 339 * methods that perform initialization. | |
| 340 */ | |
| 341 // TODO(jmesserly): we'll need to rethink this once the ES6 spec and V8 | |
| 342 // settles. See <https://github.com/dart-lang/dart-dev-compiler/issues/51>. | |
| 343 // Performance of this pattern is likely to be bad. | |
| 344 core.Object = function Object() { | |
| 345 // Get the class name for this instance. | |
| 346 var name = this.constructor.name; | |
| 347 // Call the default constructor. | |
| 348 var init = this[name]; | |
| 349 var result = void 0; | |
| 350 if (init) result = init.apply(this, arguments); | |
| 351 return result === void 0 ? this : result; | |
| 352 }; | |
| 353 // The initializer for Object | |
| 354 core.Object.prototype.Object = function() {}; | |
| 355 core.Object.prototype.constructor = core.Object; | |
| 356 | 333 |
| 357 })(dart || (dart = {})); | 334 })(dart || (dart = {})); |
| OLD | NEW |