eslint-plugin-absolute 0.2.5 → 0.2.7

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
@@ -187,6 +187,23 @@ var explicitObjectTypes = {
187
187
  // src/rules/sort-keys-fixable.ts
188
188
  var SORT_BEFORE = -1;
189
189
  var PURE_CONSTRUCTORS = new Set(["Date"]);
190
+ var PURE_GLOBAL_IDENTIFIERS = new Set([
191
+ "Array",
192
+ "BigInt",
193
+ "Boolean",
194
+ "Date",
195
+ "Function",
196
+ "Map",
197
+ "Number",
198
+ "Object",
199
+ "Promise",
200
+ "RegExp",
201
+ "Set",
202
+ "String",
203
+ "Symbol",
204
+ "URL",
205
+ "undefined"
206
+ ]);
190
207
  var PURE_GLOBAL_FUNCTIONS = new Set(["Boolean", "Number", "String"]);
191
208
  var PURE_MEMBER_METHODS = new Set([
192
209
  "getDay",
@@ -219,42 +236,6 @@ var sortKeysFixable = {
219
236
  const natural = option && typeof option.natural === "boolean" ? option.natural : false;
220
237
  const minKeys = option && typeof option.minKeys === "number" ? option.minKeys : 2;
221
238
  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
239
  const compareKeys = (keyLeft, keyRight) => {
259
240
  let left = keyLeft;
260
241
  let right = keyRight;
@@ -269,63 +250,124 @@ var sortKeysFixable = {
269
250
  }
270
251
  return left.localeCompare(right);
271
252
  };
272
- const addBoundIdentifiers = (node, stableLocals) => {
273
- if (!node) {
253
+ const addImportBindings = (statement) => {
254
+ if (statement.specifiers.length === 0) {
274
255
  return;
275
256
  }
276
- if (node.type === "Identifier") {
277
- stableLocals.add(node.name);
257
+ for (const specifier of statement.specifiers) {
258
+ topLevelBindings.set(specifier.local.name, {
259
+ kind: "import"
260
+ });
261
+ }
262
+ };
263
+ const addVariableBinding = (declaration) => {
264
+ if (declaration.id.type !== "Identifier" || !declaration.init) {
278
265
  return;
279
266
  }
280
- if (node.type === "AssignmentPattern") {
281
- addBoundIdentifiers(node.left, stableLocals);
267
+ if (declaration.init.type === "ArrowFunctionExpression" || declaration.init.type === "FunctionExpression") {
268
+ topLevelBindings.set(declaration.id.name, {
269
+ kind: "function",
270
+ node: declaration.init
271
+ });
282
272
  return;
283
273
  }
284
- if (node.type === "RestElement") {
285
- addBoundIdentifiers(node.argument, stableLocals);
274
+ topLevelBindings.set(declaration.id.name, {
275
+ kind: "value",
276
+ node: declaration.init
277
+ });
278
+ };
279
+ const addTopLevelBindings = (statement) => {
280
+ if (statement.type === "ImportDeclaration") {
281
+ addImportBindings(statement);
286
282
  return;
287
283
  }
288
- if (node.type === "ArrayPattern") {
289
- for (const element of node.elements) {
290
- if (!element) {
291
- continue;
292
- }
293
- addBoundIdentifiers(element, stableLocals);
294
- }
284
+ if (statement.type === "FunctionDeclaration" && statement.id) {
285
+ topLevelBindings.set(statement.id.name, {
286
+ kind: "function",
287
+ node: statement
288
+ });
289
+ return;
290
+ }
291
+ if (statement.type !== "VariableDeclaration" || statement.kind !== "const") {
292
+ return;
293
+ }
294
+ for (const declaration of statement.declarations) {
295
+ addVariableBinding(declaration);
296
+ }
297
+ };
298
+ for (const statement of sourceCode.ast.body) {
299
+ addTopLevelBindings(statement);
300
+ }
301
+ const addBoundIdentifiers = (node, stableLocals) => {
302
+ if (!node) {
295
303
  return;
296
304
  }
297
- if (node.type === "ObjectPattern") {
298
- for (const property of node.properties) {
299
- if (property.type === "RestElement") {
300
- addBoundIdentifiers(property.argument, stableLocals);
301
- continue;
305
+ switch (node.type) {
306
+ case "Identifier":
307
+ stableLocals.add(node.name);
308
+ return;
309
+ case "AssignmentPattern":
310
+ addBoundIdentifiers(node.left, stableLocals);
311
+ return;
312
+ case "RestElement":
313
+ addBoundIdentifiers(node.argument, stableLocals);
314
+ return;
315
+ case "ArrayPattern":
316
+ for (const element of node.elements.filter(Boolean)) {
317
+ addBoundIdentifiers(element, stableLocals);
318
+ }
319
+ break;
320
+ case "ObjectPattern":
321
+ for (const property of node.properties) {
322
+ const bindingNode = property.type === "RestElement" ? property.argument : property.value;
323
+ addBoundIdentifiers(bindingNode, stableLocals);
302
324
  }
303
- addBoundIdentifiers(property.value, stableLocals);
325
+ break;
326
+ default:
327
+ break;
328
+ }
329
+ };
330
+ const addFunctionParamBindings = (functionNode, stableLocals) => {
331
+ for (const parameter of functionNode.params) {
332
+ addBoundIdentifiers(parameter, stableLocals);
333
+ }
334
+ };
335
+ const addAncestorConstBindings = (ancestor, node, stableLocals) => {
336
+ const addDeclarationBindings = (statement) => {
337
+ if (statement.type !== "VariableDeclaration" || statement.kind !== "const") {
338
+ return;
304
339
  }
340
+ for (const declaration of statement.declarations) {
341
+ addBoundIdentifiers(declaration.id, stableLocals);
342
+ }
343
+ };
344
+ for (const statement of ancestor.body) {
345
+ if (statement.range[0] >= node.range[0]) {
346
+ return;
347
+ }
348
+ addDeclarationBindings(statement);
349
+ }
350
+ };
351
+ const addAncestorBindingsForNode = (ancestor, node, stableLocals) => {
352
+ if (ancestor.type !== "Program" && ancestor.type !== "BlockStatement") {
353
+ return;
354
+ }
355
+ addAncestorConstBindings(ancestor, node, stableLocals);
356
+ };
357
+ const addFunctionBindingsForAncestor = (ancestor, stableLocals) => {
358
+ if (ancestor.type !== "FunctionDeclaration" && ancestor.type !== "FunctionExpression" && ancestor.type !== "ArrowFunctionExpression") {
359
+ return;
305
360
  }
361
+ addFunctionParamBindings(ancestor, stableLocals);
306
362
  };
307
363
  const getStableLocalsForNode = (node) => {
308
364
  const stableLocals = new Set;
309
365
  const ancestors = sourceCode.getAncestors(node);
310
366
  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
- }
367
+ addFunctionBindingsForAncestor(ancestor, stableLocals);
316
368
  }
317
369
  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
- }
370
+ addAncestorBindingsForNode(ancestor, node, stableLocals);
329
371
  }
330
372
  return stableLocals;
331
373
  };
@@ -339,6 +381,9 @@ var sortKeysFixable = {
339
381
  return null;
340
382
  };
341
383
  const isStableIdentifier = (name, stableLocals) => {
384
+ if (PURE_GLOBAL_IDENTIFIERS.has(name)) {
385
+ return true;
386
+ }
342
387
  if (stableLocals.has(name)) {
343
388
  return true;
344
389
  }
@@ -354,6 +399,39 @@ var sortKeysFixable = {
354
399
  }
355
400
  return false;
356
401
  };
402
+ const isPureConstStatement = (statement, stableLocals, checkExpression) => {
403
+ if (statement.kind !== "const") {
404
+ return false;
405
+ }
406
+ for (const declaration of statement.declarations) {
407
+ if (declaration.id.type !== "Identifier" || !declaration.init) {
408
+ return false;
409
+ }
410
+ if (!checkExpression(declaration.init)) {
411
+ return false;
412
+ }
413
+ stableLocals.add(declaration.id.name);
414
+ }
415
+ return true;
416
+ };
417
+ const isPureFunctionStatement = (statement, stableLocals, checkExpression) => {
418
+ if (statement.type === "ReturnStatement") {
419
+ return !statement.argument || checkExpression(statement.argument);
420
+ }
421
+ if (statement.type === "VariableDeclaration") {
422
+ return isPureConstStatement(statement, stableLocals, checkExpression);
423
+ }
424
+ return false;
425
+ };
426
+ const isPureFunctionBody = (body, stableLocals, checkExpression) => {
427
+ for (const statement of body.body) {
428
+ const statementIsPure = isPureFunctionStatement(statement, stableLocals, checkExpression);
429
+ if (!statementIsPure) {
430
+ return false;
431
+ }
432
+ }
433
+ return true;
434
+ };
357
435
  const isPureTopLevelFunction = (functionNode) => {
358
436
  const cached = pureFunctionCache.get(functionNode);
359
437
  if (cached !== undefined) {
@@ -364,44 +442,23 @@ var sortKeysFixable = {
364
442
  }
365
443
  pureFunctionInProgress.add(functionNode);
366
444
  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;
445
+ addFunctionParamBindings(functionNode, stableLocals);
373
446
  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
- }
447
+ const isPure = functionNode.body.type === "BlockStatement" ? isPureFunctionBody(functionNode.body, stableLocals, checkExpression) : checkExpression(functionNode.body);
401
448
  pureFunctionInProgress.delete(functionNode);
402
449
  pureFunctionCache.set(functionNode, isPure);
403
450
  return isPure;
404
451
  };
452
+ const isPureIdentifierCall = (callExpression) => {
453
+ if (callExpression.callee.type !== "Identifier") {
454
+ return false;
455
+ }
456
+ if (PURE_GLOBAL_FUNCTIONS.has(callExpression.callee.name)) {
457
+ return true;
458
+ }
459
+ const binding = topLevelBindings.get(callExpression.callee.name);
460
+ return binding?.kind === "function" ? isPureTopLevelFunction(binding.node) : false;
461
+ };
405
462
  const isPureRuntimeExpression = (node, stableLocals) => {
406
463
  if (!node || node.type === "PrivateIdentifier") {
407
464
  return false;
@@ -465,11 +522,7 @@ var sortKeysFixable = {
465
522
  return false;
466
523
  }
467
524
  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);
525
+ return isPureIdentifierCall(node);
473
526
  }
474
527
  if (node.callee.type !== "MemberExpression") {
475
528
  return false;
@@ -484,7 +537,6 @@ var sortKeysFixable = {
484
537
  return false;
485
538
  }
486
539
  };
487
- const isSafeToReorderExpression = (node) => isPureRuntimeExpression(node, new Set);
488
540
  const isSafeJSXAttributeValue = (value, scopeNode) => {
489
541
  if (value === null) {
490
542
  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.7"
34
34
  }