@intentius/chant 0.18.18 → 0.18.19
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evl002-control-flow-resource.d.ts","sourceRoot":"","sources":["../../../src/lint/rules/evl002-control-flow-resource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAA+B,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"evl002-control-flow-resource.d.ts","sourceRoot":"","sources":["../../../src/lint/rules/evl002-control-flow-resource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAA+B,MAAM,SAAS,CAAC;AAmErE,eAAO,MAAM,6BAA6B,EAAE,QAU3C,CAAC"}
|
package/package.json
CHANGED
|
@@ -32,6 +32,18 @@ describe("EVL002: control-flow-resource", () => {
|
|
|
32
32
|
expect(diags[0].message).toContain("control flow");
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
+
test("does not flag a built-in constructor in control flow (guard clauses, collections)", () => {
|
|
36
|
+
// `new Error()` in a guard, or a local `new Map()`/`new Set()`, is not a resource.
|
|
37
|
+
for (const code of [
|
|
38
|
+
`if (bad) { throw new Error("boom"); }`,
|
|
39
|
+
`if (bad) { throw new TypeError("boom"); }`,
|
|
40
|
+
`for (const x of xs) { const m = new Map(); }`,
|
|
41
|
+
`if (cond) { const s = new Set([1]); }`,
|
|
42
|
+
]) {
|
|
43
|
+
expect(evl002ControlFlowResourceRule.check(createContext(code))).toHaveLength(0);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
35
47
|
test("flags resource inside for loop", () => {
|
|
36
48
|
const ctx = createContext(`
|
|
37
49
|
for (let i = 0; i < 3; i++) {
|
|
@@ -20,6 +20,23 @@ const CONTROL_FLOW_KINDS = new Set([
|
|
|
20
20
|
ts.SyntaxKind.TryStatement,
|
|
21
21
|
]);
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* JS built-ins that are never a cloud resource. The rule guards resource
|
|
25
|
+
* declarations, so a guard clause like `if (bad) throw new Error(...)` — or a
|
|
26
|
+
* local `new Map()`/`new Set()` — must not be flagged as a control-flow resource.
|
|
27
|
+
*/
|
|
28
|
+
const NON_RESOURCE_CONSTRUCTORS = new Set([
|
|
29
|
+
"Error", "TypeError", "RangeError", "SyntaxError", "ReferenceError",
|
|
30
|
+
"EvalError", "URIError", "AggregateError",
|
|
31
|
+
"Map", "Set", "WeakMap", "WeakSet", "WeakRef", "Date", "RegExp", "Promise",
|
|
32
|
+
"Array", "Object", "String", "Number", "Boolean",
|
|
33
|
+
]);
|
|
34
|
+
|
|
35
|
+
/** The constructor identifier of a `new X(...)`, if it's a bare name. */
|
|
36
|
+
function constructorName(node: ts.NewExpression): string | undefined {
|
|
37
|
+
return ts.isIdentifier(node.expression) ? node.expression.text : undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
23
40
|
function isInsideControlFlow(node: ts.Node): boolean {
|
|
24
41
|
let current = node.parent;
|
|
25
42
|
while (current) {
|
|
@@ -30,7 +47,7 @@ function isInsideControlFlow(node: ts.Node): boolean {
|
|
|
30
47
|
}
|
|
31
48
|
|
|
32
49
|
function checkNode(node: ts.Node, context: LintContext, diagnostics: LintDiagnostic[]): void {
|
|
33
|
-
if (ts.isNewExpression(node)) {
|
|
50
|
+
if (ts.isNewExpression(node) && !NON_RESOURCE_CONSTRUCTORS.has(constructorName(node) ?? "")) {
|
|
34
51
|
if (isInsideControlFlow(node)) {
|
|
35
52
|
const { line, character } = context.sourceFile.getLineAndCharacterOfPosition(
|
|
36
53
|
node.getStart(context.sourceFile),
|