eslint-plugin-code-style 1.6.1 → 1.6.6
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/CHANGELOG.md +45 -0
- package/index.js +293 -27
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [1.6.6] - 2026-02-01
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **`component-props-destructure`** - Detect body destructuring patterns (e.g., `const { name } = data;`) even without type annotations
|
|
15
|
+
- **`component-props-destructure`** - Add auto-fix for body destructuring: moves props to parameter and removes body declaration
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## [1.6.5] - 2026-02-01
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **`function-object-destructure`** - Add auto-fix: replaces destructured usages with dot notation and removes declaration
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## [1.6.4] - 2026-02-01
|
|
28
|
+
|
|
29
|
+
### Enhanced
|
|
30
|
+
|
|
31
|
+
- **`function-object-destructure`** - Add more module paths: apis, configs, utilities, routes
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## [1.6.3] - 2026-02-01
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- **`component-props-destructure`** - Preserve TypeScript type annotation when auto-fixing
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## [1.6.2] - 2026-02-01
|
|
44
|
+
|
|
45
|
+
### Enhanced
|
|
46
|
+
|
|
47
|
+
- **`function-object-destructure`** - Expand to check more module paths (services, constants, config, api, utils, helpers, lib) for dot notation enforcement
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
10
51
|
## [1.6.1] - 2026-02-01
|
|
11
52
|
|
|
12
53
|
### Enhanced
|
|
@@ -987,6 +1028,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
987
1028
|
|
|
988
1029
|
---
|
|
989
1030
|
|
|
1031
|
+
[1.6.5]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.6.4...v1.6.5
|
|
1032
|
+
[1.6.4]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.6.3...v1.6.4
|
|
1033
|
+
[1.6.3]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.6.2...v1.6.3
|
|
1034
|
+
[1.6.2]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.6.1...v1.6.2
|
|
990
1035
|
[1.6.1]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.6.0...v1.6.1
|
|
991
1036
|
[1.6.0]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.5.2...v1.6.0
|
|
992
1037
|
[1.5.2]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.5.1...v1.5.2
|
package/index.js
CHANGED
|
@@ -12414,15 +12414,32 @@ const functionObjectDestructure = {
|
|
|
12414
12414
|
create(context) {
|
|
12415
12415
|
const sourceCode = context.sourceCode || context.getSourceCode();
|
|
12416
12416
|
|
|
12417
|
-
// Track imports from
|
|
12418
|
-
|
|
12419
|
-
|
|
12420
|
-
|
|
12421
|
-
|
|
12422
|
-
|
|
12423
|
-
|
|
12424
|
-
|
|
12425
|
-
|
|
12417
|
+
// Track imports from module paths that should use dot notation, not destructure
|
|
12418
|
+
// This improves searchability: api.loginHandler is easier to find than loginHandler
|
|
12419
|
+
const moduleImports = new Set();
|
|
12420
|
+
|
|
12421
|
+
// Folders that contain modules which should be accessed via dot notation
|
|
12422
|
+
const modulePathPatterns = [
|
|
12423
|
+
"api",
|
|
12424
|
+
"apis",
|
|
12425
|
+
"config",
|
|
12426
|
+
"configs",
|
|
12427
|
+
"constants",
|
|
12428
|
+
"data",
|
|
12429
|
+
"helpers",
|
|
12430
|
+
"lib",
|
|
12431
|
+
"routes",
|
|
12432
|
+
"services",
|
|
12433
|
+
"utils",
|
|
12434
|
+
"utilities",
|
|
12435
|
+
];
|
|
12436
|
+
|
|
12437
|
+
const isModuleImportPath = (importPath) => {
|
|
12438
|
+
// Match paths like @/services, @/constants, ./data, ../config, etc.
|
|
12439
|
+
return modulePathPatterns.some((pattern) => importPath === `@/${pattern}`
|
|
12440
|
+
|| importPath.endsWith(`/${pattern}`)
|
|
12441
|
+
|| importPath.includes(`/${pattern}/`)
|
|
12442
|
+
|| new RegExp(`^\\.?\\.?/${pattern}$`).test(importPath));
|
|
12426
12443
|
};
|
|
12427
12444
|
|
|
12428
12445
|
const checkImportHandler = (node) => {
|
|
@@ -12430,31 +12447,72 @@ const functionObjectDestructure = {
|
|
|
12430
12447
|
|
|
12431
12448
|
const importPath = node.source.value;
|
|
12432
12449
|
|
|
12433
|
-
if (
|
|
12434
|
-
// Track all imported specifiers from
|
|
12450
|
+
if (isModuleImportPath(importPath)) {
|
|
12451
|
+
// Track all imported specifiers from module paths
|
|
12435
12452
|
node.specifiers.forEach((spec) => {
|
|
12436
12453
|
if (spec.type === "ImportSpecifier" && spec.local && spec.local.name) {
|
|
12437
|
-
|
|
12454
|
+
moduleImports.add(spec.local.name);
|
|
12438
12455
|
} else if (spec.type === "ImportDefaultSpecifier" && spec.local && spec.local.name) {
|
|
12439
|
-
|
|
12456
|
+
moduleImports.add(spec.local.name);
|
|
12440
12457
|
}
|
|
12441
12458
|
});
|
|
12442
12459
|
}
|
|
12443
12460
|
};
|
|
12444
12461
|
|
|
12445
|
-
//
|
|
12462
|
+
// Find all references to a variable name in a scope (with parent tracking)
|
|
12463
|
+
const findAllReferencesHandler = (scope, varName, declNode) => {
|
|
12464
|
+
const references = [];
|
|
12465
|
+
|
|
12466
|
+
const visitNode = (n, parent) => {
|
|
12467
|
+
if (!n || typeof n !== "object") return;
|
|
12468
|
+
|
|
12469
|
+
// Skip the declaration itself
|
|
12470
|
+
if (n === declNode) return;
|
|
12471
|
+
|
|
12472
|
+
// Found a reference
|
|
12473
|
+
if (n.type === "Identifier" && n.name === varName) {
|
|
12474
|
+
// Make sure it's not a property key or part of a member expression property
|
|
12475
|
+
const isMemberProp = parent && parent.type === "MemberExpression" && parent.property === n && !parent.computed;
|
|
12476
|
+
const isObjectKey = parent && parent.type === "Property" && parent.key === n && !parent.computed;
|
|
12477
|
+
const isShorthandValue = parent && parent.type === "Property" && parent.shorthand && parent.value === n;
|
|
12478
|
+
|
|
12479
|
+
// Include shorthand properties as references (they use the variable)
|
|
12480
|
+
if (!isMemberProp && !isObjectKey) {
|
|
12481
|
+
references.push(n);
|
|
12482
|
+
}
|
|
12483
|
+
}
|
|
12484
|
+
|
|
12485
|
+
for (const key of Object.keys(n)) {
|
|
12486
|
+
if (key === "parent" || key === "range" || key === "loc") continue;
|
|
12487
|
+
|
|
12488
|
+
const child = n[key];
|
|
12489
|
+
|
|
12490
|
+
if (Array.isArray(child)) {
|
|
12491
|
+
child.forEach((c) => visitNode(c, n));
|
|
12492
|
+
} else if (child && typeof child === "object" && child.type) {
|
|
12493
|
+
visitNode(child, n);
|
|
12494
|
+
}
|
|
12495
|
+
}
|
|
12496
|
+
};
|
|
12497
|
+
|
|
12498
|
+
visitNode(scope, null);
|
|
12499
|
+
|
|
12500
|
+
return references;
|
|
12501
|
+
};
|
|
12502
|
+
|
|
12503
|
+
// Check for destructuring of module imports (not allowed)
|
|
12446
12504
|
const checkVariableDeclarationHandler = (node) => {
|
|
12447
12505
|
for (const decl of node.declarations) {
|
|
12448
12506
|
// Check for ObjectPattern destructuring
|
|
12449
12507
|
if (decl.id.type === "ObjectPattern" && decl.init) {
|
|
12450
12508
|
let sourceVarName = null;
|
|
12451
12509
|
|
|
12452
|
-
// Direct destructuring: const { x } =
|
|
12510
|
+
// Direct destructuring: const { x } = moduleImport
|
|
12453
12511
|
if (decl.init.type === "Identifier") {
|
|
12454
12512
|
sourceVarName = decl.init.name;
|
|
12455
12513
|
}
|
|
12456
12514
|
|
|
12457
|
-
// Nested destructuring: const { x } =
|
|
12515
|
+
// Nested destructuring: const { x } = moduleImport.nested
|
|
12458
12516
|
if (decl.init.type === "MemberExpression") {
|
|
12459
12517
|
let obj = decl.init;
|
|
12460
12518
|
|
|
@@ -12467,15 +12525,77 @@ const functionObjectDestructure = {
|
|
|
12467
12525
|
}
|
|
12468
12526
|
}
|
|
12469
12527
|
|
|
12470
|
-
if (sourceVarName &&
|
|
12528
|
+
if (sourceVarName && moduleImports.has(sourceVarName)) {
|
|
12529
|
+
// Get destructured properties with their local names
|
|
12471
12530
|
const destructuredProps = decl.id.properties
|
|
12472
12531
|
.filter((p) => p.type === "Property" && p.key && p.key.name)
|
|
12473
|
-
.map((p) =>
|
|
12532
|
+
.map((p) => ({
|
|
12533
|
+
key: p.key.name,
|
|
12534
|
+
local: p.value && p.value.type === "Identifier" ? p.value.name : p.key.name,
|
|
12535
|
+
}));
|
|
12474
12536
|
|
|
12475
12537
|
const sourceText = sourceCode.getText(decl.init);
|
|
12476
12538
|
|
|
12539
|
+
// Find the containing function/program to search for references
|
|
12540
|
+
let scope = node.parent;
|
|
12541
|
+
|
|
12542
|
+
while (scope && scope.type !== "BlockStatement" && scope.type !== "Program") {
|
|
12543
|
+
scope = scope.parent;
|
|
12544
|
+
}
|
|
12545
|
+
|
|
12477
12546
|
context.report({
|
|
12478
|
-
|
|
12547
|
+
fix: scope
|
|
12548
|
+
? (fixer) => {
|
|
12549
|
+
const fixes = [];
|
|
12550
|
+
|
|
12551
|
+
// Replace all references with dot notation
|
|
12552
|
+
destructuredProps.forEach(({ key, local }) => {
|
|
12553
|
+
const refs = findAllReferencesHandler(scope, local, decl);
|
|
12554
|
+
|
|
12555
|
+
refs.forEach((ref) => {
|
|
12556
|
+
fixes.push(fixer.replaceText(ref, `${sourceText}.${key}`));
|
|
12557
|
+
});
|
|
12558
|
+
});
|
|
12559
|
+
|
|
12560
|
+
// Remove the entire declaration statement
|
|
12561
|
+
// If it's the only declaration in the statement, remove the whole statement
|
|
12562
|
+
if (node.declarations.length === 1) {
|
|
12563
|
+
// Find the full statement including newline
|
|
12564
|
+
const tokenBefore = sourceCode.getTokenBefore(node);
|
|
12565
|
+
const tokenAfter = sourceCode.getTokenAfter(node);
|
|
12566
|
+
let start = node.range[0];
|
|
12567
|
+
let end = node.range[1];
|
|
12568
|
+
|
|
12569
|
+
// Include leading whitespace/newline
|
|
12570
|
+
if (tokenBefore) {
|
|
12571
|
+
const textBetween = sourceCode.text.slice(tokenBefore.range[1], node.range[0]);
|
|
12572
|
+
const newlineIndex = textBetween.lastIndexOf("\n");
|
|
12573
|
+
|
|
12574
|
+
if (newlineIndex !== -1) {
|
|
12575
|
+
start = tokenBefore.range[1] + newlineIndex;
|
|
12576
|
+
}
|
|
12577
|
+
}
|
|
12578
|
+
|
|
12579
|
+
// Include trailing newline
|
|
12580
|
+
if (tokenAfter) {
|
|
12581
|
+
const textBetween = sourceCode.text.slice(node.range[1], tokenAfter.range[0]);
|
|
12582
|
+
const newlineIndex = textBetween.indexOf("\n");
|
|
12583
|
+
|
|
12584
|
+
if (newlineIndex !== -1) {
|
|
12585
|
+
end = node.range[1] + newlineIndex + 1;
|
|
12586
|
+
}
|
|
12587
|
+
}
|
|
12588
|
+
|
|
12589
|
+
fixes.push(fixer.removeRange([start, end]));
|
|
12590
|
+
} else {
|
|
12591
|
+
// Remove just this declarator
|
|
12592
|
+
fixes.push(fixer.remove(decl));
|
|
12593
|
+
}
|
|
12594
|
+
|
|
12595
|
+
return fixes;
|
|
12596
|
+
}
|
|
12597
|
+
: undefined,
|
|
12598
|
+
message: `Do not destructure module imports. Use dot notation for searchability: "${sourceText}.${destructuredProps[0].key}" instead of destructuring`,
|
|
12479
12599
|
node: decl.id,
|
|
12480
12600
|
});
|
|
12481
12601
|
}
|
|
@@ -13258,6 +13378,66 @@ const componentPropsDestructure = {
|
|
|
13258
13378
|
return accesses;
|
|
13259
13379
|
};
|
|
13260
13380
|
|
|
13381
|
+
// Find body destructuring like: const { name } = data; or const { name, age } = data;
|
|
13382
|
+
const findBodyDestructuringHandler = (body, paramName) => {
|
|
13383
|
+
const results = [];
|
|
13384
|
+
|
|
13385
|
+
if (body.type !== "BlockStatement") return results;
|
|
13386
|
+
|
|
13387
|
+
for (const statement of body.body) {
|
|
13388
|
+
if (statement.type === "VariableDeclaration") {
|
|
13389
|
+
for (const declarator of statement.declarations) {
|
|
13390
|
+
// Check if it's destructuring from the param: const { x } = paramName
|
|
13391
|
+
if (
|
|
13392
|
+
declarator.id.type === "ObjectPattern" &&
|
|
13393
|
+
declarator.init &&
|
|
13394
|
+
declarator.init.type === "Identifier" &&
|
|
13395
|
+
declarator.init.name === paramName
|
|
13396
|
+
) {
|
|
13397
|
+
const props = [];
|
|
13398
|
+
|
|
13399
|
+
for (const prop of declarator.id.properties) {
|
|
13400
|
+
if (prop.type === "Property" && prop.key.type === "Identifier") {
|
|
13401
|
+
// Handle both { name } and { name: alias }
|
|
13402
|
+
const keyName = prop.key.name;
|
|
13403
|
+
const valueName = prop.value.type === "Identifier" ? prop.value.name : null;
|
|
13404
|
+
const hasDefault = prop.value.type === "AssignmentPattern";
|
|
13405
|
+
let defaultValue = null;
|
|
13406
|
+
|
|
13407
|
+
if (hasDefault && prop.value.right) {
|
|
13408
|
+
defaultValue = sourceCode.getText(prop.value.right);
|
|
13409
|
+
}
|
|
13410
|
+
|
|
13411
|
+
props.push({
|
|
13412
|
+
default: defaultValue,
|
|
13413
|
+
hasAlias: keyName !== valueName && !hasDefault,
|
|
13414
|
+
key: keyName,
|
|
13415
|
+
value: hasDefault ? prop.value.left.name : valueName,
|
|
13416
|
+
});
|
|
13417
|
+
} else if (prop.type === "RestElement" && prop.argument.type === "Identifier") {
|
|
13418
|
+
props.push({
|
|
13419
|
+
isRest: true,
|
|
13420
|
+
key: prop.argument.name,
|
|
13421
|
+
value: prop.argument.name,
|
|
13422
|
+
});
|
|
13423
|
+
}
|
|
13424
|
+
}
|
|
13425
|
+
|
|
13426
|
+
results.push({
|
|
13427
|
+
declarator,
|
|
13428
|
+
props,
|
|
13429
|
+
statement,
|
|
13430
|
+
// Track if this is the only declarator in the statement
|
|
13431
|
+
statementHasOnlyThisDeclarator: statement.declarations.length === 1,
|
|
13432
|
+
});
|
|
13433
|
+
}
|
|
13434
|
+
}
|
|
13435
|
+
}
|
|
13436
|
+
}
|
|
13437
|
+
|
|
13438
|
+
return results;
|
|
13439
|
+
};
|
|
13440
|
+
|
|
13261
13441
|
const checkComponentPropsHandler = (node) => {
|
|
13262
13442
|
if (!isReactComponentHandler(node)) return;
|
|
13263
13443
|
|
|
@@ -13271,14 +13451,33 @@ const componentPropsDestructure = {
|
|
|
13271
13451
|
|
|
13272
13452
|
if (firstParam.type === "Identifier") {
|
|
13273
13453
|
const paramName = firstParam.name;
|
|
13454
|
+
|
|
13455
|
+
// Find dot notation accesses: props.name
|
|
13274
13456
|
const accesses = findPropAccessesHandler(node.body, paramName);
|
|
13275
|
-
const accessedProps = [...new Set(accesses.map((a) => a.property))];
|
|
13276
13457
|
|
|
13277
|
-
//
|
|
13458
|
+
// Find body destructuring: const { name } = props
|
|
13459
|
+
const bodyDestructures = findBodyDestructuringHandler(node.body, paramName);
|
|
13460
|
+
|
|
13461
|
+
// Collect all accessed props from dot notation
|
|
13462
|
+
const dotNotationProps = [...new Set(accesses.map((a) => a.property))];
|
|
13463
|
+
|
|
13464
|
+
// Collect all props from body destructuring
|
|
13465
|
+
const bodyDestructuredProps = [];
|
|
13466
|
+
|
|
13467
|
+
bodyDestructures.forEach((bd) => {
|
|
13468
|
+
bd.props.forEach((p) => {
|
|
13469
|
+
bodyDestructuredProps.push(p);
|
|
13470
|
+
});
|
|
13471
|
+
});
|
|
13472
|
+
|
|
13473
|
+
// Check if param is used anywhere that we can't handle
|
|
13278
13474
|
const allRefs = [];
|
|
13279
|
-
const countRefs = (n) => {
|
|
13475
|
+
const countRefs = (n, skipNodes = []) => {
|
|
13280
13476
|
if (!n || typeof n !== "object") return;
|
|
13281
13477
|
|
|
13478
|
+
// Skip nodes we're already accounting for
|
|
13479
|
+
if (skipNodes.includes(n)) return;
|
|
13480
|
+
|
|
13282
13481
|
if (n.type === "Identifier" && n.name === paramName) allRefs.push(n);
|
|
13283
13482
|
|
|
13284
13483
|
for (const key of Object.keys(n)) {
|
|
@@ -13286,29 +13485,96 @@ const componentPropsDestructure = {
|
|
|
13286
13485
|
|
|
13287
13486
|
const child = n[key];
|
|
13288
13487
|
|
|
13289
|
-
if (Array.isArray(child)) child.forEach(countRefs);
|
|
13290
|
-
else if (child && typeof child === "object" && child.type) countRefs(child);
|
|
13488
|
+
if (Array.isArray(child)) child.forEach((c) => countRefs(c, skipNodes));
|
|
13489
|
+
else if (child && typeof child === "object" && child.type) countRefs(child, skipNodes);
|
|
13291
13490
|
}
|
|
13292
13491
|
};
|
|
13293
13492
|
|
|
13294
13493
|
countRefs(node.body);
|
|
13295
13494
|
|
|
13296
|
-
//
|
|
13297
|
-
const
|
|
13495
|
+
// Count expected refs: dot notation accesses + body destructuring init nodes
|
|
13496
|
+
const expectedRefCount = accesses.length + bodyDestructures.length;
|
|
13497
|
+
|
|
13498
|
+
// Can auto-fix if:
|
|
13499
|
+
// 1. We have either dot notation props OR body destructured props
|
|
13500
|
+
// 2. All references to the param are accounted for
|
|
13501
|
+
const hasSomeProps = dotNotationProps.length > 0 || bodyDestructuredProps.length > 0;
|
|
13502
|
+
const canAutoFix = hasSomeProps && allRefs.length === expectedRefCount;
|
|
13298
13503
|
|
|
13299
13504
|
context.report({
|
|
13300
13505
|
fix: canAutoFix
|
|
13301
13506
|
? (fixer) => {
|
|
13302
13507
|
const fixes = [];
|
|
13303
13508
|
|
|
13509
|
+
// Build the destructured props list for the parameter
|
|
13510
|
+
const allProps = [];
|
|
13511
|
+
|
|
13512
|
+
// Add dot notation props (simple names)
|
|
13513
|
+
dotNotationProps.forEach((p) => {
|
|
13514
|
+
if (!allProps.some((ap) => ap.key === p)) {
|
|
13515
|
+
allProps.push({ key: p, simple: true });
|
|
13516
|
+
}
|
|
13517
|
+
});
|
|
13518
|
+
|
|
13519
|
+
// Add body destructured props (may have aliases, defaults, rest)
|
|
13520
|
+
bodyDestructuredProps.forEach((p) => {
|
|
13521
|
+
// Don't duplicate if already in dot notation
|
|
13522
|
+
if (!allProps.some((ap) => ap.key === p.key)) {
|
|
13523
|
+
allProps.push(p);
|
|
13524
|
+
}
|
|
13525
|
+
});
|
|
13526
|
+
|
|
13527
|
+
// Build the destructured pattern string
|
|
13528
|
+
const propStrings = allProps.map((p) => {
|
|
13529
|
+
if (p.isRest) return `...${p.key}`;
|
|
13530
|
+
|
|
13531
|
+
if (p.simple) return p.key;
|
|
13532
|
+
|
|
13533
|
+
if (p.default) return `${p.key} = ${p.default}`;
|
|
13534
|
+
|
|
13535
|
+
if (p.hasAlias) return `${p.key}: ${p.value}`;
|
|
13536
|
+
|
|
13537
|
+
return p.key;
|
|
13538
|
+
});
|
|
13539
|
+
const destructuredPattern = `{ ${propStrings.join(", ")} }`;
|
|
13540
|
+
let replacement = destructuredPattern;
|
|
13541
|
+
|
|
13542
|
+
// Preserve TypeScript type annotation if present
|
|
13543
|
+
if (firstParam.typeAnnotation) {
|
|
13544
|
+
const typeText = sourceCode.getText(firstParam.typeAnnotation);
|
|
13545
|
+
|
|
13546
|
+
replacement = `${destructuredPattern}${typeText}`;
|
|
13547
|
+
}
|
|
13548
|
+
|
|
13304
13549
|
// Replace param with destructured pattern
|
|
13305
|
-
fixes.push(fixer.replaceText(firstParam,
|
|
13550
|
+
fixes.push(fixer.replaceText(firstParam, replacement));
|
|
13306
13551
|
|
|
13307
13552
|
// Replace all props.x with just x
|
|
13308
13553
|
accesses.forEach((access) => {
|
|
13309
13554
|
fixes.push(fixer.replaceText(access.node, access.property));
|
|
13310
13555
|
});
|
|
13311
13556
|
|
|
13557
|
+
// Remove body destructuring statements
|
|
13558
|
+
bodyDestructures.forEach((bd) => {
|
|
13559
|
+
if (bd.statementHasOnlyThisDeclarator) {
|
|
13560
|
+
// Remove the entire statement including newline
|
|
13561
|
+
const statementStart = bd.statement.range[0];
|
|
13562
|
+
let statementEnd = bd.statement.range[1];
|
|
13563
|
+
|
|
13564
|
+
// Try to also remove trailing newline/whitespace
|
|
13565
|
+
const textAfter = sourceCode.getText().slice(statementEnd, statementEnd + 2);
|
|
13566
|
+
|
|
13567
|
+
if (textAfter.startsWith("\n")) statementEnd += 1;
|
|
13568
|
+
else if (textAfter.startsWith("\r\n")) statementEnd += 2;
|
|
13569
|
+
|
|
13570
|
+
fixes.push(fixer.removeRange([statementStart, statementEnd]));
|
|
13571
|
+
} else {
|
|
13572
|
+
// Only remove this declarator from a multi-declarator statement
|
|
13573
|
+
// This is more complex - for now just remove the declarator text
|
|
13574
|
+
fixes.push(fixer.remove(bd.declarator));
|
|
13575
|
+
}
|
|
13576
|
+
});
|
|
13577
|
+
|
|
13312
13578
|
return fixes;
|
|
13313
13579
|
}
|
|
13314
13580
|
: undefined,
|
package/package.json
CHANGED