Skip to content

Commit

Permalink
repl: runtime deprecate instantiating without new
Browse files Browse the repository at this point in the history
  • Loading branch information
RedYetiDev committed Sep 9, 2024
1 parent a202666 commit bb00db5
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 13 deletions.
5 changes: 4 additions & 1 deletion doc/api/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -3733,9 +3733,12 @@ changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/54842
description: Documentation-only deprecation.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/TODO

Check warning on line 3737 in doc/api/deprecations.md

View workflow job for this annotation

GitHub Actions / lint-pr-url

pr-url doesn't match the URL of the current PR.
description: Runtime deprecation.
-->

Type: Documentation-only
Type: Runtime

Instantiating classes without the `new` qualifier exported by the `node:repl` module is deprecated.
It is recommended to use the `new` qualifier instead. This applies to all REPL classes, including
Expand Down
18 changes: 12 additions & 6 deletions lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ function isError(e) {
// each one once.
const codesWarned = new SafeSet();

let validateString;
const lazyValidateString = getLazy(() => require('internal/validators').validateString);

function getDeprecationWarningEmitter(
code, msg, deprecated, useEmitSync,
Expand Down Expand Up @@ -148,12 +148,8 @@ function pendingDeprecate(fn, msg, code) {
// Returns a modified function which warns once by default.
// If --no-deprecation is set, then it is a no-op.
function deprecate(fn, msg, code, useEmitSync) {
// Lazy-load to avoid a circular dependency.
if (validateString === undefined)
({ validateString } = require('internal/validators'));

if (code !== undefined)
validateString(code, 'code');
lazyValidateString()(code, 'code');

const emitDeprecationWarning = getDeprecationWarningEmitter(
code, msg, deprecated, useEmitSync,
Expand Down Expand Up @@ -182,6 +178,15 @@ function deprecate(fn, msg, code, useEmitSync) {
return deprecated;
}

function deprecateInstantation(target, code, ...args) {
if (code !== undefined)
lazyValidateString()(code, 'code');

getDeprecationWarningEmitter(code, `Instantiating ${target.name} without the 'new' keyword has been deprecated.`, target)();

return ReflectConstruct(target, args);
}

function decorateErrorStack(err) {
if (!(isError(err) && err.stack) || err[decorated_private_symbol])
return;
Expand Down Expand Up @@ -902,6 +907,7 @@ module.exports = {
defineLazyProperties,
defineReplaceableLazyAttribute,
deprecate,
deprecateInstantation,
emitExperimentalWarning,
encodingsMap,
exposeInterface,
Expand Down
10 changes: 4 additions & 6 deletions lib/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const {
decorateErrorStack,
isError,
deprecate,
deprecateInstantation,
SideEffectFreeRegExpPrototypeSymbolReplace,
SideEffectFreeRegExpPrototypeSymbolSplit,
} = require('internal/util');
Expand Down Expand Up @@ -262,12 +263,7 @@ function REPLServer(prompt,
ignoreUndefined,
replMode) {
if (!(this instanceof REPLServer)) {
return new REPLServer(prompt,
stream,
eval_,
useGlobal,
ignoreUndefined,
replMode);
return deprecateInstantation(REPLServer, 'DEP0185', prompt, stream, eval_, useGlobal, ignoreUndefined, replMode);
}

let options;
Expand Down Expand Up @@ -1849,6 +1845,8 @@ function defineDefaultCommands(repl) {
}

function Recoverable(err) {
if (!(this instanceof Recoverable))
return deprecateInstantation(Recoverable, 'DEP0185');
this.err = err;
}
ObjectSetPrototypeOf(Recoverable.prototype, SyntaxErrorPrototype);
Expand Down
10 changes: 10 additions & 0 deletions test/parallel/test-repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -1014,3 +1014,13 @@ function event(ee, expected) {
}));
});
}

{
const server = repl.REPLServer();
common.expectWarning({
DeprecationWarning: {
DEP0185: 'Instantiating REPLServer without the \'new\' keyword has been deprecated.',
}
});
server.emit('line', '.exit');
}

0 comments on commit bb00db5

Please sign in to comment.