Skip to content

Commit 1e26b14

Browse files
committed
util: fix util.getCallSites plurality
`util.getCallSite` returns an array of call site objects. Rename the function to reflect that it returns a given count of frames captured as an array of call site object. Renames the first parameter `frames` to be `frameCount` to indicate that it specifies the count of returned call sites.
1 parent 4379dfb commit 1e26b14

10 files changed

+89
-61
lines changed

benchmark/util/get-callsite.js

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
'use strict';
22

33
const common = require('../common');
4-
const { getCallSite } = require('node:util');
4+
const { getCallSites } = require('node:util');
55
const assert = require('node:assert');
66

77
const bench = common.createBenchmark(main, {
88
n: [1e6],
9-
method: ['ErrorCallSite', 'ErrorCallSiteSerialized', 'CPP'],
9+
method: ['ErrorCallSites', 'ErrorCallSitesSerialized', 'CPP'],
1010
});
1111

12-
function ErrorGetCallSite() {
12+
function ErrorGetCallSites() {
1313
const originalStackFormatter = Error.prepareStackTrace;
1414
Error.prepareStackTrace = (_err, stack) => {
1515
if (stack && stack.length > 1) {
@@ -25,15 +25,15 @@ function ErrorGetCallSite() {
2525
return err.stack;
2626
}
2727

28-
function ErrorCallSiteSerialized() {
29-
const callsite = ErrorGetCallSite();
28+
function ErrorCallSitesSerialized() {
29+
const callSites = ErrorGetCallSites();
3030
const serialized = [];
31-
for (let i = 0; i < callsite.length; ++i) {
31+
for (let i = 0; i < callSites.length; ++i) {
3232
serialized.push({
33-
functionName: callsite[i].getFunctionName(),
34-
scriptName: callsite[i].getFileName(),
35-
lineNumber: callsite[i].getLineNumber(),
36-
column: callsite[i].getColumnNumber(),
33+
functionName: callSites[i].getFunctionName(),
34+
scriptName: callSites[i].getFileName(),
35+
lineNumber: callSites[i].getLineNumber(),
36+
column: callSites[i].getColumnNumber(),
3737
});
3838
}
3939
return serialized;
@@ -42,14 +42,14 @@ function ErrorCallSiteSerialized() {
4242
function main({ n, method }) {
4343
let fn;
4444
switch (method) {
45-
case 'ErrorCallSite':
46-
fn = ErrorGetCallSite;
45+
case 'ErrorCallSites':
46+
fn = ErrorGetCallSites;
4747
break;
48-
case 'ErrorCallSiteSerialized':
49-
fn = ErrorCallSiteSerialized;
48+
case 'ErrorCallSitesSerialized':
49+
fn = ErrorCallSitesSerialized;
5050
break;
5151
case 'CPP':
52-
fn = getCallSite;
52+
fn = getCallSites;
5353
break;
5454
}
5555
let lastStack = {};

doc/api/deprecations.md

+14
Original file line numberDiff line numberDiff line change
@@ -3761,6 +3761,19 @@ Instantiating classes without the `new` qualifier exported by the `node:repl` mo
37613761
It is recommended to use the `new` qualifier instead. This applies to all REPL classes, including
37623762
`REPLServer` and `Recoverable`.
37633763

3764+
### DEP0186: `util.getCallSite`
3765+
3766+
<!-- YAML
3767+
changes:
3768+
- version: REPLACEME
3769+
pr-url: https://github.com/nodejs/node/pull/55626
3770+
description: Runtime deprecation.
3771+
-->
3772+
3773+
Type: Runtime
3774+
3775+
The `util.getCallSite` API has been removed. Please use [`util.getCallSites()`] instead.
3776+
37643777
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
37653778
[RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3
37663779
[RFC 8247 Section 2.4]: https://www.rfc-editor.org/rfc/rfc8247#section-2.4
@@ -3887,6 +3900,7 @@ It is recommended to use the `new` qualifier instead. This applies to all REPL c
38873900
[`url.resolve()`]: url.md#urlresolvefrom-to
38883901
[`util._extend()`]: util.md#util_extendtarget-source
38893902
[`util.getSystemErrorName()`]: util.md#utilgetsystemerrornameerr
3903+
[`util.getCallSites()`]: util.md#utilgetcallsites-framecount
38903904
[`util.inspect()`]: util.md#utilinspectobject-options
38913905
[`util.inspect.custom`]: util.md#utilinspectcustom
38923906
[`util.isArray()`]: util.md#utilisarrayobject

doc/api/util.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -364,31 +364,31 @@ util.formatWithOptions({ colors: true }, 'See object %O', { foo: 42 });
364364
// when printed to a terminal.
365365
```
366366

367-
## `util.getCallSite(frames)`
367+
## `util.getCallSites(frameCount)`
368368

369369
> Stability: 1.1 - Active development
370370
371371
<!-- YAML
372372
added: v22.9.0
373373
-->
374374

375-
* `frames` {number} Number of frames returned in the stacktrace.
375+
* `frameCount` {number} Number of frames to capture as call site objects.
376376
**Default:** `10`. Allowable range is between 1 and 200.
377-
* Returns: {Object\[]} An array of stacktrace objects
378-
* `functionName` {string} Returns the name of the function associated with this stack frame.
377+
* Returns: {Object\[]} An array of call site objects
378+
* `functionName` {string} Returns the name of the function associated with this call site.
379379
* `scriptName` {string} Returns the name of the resource that contains the script for the
380-
function for this StackFrame.
380+
function for this call site.
381381
* `lineNumber` {number} Returns the number, 1-based, of the line for the associate function call.
382382
* `column` {number} Returns the 1-based column offset on the line for the associated function call.
383383

384-
Returns an array of stacktrace objects containing the stack of
384+
Returns an array of call site objects containing the stack of
385385
the caller function.
386386

387387
```js
388388
const util = require('node:util');
389389

390390
function exampleFunction() {
391-
const callSites = util.getCallSite();
391+
const callSites = util.getCallSites();
392392

393393
console.log('Call Sites:');
394394
callSites.forEach((callSite, index) => {

lib/util.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -330,13 +330,13 @@ function parseEnv(content) {
330330

331331
/**
332332
* Returns the callSite
333-
* @param {number} frames
333+
* @param {number} frameCount
334334
* @returns {object}
335335
*/
336-
function getCallSite(frames = 10) {
336+
function getCallSites(frameCount = 10) {
337337
// Using kDefaultMaxCallStackSizeToCapture as reference
338-
validateNumber(frames, 'frames', 1, 200);
339-
return binding.getCallSite(frames);
338+
validateNumber(frameCount, 'frameCount', 1, 200);
339+
return binding.getCallSites(frameCount);
340340
};
341341

342342
// Keep the `exports =` so that various functions can still be monkeypatched
@@ -353,7 +353,12 @@ module.exports = {
353353
format,
354354
styleText,
355355
formatWithOptions,
356-
getCallSite,
356+
// Deprecated getCallSite. No deprecation code as `util.getCallSite` was in active development.
357+
// This API can be removed in next semver-minor release.
358+
getCallSite: deprecate(getCallSites,
359+
'The `util.getCallSite` API is deprecated. Please use `util.getCallSites()` instead.',
360+
'DEP0186'),
361+
getCallSites,
357362
getSystemErrorMap,
358363
getSystemErrorName,
359364
getSystemErrorMessage,

src/node_util.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ static void ParseEnv(const FunctionCallbackInfo<Value>& args) {
247247
args.GetReturnValue().Set(dotenv.ToObject(env));
248248
}
249249

250-
static void GetCallSite(const FunctionCallbackInfo<Value>& args) {
250+
static void GetCallSites(const FunctionCallbackInfo<Value>& args) {
251251
Environment* env = Environment::GetCurrent(args);
252252
Isolate* isolate = env->isolate();
253253

@@ -345,7 +345,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
345345
registry->Register(GetProxyDetails);
346346
registry->Register(GetCallerLocation);
347347
registry->Register(PreviewEntries);
348-
registry->Register(GetCallSite);
348+
registry->Register(GetCallSites);
349349
registry->Register(GetOwnNonIndexProperties);
350350
registry->Register(GetConstructorName);
351351
registry->Register(GetExternalValue);
@@ -451,7 +451,7 @@ void Initialize(Local<Object> target,
451451
SetMethodNoSideEffect(
452452
context, target, "getConstructorName", GetConstructorName);
453453
SetMethodNoSideEffect(context, target, "getExternalValue", GetExternalValue);
454-
SetMethodNoSideEffect(context, target, "getCallSite", GetCallSite);
454+
SetMethodNoSideEffect(context, target, "getCallSites", GetCallSites);
455455
SetMethod(context, target, "sleep", Sleep);
456456
SetMethod(context, target, "parseEnv", ParseEnv);
457457

test/common/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const net = require('net');
3030
// Do not require 'os' until needed so that test-os-checked-function can
3131
// monkey patch it. If 'os' is required here, that test will fail.
3232
const path = require('path');
33-
const { inspect, getCallSite } = require('util');
33+
const { inspect, getCallSites } = require('util');
3434
const { isMainThread } = require('worker_threads');
3535
const { isModuleNamespaceObject } = require('util/types');
3636

@@ -550,7 +550,7 @@ function canCreateSymLink() {
550550
}
551551

552552
function mustNotCall(msg) {
553-
const callSite = getCallSite()[1];
553+
const callSite = getCallSites()[1];
554554
return function mustNotCall(...args) {
555555
const argsInfo = args.length > 0 ?
556556
`\ncalled with arguments: ${args.map((arg) => inspect(arg)).join(', ')}` : '';

test/fixtures/get-call-site.js

-4
This file was deleted.

test/fixtures/get-call-sites.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const util = require('node:util');
2+
const assert = require('node:assert');
3+
assert.ok(util.getCallSites().length > 1);
4+
process.stdout.write(util.getCallSites()[0].scriptName);
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
3+
require('../common');
4+
const { getCallSite } = require('node:util');
5+
const { expectWarning } = require('../common');
6+
7+
const warning = 'The `util.getCallSite` API is deprecated. Please use `util.getCallSites()` instead.';
8+
expectWarning('DeprecationWarning', warning, 'DEP0186');
9+
getCallSite();

test/parallel/test-util-getCallSite.js test/parallel/test-util-getcallsites.js

+25-25
Original file line numberDiff line numberDiff line change
@@ -3,68 +3,68 @@
33
const common = require('../common');
44

55
const fixtures = require('../common/fixtures');
6-
const file = fixtures.path('get-call-site.js');
6+
const file = fixtures.path('get-call-sites.js');
77

8-
const { getCallSite } = require('node:util');
8+
const { getCallSites } = require('node:util');
99
const { spawnSync } = require('node:child_process');
1010
const assert = require('node:assert');
1111

1212
{
13-
const callsite = getCallSite();
14-
assert.ok(callsite.length > 1);
13+
const callSites = getCallSites();
14+
assert.ok(callSites.length > 1);
1515
assert.match(
16-
callsite[0].scriptName,
17-
/test-util-getCallSite/,
16+
callSites[0].scriptName,
17+
/test-util-getcallsites/,
1818
'node:util should be ignored',
1919
);
2020
}
2121

2222
{
23-
const callsite = getCallSite(3);
24-
assert.strictEqual(callsite.length, 3);
23+
const callSites = getCallSites(3);
24+
assert.strictEqual(callSites.length, 3);
2525
assert.match(
26-
callsite[0].scriptName,
27-
/test-util-getCallSite/,
26+
callSites[0].scriptName,
27+
/test-util-getcallsites/,
2828
'node:util should be ignored',
2929
);
3030
}
3131

3232
// Guarantee dot-left numbers are ignored
3333
{
34-
const callsite = getCallSite(3.6);
35-
assert.strictEqual(callsite.length, 3);
34+
const callSites = getCallSites(3.6);
35+
assert.strictEqual(callSites.length, 3);
3636
}
3737

3838
{
39-
const callsite = getCallSite(3.4);
40-
assert.strictEqual(callsite.length, 3);
39+
const callSites = getCallSites(3.4);
40+
assert.strictEqual(callSites.length, 3);
4141
}
4242

4343
{
4444
assert.throws(() => {
4545
// Max than kDefaultMaxCallStackSizeToCapture
46-
getCallSite(201);
46+
getCallSites(201);
4747
}, common.expectsError({
4848
code: 'ERR_OUT_OF_RANGE'
4949
}));
5050
assert.throws(() => {
51-
getCallSite(-1);
51+
getCallSites(-1);
5252
}, common.expectsError({
5353
code: 'ERR_OUT_OF_RANGE'
5454
}));
5555
assert.throws(() => {
56-
getCallSite({});
56+
getCallSites({});
5757
}, common.expectsError({
5858
code: 'ERR_INVALID_ARG_TYPE'
5959
}));
6060
}
6161

6262
{
63-
const callsite = getCallSite(1);
64-
assert.strictEqual(callsite.length, 1);
63+
const callSites = getCallSites(1);
64+
assert.strictEqual(callSites.length, 1);
6565
assert.match(
66-
callsite[0].scriptName,
67-
/test-util-getCallSite/,
66+
callSites[0].scriptName,
67+
/test-util-getcallsites/,
6868
'node:util should be ignored',
6969
);
7070
}
@@ -77,8 +77,8 @@ const assert = require('node:assert');
7777
'-e',
7878
`const util = require('util');
7979
const assert = require('assert');
80-
assert.ok(util.getCallSite().length > 1);
81-
process.stdout.write(util.getCallSite()[0].scriptName);
80+
assert.ok(util.getCallSites().length > 1);
81+
process.stdout.write(util.getCallSites()[0].scriptName);
8282
`,
8383
],
8484
);
@@ -100,7 +100,7 @@ const assert = require('node:assert');
100100
{
101101
const originalStackTraceLimit = Error.stackTraceLimit;
102102
Error.stackTraceLimit = 0;
103-
const callsite = getCallSite();
104-
assert.notStrictEqual(callsite.length, 0);
103+
const callSites = getCallSites();
104+
assert.notStrictEqual(callSites.length, 0);
105105
Error.stackTraceLimit = originalStackTraceLimit;
106106
}

0 commit comments

Comments
 (0)