eslint-plugin-absolute 0.3.0 → 0.5.0
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 +223 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -194,7 +194,9 @@ var PURE_GLOBAL_IDENTIFIERS = new Set([
|
|
|
194
194
|
"Boolean",
|
|
195
195
|
"Date",
|
|
196
196
|
"Function",
|
|
197
|
+
"JSON",
|
|
197
198
|
"Map",
|
|
199
|
+
"Math",
|
|
198
200
|
"Number",
|
|
199
201
|
"Object",
|
|
200
202
|
"Promise",
|
|
@@ -203,16 +205,131 @@ var PURE_GLOBAL_IDENTIFIERS = new Set([
|
|
|
203
205
|
"String",
|
|
204
206
|
"Symbol",
|
|
205
207
|
"URL",
|
|
208
|
+
"globalThis",
|
|
206
209
|
"undefined"
|
|
207
210
|
]);
|
|
208
|
-
var PURE_GLOBAL_FUNCTIONS = new Set([
|
|
211
|
+
var PURE_GLOBAL_FUNCTIONS = new Set([
|
|
212
|
+
"Boolean",
|
|
213
|
+
"Number",
|
|
214
|
+
"String",
|
|
215
|
+
"decodeURI",
|
|
216
|
+
"decodeURIComponent",
|
|
217
|
+
"encodeURI",
|
|
218
|
+
"encodeURIComponent",
|
|
219
|
+
"isFinite",
|
|
220
|
+
"isNaN",
|
|
221
|
+
"parseFloat",
|
|
222
|
+
"parseInt"
|
|
223
|
+
]);
|
|
209
224
|
var PURE_MEMBER_METHODS = new Set([
|
|
225
|
+
"toString",
|
|
226
|
+
"valueOf",
|
|
227
|
+
"at",
|
|
228
|
+
"charAt",
|
|
229
|
+
"charCodeAt",
|
|
230
|
+
"codePointAt",
|
|
231
|
+
"endsWith",
|
|
232
|
+
"includes",
|
|
233
|
+
"indexOf",
|
|
234
|
+
"lastIndexOf",
|
|
235
|
+
"match",
|
|
236
|
+
"matchAll",
|
|
237
|
+
"normalize",
|
|
238
|
+
"padEnd",
|
|
239
|
+
"padStart",
|
|
240
|
+
"repeat",
|
|
241
|
+
"replace",
|
|
242
|
+
"replaceAll",
|
|
243
|
+
"search",
|
|
244
|
+
"slice",
|
|
245
|
+
"split",
|
|
246
|
+
"startsWith",
|
|
247
|
+
"substr",
|
|
248
|
+
"substring",
|
|
249
|
+
"toLocaleLowerCase",
|
|
250
|
+
"toLocaleUpperCase",
|
|
251
|
+
"toLowerCase",
|
|
252
|
+
"toUpperCase",
|
|
253
|
+
"trim",
|
|
254
|
+
"trimEnd",
|
|
255
|
+
"trimStart",
|
|
256
|
+
"toExponential",
|
|
257
|
+
"toFixed",
|
|
258
|
+
"toPrecision",
|
|
259
|
+
"isInteger",
|
|
260
|
+
"isSafeInteger",
|
|
261
|
+
"getDate",
|
|
210
262
|
"getDay",
|
|
263
|
+
"getFullYear",
|
|
211
264
|
"getHours",
|
|
212
265
|
"getMilliseconds",
|
|
213
266
|
"getMinutes",
|
|
267
|
+
"getMonth",
|
|
214
268
|
"getSeconds",
|
|
215
|
-
"
|
|
269
|
+
"getTime",
|
|
270
|
+
"getTimezoneOffset",
|
|
271
|
+
"getUTCDate",
|
|
272
|
+
"getUTCDay",
|
|
273
|
+
"getUTCFullYear",
|
|
274
|
+
"getUTCHours",
|
|
275
|
+
"getUTCMilliseconds",
|
|
276
|
+
"getUTCMinutes",
|
|
277
|
+
"getUTCMonth",
|
|
278
|
+
"getUTCSeconds",
|
|
279
|
+
"toDateString",
|
|
280
|
+
"toISOString",
|
|
281
|
+
"toJSON",
|
|
282
|
+
"toLocaleDateString",
|
|
283
|
+
"toLocaleString",
|
|
284
|
+
"toLocaleTimeString",
|
|
285
|
+
"toTimeString",
|
|
286
|
+
"toUTCString",
|
|
287
|
+
"abs",
|
|
288
|
+
"acos",
|
|
289
|
+
"acosh",
|
|
290
|
+
"asin",
|
|
291
|
+
"asinh",
|
|
292
|
+
"atan",
|
|
293
|
+
"atan2",
|
|
294
|
+
"atanh",
|
|
295
|
+
"cbrt",
|
|
296
|
+
"ceil",
|
|
297
|
+
"clz32",
|
|
298
|
+
"cos",
|
|
299
|
+
"cosh",
|
|
300
|
+
"exp",
|
|
301
|
+
"expm1",
|
|
302
|
+
"floor",
|
|
303
|
+
"fround",
|
|
304
|
+
"hypot",
|
|
305
|
+
"log",
|
|
306
|
+
"log10",
|
|
307
|
+
"log1p",
|
|
308
|
+
"log2",
|
|
309
|
+
"max",
|
|
310
|
+
"min",
|
|
311
|
+
"pow",
|
|
312
|
+
"round",
|
|
313
|
+
"sign",
|
|
314
|
+
"sin",
|
|
315
|
+
"sinh",
|
|
316
|
+
"sqrt",
|
|
317
|
+
"tan",
|
|
318
|
+
"tanh",
|
|
319
|
+
"trunc",
|
|
320
|
+
"entries",
|
|
321
|
+
"fromEntries",
|
|
322
|
+
"getOwnPropertyNames",
|
|
323
|
+
"getOwnPropertySymbols",
|
|
324
|
+
"getPrototypeOf",
|
|
325
|
+
"hasOwn",
|
|
326
|
+
"isArray",
|
|
327
|
+
"keys",
|
|
328
|
+
"values",
|
|
329
|
+
"concat",
|
|
330
|
+
"join",
|
|
331
|
+
"parse",
|
|
332
|
+
"stringify"
|
|
216
333
|
]);
|
|
217
334
|
var hasDuplicateNames = (names) => {
|
|
218
335
|
const seen = new Set;
|
|
@@ -225,6 +342,37 @@ var hasDuplicateNames = (names) => {
|
|
|
225
342
|
}
|
|
226
343
|
return false;
|
|
227
344
|
};
|
|
345
|
+
var hasDuplicatePropertyNames = (properties) => {
|
|
346
|
+
const kindsByName = new Map;
|
|
347
|
+
for (const property of properties) {
|
|
348
|
+
if (property.type !== "Property") {
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
let keyName = null;
|
|
352
|
+
if (property.key.type === "Identifier") {
|
|
353
|
+
keyName = property.key.name;
|
|
354
|
+
} else if (property.key.type === "Literal") {
|
|
355
|
+
const { value } = property.key;
|
|
356
|
+
keyName = typeof value === "string" ? value : String(value);
|
|
357
|
+
}
|
|
358
|
+
if (keyName === null) {
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
const kinds = kindsByName.get(keyName) ?? [];
|
|
362
|
+
kinds.push(property.kind);
|
|
363
|
+
kindsByName.set(keyName, kinds);
|
|
364
|
+
}
|
|
365
|
+
for (const kinds of kindsByName.values()) {
|
|
366
|
+
if (kinds.length === 1) {
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
if (kinds.length === 2 && kinds.includes("get") && kinds.includes("set")) {
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
return true;
|
|
373
|
+
}
|
|
374
|
+
return false;
|
|
375
|
+
};
|
|
228
376
|
var sortKeysFixable = {
|
|
229
377
|
create(context) {
|
|
230
378
|
const { sourceCode } = context;
|
|
@@ -342,7 +490,7 @@ var sortKeysFixable = {
|
|
|
342
490
|
};
|
|
343
491
|
const addAncestorConstBindings = (ancestor, node, stableLocals) => {
|
|
344
492
|
const addDeclarationBindings = (statement) => {
|
|
345
|
-
if (statement.type !== "VariableDeclaration"
|
|
493
|
+
if (statement.type !== "VariableDeclaration") {
|
|
346
494
|
return;
|
|
347
495
|
}
|
|
348
496
|
for (const declaration of statement.declarations) {
|
|
@@ -377,6 +525,7 @@ var sortKeysFixable = {
|
|
|
377
525
|
for (const ancestor of ancestors) {
|
|
378
526
|
addAncestorBindingsForNode(ancestor, node, stableLocals);
|
|
379
527
|
}
|
|
528
|
+
stableLocals.add("this");
|
|
380
529
|
return stableLocals;
|
|
381
530
|
};
|
|
382
531
|
const getStaticMemberName = (memberExpression) => {
|
|
@@ -796,10 +945,66 @@ var sortKeysFixable = {
|
|
|
796
945
|
}
|
|
797
946
|
return isPureImportedCallExpression(callExpression);
|
|
798
947
|
};
|
|
948
|
+
const getCallReturnTypeSymbol = (node) => {
|
|
949
|
+
if (!tsChecker || !esTreeNodeToTSNodeMap)
|
|
950
|
+
return;
|
|
951
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
952
|
+
if (!tsNode)
|
|
953
|
+
return;
|
|
954
|
+
const type = tsChecker.getTypeAtLocation(tsNode);
|
|
955
|
+
return type.symbol ?? type.aliasSymbol;
|
|
956
|
+
};
|
|
957
|
+
const callReturnsNominalInstance = (node) => {
|
|
958
|
+
const symbol = getCallReturnTypeSymbol(node);
|
|
959
|
+
if (!symbol)
|
|
960
|
+
return false;
|
|
961
|
+
const declarations = symbol.declarations;
|
|
962
|
+
if (!declarations)
|
|
963
|
+
return false;
|
|
964
|
+
return declarations.some((declaration) => ts.isClassDeclaration(declaration) || ts.isClassExpression(declaration) || ts.isInterfaceDeclaration(declaration));
|
|
965
|
+
};
|
|
966
|
+
const isEncapsulatedFreshExpression = (node, stableLocals) => {
|
|
967
|
+
if (!node)
|
|
968
|
+
return false;
|
|
969
|
+
if (node.type === "TSAsExpression" || node.type === "TSTypeAssertion" || node.type === "TSNonNullExpression" || node.type === "TSSatisfiesExpression" || node.type === "TSInstantiationExpression") {
|
|
970
|
+
return isEncapsulatedFreshExpression(node.expression, stableLocals);
|
|
971
|
+
}
|
|
972
|
+
if (node.type === "ObjectExpression" || node.type === "ArrayExpression") {
|
|
973
|
+
return isPureRuntimeExpression(node, stableLocals);
|
|
974
|
+
}
|
|
975
|
+
if (node.type === "NewExpression") {
|
|
976
|
+
return node.arguments.every((argument) => {
|
|
977
|
+
if (argument.type === "SpreadElement") {
|
|
978
|
+
return isPureRuntimeExpression(argument.argument, stableLocals);
|
|
979
|
+
}
|
|
980
|
+
return isPureRuntimeExpression(argument, stableLocals);
|
|
981
|
+
});
|
|
982
|
+
}
|
|
983
|
+
if (node.type === "CallExpression") {
|
|
984
|
+
const argsArePure = node.arguments.every((argument) => {
|
|
985
|
+
if (argument.type === "SpreadElement") {
|
|
986
|
+
return isPureRuntimeExpression(argument.argument, stableLocals);
|
|
987
|
+
}
|
|
988
|
+
return isPureRuntimeExpression(argument, stableLocals);
|
|
989
|
+
});
|
|
990
|
+
if (!argsArePure)
|
|
991
|
+
return false;
|
|
992
|
+
if (node.callee.type === "MemberExpression") {
|
|
993
|
+
return isEncapsulatedFreshExpression(node.callee.object, stableLocals);
|
|
994
|
+
}
|
|
995
|
+
if (node.callee.type === "Identifier") {
|
|
996
|
+
return callReturnsNominalInstance(node);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
return false;
|
|
1000
|
+
};
|
|
799
1001
|
const isPureRuntimeExpression = (node, stableLocals) => {
|
|
800
1002
|
if (!node || node.type === "PrivateIdentifier") {
|
|
801
1003
|
return false;
|
|
802
1004
|
}
|
|
1005
|
+
if (node.type === "TSAsExpression" || node.type === "TSTypeAssertion" || node.type === "TSNonNullExpression" || node.type === "TSSatisfiesExpression" || node.type === "TSInstantiationExpression") {
|
|
1006
|
+
return isPureRuntimeExpression(node.expression, stableLocals);
|
|
1007
|
+
}
|
|
803
1008
|
switch (node.type) {
|
|
804
1009
|
case "Identifier":
|
|
805
1010
|
return isStableIdentifier(node.name, stableLocals);
|
|
@@ -823,9 +1028,12 @@ var sortKeysFixable = {
|
|
|
823
1028
|
return isPureRuntimeExpression(node.test, stableLocals) && isPureRuntimeExpression(node.consequent, stableLocals) && isPureRuntimeExpression(node.alternate, stableLocals);
|
|
824
1029
|
case "ArrayExpression":
|
|
825
1030
|
return node.elements.every((element) => {
|
|
826
|
-
if (!element
|
|
1031
|
+
if (!element) {
|
|
827
1032
|
return false;
|
|
828
1033
|
}
|
|
1034
|
+
if (element.type === "SpreadElement") {
|
|
1035
|
+
return isPureRuntimeExpression(element.argument, stableLocals);
|
|
1036
|
+
}
|
|
829
1037
|
return isPureRuntimeExpression(element, stableLocals);
|
|
830
1038
|
});
|
|
831
1039
|
case "ObjectExpression":
|
|
@@ -865,7 +1073,10 @@ var sortKeysFixable = {
|
|
|
865
1073
|
return true;
|
|
866
1074
|
}
|
|
867
1075
|
if (node.callee.type === "Identifier") {
|
|
868
|
-
|
|
1076
|
+
if (isPureIdentifierCall(node)) {
|
|
1077
|
+
return true;
|
|
1078
|
+
}
|
|
1079
|
+
return callReturnsNominalInstance(node);
|
|
869
1080
|
}
|
|
870
1081
|
if (node.callee.type !== "MemberExpression") {
|
|
871
1082
|
return false;
|
|
@@ -874,6 +1085,12 @@ var sortKeysFixable = {
|
|
|
874
1085
|
if (memberName && PURE_MEMBER_METHODS.has(memberName)) {
|
|
875
1086
|
return isPureRuntimeExpression(node.callee.object, stableLocals);
|
|
876
1087
|
}
|
|
1088
|
+
if (isEncapsulatedFreshExpression(node.callee.object, stableLocals)) {
|
|
1089
|
+
return true;
|
|
1090
|
+
}
|
|
1091
|
+
if (isPureRuntimeExpression(node.callee.object, stableLocals) && callReturnsNominalInstance(node)) {
|
|
1092
|
+
return true;
|
|
1093
|
+
}
|
|
877
1094
|
return isPureImportedCallExpression(node);
|
|
878
1095
|
}
|
|
879
1096
|
default:
|
|
@@ -1038,7 +1255,7 @@ ${indent}`;
|
|
|
1038
1255
|
node: prop
|
|
1039
1256
|
};
|
|
1040
1257
|
});
|
|
1041
|
-
if (
|
|
1258
|
+
if (hasDuplicatePropertyNames(node.properties)) {
|
|
1042
1259
|
autoFixable = false;
|
|
1043
1260
|
}
|
|
1044
1261
|
if (autoFixable) {
|
package/package.json
CHANGED