UNPKG

3.76 kBJavaScriptView Raw
1/*
2 * Copyright (c) 2012 Dmitri Melikyan
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to permit
9 * persons to whom the Software is furnished to do so, subject to the
10 * following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
18 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24EventEmitter = require('events').EventEmitter;
25
26var nt;
27
28exports.init = function() {
29 nt = global.nodetime;
30}
31
32var Locals = function() {
33 this.time = undefined;
34 this.stackTrace = undefined;
35 this.params = undefined;
36}
37
38
39exports.before = function(obj, meths, hook) {
40 if(!Array.isArray(meths)) meths = [meths];
41
42 meths.forEach(function(meth) {
43 var orig = obj[meth];
44 if(!orig) return;
45
46 obj[meth] = function() {
47 try { hook(this, arguments); } catch(e) { nt.error(e); }
48 return orig.apply(this, arguments);
49 };
50 });
51};
52
53
54exports.after = function(obj, meths, hook) {
55 if(!Array.isArray(meths)) meths = [meths];
56
57 meths.forEach(function(meth) {
58 var orig = obj[meth];
59 if(!orig) return;
60
61 obj[meth] = function() {
62 var ret = orig.apply(this, arguments);
63 try { hook(this, arguments, ret); } catch(e) { nt.error(e) }
64 return ret;
65 };
66 });
67};
68
69
70exports.around = function(obj, meths, hookBefore, hookAfter) {
71 if(!Array.isArray(meths)) meths = [meths];
72
73 meths.forEach(function(meth) {
74 var orig = obj[meth];
75 if(!orig) return;
76
77 obj[meth] = function() {
78 var locals = new Locals();
79 try { hookBefore(this, arguments, locals); } catch(e) { nt.error(e) }
80 var ret = orig.apply(this, arguments);
81 try { hookAfter(this, arguments, ret, locals); } catch(e) { nt.error(e) }
82 return ret;
83 };
84 });
85};
86
87
88exports.callback = function(args, pos, hookBefore, hookAfter) {
89 if(args.length <= pos) return false;
90 if(pos === -1) pos = args.length - 1;
91
92 var orig = (typeof args[pos] === 'function') ? args[pos] : undefined;
93 if(!orig) return;
94
95 args[pos] = function() {
96 if(hookBefore) try { hookBefore(this, arguments); } catch(e) { nt.error(e); }
97 var ret = orig.apply(this, arguments);
98 if(hookAfter) try { hookAfter(this, arguments); } catch(e) { nt.error(e); }
99 return ret;
100 };
101
102 orig.__proxy__ = args[pos];
103};
104
105
106exports.getter = function(obj, props, hook) {
107 if(!Array.isArray(props)) props = [props];
108
109 props.forEach(function(prop) {
110 var orig = obj.__lookupGetter__(prop);
111 if(!orig) return;
112
113 obj.__defineGetter__(prop, function() {
114 var ret = orig.apply(this, arguments);
115 try { hook(this, ret); } catch(e) { nt.error(e) }
116 return ret;
117 });
118 });
119};
120
121
122
123if(!EventEmitter.prototype.__patched__) {
124 /* make sure a wrapped listener can be removed */
125 exports.before(EventEmitter.prototype, 'removeListener', function(obj, args) {
126 if(args.length > 1 && args[1] && args[1].__proxy__) {
127 args[1] = args[1].__proxy__;
128 }
129 });
130
131 EventEmitter.prototype.__patched__ = true;
132}
133
134