Skip to content

Commit db384d1

Browse files
authoredDec 10, 2024··
fix(no-unsupported): Correctly handle recursive objects on a per module basis (#396)
1 parent 1466bec commit db384d1

File tree

2 files changed

+98
-14
lines changed

2 files changed

+98
-14
lines changed
 

‎lib/util/enumerate-property-names.js

+10-12
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@ const unprefixNodeColon = require("./unprefix-node-colon")
1515
* Enumerate property names of a given object recursively.
1616
* @param {TraceMap} traceMap The map for APIs to enumerate.
1717
* @param {string[]} [path] The path to the current map.
18-
* @param {WeakSet<TraceMap>} [recursionSet] A WeakSet used to block recursion (eg Module, Module.Module, Module.Module.Module)
18+
* @param {{ [key: string]: WeakSet<TraceMap> }} [recursion] An object to block recursion (per module)
1919
* @returns {IterableIterator<string>} The property names of the map.
2020
*/
21-
function* enumeratePropertyNames(
22-
traceMap,
23-
path = [],
24-
recursionSet = new WeakSet()
25-
) {
26-
if (recursionSet.has(traceMap)) {
21+
function* enumeratePropertyNames(traceMap, path = [], recursion = {}) {
22+
const recursionSet =
23+
typeof path[0] === "string"
24+
? (recursion[path[0]] ??= new WeakSet())
25+
: undefined
26+
27+
if (recursionSet?.has(traceMap)) {
2728
return
2829
}
2930

@@ -48,11 +49,8 @@ function* enumeratePropertyNames(
4849
yield childName
4950
}
5051

51-
yield* enumeratePropertyNames(
52-
childValue,
53-
childPath,
54-
recursionSet.add(traceMap)
55-
)
52+
recursionSet?.add(traceMap)
53+
yield* enumeratePropertyNames(childValue, childPath, recursion)
5654
}
5755
}
5856

‎tests/lib/rules/no-unsupported-features/node-builtins.js

+88-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,58 @@
44
*/
55
"use strict"
66

7+
/** @import { Linter } from 'eslint' */
8+
79
const RuleTester = require("../../../test-helpers").RuleTester
810
const rule = require("../../../../lib/rules/no-unsupported-features/node-builtins")
911

12+
/**
13+
* @typedef ValidTestCase
14+
* @property {string} [name]
15+
* @property {string} code
16+
* @property {any} [options]
17+
* @property {string | undefined} [filename]
18+
* @property {boolean} [only]
19+
* @property {Linter.LanguageOptions | undefined} [languageOptions]
20+
* @property {{ [name: string]: any } | undefined} [settings]
21+
*/
22+
/**
23+
* @typedef SuggestionOutput
24+
* @property {string} [messageId]
25+
* @property {string} [desc]
26+
* @property {Record<string, unknown> | undefined} [data]
27+
* @property {string} output
28+
*/
29+
/**
30+
* @typedef InvalidTestExtras
31+
* @property {number | Array<TestCaseError | string>} errors
32+
* @property {string | null | undefined} [output]
33+
*/
34+
/**
35+
* @typedef {ValidTestCase & InvalidTestExtras} InvalidTestCase
36+
*/
37+
/**
38+
* @typedef TestCaseError
39+
* @property {string | RegExp} [message]
40+
* @property {string} [messageId]
41+
* @property {string | undefined} [type]
42+
* @property {any} [data]
43+
* @property {number | undefined} [line]
44+
* @property {number | undefined} [column]
45+
* @property {number | undefined} [endLine]
46+
* @property {number | undefined} [endColumn]
47+
* @property {SuggestionOutput[] | undefined} [suggestions]
48+
*/
49+
/**
50+
* @typedef Pattern
51+
* @property {ValidTestCase[]} [valid]
52+
* @property {InvalidTestCase[]} [invalid]
53+
*/
54+
1055
/**
1156
* Concatenate patterns.
12-
* @param {Array<{valid:Array,invalid:Array}>} patterns The patterns to concat.
13-
* @returns {{valid:Array,invalid:Array}} The concatenated patterns.
57+
* @param {Pattern[]} patterns The patterns to concat.
58+
* @returns {Pattern} The concatenated patterns.
1459
*/
1560
function concat(patterns) {
1661
const ret = {
@@ -5372,6 +5417,47 @@ new RuleTester({ languageOptions: { sourceType: "module" } }).run(
53725417
],
53735418
},
53745419

5420+
//----------------------------------------------------------------------
5421+
// timers/promises
5422+
//----------------------------------------------------------------------
5423+
{
5424+
valid: [
5425+
{
5426+
code: `
5427+
import { scheduler } from 'node:timers/promises';
5428+
await scheduler.wait( 1000 );
5429+
`,
5430+
options: [
5431+
{
5432+
version: ">= 20.0.0",
5433+
ignores: ["timers/promises.scheduler.wait"],
5434+
},
5435+
],
5436+
languageOptions: { ecmaVersion: "latest" },
5437+
},
5438+
],
5439+
invalid: [
5440+
{
5441+
code: `
5442+
import { scheduler } from 'node:timers/promises';
5443+
await scheduler.wait( 1000 );
5444+
`,
5445+
options: [{ version: ">= 20.0.0" }],
5446+
languageOptions: { ecmaVersion: "latest" },
5447+
5448+
errors: [
5449+
{
5450+
messageId: "not-supported-yet",
5451+
data: {
5452+
name: "timers/promises.scheduler.wait",
5453+
version: ">= 20.0.0",
5454+
},
5455+
},
5456+
],
5457+
},
5458+
],
5459+
},
5460+
53755461
{
53765462
valid: [
53775463
{

0 commit comments

Comments
 (0)
Please sign in to comment.