eslint-plugin-absolute 0.2.5 → 0.2.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/dist/index.js CHANGED
@@ -219,42 +219,6 @@ var sortKeysFixable = {
219
219
  const natural = option && typeof option.natural === "boolean" ? option.natural : false;
220
220
  const minKeys = option && typeof option.minKeys === "number" ? option.minKeys : 2;
221
221
  const variablesBeforeFunctions = option && typeof option.variablesBeforeFunctions === "boolean" ? option.variablesBeforeFunctions : false;
222
- for (const statement of sourceCode.ast.body) {
223
- if (statement.type === "ImportDeclaration" && statement.specifiers.length > 0) {
224
- for (const specifier of statement.specifiers) {
225
- topLevelBindings.set(specifier.local.name, {
226
- kind: "import"
227
- });
228
- }
229
- continue;
230
- }
231
- if (statement.type === "FunctionDeclaration" && statement.id) {
232
- topLevelBindings.set(statement.id.name, {
233
- kind: "function",
234
- node: statement
235
- });
236
- continue;
237
- }
238
- if (statement.type !== "VariableDeclaration" || statement.kind !== "const") {
239
- continue;
240
- }
241
- for (const declaration of statement.declarations) {
242
- if (declaration.id.type !== "Identifier" || !declaration.init) {
243
- continue;
244
- }
245
- if (declaration.init.type === "ArrowFunctionExpression" || declaration.init.type === "FunctionExpression") {
246
- topLevelBindings.set(declaration.id.name, {
247
- kind: "function",
248
- node: declaration.init
249
- });
250
- continue;
251
- }
252
- topLevelBindings.set(declaration.id.name, {
253
- kind: "value",
254
- node: declaration.init
255
- });
256
- }
257
- }
258
222
  const compareKeys = (keyLeft, keyRight) => {
259
223
  let left = keyLeft;
260
224
  let right = keyRight;
@@ -269,63 +233,124 @@ var sortKeysFixable = {
269
233
  }
270
234
  return left.localeCompare(right);
271
235
  };
272
- const addBoundIdentifiers = (node, stableLocals) => {
273
- if (!node) {
236
+ const addImportBindings = (statement) => {
237
+ if (statement.specifiers.length === 0) {
238
+ return;
239
+ }
240
+ for (const specifier of statement.specifiers) {
241
+ topLevelBindings.set(specifier.local.name, {
242
+ kind: "import"
243
+ });
244
+ }
245
+ };
246
+ const addVariableBinding = (declaration) => {
247
+ if (declaration.id.type !== "Identifier" || !declaration.init) {
248
+ return;
249
+ }
250
+ if (declaration.init.type === "ArrowFunctionExpression" || declaration.init.type === "FunctionExpression") {
251
+ topLevelBindings.set(declaration.id.name, {
252
+ kind: "function",
253
+ node: declaration.init
254
+ });
274
255
  return;
275
256
  }
276
- if (node.type === "Identifier") {
277
- stableLocals.add(node.name);
257
+ topLevelBindings.set(declaration.id.name, {
258
+ kind: "value",
259
+ node: declaration.init
260
+ });
261
+ };
262
+ const addTopLevelBindings = (statement) => {
263
+ if (statement.type === "ImportDeclaration") {
264
+ addImportBindings(statement);
278
265
  return;
279
266
  }
280
- if (node.type === "AssignmentPattern") {
281
- addBoundIdentifiers(node.left, stableLocals);
267
+ if (statement.type === "FunctionDeclaration" && statement.id) {
268
+ topLevelBindings.set(statement.id.name, {
269
+ kind: "function",
270
+ node: statement
271
+ });
282
272
  return;
283
273
  }
284
- if (node.type === "RestElement") {
285
- addBoundIdentifiers(node.argument, stableLocals);
274
+ if (statement.type !== "VariableDeclaration" || statement.kind !== "const") {
286
275
  return;
287
276
  }
288
- if (node.type === "ArrayPattern") {
289
- for (const element of node.elements) {
290
- if (!element) {
291
- continue;
292
- }
293
- addBoundIdentifiers(element, stableLocals);
294
- }
277
+ for (const declaration of statement.declarations) {
278
+ addVariableBinding(declaration);
279
+ }
280
+ };
281
+ for (const statement of sourceCode.ast.body) {
282
+ addTopLevelBindings(statement);
283
+ }
284
+ const addBoundIdentifiers = (node, stableLocals) => {
285
+ if (!node) {
295
286
  return;
296
287
  }
297
- if (node.type === "ObjectPattern") {
298
- for (const property of node.properties) {
299
- if (property.type === "RestElement") {
300
- addBoundIdentifiers(property.argument, stableLocals);
301
- continue;
288
+ switch (node.type) {
289
+ case "Identifier":
290
+ stableLocals.add(node.name);
291
+ return;
292
+ case "AssignmentPattern":
293
+ addBoundIdentifiers(node.left, stableLocals);
294
+ return;
295
+ case "RestElement":
296
+ addBoundIdentifiers(node.argument, stableLocals);
297
+ return;
298
+ case "ArrayPattern":
299
+ for (const element of node.elements.filter(Boolean)) {
300
+ addBoundIdentifiers(element, stableLocals);
301
+ }
302
+ break;
303
+ case "ObjectPattern":
304
+ for (const property of node.properties) {
305
+ const bindingNode = property.type === "RestElement" ? property.argument : property.value;
306
+ addBoundIdentifiers(bindingNode, stableLocals);
302
307
  }
303
- addBoundIdentifiers(property.value, stableLocals);
308
+ break;
309
+ default:
310
+ break;
311
+ }
312
+ };
313
+ const addFunctionParamBindings = (functionNode, stableLocals) => {
314
+ for (const parameter of functionNode.params) {
315
+ addBoundIdentifiers(parameter, stableLocals);
316
+ }
317
+ };
318
+ const addAncestorConstBindings = (ancestor, node, stableLocals) => {
319
+ const addDeclarationBindings = (statement) => {
320
+ if (statement.type !== "VariableDeclaration" || statement.kind !== "const") {
321
+ return;
322
+ }
323
+ for (const declaration of statement.declarations) {
324
+ addBoundIdentifiers(declaration.id, stableLocals);
304
325
  }
326
+ };
327
+ for (const statement of ancestor.body) {
328
+ if (statement.range[0] >= node.range[0]) {
329
+ return;
330
+ }
331
+ addDeclarationBindings(statement);
332
+ }
333
+ };
334
+ const addAncestorBindingsForNode = (ancestor, node, stableLocals) => {
335
+ if (ancestor.type !== "Program" && ancestor.type !== "BlockStatement") {
336
+ return;
337
+ }
338
+ addAncestorConstBindings(ancestor, node, stableLocals);
339
+ };
340
+ const addFunctionBindingsForAncestor = (ancestor, stableLocals) => {
341
+ if (ancestor.type !== "FunctionDeclaration" && ancestor.type !== "FunctionExpression" && ancestor.type !== "ArrowFunctionExpression") {
342
+ return;
305
343
  }
344
+ addFunctionParamBindings(ancestor, stableLocals);
306
345
  };
307
346
  const getStableLocalsForNode = (node) => {
308
347
  const stableLocals = new Set;
309
348
  const ancestors = sourceCode.getAncestors(node);
310
349
  for (const ancestor of ancestors) {
311
- if (ancestor.type === "FunctionDeclaration" || ancestor.type === "FunctionExpression" || ancestor.type === "ArrowFunctionExpression") {
312
- for (const parameter of ancestor.params) {
313
- addBoundIdentifiers(parameter, stableLocals);
314
- }
315
- }
350
+ addFunctionBindingsForAncestor(ancestor, stableLocals);
316
351
  }
317
352
  for (const ancestor of ancestors) {
318
- if (ancestor.type !== "Program" && ancestor.type !== "BlockStatement") {
319
- continue;
320
- }
321
- for (const statement of ancestor.body) {
322
- if (statement.range[0] >= node.range[0] || statement.type !== "VariableDeclaration" || statement.kind !== "const") {
323
- break;
324
- }
325
- for (const declaration of statement.declarations) {
326
- addBoundIdentifiers(declaration.id, stableLocals);
327
- }
328
- }
353
+ addAncestorBindingsForNode(ancestor, node, stableLocals);
329
354
  }
330
355
  return stableLocals;
331
356
  };
@@ -354,6 +379,39 @@ var sortKeysFixable = {
354
379
  }
355
380
  return false;
356
381
  };
382
+ const isPureConstStatement = (statement, stableLocals, checkExpression) => {
383
+ if (statement.kind !== "const") {
384
+ return false;
385
+ }
386
+ for (const declaration of statement.declarations) {
387
+ if (declaration.id.type !== "Identifier" || !declaration.init) {
388
+ return false;
389
+ }
390
+ if (!checkExpression(declaration.init)) {
391
+ return false;
392
+ }
393
+ stableLocals.add(declaration.id.name);
394
+ }
395
+ return true;
396
+ };
397
+ const isPureFunctionStatement = (statement, stableLocals, checkExpression) => {
398
+ if (statement.type === "ReturnStatement") {
399
+ return !statement.argument || checkExpression(statement.argument);
400
+ }
401
+ if (statement.type === "VariableDeclaration") {
402
+ return isPureConstStatement(statement, stableLocals, checkExpression);
403
+ }
404
+ return false;
405
+ };
406
+ const isPureFunctionBody = (body, stableLocals, checkExpression) => {
407
+ for (const statement of body.body) {
408
+ const statementIsPure = isPureFunctionStatement(statement, stableLocals, checkExpression);
409
+ if (!statementIsPure) {
410
+ return false;
411
+ }
412
+ }
413
+ return true;
414
+ };
357
415
  const isPureTopLevelFunction = (functionNode) => {
358
416
  const cached = pureFunctionCache.get(functionNode);
359
417
  if (cached !== undefined) {
@@ -364,44 +422,23 @@ var sortKeysFixable = {
364
422
  }
365
423
  pureFunctionInProgress.add(functionNode);
366
424
  const stableLocals = new Set;
367
- for (const parameter of functionNode.params) {
368
- if (parameter.type === "Identifier") {
369
- stableLocals.add(parameter.name);
370
- }
371
- }
372
- let isPure = true;
425
+ addFunctionParamBindings(functionNode, stableLocals);
373
426
  const checkExpression = (expression) => isPureRuntimeExpression(expression, stableLocals);
374
- if (functionNode.body.type === "BlockStatement") {
375
- for (const statement of functionNode.body.body) {
376
- if (statement.type === "ReturnStatement") {
377
- if (statement.argument && !checkExpression(statement.argument)) {
378
- isPure = false;
379
- }
380
- continue;
381
- }
382
- if (statement.type === "VariableDeclaration" && statement.kind === "const") {
383
- for (const declaration of statement.declarations) {
384
- if (declaration.id.type !== "Identifier" || !declaration.init || !checkExpression(declaration.init)) {
385
- isPure = false;
386
- break;
387
- }
388
- stableLocals.add(declaration.id.name);
389
- }
390
- if (!isPure) {
391
- break;
392
- }
393
- continue;
394
- }
395
- isPure = false;
396
- break;
397
- }
398
- } else {
399
- isPure = checkExpression(functionNode.body);
400
- }
427
+ const isPure = functionNode.body.type === "BlockStatement" ? isPureFunctionBody(functionNode.body, stableLocals, checkExpression) : checkExpression(functionNode.body);
401
428
  pureFunctionInProgress.delete(functionNode);
402
429
  pureFunctionCache.set(functionNode, isPure);
403
430
  return isPure;
404
431
  };
432
+ const isPureIdentifierCall = (callExpression) => {
433
+ if (callExpression.callee.type !== "Identifier") {
434
+ return false;
435
+ }
436
+ if (PURE_GLOBAL_FUNCTIONS.has(callExpression.callee.name)) {
437
+ return true;
438
+ }
439
+ const binding = topLevelBindings.get(callExpression.callee.name);
440
+ return binding?.kind === "function" ? isPureTopLevelFunction(binding.node) : false;
441
+ };
405
442
  const isPureRuntimeExpression = (node, stableLocals) => {
406
443
  if (!node || node.type === "PrivateIdentifier") {
407
444
  return false;
@@ -465,11 +502,7 @@ var sortKeysFixable = {
465
502
  return false;
466
503
  }
467
504
  if (node.callee.type === "Identifier") {
468
- if (PURE_GLOBAL_FUNCTIONS.has(node.callee.name)) {
469
- return true;
470
- }
471
- const binding = topLevelBindings.get(node.callee.name);
472
- return binding?.kind === "function" && isPureTopLevelFunction(binding.node);
505
+ return isPureIdentifierCall(node);
473
506
  }
474
507
  if (node.callee.type !== "MemberExpression") {
475
508
  return false;
@@ -484,7 +517,6 @@ var sortKeysFixable = {
484
517
  return false;
485
518
  }
486
519
  };
487
- const isSafeToReorderExpression = (node) => isPureRuntimeExpression(node, new Set);
488
520
  const isSafeJSXAttributeValue = (value, scopeNode) => {
489
521
  if (value === null) {
490
522
  return true;
package/package.json CHANGED
@@ -30,5 +30,5 @@
30
30
  "typecheck": "bun run tsc --noEmit"
31
31
  },
32
32
  "type": "module",
33
- "version": "0.2.5"
33
+ "version": "0.2.6"
34
34
  }