Skip to content

Commit 295d1ea

Browse files
vdeturckheimcjihrig
authored andcommitted
util: support classes in util.deprecate()
Classes cannot be instantiated without new, but util.deprecate() uses Function.prototype.apply(). This commit uses new.target to detect constructor calls, allowing classes to be deprecated. PR-URL: #7690 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent df35ae6 commit 295d1ea

File tree

5 files changed

+62
-4
lines changed

5 files changed

+62
-4
lines changed

‎doc/api/util.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ environment variable. For example: `NODE_DEBUG=fs,net,tls`.
4646

4747
## util.deprecate(function, string)
4848

49-
The `util.deprecate()` method wraps the given `function` in such a way that
49+
The `util.deprecate()` method wraps the given `function`or class in such a way that
5050
it is marked as deprecated.
5151

5252
```js

‎lib/internal/util.js‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,18 @@ exports._deprecate = function(fn, msg){
5757
varwarned=false;
5858
functiondeprecated(){
5959
warned=exports.printDeprecationMessage(msg,warned,deprecated);
60+
if(new.target){
61+
returnReflect.construct(fn,arguments,new.target);
62+
}
6063
returnfn.apply(this,arguments);
6164
}
6265

66+
// The wrapper will keep the same prototype as fn to maintain prototype chain
67+
Object.setPrototypeOf(deprecated,fn);
68+
if(fn.prototype){
69+
Object.setPrototypeOf(deprecated.prototype,fn.prototype);
70+
}
71+
6372
returndeprecated;
6473
};
6574

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
constutil=require('util');
2+
constassert=require('assert');
3+
4+
classdeprecatedClass{
5+
}
6+
7+
constdeprecated=util.deprecate(deprecatedClass,'deprecatedClass is deprecated.');
8+
9+
constinstance=newdeprecated();
10+
11+
assert(instanceinstanceofdeprecated);
12+
assert(instanceinstanceofdeprecatedClass);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
constutil=require('util');
2+
constassert=require('assert');
3+
4+
classdeprecatedClass{
5+
}
6+
7+
constdeprecated=util.deprecate(deprecatedClass,'deprecatedClass is deprecated.');
8+
9+
classsubclassextendsdeprecated{
10+
constructor(){
11+
super();
12+
}
13+
}
14+
15+
constinstance=newsubclass();
16+
17+
assert(instanceinstanceofsubclass);
18+
assert(instanceinstanceofdeprecated);
19+
assert(instanceinstanceofdeprecatedClass);

‎test/sequential/test-deprecation-flags.js‎

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@ const execFile = require('child_process').execFile;
55
constdepmod=require.resolve(common.fixturesDir+'/deprecated.js');
66
constnode=process.execPath;
77

8-
constdepUserland=
9-
require.resolve(common.fixturesDir+'/deprecated-userland-function.js');
8+
constdepUserlandFunction=
9+
require.resolve(common.fixturesDir+'/deprecated-userland-function.js');
10+
11+
constdepUserlandClass=
12+
require.resolve(common.fixturesDir+'/deprecated-userland-class.js');
13+
14+
constdepUserlandSubClass=
15+
require.resolve(common.fixturesDir+'/deprecated-userland-subclass.js');
1016

1117
constnormal=[depmod];
1218
constnoDep=['--no-deprecation',depmod];
@@ -39,10 +45,22 @@ execFile(node, traceDep, function(er, stdout, stderr){
3945
console.log('trace ok');
4046
});
4147

42-
execFile(node,[depUserland],function(er,stdout,stderr){
48+
execFile(node,[depUserlandFunction],function(er,stdout,stderr){
4349
console.error('normal: testing deprecated userland function');
4450
assert.equal(er,null);
4551
assert.equal(stdout,'');
4652
assert(/deprecatedFunctionisdeprecated/.test(stderr));
4753
console.error('normal: ok');
4854
});
55+
56+
execFile(node,[depUserlandClass],function(er,stdout,stderr){
57+
assert.strictEqual(er,null);
58+
assert.strictEqual(stdout,'');
59+
assert(/deprecatedClassisdeprecated/.test(stderr));
60+
});
61+
62+
execFile(node,[depUserlandSubClass],function(er,stdout,stderr){
63+
assert.strictEqual(er,null);
64+
assert.strictEqual(stdout,'');
65+
assert(/deprecatedClassisdeprecated/.test(stderr));
66+
});

0 commit comments

Comments
(0)