@fedify/lint 2.4.0-dev.2141 → 2.4.0-dev.2155

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/deno.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/lint",
3
- "version": "2.4.0-dev.2141+881cc858",
3
+ "version": "2.4.0-dev.2155+2ccc5085",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./src/mod.ts",
package/dist/index.cjs CHANGED
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  enumerable: true
25
25
  }) : target, mod));
26
26
  //#endregion
27
- const require_outbox_listener_delivery_required = require("./outbox-listener-delivery-required-DOT5R6Fg.cjs");
27
+ const require_outbox_listener_delivery_required = require("./outbox-listener-delivery-required-rhAvEA9G.cjs");
28
28
  let _fxts_core = require("@fxts/core");
29
29
  let _typescript_eslint_parser = require("@typescript-eslint/parser");
30
30
  _typescript_eslint_parser = __toESM(_typescript_eslint_parser, 1);
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as name, C as eslint$5, D as eslint$11, E as eslint$10, O as eslint$21, S as eslint$4, T as eslint$13, _ as eslint$15, a as eslint$23, b as eslint$2, c as eslint$16, d as eslint$22, f as eslint$6, g as eslint$14, h as eslint$9, i as eslint$27, j as version, k as RULE_IDS, l as eslint$17, m as eslint$8, n as eslint$25, o as eslint$18, p as eslint$7, r as eslint$26, s as eslint$19, t as eslint$24, u as eslint$20, v as eslint$1, w as eslint$12, x as eslint$3, y as eslint } from "./outbox-listener-delivery-required-Cj8oaGNC.js";
1
+ import { A as name, C as eslint$5, D as eslint$11, E as eslint$10, O as eslint$21, S as eslint$4, T as eslint$13, _ as eslint$15, a as eslint$23, b as eslint$2, c as eslint$16, d as eslint$22, f as eslint$6, g as eslint$14, h as eslint$9, i as eslint$27, j as version, k as RULE_IDS, l as eslint$17, m as eslint$8, n as eslint$25, o as eslint$18, p as eslint$7, r as eslint$26, s as eslint$19, t as eslint$24, u as eslint$20, v as eslint$1, w as eslint$12, x as eslint$3, y as eslint } from "./outbox-listener-delivery-required-vNt3zM_a.js";
2
2
  import { fromEntries, keys, map, pipe } from "@fxts/core";
3
3
  import parser from "@typescript-eslint/parser";
4
4
  //#region src/index.ts
@@ -1,7 +1,7 @@
1
1
  let _fxts_core = require("@fxts/core");
2
2
  //#region deno.json
3
3
  var name = "@fedify/lint";
4
- var version = "2.4.0-dev.2141+881cc858";
4
+ var version = "2.4.0-dev.2155+2ccc5085";
5
5
  //#endregion
6
6
  //#region src/lib/const.ts
7
7
  /**
@@ -1324,6 +1324,10 @@ function getAssignmentTargetName(target) {
1324
1324
  function collectBoundNames(pattern, out) {
1325
1325
  if (pattern == null || typeof pattern !== "object" || !isNode(pattern)) return;
1326
1326
  const p = pattern;
1327
+ if (p.type === "TSParameterProperty") {
1328
+ collectBoundNames(p.parameter, out);
1329
+ return;
1330
+ }
1327
1331
  switch (p.type) {
1328
1332
  case "Identifier":
1329
1333
  out.push(p.name);
@@ -1343,6 +1347,84 @@ function collectBoundNames(pattern, out) {
1343
1347
  }
1344
1348
  }
1345
1349
  /**
1350
+ * Every name the function scope rooted at `root` binds or rebinds anywhere,
1351
+ * reachable or not: `fn`'s parameters and own name, any declaration (in a
1352
+ * block, a loop head, a `catch` clause, a class static block or a TypeScript
1353
+ * enum too), and any assignment or update of the name itself. Does not
1354
+ * descend into a nested function's body. Deliberately broad, since a name
1355
+ * outside this set is taken to be an enclosing scope's binding throughout
1356
+ * `root`.
1357
+ */
1358
+ function collectScopeBoundNames(root, fn) {
1359
+ const names = /* @__PURE__ */ new Set();
1360
+ const add = (pattern) => {
1361
+ const bound = [];
1362
+ collectBoundNames(pattern, bound);
1363
+ for (const name of bound) names.add(name);
1364
+ };
1365
+ const addAssigned = (target) => {
1366
+ let current = target;
1367
+ while (isNode(current) && TS_EXPRESSION_WRAPPERS.has(current.type)) current = current.expression;
1368
+ add(current);
1369
+ };
1370
+ for (const param of fn?.params ?? []) add(param);
1371
+ if (fn?.type === "FunctionExpression") add(fn.id);
1372
+ const visit = (node) => {
1373
+ if (node == null || typeof node !== "object") return;
1374
+ if (Array.isArray(node)) {
1375
+ for (const item of node) visit(item);
1376
+ return;
1377
+ }
1378
+ if (!isNode(node)) return;
1379
+ const record = node;
1380
+ switch (node.type) {
1381
+ case "FunctionDeclaration":
1382
+ case "TSDeclareFunction":
1383
+ add(record.id);
1384
+ return;
1385
+ case "FunctionExpression":
1386
+ case "ArrowFunctionExpression": return;
1387
+ case "ClassDeclaration":
1388
+ case "ClassExpression":
1389
+ case "VariableDeclarator":
1390
+ case "TSEnumDeclaration":
1391
+ case "TSModuleDeclaration":
1392
+ case "TSImportEqualsDeclaration":
1393
+ add(record.id);
1394
+ break;
1395
+ case "TSEnumMember": {
1396
+ const id = record.id;
1397
+ if (id.type === "Identifier") names.add(id.name);
1398
+ else if (id.type === "Literal" && typeof id.value === "string") names.add(id.value);
1399
+ break;
1400
+ }
1401
+ case "CatchClause":
1402
+ add(record.param);
1403
+ break;
1404
+ case "AssignmentExpression":
1405
+ addAssigned(record.left);
1406
+ break;
1407
+ case "UpdateExpression":
1408
+ addAssigned(record.argument);
1409
+ break;
1410
+ case "ForInStatement":
1411
+ case "ForOfStatement":
1412
+ addAssigned(record.left);
1413
+ break;
1414
+ }
1415
+ for (const key in record) if (key !== "parent") visit(record[key]);
1416
+ };
1417
+ for (const param of fn?.params ?? []) visit(param);
1418
+ visit(root);
1419
+ return names;
1420
+ }
1421
+ const TS_EXPRESSION_WRAPPERS = /* @__PURE__ */ new Set([
1422
+ "TSAsExpression",
1423
+ "TSNonNullExpression",
1424
+ "TSSatisfiesExpression",
1425
+ "TSTypeAssertion"
1426
+ ]);
1427
+ /**
1346
1428
  * Finds the function literals a value holds itself: the value is the
1347
1429
  * function, or it sits in an object or array literal, a conditional, or a
1348
1430
  * class body. Stops at a call, so a function handed to one as an argument,
@@ -1378,12 +1460,15 @@ function collectHeldFunctions(node, out) {
1378
1460
  * function. Does not descend into a found function's own body: a name bound
1379
1461
  * inside it is only found once that function is itself resolved as
1380
1462
  * reachable, so it can be layered on top of (and correctly shadow) the outer
1381
- * scope's names.
1463
+ * scope's names. What goes into `augmentingAssignments` instead of `out`
1464
+ * extends the names' enclosing candidates rather than shadowing them: an
1465
+ * assignment-form loop default, and a property write through an object that
1466
+ * this scope inherits (a name not in `localNames`).
1382
1467
  */
1383
- function collectFunctionsByName(node, out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations) {
1468
+ function collectFunctionsByName(node, out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames) {
1384
1469
  if (node == null || typeof node !== "object") return;
1385
1470
  if (Array.isArray(node)) {
1386
- for (const item of node) collectFunctionsByName(item, out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations);
1471
+ for (const item of node) collectFunctionsByName(item, out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1387
1472
  return;
1388
1473
  }
1389
1474
  if (!isNode(node)) return;
@@ -1404,7 +1489,7 @@ function collectFunctionsByName(node, out, assignmentDefaults, declarationPatter
1404
1489
  }
1405
1490
  if (isFunctionLikeNode(n)) return;
1406
1491
  if (n.type === "StaticBlock") {
1407
- collectFunctionsByName(n.body, out, assignmentDefaults, declarationPatterns, /* @__PURE__ */ new Set(), scopeDeclarations);
1492
+ collectFunctionsByName(n.body, out, augmentingAssignments, declarationPatterns, /* @__PURE__ */ new Set(), scopeDeclarations, localNames);
1408
1493
  return;
1409
1494
  }
1410
1495
  if (n.type === "VariableDeclaration") {
@@ -1413,7 +1498,7 @@ function collectFunctionsByName(node, out, assignmentDefaults, declarationPatter
1413
1498
  collectBoundNames(decl.id, names);
1414
1499
  for (const name of names) declaredHere.add(name);
1415
1500
  }
1416
- for (const decl of n.declarations) collectFunctionsByName(decl, out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations);
1501
+ for (const decl of n.declarations) collectFunctionsByName(decl, out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1417
1502
  return;
1418
1503
  }
1419
1504
  if (n.type === "VariableDeclarator") {
@@ -1422,7 +1507,7 @@ function collectFunctionsByName(node, out, assignmentDefaults, declarationPatter
1422
1507
  collectBoundNames(decl.id, names);
1423
1508
  if (decl.init != null) {
1424
1509
  bindTo(names, decl.init);
1425
- collectFunctionsByName(decl.init, out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations);
1510
+ collectFunctionsByName(decl.init, out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1426
1511
  }
1427
1512
  return;
1428
1513
  }
@@ -1432,20 +1517,20 @@ function collectFunctionsByName(node, out, assignmentDefaults, declarationPatter
1432
1517
  const name = getAssignmentTargetName(n.left);
1433
1518
  if (name != null) names.push(name);
1434
1519
  } else collectBoundNames(n.left, names);
1435
- bindTo(names, n.right, n.left.type === "MemberExpression" || !declarationPatterns.has(n) ? assignmentDefaults : out);
1436
- collectFunctionsByName(n.right, out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations);
1520
+ bindTo(names, n.right, n.left.type === "MemberExpression" || !declarationPatterns.has(n) ? augmentingAssignments : out);
1521
+ collectFunctionsByName(n.right, out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1437
1522
  return;
1438
1523
  }
1439
1524
  if (n.type === "AssignmentExpression") {
1440
1525
  const name = getAssignmentTargetName(n.left);
1441
- if (name != null) bindTo([name], n.right);
1442
- collectFunctionsByName(n.right, out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations);
1526
+ if (name != null) bindTo([name], n.right, n.left.type === "MemberExpression" && !localNames.has(name) ? augmentingAssignments : out);
1527
+ collectFunctionsByName(n.right, out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1443
1528
  return;
1444
1529
  }
1445
1530
  const record = n;
1446
1531
  for (const key in record) {
1447
1532
  if (key === "parent") continue;
1448
- collectFunctionsByName(record[key], out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations);
1533
+ collectFunctionsByName(record[key], out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1449
1534
  }
1450
1535
  }
1451
1536
  /**
@@ -1484,7 +1569,7 @@ function collectNestedFunctions(node, out) {
1484
1569
  function walkUsedScopes(root, visit) {
1485
1570
  const used = /* @__PURE__ */ new Set();
1486
1571
  const visited = /* @__PURE__ */ new Set();
1487
- const processScope = (scopeRoot, scopeFn, outerFunctionsByName) => {
1572
+ const processScope = (scopeRoot, scopeFn, outerFunctionsByName, outerStaleNames) => {
1488
1573
  if (visited.has(scopeRoot)) return;
1489
1574
  visited.add(scopeRoot);
1490
1575
  const statements = [];
@@ -1495,17 +1580,20 @@ function walkUsedScopes(root, visit) {
1495
1580
  declaredHere
1496
1581
  });
1497
1582
  const functionsHere = /* @__PURE__ */ new Map();
1498
- const assignmentDefaultsHere = /* @__PURE__ */ new Map();
1583
+ const augmentingAssignmentsHere = /* @__PURE__ */ new Map();
1499
1584
  for (const param of scopeFn?.params ?? []) {
1500
1585
  const names = [];
1501
1586
  collectBoundNames(param, names);
1502
1587
  for (const name of names) functionsHere.set(name, []);
1503
1588
  }
1504
1589
  const scopeDeclarations = new Set(scopeRoot.type === "BlockStatement" ? scopeRoot.body : []);
1505
- for (const statement of statements) collectFunctionsByName(statement, functionsHere, assignmentDefaultsHere, declarationPatterns, declaredHere, scopeDeclarations);
1590
+ const scopeBoundNames = collectScopeBoundNames(scopeRoot, scopeFn);
1591
+ const localNames = /* @__PURE__ */ new Set([...scopeBoundNames, ...outerStaleNames]);
1592
+ for (const statement of statements) collectFunctionsByName(statement, functionsHere, augmentingAssignmentsHere, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1593
+ const staleNames = new Set([...localNames].filter((name) => !functionsHere.has(name)));
1506
1594
  const functionsByName = new Map(outerFunctionsByName);
1507
1595
  for (const [name, functions] of functionsHere) functionsByName.set(name, functions);
1508
- for (const [name, functions] of assignmentDefaultsHere) {
1596
+ for (const [name, functions] of augmentingAssignmentsHere) {
1509
1597
  const base = declaredHere.has(name) ? functionsHere.get(name) ?? [] : functionsByName.get(name) ?? [];
1510
1598
  functionsByName.set(name, [...base, ...functions]);
1511
1599
  }
@@ -1522,7 +1610,7 @@ function walkUsedScopes(root, visit) {
1522
1610
  for (const fn of functions) reached.add(fn);
1523
1611
  }
1524
1612
  const held = /* @__PURE__ */ new Set();
1525
- for (const bindings of [functionsHere, assignmentDefaultsHere]) for (const functions of bindings.values()) for (const fn of functions) held.add(fn);
1613
+ for (const bindings of [functionsHere, augmentingAssignmentsHere]) for (const functions of bindings.values()) for (const fn of functions) held.add(fn);
1526
1614
  for (const statement of statements) {
1527
1615
  const nested = [];
1528
1616
  collectNestedFunctions(statement, nested);
@@ -1530,10 +1618,10 @@ function walkUsedScopes(root, visit) {
1530
1618
  }
1531
1619
  for (const reachedFn of reached) {
1532
1620
  used.add(reachedFn);
1533
- processScope(reachedFn.body, reachedFn, functionsByName);
1621
+ processScope(reachedFn.body, reachedFn, functionsByName, staleNames);
1534
1622
  }
1535
1623
  };
1536
- processScope(root, null, /* @__PURE__ */ new Map());
1624
+ processScope(root, null, /* @__PURE__ */ new Map(), /* @__PURE__ */ new Set());
1537
1625
  return used;
1538
1626
  }
1539
1627
  /**
@@ -1,7 +1,7 @@
1
1
  import { always, every, head, isEmpty, isObject, negate, pipe, pipeLazy, prop, some, toArray, unless, when } from "@fxts/core";
2
2
  //#region deno.json
3
3
  var name = "@fedify/lint";
4
- var version = "2.4.0-dev.2141+881cc858";
4
+ var version = "2.4.0-dev.2155+2ccc5085";
5
5
  //#endregion
6
6
  //#region src/lib/const.ts
7
7
  /**
@@ -1324,6 +1324,10 @@ function getAssignmentTargetName(target) {
1324
1324
  function collectBoundNames(pattern, out) {
1325
1325
  if (pattern == null || typeof pattern !== "object" || !isNode(pattern)) return;
1326
1326
  const p = pattern;
1327
+ if (p.type === "TSParameterProperty") {
1328
+ collectBoundNames(p.parameter, out);
1329
+ return;
1330
+ }
1327
1331
  switch (p.type) {
1328
1332
  case "Identifier":
1329
1333
  out.push(p.name);
@@ -1343,6 +1347,84 @@ function collectBoundNames(pattern, out) {
1343
1347
  }
1344
1348
  }
1345
1349
  /**
1350
+ * Every name the function scope rooted at `root` binds or rebinds anywhere,
1351
+ * reachable or not: `fn`'s parameters and own name, any declaration (in a
1352
+ * block, a loop head, a `catch` clause, a class static block or a TypeScript
1353
+ * enum too), and any assignment or update of the name itself. Does not
1354
+ * descend into a nested function's body. Deliberately broad, since a name
1355
+ * outside this set is taken to be an enclosing scope's binding throughout
1356
+ * `root`.
1357
+ */
1358
+ function collectScopeBoundNames(root, fn) {
1359
+ const names = /* @__PURE__ */ new Set();
1360
+ const add = (pattern) => {
1361
+ const bound = [];
1362
+ collectBoundNames(pattern, bound);
1363
+ for (const name of bound) names.add(name);
1364
+ };
1365
+ const addAssigned = (target) => {
1366
+ let current = target;
1367
+ while (isNode(current) && TS_EXPRESSION_WRAPPERS.has(current.type)) current = current.expression;
1368
+ add(current);
1369
+ };
1370
+ for (const param of fn?.params ?? []) add(param);
1371
+ if (fn?.type === "FunctionExpression") add(fn.id);
1372
+ const visit = (node) => {
1373
+ if (node == null || typeof node !== "object") return;
1374
+ if (Array.isArray(node)) {
1375
+ for (const item of node) visit(item);
1376
+ return;
1377
+ }
1378
+ if (!isNode(node)) return;
1379
+ const record = node;
1380
+ switch (node.type) {
1381
+ case "FunctionDeclaration":
1382
+ case "TSDeclareFunction":
1383
+ add(record.id);
1384
+ return;
1385
+ case "FunctionExpression":
1386
+ case "ArrowFunctionExpression": return;
1387
+ case "ClassDeclaration":
1388
+ case "ClassExpression":
1389
+ case "VariableDeclarator":
1390
+ case "TSEnumDeclaration":
1391
+ case "TSModuleDeclaration":
1392
+ case "TSImportEqualsDeclaration":
1393
+ add(record.id);
1394
+ break;
1395
+ case "TSEnumMember": {
1396
+ const id = record.id;
1397
+ if (id.type === "Identifier") names.add(id.name);
1398
+ else if (id.type === "Literal" && typeof id.value === "string") names.add(id.value);
1399
+ break;
1400
+ }
1401
+ case "CatchClause":
1402
+ add(record.param);
1403
+ break;
1404
+ case "AssignmentExpression":
1405
+ addAssigned(record.left);
1406
+ break;
1407
+ case "UpdateExpression":
1408
+ addAssigned(record.argument);
1409
+ break;
1410
+ case "ForInStatement":
1411
+ case "ForOfStatement":
1412
+ addAssigned(record.left);
1413
+ break;
1414
+ }
1415
+ for (const key in record) if (key !== "parent") visit(record[key]);
1416
+ };
1417
+ for (const param of fn?.params ?? []) visit(param);
1418
+ visit(root);
1419
+ return names;
1420
+ }
1421
+ const TS_EXPRESSION_WRAPPERS = /* @__PURE__ */ new Set([
1422
+ "TSAsExpression",
1423
+ "TSNonNullExpression",
1424
+ "TSSatisfiesExpression",
1425
+ "TSTypeAssertion"
1426
+ ]);
1427
+ /**
1346
1428
  * Finds the function literals a value holds itself: the value is the
1347
1429
  * function, or it sits in an object or array literal, a conditional, or a
1348
1430
  * class body. Stops at a call, so a function handed to one as an argument,
@@ -1378,12 +1460,15 @@ function collectHeldFunctions(node, out) {
1378
1460
  * function. Does not descend into a found function's own body: a name bound
1379
1461
  * inside it is only found once that function is itself resolved as
1380
1462
  * reachable, so it can be layered on top of (and correctly shadow) the outer
1381
- * scope's names.
1463
+ * scope's names. What goes into `augmentingAssignments` instead of `out`
1464
+ * extends the names' enclosing candidates rather than shadowing them: an
1465
+ * assignment-form loop default, and a property write through an object that
1466
+ * this scope inherits (a name not in `localNames`).
1382
1467
  */
1383
- function collectFunctionsByName(node, out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations) {
1468
+ function collectFunctionsByName(node, out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames) {
1384
1469
  if (node == null || typeof node !== "object") return;
1385
1470
  if (Array.isArray(node)) {
1386
- for (const item of node) collectFunctionsByName(item, out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations);
1471
+ for (const item of node) collectFunctionsByName(item, out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1387
1472
  return;
1388
1473
  }
1389
1474
  if (!isNode(node)) return;
@@ -1404,7 +1489,7 @@ function collectFunctionsByName(node, out, assignmentDefaults, declarationPatter
1404
1489
  }
1405
1490
  if (isFunctionLikeNode(n)) return;
1406
1491
  if (n.type === "StaticBlock") {
1407
- collectFunctionsByName(n.body, out, assignmentDefaults, declarationPatterns, /* @__PURE__ */ new Set(), scopeDeclarations);
1492
+ collectFunctionsByName(n.body, out, augmentingAssignments, declarationPatterns, /* @__PURE__ */ new Set(), scopeDeclarations, localNames);
1408
1493
  return;
1409
1494
  }
1410
1495
  if (n.type === "VariableDeclaration") {
@@ -1413,7 +1498,7 @@ function collectFunctionsByName(node, out, assignmentDefaults, declarationPatter
1413
1498
  collectBoundNames(decl.id, names);
1414
1499
  for (const name of names) declaredHere.add(name);
1415
1500
  }
1416
- for (const decl of n.declarations) collectFunctionsByName(decl, out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations);
1501
+ for (const decl of n.declarations) collectFunctionsByName(decl, out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1417
1502
  return;
1418
1503
  }
1419
1504
  if (n.type === "VariableDeclarator") {
@@ -1422,7 +1507,7 @@ function collectFunctionsByName(node, out, assignmentDefaults, declarationPatter
1422
1507
  collectBoundNames(decl.id, names);
1423
1508
  if (decl.init != null) {
1424
1509
  bindTo(names, decl.init);
1425
- collectFunctionsByName(decl.init, out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations);
1510
+ collectFunctionsByName(decl.init, out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1426
1511
  }
1427
1512
  return;
1428
1513
  }
@@ -1432,20 +1517,20 @@ function collectFunctionsByName(node, out, assignmentDefaults, declarationPatter
1432
1517
  const name = getAssignmentTargetName(n.left);
1433
1518
  if (name != null) names.push(name);
1434
1519
  } else collectBoundNames(n.left, names);
1435
- bindTo(names, n.right, n.left.type === "MemberExpression" || !declarationPatterns.has(n) ? assignmentDefaults : out);
1436
- collectFunctionsByName(n.right, out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations);
1520
+ bindTo(names, n.right, n.left.type === "MemberExpression" || !declarationPatterns.has(n) ? augmentingAssignments : out);
1521
+ collectFunctionsByName(n.right, out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1437
1522
  return;
1438
1523
  }
1439
1524
  if (n.type === "AssignmentExpression") {
1440
1525
  const name = getAssignmentTargetName(n.left);
1441
- if (name != null) bindTo([name], n.right);
1442
- collectFunctionsByName(n.right, out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations);
1526
+ if (name != null) bindTo([name], n.right, n.left.type === "MemberExpression" && !localNames.has(name) ? augmentingAssignments : out);
1527
+ collectFunctionsByName(n.right, out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1443
1528
  return;
1444
1529
  }
1445
1530
  const record = n;
1446
1531
  for (const key in record) {
1447
1532
  if (key === "parent") continue;
1448
- collectFunctionsByName(record[key], out, assignmentDefaults, declarationPatterns, declaredHere, scopeDeclarations);
1533
+ collectFunctionsByName(record[key], out, augmentingAssignments, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1449
1534
  }
1450
1535
  }
1451
1536
  /**
@@ -1484,7 +1569,7 @@ function collectNestedFunctions(node, out) {
1484
1569
  function walkUsedScopes(root, visit) {
1485
1570
  const used = /* @__PURE__ */ new Set();
1486
1571
  const visited = /* @__PURE__ */ new Set();
1487
- const processScope = (scopeRoot, scopeFn, outerFunctionsByName) => {
1572
+ const processScope = (scopeRoot, scopeFn, outerFunctionsByName, outerStaleNames) => {
1488
1573
  if (visited.has(scopeRoot)) return;
1489
1574
  visited.add(scopeRoot);
1490
1575
  const statements = [];
@@ -1495,17 +1580,20 @@ function walkUsedScopes(root, visit) {
1495
1580
  declaredHere
1496
1581
  });
1497
1582
  const functionsHere = /* @__PURE__ */ new Map();
1498
- const assignmentDefaultsHere = /* @__PURE__ */ new Map();
1583
+ const augmentingAssignmentsHere = /* @__PURE__ */ new Map();
1499
1584
  for (const param of scopeFn?.params ?? []) {
1500
1585
  const names = [];
1501
1586
  collectBoundNames(param, names);
1502
1587
  for (const name of names) functionsHere.set(name, []);
1503
1588
  }
1504
1589
  const scopeDeclarations = new Set(scopeRoot.type === "BlockStatement" ? scopeRoot.body : []);
1505
- for (const statement of statements) collectFunctionsByName(statement, functionsHere, assignmentDefaultsHere, declarationPatterns, declaredHere, scopeDeclarations);
1590
+ const scopeBoundNames = collectScopeBoundNames(scopeRoot, scopeFn);
1591
+ const localNames = /* @__PURE__ */ new Set([...scopeBoundNames, ...outerStaleNames]);
1592
+ for (const statement of statements) collectFunctionsByName(statement, functionsHere, augmentingAssignmentsHere, declarationPatterns, declaredHere, scopeDeclarations, localNames);
1593
+ const staleNames = new Set([...localNames].filter((name) => !functionsHere.has(name)));
1506
1594
  const functionsByName = new Map(outerFunctionsByName);
1507
1595
  for (const [name, functions] of functionsHere) functionsByName.set(name, functions);
1508
- for (const [name, functions] of assignmentDefaultsHere) {
1596
+ for (const [name, functions] of augmentingAssignmentsHere) {
1509
1597
  const base = declaredHere.has(name) ? functionsHere.get(name) ?? [] : functionsByName.get(name) ?? [];
1510
1598
  functionsByName.set(name, [...base, ...functions]);
1511
1599
  }
@@ -1522,7 +1610,7 @@ function walkUsedScopes(root, visit) {
1522
1610
  for (const fn of functions) reached.add(fn);
1523
1611
  }
1524
1612
  const held = /* @__PURE__ */ new Set();
1525
- for (const bindings of [functionsHere, assignmentDefaultsHere]) for (const functions of bindings.values()) for (const fn of functions) held.add(fn);
1613
+ for (const bindings of [functionsHere, augmentingAssignmentsHere]) for (const functions of bindings.values()) for (const fn of functions) held.add(fn);
1526
1614
  for (const statement of statements) {
1527
1615
  const nested = [];
1528
1616
  collectNestedFunctions(statement, nested);
@@ -1530,10 +1618,10 @@ function walkUsedScopes(root, visit) {
1530
1618
  }
1531
1619
  for (const reachedFn of reached) {
1532
1620
  used.add(reachedFn);
1533
- processScope(reachedFn.body, reachedFn, functionsByName);
1621
+ processScope(reachedFn.body, reachedFn, functionsByName, staleNames);
1534
1622
  }
1535
1623
  };
1536
- processScope(root, null, /* @__PURE__ */ new Map());
1624
+ processScope(root, null, /* @__PURE__ */ new Map(), /* @__PURE__ */ new Set());
1537
1625
  return used;
1538
1626
  }
1539
1627
  /**
package/dist/oxlint.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_outbox_listener_delivery_required = require("./outbox-listener-delivery-required-DOT5R6Fg.cjs");
1
+ const require_outbox_listener_delivery_required = require("./outbox-listener-delivery-required-rhAvEA9G.cjs");
2
2
  //#region src/oxlint.ts
3
3
  const rules = {
4
4
  [require_outbox_listener_delivery_required.RULE_IDS.actorIdMismatch]: require_outbox_listener_delivery_required.eslint$18,
package/dist/oxlint.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as name, C as eslint$5, D as eslint$11, E as eslint$10, O as eslint$21, S as eslint$4, T as eslint$13, _ as eslint$15, a as eslint$23, b as eslint$2, c as eslint$16, d as eslint$22, f as eslint$6, g as eslint$14, h as eslint$9, i as eslint$27, j as version, k as RULE_IDS, l as eslint$17, m as eslint$8, n as eslint$25, o as eslint$18, p as eslint$7, r as eslint$26, s as eslint$19, t as eslint$24, u as eslint$20, v as eslint$1, w as eslint$12, x as eslint$3, y as eslint } from "./outbox-listener-delivery-required-Cj8oaGNC.js";
1
+ import { A as name, C as eslint$5, D as eslint$11, E as eslint$10, O as eslint$21, S as eslint$4, T as eslint$13, _ as eslint$15, a as eslint$23, b as eslint$2, c as eslint$16, d as eslint$22, f as eslint$6, g as eslint$14, h as eslint$9, i as eslint$27, j as version, k as RULE_IDS, l as eslint$17, m as eslint$8, n as eslint$25, o as eslint$18, p as eslint$7, r as eslint$26, s as eslint$19, t as eslint$24, u as eslint$20, v as eslint$1, w as eslint$12, x as eslint$3, y as eslint } from "./outbox-listener-delivery-required-vNt3zM_a.js";
2
2
  //#region src/oxlint.ts
3
3
  const rules = {
4
4
  [RULE_IDS.actorIdMismatch]: eslint,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/lint",
3
- "version": "2.4.0-dev.2141+881cc858",
3
+ "version": "2.4.0-dev.2155+2ccc5085",
4
4
  "description": "Fedify linting rules and plugins",
5
5
  "keywords": [
6
6
  "Fedify",
@@ -51,7 +51,7 @@
51
51
  ],
52
52
  "peerDependencies": {
53
53
  "eslint": ">=9.0.0",
54
- "@fedify/fedify": "^2.4.0-dev.2141+881cc858"
54
+ "@fedify/fedify": "^2.4.0-dev.2155+2ccc5085"
55
55
  },
56
56
  "peerDependenciesMeta": {
57
57
  "eslint": {
@@ -71,7 +71,7 @@
71
71
  "tsdown": "^0.22.0",
72
72
  "typescript": "^6.0.0",
73
73
  "@fedify/fixture": "2.0.0",
74
- "@fedify/vocab": "2.4.0-dev.2141+881cc858"
74
+ "@fedify/vocab": "2.4.0-dev.2155+2ccc5085"
75
75
  },
76
76
  "scripts": {
77
77
  "build:self": "tsdown",