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: https://github.com/nodejs/node/pull/7690 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Michaël Zasso <mic.besace@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
e1643ccc5a
commit
320f433dcd
@ -46,7 +46,7 @@ environment variable. For example: `NODE_DEBUG=fs,net,tls`.
|
||||
|
||||
## util.deprecate(function, string)
|
||||
|
||||
The `util.deprecate()` method wraps the given `function` in such a way that
|
||||
The `util.deprecate()` method wraps the given `function` or class in such a way that
|
||||
it is marked as deprecated.
|
||||
|
||||
```js
|
||||
|
@ -60,9 +60,18 @@ exports._deprecate = function(fn, msg) {
|
||||
var warned = false;
|
||||
function deprecated() {
|
||||
warned = exports.printDeprecationMessage(msg, warned, deprecated);
|
||||
if (new.target) {
|
||||
return Reflect.construct(fn, arguments, new.target);
|
||||
}
|
||||
return fn.apply(this, arguments);
|
||||
}
|
||||
|
||||
// The wrapper will keep the same prototype as fn to maintain prototype chain
|
||||
Object.setPrototypeOf(deprecated, fn);
|
||||
if (fn.prototype) {
|
||||
Object.setPrototypeOf(deprecated.prototype, fn.prototype);
|
||||
}
|
||||
|
||||
return deprecated;
|
||||
};
|
||||
|
||||
|
12
test/fixtures/deprecated-userland-class.js
vendored
Normal file
12
test/fixtures/deprecated-userland-class.js
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
const util = require('util');
|
||||
const assert = require('assert');
|
||||
|
||||
class deprecatedClass {
|
||||
}
|
||||
|
||||
const deprecated = util.deprecate(deprecatedClass, 'deprecatedClass is deprecated.');
|
||||
|
||||
const instance = new deprecated();
|
||||
|
||||
assert(instance instanceof deprecated);
|
||||
assert(instance instanceof deprecatedClass);
|
19
test/fixtures/deprecated-userland-subclass.js
vendored
Normal file
19
test/fixtures/deprecated-userland-subclass.js
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
const util = require('util');
|
||||
const assert = require('assert');
|
||||
|
||||
class deprecatedClass {
|
||||
}
|
||||
|
||||
const deprecated = util.deprecate(deprecatedClass, 'deprecatedClass is deprecated.');
|
||||
|
||||
class subclass extends deprecated {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
const instance = new subclass();
|
||||
|
||||
assert(instance instanceof subclass);
|
||||
assert(instance instanceof deprecated);
|
||||
assert(instance instanceof deprecatedClass);
|
@ -5,8 +5,14 @@ const execFile = require('child_process').execFile;
|
||||
const depmod = require.resolve(common.fixturesDir + '/deprecated.js');
|
||||
const node = process.execPath;
|
||||
|
||||
const depUserland =
|
||||
require.resolve(common.fixturesDir + '/deprecated-userland-function.js');
|
||||
const depUserlandFunction =
|
||||
require.resolve(common.fixturesDir + '/deprecated-userland-function.js');
|
||||
|
||||
const depUserlandClass =
|
||||
require.resolve(common.fixturesDir + '/deprecated-userland-class.js');
|
||||
|
||||
const depUserlandSubClass =
|
||||
require.resolve(common.fixturesDir + '/deprecated-userland-subclass.js');
|
||||
|
||||
const normal = [depmod];
|
||||
const noDep = ['--no-deprecation', depmod];
|
||||
@ -39,10 +45,22 @@ execFile(node, traceDep, function(er, stdout, stderr) {
|
||||
console.log('trace ok');
|
||||
});
|
||||
|
||||
execFile(node, [depUserland], function(er, stdout, stderr) {
|
||||
execFile(node, [depUserlandFunction], function(er, stdout, stderr) {
|
||||
console.error('normal: testing deprecated userland function');
|
||||
assert.equal(er, null);
|
||||
assert.equal(stdout, '');
|
||||
assert(/deprecatedFunction is deprecated/.test(stderr));
|
||||
console.error('normal: ok');
|
||||
});
|
||||
|
||||
execFile(node, [depUserlandClass], function(er, stdout, stderr) {
|
||||
assert.strictEqual(er, null);
|
||||
assert.strictEqual(stdout, '');
|
||||
assert(/deprecatedClass is deprecated/.test(stderr));
|
||||
});
|
||||
|
||||
execFile(node, [depUserlandSubClass], function(er, stdout, stderr) {
|
||||
assert.strictEqual(er, null);
|
||||
assert.strictEqual(stdout, '');
|
||||
assert(/deprecatedClass is deprecated/.test(stderr));
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user