| 11 | |
| 12 | exports.wrap = function (entity) { |
| 13 | function wrapRoot(path, proto) { |
| 14 | return Proxy.create({ |
| 15 | get : function (receiver, name) { |
| 16 | if (Array.isArray(proto) && name === 'length') { |
| 17 | var arr = entity.scopeTable.get(path); |
| 18 | return entity.scopeTable.flagAsArray(path, arr.length && (1 + 1 * arr[arr.length - 1])); |
| 19 | } |
| 20 | var fqn = path + '.' + name; |
| 21 | var returnObj = entity.get(fqn); |
| 22 | if (returnObj && typeof returnObj === 'object') { |
| 23 | var p = (entity.scopeTable.arrays[fqn] === undefined) ? Object.prototype : Array.prototype; |
| 24 | if (p === Array.prototype) { |
| 25 | entity.scopeTable.flagAsArray(fqn, returnObj[returnObj.length - 1] || 0); |
| 26 | } |
| 27 | return wrapRoot(fqn, p); |
| 28 | } |
| 29 | if (returnObj === undefined && proto[name]) { |
| 30 | return proto[name]; |
| 31 | } |
| 32 | return returnObj; |
| 33 | }, |
| 34 | set : function (receiver, name, value) { |
| 35 | var fqn = path + '.' + name; |
| 36 | if (proto === Array.prototype) { |
| 37 | var len = 1 * entity.scopeTable.arrays[path] || 0; |
| 38 | if (name === 'length') { |
| 39 | return entity.scopeTable.flagAsArray(path, value); |
| 40 | } |
| 41 | if (name > len) { |
| 42 | entity.scopeTable.flagAsArray(path, 1 + name); |
| 43 | while (len <= name) { |
| 44 | receiver[len++] = undefined; |
| 45 | } |
| 46 | } |
| 47 | } |
| 48 | entity.set(fqn, value); |
| 49 | if (!value || typeof value !== 'object') { |
| 50 | return value; |
| 51 | } |
| 52 | if (Array.isArray(value)) { |
| 53 | entity.scopeTable.flagAsArray(fqn, value.length); |
| 54 | } |
| 55 | return wrapRoot(fqn, value.constructor.prototype); |
| 56 | }, |
| 57 | enumerate : function () { |
| 58 | return entity.scopeTable.get(path); |
| 59 | }, |
| 60 | hasOwn : function (name) { |
| 61 | return entity.scopeTable.get(path + '.' + name) !== undefined; |
| 62 | }, |
| 63 | delete : function (name) { |
| 64 | var fqn = path + '.' + name; |
| 65 | entity.deleteVar(fqn); |
| 66 | }, |
| 67 | fix : function () { |
| 68 | return undefined; |
| 69 | } |
| 70 | }, proto); |