@flint.fyi/ts 0.14.2 → 0.14.3
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 +7 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/nodes.d.ts +1 -0
- package/lib/plugin.d.ts +121 -1
- package/lib/plugin.js +60 -0
- package/lib/rules/asyncPromiseExecutors.d.ts +6 -0
- package/lib/rules/asyncPromiseExecutors.js +51 -0
- package/lib/rules/asyncPromiseExecutors.test.d.ts +1 -0
- package/lib/rules/asyncPromiseExecutors.test.js +71 -0
- package/lib/rules/caseDeclarations.d.ts +6 -0
- package/lib/rules/caseDeclarations.js +53 -0
- package/lib/rules/caseDeclarations.test.d.ts +1 -0
- package/lib/rules/caseDeclarations.test.js +227 -0
- package/lib/rules/chainedAssignments.d.ts +6 -0
- package/lib/rules/chainedAssignments.js +48 -0
- package/lib/rules/chainedAssignments.test.d.ts +1 -0
- package/lib/rules/chainedAssignments.test.js +238 -0
- package/lib/rules/classAssignments.d.ts +6 -0
- package/lib/rules/classAssignments.js +42 -0
- package/lib/rules/classAssignments.test.d.ts +1 -0
- package/lib/rules/classAssignments.test.js +156 -0
- package/lib/rules/constantAssignments.d.ts +6 -0
- package/lib/rules/constantAssignments.js +61 -0
- package/lib/rules/constantAssignments.test.d.ts +1 -0
- package/lib/rules/constantAssignments.test.js +221 -0
- package/lib/rules/constructorReturns.d.ts +6 -0
- package/lib/rules/constructorReturns.js +52 -0
- package/lib/rules/constructorReturns.test.d.ts +1 -0
- package/lib/rules/constructorReturns.test.js +96 -0
- package/lib/rules/defaultCaseLast.d.ts +6 -0
- package/lib/rules/defaultCaseLast.js +43 -0
- package/lib/rules/defaultCaseLast.test.d.ts +1 -0
- package/lib/rules/defaultCaseLast.test.js +195 -0
- package/lib/rules/duplicateArguments.d.ts +6 -0
- package/lib/rules/duplicateArguments.js +51 -0
- package/lib/rules/duplicateArguments.test.d.ts +1 -0
- package/lib/rules/duplicateArguments.test.js +139 -0
- package/lib/rules/emptyDestructures.d.ts +6 -0
- package/lib/rules/emptyDestructures.js +40 -0
- package/lib/rules/emptyDestructures.test.d.ts +1 -0
- package/lib/rules/emptyDestructures.test.js +186 -0
- package/lib/rules/emptyStaticBlocks.d.ts +6 -0
- package/lib/rules/emptyStaticBlocks.js +54 -0
- package/lib/rules/emptyStaticBlocks.test.d.ts +1 -0
- package/lib/rules/emptyStaticBlocks.test.js +167 -0
- package/lib/rules/exceptionAssignments.d.ts +6 -0
- package/lib/rules/exceptionAssignments.js +61 -0
- package/lib/rules/exceptionAssignments.test.d.ts +1 -0
- package/lib/rules/exceptionAssignments.test.js +264 -0
- package/lib/rules/functionAssignments.d.ts +6 -0
- package/lib/rules/functionAssignments.js +42 -0
- package/lib/rules/functionAssignments.test.d.ts +1 -0
- package/lib/rules/functionAssignments.test.js +209 -0
- package/lib/rules/generatorFunctionYields.d.ts +6 -0
- package/lib/rules/generatorFunctionYields.js +57 -0
- package/lib/rules/generatorFunctionYields.test.d.ts +1 -0
- package/lib/rules/generatorFunctionYields.test.js +151 -0
- package/lib/rules/globalAssignments.d.ts +6 -0
- package/lib/rules/globalAssignments.js +59 -0
- package/lib/rules/globalAssignments.test.d.ts +1 -0
- package/lib/rules/globalAssignments.test.js +215 -0
- package/lib/rules/globalObjectCalls.d.ts +6 -0
- package/lib/rules/globalObjectCalls.js +43 -0
- package/lib/rules/globalObjectCalls.test.d.ts +1 -0
- package/lib/rules/globalObjectCalls.test.js +93 -0
- package/lib/rules/negativeZeroComparisons.d.ts +6 -0
- package/lib/rules/negativeZeroComparisons.js +83 -0
- package/lib/rules/negativeZeroComparisons.test.d.ts +1 -0
- package/lib/rules/negativeZeroComparisons.test.js +209 -0
- package/lib/rules/newExpressions.d.ts +6 -0
- package/lib/rules/newExpressions.js +54 -0
- package/lib/rules/newExpressions.test.d.ts +1 -0
- package/lib/rules/newExpressions.test.js +79 -0
- package/lib/rules/newNativeNonConstructors.d.ts +6 -0
- package/lib/rules/newNativeNonConstructors.js +49 -0
- package/lib/rules/newNativeNonConstructors.test.d.ts +1 -0
- package/lib/rules/newNativeNonConstructors.test.js +94 -0
- package/lib/rules/objectProto.d.ts +6 -0
- package/lib/rules/objectProto.js +54 -0
- package/lib/rules/objectProto.test.d.ts +1 -0
- package/lib/rules/objectProto.test.js +96 -0
- package/lib/rules/octalNumbers.d.ts +6 -0
- package/lib/rules/octalNumbers.js +68 -0
- package/lib/rules/octalNumbers.test.d.ts +1 -0
- package/lib/rules/octalNumbers.test.js +245 -0
- package/lib/rules/returnAssignments.d.ts +6 -0
- package/lib/rules/returnAssignments.js +50 -0
- package/lib/rules/returnAssignments.test.d.ts +1 -0
- package/lib/rules/returnAssignments.test.js +185 -0
- package/lib/rules/sparseArrays.d.ts +6 -0
- package/lib/rules/sparseArrays.js +54 -0
- package/lib/rules/sparseArrays.test.d.ts +1 -0
- package/lib/rules/sparseArrays.test.js +110 -0
- package/lib/rules/symbolDescriptions.d.ts +6 -0
- package/lib/rules/symbolDescriptions.js +41 -0
- package/lib/rules/symbolDescriptions.test.d.ts +1 -0
- package/lib/rules/symbolDescriptions.test.js +89 -0
- package/lib/rules/unassignedVariables.d.ts +6 -0
- package/lib/rules/unassignedVariables.js +55 -0
- package/lib/rules/unassignedVariables.test.d.ts +1 -0
- package/lib/rules/unassignedVariables.test.js +72 -0
- package/lib/rules/undefinedVariables.d.ts +6 -0
- package/lib/rules/undefinedVariables.js +76 -0
- package/lib/rules/undefinedVariables.test.d.ts +1 -0
- package/lib/rules/undefinedVariables.test.js +80 -0
- package/lib/rules/unicodeBOMs.d.ts +6 -0
- package/lib/rules/unicodeBOMs.js +41 -0
- package/lib/rules/unicodeBOMs.test.d.ts +1 -0
- package/lib/rules/unicodeBOMs.test.js +65 -0
- package/lib/rules/unnecessaryCatches.d.ts +6 -0
- package/lib/rules/unnecessaryCatches.js +68 -0
- package/lib/rules/unnecessaryCatches.test.d.ts +1 -0
- package/lib/rules/unnecessaryCatches.test.js +210 -0
- package/lib/rules/unsafeNegations.d.ts +6 -0
- package/lib/rules/unsafeNegations.js +50 -0
- package/lib/rules/unsafeNegations.test.d.ts +1 -0
- package/lib/rules/unsafeNegations.test.js +63 -0
- package/lib/rules/variableDeletions.d.ts +6 -0
- package/lib/rules/variableDeletions.js +39 -0
- package/lib/rules/variableDeletions.test.d.ts +1 -0
- package/lib/rules/variableDeletions.test.js +75 -0
- package/lib/rules/voidOperator.d.ts +6 -0
- package/lib/rules/voidOperator.js +36 -0
- package/lib/rules/voidOperator.test.d.ts +1 -0
- package/lib/rules/voidOperator.test.js +98 -0
- package/lib/utils/declarationsIncludeGlobal.d.ts +2 -0
- package/lib/utils/declarationsIncludeGlobal.js +7 -0
- package/lib/utils/getModifyingReferences.d.ts +8 -0
- package/lib/utils/getModifyingReferences.js +42 -0
- package/lib/utils/isGlobalDeclaration.d.ts +2 -0
- package/lib/utils/isGlobalDeclaration.js +5 -0
- package/lib/utils/isGlobalVariable.d.ts +8 -0
- package/lib/utils/isGlobalVariable.js +21 -0
- package/lib/utils/unwrapParentParenthesizedExpressions.d.ts +2 -0
- package/lib/utils/unwrapParentParenthesizedExpressions.js +6 -0
- package/lib/utils/unwrapParenthesizedExpression.d.ts +2 -0
- package/lib/utils/unwrapParenthesizedExpression.js +6 -0
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/nodes.ts +1 -0
- package/src/plugin.ts +60 -0
- package/src/rules/asyncPromiseExecutors.test.ts +72 -0
- package/src/rules/asyncPromiseExecutors.ts +61 -0
- package/src/rules/caseDeclarations.test.ts +228 -0
- package/src/rules/caseDeclarations.ts +70 -0
- package/src/rules/chainedAssignments.test.ts +239 -0
- package/src/rules/chainedAssignments.ts +55 -0
- package/src/rules/classAssignments.test.ts +157 -0
- package/src/rules/classAssignments.ts +50 -0
- package/src/rules/constantAssignments.test.ts +222 -0
- package/src/rules/constantAssignments.ts +78 -0
- package/src/rules/constructorReturns.test.ts +97 -0
- package/src/rules/constructorReturns.ts +59 -0
- package/src/rules/defaultCaseLast.test.ts +196 -0
- package/src/rules/defaultCaseLast.ts +54 -0
- package/src/rules/duplicateArguments.test.ts +140 -0
- package/src/rules/duplicateArguments.ts +58 -0
- package/src/rules/emptyDestructures.test.ts +187 -0
- package/src/rules/emptyDestructures.ts +48 -0
- package/src/rules/emptyStaticBlocks.test.ts +168 -0
- package/src/rules/emptyStaticBlocks.ts +60 -0
- package/src/rules/exceptionAssignments.test.ts +265 -0
- package/src/rules/exceptionAssignments.ts +77 -0
- package/src/rules/functionAssignments.test.ts +210 -0
- package/src/rules/functionAssignments.ts +51 -0
- package/src/rules/generatorFunctionYields.test.ts +152 -0
- package/src/rules/generatorFunctionYields.ts +71 -0
- package/src/rules/globalAssignments.test.ts +216 -0
- package/src/rules/globalAssignments.ts +67 -0
- package/src/rules/globalObjectCalls.test.ts +94 -0
- package/src/rules/globalObjectCalls.ts +52 -0
- package/src/rules/negativeZeroComparisons.test.ts +210 -0
- package/src/rules/negativeZeroComparisons.ts +106 -0
- package/src/rules/newExpressions.test.ts +80 -0
- package/src/rules/newExpressions.ts +67 -0
- package/src/rules/newNativeNonConstructors.test.ts +95 -0
- package/src/rules/newNativeNonConstructors.ts +59 -0
- package/src/rules/objectProto.test.ts +97 -0
- package/src/rules/objectProto.ts +62 -0
- package/src/rules/octalNumbers.test.ts +246 -0
- package/src/rules/octalNumbers.ts +75 -0
- package/src/rules/returnAssignments.test.ts +186 -0
- package/src/rules/returnAssignments.ts +57 -0
- package/src/rules/sparseArrays.test.ts +111 -0
- package/src/rules/sparseArrays.ts +61 -0
- package/src/rules/symbolDescriptions.test.ts +90 -0
- package/src/rules/symbolDescriptions.ts +47 -0
- package/src/rules/unassignedVariables.test.ts +73 -0
- package/src/rules/unassignedVariables.ts +69 -0
- package/src/rules/undefinedVariables.test.ts +81 -0
- package/src/rules/undefinedVariables.ts +97 -0
- package/src/rules/unicodeBOMs.test.ts +66 -0
- package/src/rules/unicodeBOMs.ts +44 -0
- package/src/rules/unnecessaryCatches.test.ts +211 -0
- package/src/rules/unnecessaryCatches.ts +84 -0
- package/src/rules/unsafeNegations.test.ts +64 -0
- package/src/rules/unsafeNegations.ts +59 -0
- package/src/rules/variableDeletions.test.ts +76 -0
- package/src/rules/variableDeletions.ts +43 -0
- package/src/rules/voidOperator.test.ts +99 -0
- package/src/rules/voidOperator.ts +38 -0
- package/src/utils/declarationsIncludeGlobal.ts +11 -0
- package/src/utils/getModifyingReferences.ts +58 -0
- package/src/utils/isGlobalDeclaration.ts +12 -0
- package/src/utils/isGlobalVariable.ts +30 -0
- package/src/utils/unwrapParentParenthesizedExpressions.ts +7 -0
- package/src/utils/unwrapParenthesizedExpression.ts +9 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import rule from "./newNativeNonConstructors.js";
|
|
2
|
+
import { ruleTester } from "./ruleTester.js";
|
|
3
|
+
ruleTester.describe(rule, {
|
|
4
|
+
invalid: [
|
|
5
|
+
{
|
|
6
|
+
code: `
|
|
7
|
+
new Symbol("description");
|
|
8
|
+
`,
|
|
9
|
+
output: `
|
|
10
|
+
Symbol("description");
|
|
11
|
+
`,
|
|
12
|
+
snapshot: `
|
|
13
|
+
new Symbol("description");
|
|
14
|
+
~~~
|
|
15
|
+
Symbol cannot be called with \`new\`.
|
|
16
|
+
`,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
code: `
|
|
20
|
+
new BigInt(42);
|
|
21
|
+
`,
|
|
22
|
+
output: `
|
|
23
|
+
BigInt(42);
|
|
24
|
+
`,
|
|
25
|
+
snapshot: `
|
|
26
|
+
new BigInt(42);
|
|
27
|
+
~~~
|
|
28
|
+
BigInt cannot be called with \`new\`.
|
|
29
|
+
`,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
code: `
|
|
33
|
+
const value = new Symbol();
|
|
34
|
+
`,
|
|
35
|
+
output: `
|
|
36
|
+
const value = Symbol();
|
|
37
|
+
`,
|
|
38
|
+
snapshot: `
|
|
39
|
+
const value = new Symbol();
|
|
40
|
+
~~~
|
|
41
|
+
Symbol cannot be called with \`new\`.
|
|
42
|
+
`,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
code: `
|
|
46
|
+
function create() {
|
|
47
|
+
return new BigInt(100);
|
|
48
|
+
}
|
|
49
|
+
`,
|
|
50
|
+
output: `
|
|
51
|
+
function create() {
|
|
52
|
+
return BigInt(100);
|
|
53
|
+
}
|
|
54
|
+
`,
|
|
55
|
+
snapshot: `
|
|
56
|
+
function create() {
|
|
57
|
+
return new BigInt(100);
|
|
58
|
+
~~~
|
|
59
|
+
BigInt cannot be called with \`new\`.
|
|
60
|
+
}
|
|
61
|
+
`,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
valid: [
|
|
65
|
+
`Symbol("description");`,
|
|
66
|
+
`BigInt(42);`,
|
|
67
|
+
`const value = Symbol();`,
|
|
68
|
+
`const number = BigInt(100);`,
|
|
69
|
+
`function create() { return Symbol("key"); }`,
|
|
70
|
+
`const array = [Symbol("a"), Symbol("b")];`,
|
|
71
|
+
`new String("text");`,
|
|
72
|
+
`new Number(42);`,
|
|
73
|
+
`new Boolean(true);`,
|
|
74
|
+
`new Object();`,
|
|
75
|
+
`new Array();`,
|
|
76
|
+
`new Date();`,
|
|
77
|
+
`new Error("message");`,
|
|
78
|
+
`new Map();`,
|
|
79
|
+
`new Set();`,
|
|
80
|
+
`new Promise((resolve) => resolve());`,
|
|
81
|
+
`new WeakMap();`,
|
|
82
|
+
`new WeakSet();`,
|
|
83
|
+
`
|
|
84
|
+
class BigInt {}
|
|
85
|
+
new BigInt();
|
|
86
|
+
export {}
|
|
87
|
+
`,
|
|
88
|
+
`
|
|
89
|
+
class Symbol {}
|
|
90
|
+
new Symbol();
|
|
91
|
+
export {}
|
|
92
|
+
`,
|
|
93
|
+
],
|
|
94
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports using the deprecated __proto__ property to access or modify an object's prototype.";
|
|
3
|
+
readonly id: "objectProto";
|
|
4
|
+
readonly preset: "untyped";
|
|
5
|
+
}, import("../nodes.js").TSNodesByName, import("../language.js").TypeScriptServices, "noProto", undefined>;
|
|
6
|
+
export default _default;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import { typescriptLanguage } from "../language.js";
|
|
3
|
+
export default typescriptLanguage.createRule({
|
|
4
|
+
about: {
|
|
5
|
+
description: "Reports using the deprecated __proto__ property to access or modify an object's prototype.",
|
|
6
|
+
id: "objectProto",
|
|
7
|
+
preset: "untyped",
|
|
8
|
+
},
|
|
9
|
+
messages: {
|
|
10
|
+
noProto: {
|
|
11
|
+
primary: "Use Object.getPrototypeOf or Object.setPrototypeOf instead of the deprecated __proto__ property.",
|
|
12
|
+
secondary: [
|
|
13
|
+
"The __proto__ property is deprecated and not part of the ECMAScript standard.",
|
|
14
|
+
"It is maintained for compatibility with older browsers but can cause performance issues and unexpected behavior.",
|
|
15
|
+
"Direct manipulation of an object's prototype can lead to hidden classes deoptimizations in JavaScript engines.",
|
|
16
|
+
],
|
|
17
|
+
suggestions: [
|
|
18
|
+
"Use Object.getPrototypeOf(obj) to read the prototype of an object.",
|
|
19
|
+
"Use Object.setPrototypeOf(obj, proto) to set the prototype of an object.",
|
|
20
|
+
"Use Object.create(proto) when creating new objects with a specific prototype.",
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
setup(context) {
|
|
25
|
+
return {
|
|
26
|
+
visitors: {
|
|
27
|
+
ElementAccessExpression: (node) => {
|
|
28
|
+
if (ts.isStringLiteral(node.argumentExpression) &&
|
|
29
|
+
node.argumentExpression.text === "__proto__") {
|
|
30
|
+
context.report({
|
|
31
|
+
message: "noProto",
|
|
32
|
+
range: {
|
|
33
|
+
begin: node.argumentExpression.getStart(context.sourceFile),
|
|
34
|
+
end: node.argumentExpression.getEnd(),
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
PropertyAccessExpression: (node) => {
|
|
40
|
+
if (node.name.kind === ts.SyntaxKind.Identifier &&
|
|
41
|
+
node.name.text === "__proto__") {
|
|
42
|
+
context.report({
|
|
43
|
+
message: "noProto",
|
|
44
|
+
range: {
|
|
45
|
+
begin: node.name.getStart(context.sourceFile),
|
|
46
|
+
end: node.name.getEnd(),
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import rule from "./objectProto.js";
|
|
2
|
+
import { ruleTester } from "./ruleTester.js";
|
|
3
|
+
ruleTester.describe(rule, {
|
|
4
|
+
invalid: [
|
|
5
|
+
{
|
|
6
|
+
code: `
|
|
7
|
+
const proto = obj.__proto__;
|
|
8
|
+
`,
|
|
9
|
+
snapshot: `
|
|
10
|
+
const proto = obj.__proto__;
|
|
11
|
+
~~~~~~~~~
|
|
12
|
+
Use Object.getPrototypeOf or Object.setPrototypeOf instead of the deprecated __proto__ property.
|
|
13
|
+
`,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
code: `
|
|
17
|
+
obj.__proto__ = prototype;
|
|
18
|
+
`,
|
|
19
|
+
snapshot: `
|
|
20
|
+
obj.__proto__ = prototype;
|
|
21
|
+
~~~~~~~~~
|
|
22
|
+
Use Object.getPrototypeOf or Object.setPrototypeOf instead of the deprecated __proto__ property.
|
|
23
|
+
`,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
code: `
|
|
27
|
+
const descriptor = Object.getOwnPropertyDescriptor(obj, "__proto__");
|
|
28
|
+
const proto = obj.__proto__;
|
|
29
|
+
`,
|
|
30
|
+
snapshot: `
|
|
31
|
+
const descriptor = Object.getOwnPropertyDescriptor(obj, "__proto__");
|
|
32
|
+
const proto = obj.__proto__;
|
|
33
|
+
~~~~~~~~~
|
|
34
|
+
Use Object.getPrototypeOf or Object.setPrototypeOf instead of the deprecated __proto__ property.
|
|
35
|
+
`,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
code: `
|
|
39
|
+
const value = obj["__proto__"];
|
|
40
|
+
`,
|
|
41
|
+
snapshot: `
|
|
42
|
+
const value = obj["__proto__"];
|
|
43
|
+
~~~~~~~~~~~
|
|
44
|
+
Use Object.getPrototypeOf or Object.setPrototypeOf instead of the deprecated __proto__ property.
|
|
45
|
+
`,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
code: `
|
|
49
|
+
obj["__proto__"] = prototype;
|
|
50
|
+
`,
|
|
51
|
+
snapshot: `
|
|
52
|
+
obj["__proto__"] = prototype;
|
|
53
|
+
~~~~~~~~~~~
|
|
54
|
+
Use Object.getPrototypeOf or Object.setPrototypeOf instead of the deprecated __proto__ property.
|
|
55
|
+
`,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
code: `
|
|
59
|
+
if (obj.__proto__ === null) {
|
|
60
|
+
console.log("No prototype");
|
|
61
|
+
}
|
|
62
|
+
`,
|
|
63
|
+
snapshot: `
|
|
64
|
+
if (obj.__proto__ === null) {
|
|
65
|
+
~~~~~~~~~
|
|
66
|
+
Use Object.getPrototypeOf or Object.setPrototypeOf instead of the deprecated __proto__ property.
|
|
67
|
+
console.log("No prototype");
|
|
68
|
+
}
|
|
69
|
+
`,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
code: `
|
|
73
|
+
function getProto(obj: object) {
|
|
74
|
+
return obj.__proto__;
|
|
75
|
+
}
|
|
76
|
+
`,
|
|
77
|
+
snapshot: `
|
|
78
|
+
function getProto(obj: object) {
|
|
79
|
+
return obj.__proto__;
|
|
80
|
+
~~~~~~~~~
|
|
81
|
+
Use Object.getPrototypeOf or Object.setPrototypeOf instead of the deprecated __proto__ property.
|
|
82
|
+
}
|
|
83
|
+
`,
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
valid: [
|
|
87
|
+
`const proto = Object.getPrototypeOf(obj);`,
|
|
88
|
+
`Object.setPrototypeOf(obj, prototype);`,
|
|
89
|
+
`const obj = Object.create(prototype);`,
|
|
90
|
+
`const descriptor = Object.getOwnPropertyDescriptor(obj, "__proto__");`,
|
|
91
|
+
`const key = "__proto__";`,
|
|
92
|
+
`const string = "obj.__proto__";`,
|
|
93
|
+
`const obj = { "__proto__": null };`,
|
|
94
|
+
`const obj = { __proto__: null };`,
|
|
95
|
+
],
|
|
96
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports using legacy octal numeric literals.";
|
|
3
|
+
readonly id: "octalNumbers";
|
|
4
|
+
readonly preset: "untyped";
|
|
5
|
+
}, import("../nodes.js").TSNodesByName, import("../language.js").TypeScriptServices, "noOctalNumber", undefined>;
|
|
6
|
+
export default _default;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { typescriptLanguage } from "../language.js";
|
|
2
|
+
export default typescriptLanguage.createRule({
|
|
3
|
+
about: {
|
|
4
|
+
description: "Reports using legacy octal numeric literals.",
|
|
5
|
+
id: "octalNumbers",
|
|
6
|
+
preset: "untyped",
|
|
7
|
+
},
|
|
8
|
+
messages: {
|
|
9
|
+
noOctalNumber: {
|
|
10
|
+
primary: "This legacy octal numeric literal evaluates to {{ raw }}. Did you mean that value, or to use a modern octal syntax such as {{ equivalent }}?",
|
|
11
|
+
secondary: [
|
|
12
|
+
"Legacy octal numeric literals (e.g., `077`, `0123`) are a deprecated feature in JavaScript that can lead to confusion and errors.",
|
|
13
|
+
"They are forbidden in strict mode and are less readable than their modern alternatives.",
|
|
14
|
+
"The digit `0` by itself is allowed as it represents zero, not an octal literal.",
|
|
15
|
+
],
|
|
16
|
+
suggestions: [
|
|
17
|
+
"Use the explicit octal syntax (e.g., `0o77`) introduced in ES6, which is clearer and works in both strict and non-strict modes.",
|
|
18
|
+
"Remove the leading `0` if you intended to use the decimal value.",
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
setup(context) {
|
|
23
|
+
return {
|
|
24
|
+
visitors: {
|
|
25
|
+
NumericLiteral: (node) => {
|
|
26
|
+
const text = node.getText(context.sourceFile);
|
|
27
|
+
// Check for legacy octal literal: starts with 0 followed by octal digits (0-7)
|
|
28
|
+
// But not just "0" alone, and not modern formats like 0x, 0o, 0b
|
|
29
|
+
// cspell:ignore xobi
|
|
30
|
+
if (text.length > 1 &&
|
|
31
|
+
text.startsWith("0") &&
|
|
32
|
+
text[1] >= "0" &&
|
|
33
|
+
text[1] <= "7" &&
|
|
34
|
+
!/^0[xobi]/i.test(text)) {
|
|
35
|
+
const range = {
|
|
36
|
+
begin: node.getStart(context.sourceFile),
|
|
37
|
+
end: node.getEnd(),
|
|
38
|
+
};
|
|
39
|
+
// Parse the octal value
|
|
40
|
+
const octalValue = parseInt(text, 8);
|
|
41
|
+
const modernOctalSyntax = `0o${text.slice(1)}`;
|
|
42
|
+
const decimalWithoutLeadingZero = text.slice(1);
|
|
43
|
+
context.report({
|
|
44
|
+
data: {
|
|
45
|
+
equivalent: modernOctalSyntax,
|
|
46
|
+
raw: octalValue.toString(),
|
|
47
|
+
},
|
|
48
|
+
message: "noOctalNumber",
|
|
49
|
+
range,
|
|
50
|
+
suggestions: [
|
|
51
|
+
{
|
|
52
|
+
id: "useModernOctalSyntax",
|
|
53
|
+
range,
|
|
54
|
+
text: modernOctalSyntax,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "removeLeadingZero",
|
|
58
|
+
range,
|
|
59
|
+
text: decimalWithoutLeadingZero,
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import rule from "./octalNumbers.js";
|
|
2
|
+
import { ruleTester } from "./ruleTester.js";
|
|
3
|
+
ruleTester.describe(rule, {
|
|
4
|
+
invalid: [
|
|
5
|
+
{
|
|
6
|
+
code: `
|
|
7
|
+
const value = 07;
|
|
8
|
+
`,
|
|
9
|
+
snapshot: `
|
|
10
|
+
const value = 07;
|
|
11
|
+
~~
|
|
12
|
+
This legacy octal numeric literal evaluates to 7. Did you mean that value, or to use a modern octal syntax such as 0o7?
|
|
13
|
+
`,
|
|
14
|
+
suggestions: [
|
|
15
|
+
{
|
|
16
|
+
id: "useModernOctalSyntax",
|
|
17
|
+
updated: `
|
|
18
|
+
const value = 0o7;
|
|
19
|
+
`,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "removeLeadingZero",
|
|
23
|
+
updated: `
|
|
24
|
+
const value = 7;
|
|
25
|
+
`,
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
code: `
|
|
31
|
+
const value = 077;
|
|
32
|
+
`,
|
|
33
|
+
snapshot: `
|
|
34
|
+
const value = 077;
|
|
35
|
+
~~~
|
|
36
|
+
This legacy octal numeric literal evaluates to 63. Did you mean that value, or to use a modern octal syntax such as 0o77?
|
|
37
|
+
`,
|
|
38
|
+
suggestions: [
|
|
39
|
+
{
|
|
40
|
+
id: "useModernOctalSyntax",
|
|
41
|
+
updated: `
|
|
42
|
+
const value = 0o77;
|
|
43
|
+
`,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: "removeLeadingZero",
|
|
47
|
+
updated: `
|
|
48
|
+
const value = 77;
|
|
49
|
+
`,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
code: `
|
|
55
|
+
const value = 0123;
|
|
56
|
+
`,
|
|
57
|
+
snapshot: `
|
|
58
|
+
const value = 0123;
|
|
59
|
+
~~~~
|
|
60
|
+
This legacy octal numeric literal evaluates to 83. Did you mean that value, or to use a modern octal syntax such as 0o123?
|
|
61
|
+
`,
|
|
62
|
+
suggestions: [
|
|
63
|
+
{
|
|
64
|
+
id: "useModernOctalSyntax",
|
|
65
|
+
updated: `
|
|
66
|
+
const value = 0o123;
|
|
67
|
+
`,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: "removeLeadingZero",
|
|
71
|
+
updated: `
|
|
72
|
+
const value = 123;
|
|
73
|
+
`,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
code: `
|
|
79
|
+
const value = 01234567;
|
|
80
|
+
`,
|
|
81
|
+
snapshot: `
|
|
82
|
+
const value = 01234567;
|
|
83
|
+
~~~~~~~~
|
|
84
|
+
This legacy octal numeric literal evaluates to 342391. Did you mean that value, or to use a modern octal syntax such as 0o1234567?
|
|
85
|
+
`,
|
|
86
|
+
suggestions: [
|
|
87
|
+
{
|
|
88
|
+
id: "useModernOctalSyntax",
|
|
89
|
+
updated: `
|
|
90
|
+
const value = 0o1234567;
|
|
91
|
+
`,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: "removeLeadingZero",
|
|
95
|
+
updated: `
|
|
96
|
+
const value = 1234567;
|
|
97
|
+
`,
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
code: `
|
|
103
|
+
const values = [01, 02, 03];
|
|
104
|
+
`,
|
|
105
|
+
snapshot: `
|
|
106
|
+
const values = [01, 02, 03];
|
|
107
|
+
~~
|
|
108
|
+
This legacy octal numeric literal evaluates to 1. Did you mean that value, or to use a modern octal syntax such as 0o1?
|
|
109
|
+
~~
|
|
110
|
+
This legacy octal numeric literal evaluates to 2. Did you mean that value, or to use a modern octal syntax such as 0o2?
|
|
111
|
+
~~
|
|
112
|
+
This legacy octal numeric literal evaluates to 3. Did you mean that value, or to use a modern octal syntax such as 0o3?
|
|
113
|
+
`,
|
|
114
|
+
suggestions: [
|
|
115
|
+
{
|
|
116
|
+
id: "useModernOctalSyntax",
|
|
117
|
+
updated: `
|
|
118
|
+
const values = [0o1, 02, 03];
|
|
119
|
+
`,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: "removeLeadingZero",
|
|
123
|
+
updated: `
|
|
124
|
+
const values = [1, 02, 03];
|
|
125
|
+
`,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: "useModernOctalSyntax",
|
|
129
|
+
updated: `
|
|
130
|
+
const values = [01, 0o2, 03];
|
|
131
|
+
`,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: "removeLeadingZero",
|
|
135
|
+
updated: `
|
|
136
|
+
const values = [01, 2, 03];
|
|
137
|
+
`,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: "useModernOctalSyntax",
|
|
141
|
+
updated: `
|
|
142
|
+
const values = [01, 02, 0o3];
|
|
143
|
+
`,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
id: "removeLeadingZero",
|
|
147
|
+
updated: `
|
|
148
|
+
const values = [01, 02, 3];
|
|
149
|
+
`,
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
code: `
|
|
155
|
+
function calculate() {
|
|
156
|
+
return 077;
|
|
157
|
+
}
|
|
158
|
+
`,
|
|
159
|
+
snapshot: `
|
|
160
|
+
function calculate() {
|
|
161
|
+
return 077;
|
|
162
|
+
~~~
|
|
163
|
+
This legacy octal numeric literal evaluates to 63. Did you mean that value, or to use a modern octal syntax such as 0o77?
|
|
164
|
+
}
|
|
165
|
+
`,
|
|
166
|
+
suggestions: [
|
|
167
|
+
{
|
|
168
|
+
id: "useModernOctalSyntax",
|
|
169
|
+
updated: `
|
|
170
|
+
function calculate() {
|
|
171
|
+
return 0o77;
|
|
172
|
+
}
|
|
173
|
+
`,
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
id: "removeLeadingZero",
|
|
177
|
+
updated: `
|
|
178
|
+
function calculate() {
|
|
179
|
+
return 77;
|
|
180
|
+
}
|
|
181
|
+
`,
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
code: `
|
|
187
|
+
const result = 010 + 020;
|
|
188
|
+
`,
|
|
189
|
+
snapshot: `
|
|
190
|
+
const result = 010 + 020;
|
|
191
|
+
~~~
|
|
192
|
+
This legacy octal numeric literal evaluates to 8. Did you mean that value, or to use a modern octal syntax such as 0o10?
|
|
193
|
+
~~~
|
|
194
|
+
This legacy octal numeric literal evaluates to 16. Did you mean that value, or to use a modern octal syntax such as 0o20?
|
|
195
|
+
`,
|
|
196
|
+
suggestions: [
|
|
197
|
+
{
|
|
198
|
+
id: "useModernOctalSyntax",
|
|
199
|
+
updated: `
|
|
200
|
+
const result = 0o10 + 020;
|
|
201
|
+
`,
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
id: "removeLeadingZero",
|
|
205
|
+
updated: `
|
|
206
|
+
const result = 10 + 020;
|
|
207
|
+
`,
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
id: "useModernOctalSyntax",
|
|
211
|
+
updated: `
|
|
212
|
+
const result = 010 + 0o20;
|
|
213
|
+
`,
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
id: "removeLeadingZero",
|
|
217
|
+
updated: `
|
|
218
|
+
const result = 010 + 20;
|
|
219
|
+
`,
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
},
|
|
223
|
+
],
|
|
224
|
+
valid: [
|
|
225
|
+
`const value = 0;`,
|
|
226
|
+
`const value = 1;`,
|
|
227
|
+
`const value = 10;`,
|
|
228
|
+
`const value = 100;`,
|
|
229
|
+
`const value = 0x7F;`,
|
|
230
|
+
`const value = 0o77;`,
|
|
231
|
+
`const value = 0O77;`,
|
|
232
|
+
`const value = 0b111;`,
|
|
233
|
+
`const value = 0B111;`,
|
|
234
|
+
`const value = 0.8;`,
|
|
235
|
+
`const value = 8;`,
|
|
236
|
+
`const value = 9;`,
|
|
237
|
+
`const value = 123;`,
|
|
238
|
+
`const values = [0, 1, 10, 100];`,
|
|
239
|
+
`const hex = 0xFF;`,
|
|
240
|
+
`const binary = 0b1010;`,
|
|
241
|
+
`const octal = 0o755;`,
|
|
242
|
+
`const notOctal = 08;`,
|
|
243
|
+
`const alsoNotOctal = 09;`,
|
|
244
|
+
],
|
|
245
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports using assignment expressions in return statements.";
|
|
3
|
+
readonly id: "returnAssignments";
|
|
4
|
+
readonly preset: "stylistic";
|
|
5
|
+
}, import("../nodes.js").TSNodesByName, import("../language.js").TypeScriptServices, "noReturnAssign", undefined>;
|
|
6
|
+
export default _default;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as tsutils from "ts-api-utils";
|
|
2
|
+
import * as ts from "typescript";
|
|
3
|
+
import { getTSNodeRange } from "../getTSNodeRange.js";
|
|
4
|
+
import { typescriptLanguage } from "../language.js";
|
|
5
|
+
import { unwrapParenthesizedExpression } from "../utils/unwrapParenthesizedExpression.js";
|
|
6
|
+
export default typescriptLanguage.createRule({
|
|
7
|
+
about: {
|
|
8
|
+
description: "Reports using assignment expressions in return statements.",
|
|
9
|
+
id: "returnAssignments",
|
|
10
|
+
preset: "stylistic",
|
|
11
|
+
},
|
|
12
|
+
messages: {
|
|
13
|
+
noReturnAssign: {
|
|
14
|
+
primary: "Placing an assignment inside a return statement can be misleading and is often a sign of a logical mistake.",
|
|
15
|
+
secondary: [
|
|
16
|
+
"Using assignments in return statements can make code harder to read and can lead to confusion about whether the assignment or the returned value is the primary intent.",
|
|
17
|
+
"Assignment expressions return the assigned value, but mixing assignment with return makes the control flow less clear.",
|
|
18
|
+
],
|
|
19
|
+
suggestions: [
|
|
20
|
+
"Perform the assignment on a separate line before the return statement.",
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
setup(context) {
|
|
25
|
+
function checkForAssignment(node) {
|
|
26
|
+
const unwrapped = unwrapParenthesizedExpression(node);
|
|
27
|
+
if (ts.isBinaryExpression(unwrapped) &&
|
|
28
|
+
tsutils.isAssignmentKind(unwrapped.operatorToken.kind)) {
|
|
29
|
+
context.report({
|
|
30
|
+
message: "noReturnAssign",
|
|
31
|
+
range: getTSNodeRange(unwrapped.operatorToken, context.sourceFile),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
visitors: {
|
|
37
|
+
ArrowFunction: (node) => {
|
|
38
|
+
if (!ts.isBlock(node.body)) {
|
|
39
|
+
checkForAssignment(node.body);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
ReturnStatement: (node) => {
|
|
43
|
+
if (node.expression) {
|
|
44
|
+
checkForAssignment(node.expression);
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|