Skip to content

Commit

Permalink
[experimental] play with metadata reflection api, #152
Browse files Browse the repository at this point in the history
  • Loading branch information
zloirock committed Dec 29, 2015
1 parent 7bf885b commit 4feb559
Show file tree
Hide file tree
Showing 28 changed files with 404 additions and 9 deletions.
21 changes: 20 additions & 1 deletion build/build.ls
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@ list = <[
es7.math.isubh
es7.math.imulh
es7.math.umulh
es7.reflect.define-metadata
es7.reflect.delete-metadata
es7.reflect.get-metadata
es7.reflect.get-metadata-keys
es7.reflect.get-own-matadata
es7.reflect.get-own-metadata-keys
es7.reflect.has-metadata
es7.reflect.has-own-metadata
es7.reflect.metadata
web.immediate
web.dom.iterable
web.timers
Expand All @@ -149,7 +158,17 @@ list = <[
core.string.unescape-html
]>

experimental = <[ ]>
experimental = <[
es7.reflect.define-metadata
es7.reflect.delete-metadata
es7.reflect.get-metadata
es7.reflect.get-metadata-keys
es7.reflect.get-own-matadata
es7.reflect.get-own-metadata-keys
es7.reflect.has-metadata
es7.reflect.has-own-metadata
es7.reflect.metadata
]>

libraryBlacklist = <[
es6.object.to-string
Expand Down
4 changes: 2 additions & 2 deletions build/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 53 additions & 0 deletions library/modules/_metadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
var Map = require('./es6.map')
, $export = require('./_export')
, shared = require('./_shared')('metadata')
, store = shared.store || (shared.store = new (require('./es6.weak-map')));

var getOrCreateMetadataMap = function(target, targetKey, create){
var targetMetadata = store.get(target);
if(!targetMetadata){
if(!create)return undefined;
targetMetadata = new Map();
store.set(target, targetMetadata);
}
var keyMetadata = targetMetadata.get(targetKey);
if(!keyMetadata){
if(!create)return undefined;
keyMetadata = new Map();
targetMetadata.set(targetKey, keyMetadata);
} return keyMetadata;
};
var ordinaryHasOwnMetadata = function(MetadataKey, O, P){
var metadataMap = getOrCreateMetadataMap(O, P, false);
return metadataMap === undefined ? false : metadataMap.has(MetadataKey);
};
var ordinaryGetOwnMetadata = function(MetadataKey, O, P){
var metadataMap = getOrCreateMetadataMap(O, P, false);
return metadataMap === undefined ? undefined : metadataMap.get(MetadataKey);
};
var ordinaryDefineOwnMetadata = function(MetadataKey, MetadataValue, O, P){
getOrCreateMetadataMap(O, P, true).set(MetadataKey, MetadataValue);
};
var ordinaryOwnMetadataKeys = function(target, targetKey) {
var metadataMap = getOrCreateMetadataMap(target, targetKey, false);
var keys = [];
if(metadataMap)metadataMap.forEach(function(_, key){ keys.push(key); });
return keys;
};
var toMetaKey = function(it) {
return it === undefined || typeof it == 'symbol' ? it : String(it);
};
var exp = function(O){
$export($export.S, 'Reflect', O);
};

module.exports = {
store: store,
map: getOrCreateMetadataMap,
has: ordinaryHasOwnMetadata,
get: ordinaryGetOwnMetadata,
set: ordinaryDefineOwnMetadata,
keys: ordinaryOwnMetadataKeys,
key: toMetaKey,
exp: exp
};
2 changes: 1 addition & 1 deletion library/modules/es6.map.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
var strong = require('./_collection-strong');

// 23.1 Map Objects
require('./_collection')('Map', function(get){
module.exports = require('./_collection')('Map', function(get){
return function Map(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
// 23.1.3.6 Map.prototype.get(key)
Expand Down
2 changes: 1 addition & 1 deletion library/modules/es6.set.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
var strong = require('./_collection-strong');

// 23.2 Set Objects
require('./_collection')('Set', function(get){
module.exports = require('./_collection')('Set', function(get){
return function Set(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
// 23.2.3.1 Set.prototype.add(value)
Expand Down
2 changes: 1 addition & 1 deletion library/modules/es6.weak-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ var methods = {
};

// 23.3 WeakMap Objects
var $WeakMap = require('./_collection')('WeakMap', wrapper, methods, weak, true, true);
var $WeakMap = module.exports = require('./_collection')('WeakMap', wrapper, methods, weak, true, true);

// IE11 WeakMap frozen keys fix
if(new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7){
Expand Down
8 changes: 8 additions & 0 deletions library/modules/es7.reflect.define-metadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var metadata = require('./_metadata')
, anObject = require('./_an-object')
, toMetaKey = metadata.key
, ordinaryDefineOwnMetadata = metadata.set;

metadata.exp({defineMetadata: function defineMetadata(metadataKey, metadataValue, target, targetKey){
return ordinaryDefineOwnMetadata(metadataKey, metadataValue, anObject(target), toMetaKey(targetKey));
}});
18 changes: 18 additions & 0 deletions library/modules/es7.reflect.delete-metadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
var metadata = require('./_metadata')
, anObject = require('./_an-object')
, toPropertyKey = metadata.key
, getOrCreateMetadataMap = metadata.map
, store = metadata.store;

metadata.exp({deleteMetadata: function deleteMetadata(metadataKey, target, targetKey){
anObject(target);
if(targetKey !== undefined)targetKey = toPropertyKey(targetKey);
var metadataMap = getOrCreateMetadataMap(target, targetKey, false);
if(metadataMap === undefined || !metadataMap['delete'](metadataKey))return false;
if(metadataMap.size)return true;
var targetMetadata = store.get(target);
targetMetadata['delete'](targetKey);
if(targetMetadata.size)return true;
store['delete'](target);
return true;
}});
37 changes: 37 additions & 0 deletions library/modules/es7.reflect.get-metadata-keys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
var Set = require('./es6.set')
, metadata = require('./_metadata')
, anObject = require('./_an-object')
, getPrototypeOf = require('./_').getProto
, ordinaryOwnMetadataKeys = metadata.keys
, toMetaKey = metadata.key;

var ordinaryMetadataKeys = function(O, P){
var ownKeys = ordinaryOwnMetadataKeys(O, P);
var parent = getPrototypeOf(O);
if(parent === null)return ownKeys;
var parentKeys = ordinaryMetadataKeys(parent, P);
if(parentKeys.length <= 0)return ownKeys;
if(ownKeys.length <= 0)return parentKeys;
var set = new Set();
var keys = [];
for(var i = 0; i < ownKeys.length; i++){
var key = ownKeys[i];
var hasKey = set.has(key);
if(!hasKey){
set.add(key);
keys.push(key);
}
}
for(var j = 0; j < parentKeys.length; j++){
var key = parentKeys[j];
var hasKey = set.has(key);
if(!hasKey){
set.add(key);
keys.push(key);
}
} return keys;
};

metadata.exp({getMetadataKeys: function getMetadataKeys(target, targetKey){
return ordinaryMetadataKeys(anObject(target), toMetaKey(targetKey));
}});
17 changes: 17 additions & 0 deletions library/modules/es7.reflect.get-metadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
var metadata = require('./_metadata')
, anObject = require('./_an-object')
, getPrototypeOf = require('./_').getProto
, ordinaryHasOwnMetadata = metadata.has
, ordinaryGetOwnMetadata = metadata.get
, toMetaKey = metadata.key;

var ordinaryGetMetadata = function(MetadataKey, O, P){
var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);
if(hasOwn)return ordinaryGetOwnMetadata(MetadataKey, O, P);
var parent = getPrototypeOf(O);
return parent !== null ? ordinaryGetMetadata(MetadataKey, parent, P) : undefined;
};

metadata.exp({getMetadata: function getMetadata(metadataKey, target, targetKey){
return ordinaryGetMetadata(metadataKey, anObject(target), toMetaKey(targetKey));
}});
8 changes: 8 additions & 0 deletions library/modules/es7.reflect.get-own-matadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var metadata = require('./_metadata')
, anObject = require('./_an-object')
, ordinaryGetOwnMetadata = metadata.get
, toMetaKey = metadata.key;

metadata.exp({getOwnMetadata: function getOwnMetadata(metadataKey, target, targetKey){
return ordinaryGetOwnMetadata(metadataKey, anObject(target), toMetaKey(targetKey));
}});
8 changes: 8 additions & 0 deletions library/modules/es7.reflect.get-own-metadata-keys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var metadata = require('./_metadata')
, anObject = require('./_an-object')
, ordinaryOwnMetadataKeys = metadata.keys
, toMetaKey = metadata.key;

metadata.exp({getOwnMetadataKeys: function getOwnMetadataKeys(target, targetKey){
return ordinaryOwnMetadataKeys(anObject(target), toMetaKey(targetKey));
}});
16 changes: 16 additions & 0 deletions library/modules/es7.reflect.has-metadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
var metadata = require('./_metadata')
, anObject = require('./_an-object')
, getPrototypeOf = require('./_').getProto
, ordinaryHasOwnMetadata = metadata.has
, toMetaKey = metadata.key;

var ordinaryHasMetadata = function(MetadataKey, O, P){
var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);
if(hasOwn)return true;
var parent = getPrototypeOf(O);
return parent !== null ? ordinaryHasMetadata(MetadataKey, parent, P) : false;
};

metadata.exp({hasMetadata: function hasMetadata(metadataKey, target, targetKey){
return ordinaryHasMetadata(metadataKey, anObject(target), toMetaKey(targetKey));
}});
8 changes: 8 additions & 0 deletions library/modules/es7.reflect.has-own-metadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var metadata = require('./_metadata')
, anObject = require('./_an-object')
, ordinaryHasOwnMetadata = metadata.has
, toMetaKey = metadata.key;

metadata.exp({hasOwnMetadata: function hasOwnMetadata(metadataKey, target, targetKey){
return ordinaryHasOwnMetadata(metadataKey, anObject(target), toMetaKey(targetKey));
}});
15 changes: 15 additions & 0 deletions library/modules/es7.reflect.metadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
var metadata = require('./_metadata')
, anObject = require('./_an-object')
, aFunction = require('./_a-function')
, toMetaKey = metadata.key
, ordinaryDefineOwnMetadata = metadata.set;

metadata.exp({metadata: function metadata(metadataKey, metadataValue) {
return function decorator(target, targetKey){
ordinaryDefineOwnMetadata(
metadataKey, metadataValue,
(targetKey !== undefined ? anObject : aFunction)(target),
toMetaKey(targetKey)
);
};
}});
53 changes: 53 additions & 0 deletions modules/_metadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
var Map = require('./es6.map')
, $export = require('./_export')
, shared = require('./_shared')('metadata')
, store = shared.store || (shared.store = new (require('./es6.weak-map')));

var getOrCreateMetadataMap = function(target, targetKey, create){
var targetMetadata = store.get(target);
if(!targetMetadata){
if(!create)return undefined;
targetMetadata = new Map();
store.set(target, targetMetadata);
}
var keyMetadata = targetMetadata.get(targetKey);
if(!keyMetadata){
if(!create)return undefined;
keyMetadata = new Map();
targetMetadata.set(targetKey, keyMetadata);
} return keyMetadata;
};
var ordinaryHasOwnMetadata = function(MetadataKey, O, P){
var metadataMap = getOrCreateMetadataMap(O, P, false);
return metadataMap === undefined ? false : metadataMap.has(MetadataKey);
};
var ordinaryGetOwnMetadata = function(MetadataKey, O, P){
var metadataMap = getOrCreateMetadataMap(O, P, false);
return metadataMap === undefined ? undefined : metadataMap.get(MetadataKey);
};
var ordinaryDefineOwnMetadata = function(MetadataKey, MetadataValue, O, P){
getOrCreateMetadataMap(O, P, true).set(MetadataKey, MetadataValue);
};
var ordinaryOwnMetadataKeys = function(target, targetKey) {
var metadataMap = getOrCreateMetadataMap(target, targetKey, false);
var keys = [];
if(metadataMap)metadataMap.forEach(function(_, key){ keys.push(key); });
return keys;
};
var toMetaKey = function(it) {
return it === undefined || typeof it == 'symbol' ? it : String(it);
};
var exp = function(O){
$export($export.S, 'Reflect', O);
};

module.exports = {
store: store,
map: getOrCreateMetadataMap,
has: ordinaryHasOwnMetadata,
get: ordinaryGetOwnMetadata,
set: ordinaryDefineOwnMetadata,
keys: ordinaryOwnMetadataKeys,
key: toMetaKey,
exp: exp
};
2 changes: 1 addition & 1 deletion modules/es6.map.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
var strong = require('./_collection-strong');

// 23.1 Map Objects
require('./_collection')('Map', function(get){
module.exports = require('./_collection')('Map', function(get){
return function Map(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
// 23.1.3.6 Map.prototype.get(key)
Expand Down
2 changes: 1 addition & 1 deletion modules/es6.set.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
var strong = require('./_collection-strong');

// 23.2 Set Objects
require('./_collection')('Set', function(get){
module.exports = require('./_collection')('Set', function(get){
return function Set(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
// 23.2.3.1 Set.prototype.add(value)
Expand Down
2 changes: 1 addition & 1 deletion modules/es6.weak-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ var methods = {
};

// 23.3 WeakMap Objects
var $WeakMap = require('./_collection')('WeakMap', wrapper, methods, weak, true, true);
var $WeakMap = module.exports = require('./_collection')('WeakMap', wrapper, methods, weak, true, true);

// IE11 WeakMap frozen keys fix
if(new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7){
Expand Down
Loading

0 comments on commit 4feb559

Please sign in to comment.