-
Notifications
You must be signed in to change notification settings - Fork 0
/
debug-decorator.js
85 lines (68 loc) · 2.29 KB
/
debug-decorator.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
'use strict';
module.exports = function debugDecorate(target) {
function getKeys(obj) {
let keys = Object.getOwnPropertyNames(obj);
if (Object.getOwnPropertySymbols) {
keys.concat(Object.getOwnPropertySymbols(obj));
}
return keys.filter(key => key !== 'constructor').map(key => ({ obj: obj, key: key }));
}
let keys = [];
let proto = target;
while (proto) {
// don't touch the Function.__proto__
if (proto === Object.getPrototypeOf(Function)) break;
keys = keys.concat(getKeys(proto));
proto = Object.getPrototypeOf(proto);
}
proto = target.prototype;
while (proto) {
// don't touch the Object.prototype
if (proto === Object.prototype) break;
keys = keys.concat(getKeys(proto));
proto = Object.getPrototypeOf(proto);
}
keys.forEach(item => {
let obj = item.obj;
let key = item.key;
let descriptor = Object.getOwnPropertyDescriptor(obj, key);
if (typeof descriptor.value === 'function') {
obj[key] = function () {
let args = Array.from(arguments);
let message = '';
// static methods
if (typeof obj === 'function') {
// check if a method has been invoked on the target class
if (this === target) {
// own static method
if (obj === target) {
// TODO check for override
message = `${target.name}.${key}`;
// inherited static method
} else {
message = `${target.name}.${key} (inherited from ${obj.name})`;
}
}
// prototype methods
} else {
// check if a method has been invoked on the target class
if (this.constructor === target) {
// own prototype method
if (this.constructor === obj.constructor) {
// TODO check for override
message = `${this.constructor.name}.prototype.${key}`;
// inherited prototype method
} else {
message = `${this.constructor.name}.prototype.${key} (inherited from ${obj.constructor.name})`;
}
}
}
let result = descriptor.value.apply(this, args);
if (message) {
console.info(message, args, '=>', result);
}
return result;
};
}
});
}