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)
|
## 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.
|
it is marked as deprecated.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -60,9 +60,18 @@ exports._deprecate = function(fn, msg) {
|
|||||||
var warned = false;
|
var warned = false;
|
||||||
function deprecated() {
|
function deprecated() {
|
||||||
warned = exports.printDeprecationMessage(msg, warned, deprecated);
|
warned = exports.printDeprecationMessage(msg, warned, deprecated);
|
||||||
|
if (new.target) {
|
||||||
|
return Reflect.construct(fn, arguments, new.target);
|
||||||
|
}
|
||||||
return fn.apply(this, arguments);
|
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;
|
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,9 +5,15 @@ const execFile = require('child_process').execFile;
|
|||||||
const depmod = require.resolve(common.fixturesDir + '/deprecated.js');
|
const depmod = require.resolve(common.fixturesDir + '/deprecated.js');
|
||||||
const node = process.execPath;
|
const node = process.execPath;
|
||||||
|
|
||||||
const depUserland =
|
const depUserlandFunction =
|
||||||
require.resolve(common.fixturesDir + '/deprecated-userland-function.js');
|
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 normal = [depmod];
|
||||||
const noDep = ['--no-deprecation', depmod];
|
const noDep = ['--no-deprecation', depmod];
|
||||||
const traceDep = ['--trace-deprecation', depmod];
|
const traceDep = ['--trace-deprecation', depmod];
|
||||||
@ -39,10 +45,22 @@ execFile(node, traceDep, function(er, stdout, stderr) {
|
|||||||
console.log('trace ok');
|
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');
|
console.error('normal: testing deprecated userland function');
|
||||||
assert.equal(er, null);
|
assert.equal(er, null);
|
||||||
assert.equal(stdout, '');
|
assert.equal(stdout, '');
|
||||||
assert(/deprecatedFunction is deprecated/.test(stderr));
|
assert(/deprecatedFunction is deprecated/.test(stderr));
|
||||||
console.error('normal: ok');
|
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