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/.absolutejs/eslint.cache.json +1 -5
- package/.absolutejs/prettier.cache.json +2 -2
- package/.absolutejs/tsconfig.tsbuildinfo +1 -1
- package/dist/index.js +144 -112
- package/package.json +1 -1
- package/src/rules/sort-keys-fixable.ts +243 -169
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
|
|
273
|
-
if (
|
|
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
|
-
|
|
277
|
-
|
|
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 (
|
|
281
|
-
|
|
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 (
|
|
285
|
-
addBoundIdentifiers(node.argument, stableLocals);
|
|
274
|
+
if (statement.type !== "VariableDeclaration" || statement.kind !== "const") {
|
|
286
275
|
return;
|
|
287
276
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
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
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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