]> git.r.bdr.sh - rbdr/dotfiles/blob - atom/packages/vim-mode/node_modules/grim/node_modules/emissary/node_modules/es6-weak-map/node_modules/d/lazy.js
61e466535f3dabcc6be59bdbbe0fdcf48a118614
[rbdr/dotfiles] / atom / packages / vim-mode / node_modules / grim / node_modules / emissary / node_modules / es6-weak-map / node_modules / d / lazy.js
1 'use strict';
2
3 var map = require('es5-ext/object/map')
4 , isCallable = require('es5-ext/object/is-callable')
5 , validValue = require('es5-ext/object/valid-value')
6 , contains = require('es5-ext/string/#/contains')
7
8 , call = Function.prototype.call
9 , defineProperty = Object.defineProperty
10 , getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor
11 , getPrototypeOf = Object.getPrototypeOf
12 , hasOwnProperty = Object.prototype.hasOwnProperty
13 , cacheDesc = { configurable: false, enumerable: false, writable: false,
14 value: null }
15 , define;
16
17 define = function (name, options) {
18 var value, dgs, cacheName, desc, writable = false, resolvable
19 , flat;
20 options = Object(validValue(options));
21 cacheName = options.cacheName;
22 flat = options.flat;
23 if (cacheName == null) cacheName = name;
24 delete options.cacheName;
25 value = options.value;
26 resolvable = isCallable(value);
27 delete options.value;
28 dgs = { configurable: Boolean(options.configurable),
29 enumerable: Boolean(options.enumerable) };
30 if (name !== cacheName) {
31 dgs.get = function () {
32 if (hasOwnProperty.call(this, cacheName)) return this[cacheName];
33 cacheDesc.value = resolvable ? call.call(value, this, options) : value;
34 cacheDesc.writable = writable;
35 defineProperty(this, cacheName, cacheDesc);
36 cacheDesc.value = null;
37 if (desc) defineProperty(this, name, desc);
38 return this[cacheName];
39 };
40 } else if (!flat) {
41 dgs.get = function self() {
42 var ownDesc;
43 if (hasOwnProperty.call(this, name)) {
44 ownDesc = getOwnPropertyDescriptor(this, name);
45 // It happens in Safari, that getter is still called after property
46 // was defined with a value, following workarounds that
47 if (ownDesc.hasOwnProperty('value')) return ownDesc.value;
48 if ((typeof ownDesc.get === 'function') && (ownDesc.get !== self)) {
49 return ownDesc.get.call(this);
50 }
51 return value;
52 }
53 desc.value = resolvable ? call.call(value, this, options) : value;
54 defineProperty(this, name, desc);
55 desc.value = null;
56 return this[name];
57 };
58 } else {
59 dgs.get = function self() {
60 var base = this, ownDesc;
61 if (hasOwnProperty.call(this, name)) {
62 // It happens in Safari, that getter is still called after property
63 // was defined with a value, following workarounds that
64 ownDesc = getOwnPropertyDescriptor(this, name);
65 if (ownDesc.hasOwnProperty('value')) return ownDesc.value;
66 if ((typeof ownDesc.get === 'function') && (ownDesc.get !== self)) {
67 return ownDesc.get.call(this);
68 }
69 }
70 while (!hasOwnProperty.call(base, name)) base = getPrototypeOf(base);
71 desc.value = resolvable ? call.call(value, base, options) : value;
72 defineProperty(base, name, desc);
73 desc.value = null;
74 return base[name];
75 };
76 }
77 dgs.set = function (value) {
78 dgs.get.call(this);
79 this[cacheName] = value;
80 };
81 if (options.desc) {
82 desc = {
83 configurable: contains.call(options.desc, 'c'),
84 enumerable: contains.call(options.desc, 'e')
85 };
86 if (cacheName === name) {
87 desc.writable = contains.call(options.desc, 'w');
88 desc.value = null;
89 } else {
90 writable = contains.call(options.desc, 'w');
91 desc.get = dgs.get;
92 desc.set = dgs.set;
93 }
94 delete options.desc;
95 } else if (cacheName === name) {
96 desc = {
97 configurable: Boolean(options.configurable),
98 enumerable: Boolean(options.enumerable),
99 writable: Boolean(options.writable),
100 value: null
101 };
102 }
103 delete options.configurable;
104 delete options.enumerable;
105 delete options.writable;
106 return dgs;
107 };
108
109 module.exports = function (props) {
110 return map(props, function (desc, name) { return define(name, desc); });
111 };