Skip to content

Commit

Permalink
fix: aliases, parserOptions.project & recursives
Browse files Browse the repository at this point in the history
  • Loading branch information
Akronae committed Sep 22, 2024
1 parent 892f752 commit 9f78231
Show file tree
Hide file tree
Showing 17 changed files with 681 additions and 336 deletions.
2 changes: 1 addition & 1 deletion eslint.config.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @ts-check

import tseslint from "typescript-eslint";
import { plugin as ex } from "./dist/index.mjs";
import { plugin as ex } from "./dist/src/index.js";
import config from "./eslint.config.js";

const ignores = [
Expand Down
35 changes: 13 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,45 +25,36 @@
"engines": {
"node": ">=20"
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.cts",
"exports": {
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
},
"import": {
"types": "./dist/index.d.mts",
"default": "./dist/index.mjs"
}
},
"imports": {
"@": "./"
},
"main": "./dist/src/index.js",
"module": "./dist/src/index.js",
"types": "./dist/src/index.d.ts",
"files": [
"dist"
"dist/src"
],
"scripts": {
"build": "pkgroll",
"build": "yarn rimraf dist && tsc && tsc-alias",
"test": "yarn build && vitest run --reporter verbose",
"docs": "yarn build && eslint-doc-generator && eslint-doc-generator --init-rule-docs && eslint-doc-generator",
"v:major": "npm version major -m \"chore: bump major to %s\"",
"v:minor": "npm version minor -m \"chore: bump minor to %s\"",
"v:patch": "npm version patch -m \"chore: bump patch to %s\""
},
"dependencies": {
"@types/eslint": "^8.56.10",
"@typescript-eslint/types": "^7.9.0",
"@typescript-eslint/utils": "^7.9.0",
"eslint": "^9.3.0"
},
"devDependencies": {
"@types/eslint": "^9.6.1",
"@types/espree": "^10.1.0",
"@types/node": "^20.12.12",
"@typescript-eslint/parser": "^7.9.0",
"@typescript-eslint/rule-tester": "^7.9.0",
"@typescript-eslint/types": "^7.9.0",
"@typescript-eslint/utils": "^7.9.0",
"eslint-doc-generator": "^1.7.1",
"pkgroll": "^2.1.0",
"espree": "^10.1.0",
"rimraf": "^6.0.1",
"tsc": "^2.0.4",
"tsc-alias": "^1.8.10",
"typescript": "^5.4.5",
"typescript-eslint": "^7.9.0",
"vite-tsconfig-paths": "^4.3.2",
Expand Down
55 changes: 55 additions & 0 deletions scripts/node-runtime-scan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { readdir, readFile } from "fs/promises";
import { join, resolve } from "path";
import { parse } from "espree";
import {
exploreChildren,
findInChildren,
findInParent,
isCallExpression,
isIdentifier,
isMemberExpression,
isVariableDeclarator,
} from "../src/utils";
import { TSESTree } from "@typescript-eslint/types";

const dir = resolve("..", "node-main");
const testfiles = await readdir(join(dir, "test"), {
recursive: true,
withFileTypes: true,
}).then((x) =>
x
.filter((x) => x.isFile() && x.name.endsWith(".js"))
.map((x) => join(x.parentPath ?? x.path, x.name))
);
const content = await readFile(testfiles[30], "utf-8");
const parsed = parse(content, { ecmaVersion: 2022 });
const asserts: TSESTree.CallExpression[] = [];
const imports: TSESTree.VariableDeclarator[] = [];

exploreChildren(parsed.body as any, (node, parent) => {
node.parent = parent;
if (
isIdentifier(node) &&
node.name === "throws" &&
isMemberExpression(node.parent) &&
isIdentifier(node.parent.object) &&
node.parent.object.name === "assert"
) {
console.log(node);
const ca = findInParent(node, isCallExpression);
if (!ca) return;
asserts.push(ca);
}

if (
isIdentifier(node) &&
node.name == "require" &&
isCallExpression(parent)
) {
const de = findInParent(parent, isVariableDeclarator);
if (!de) return;
imports.push(de);
}
});

console.log(imports);
2 changes: 1 addition & 1 deletion src/rules/might-throw/might-throw.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { testFile } from "@/src/utils";
import { testFile } from "@/src/utils/test-file";
import rule from "./might-throw";

await testFile(
Expand Down
3 changes: 2 additions & 1 deletion src/rules/might-throw/might-throw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { findInParent, isFunctionDeclaration } from "@/src/utils";
import { getFunctionId } from "@/src/utils/get-function-id";
import { getCallExprId } from "@/src/utils/get-call-expr-id";
import { createRule } from "@/src/rules/create-rule";
import { canFuncThrow } from "@/src/rules/no-unhandled";
import { canFuncThrow, canFuncThrowClear } from "@/src/utils/can-func-throw";

const name = "might-throw";
const rule = createRule({
Expand All @@ -19,6 +19,7 @@ const rule = createRule({
},
defaultOptions: [],
create: (context) => {
canFuncThrowClear();
const throwFunctions = new Set<string>();

return {
Expand Down
11 changes: 11 additions & 0 deletions src/rules/no-unhandled/no-unhandled.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,14 @@ await testFile(
[rule.name],
[]
);
await testFile(
"src/rules/no-unhandled/tests/alias-err.ts",
[rule.name],
[
{
messageId: "noUnhandled",
line: 54,
},
]
);
await testFile("src/rules/no-unhandled/tests/alias-ok.ts", [rule.name], []);
88 changes: 2 additions & 86 deletions src/rules/no-unhandled/no-unhandled.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
import { TSESTree } from "@typescript-eslint/utils";
import { isIdentifier } from "@typescript-eslint/utils/ast-utils";
import {
findInParent,
isCallExpression,
isFunctionDeclaration,
isThrowStatement,
isTryStatement,
findInChildren,
exploreChildren,
getFunctionId,
resolveFunc,
getCallExprId,
isCatchClause,
isMethodDefinition,
} from "@/src/utils";
import { RuleContext } from "@typescript-eslint/utils/ts-eslint";
import { createRule } from "@/src/rules/create-rule";
import { nativeThrowing } from "@/src/utils/native-throwing";

const throwFunctions = new Set<string>();
const scannedFunctions = new Set<string>();
import { canFuncThrow, canFuncThrowClear } from "@/src/utils/can-func-throw";

const name = "no-unhandled";
const rule = createRule({
Expand All @@ -37,8 +25,7 @@ const rule = createRule({
},
defaultOptions: [],
create: (context) => {
throwFunctions.clear();
scannedFunctions.clear();
canFuncThrowClear();

return {
CallExpression(called) {
Expand All @@ -65,75 +52,4 @@ const rule = createRule({
},
});

export function canFuncThrow(
node: TSESTree.Identifier | TSESTree.PrivateIdentifier,
context: RuleContext<string, unknown[]>
): boolean {
const try_ = findInParent(node, isTryStatement);
if (try_) {
return false;
}

const res = resolveFunc(node, context);
if (res?.module) {
const found = nativeThrowing.some(
(x) => x.module === res.module && x.method === res.func.id?.name
);
if (found) {
return true;
}
}
if (!res?.func) return false;
return scanfunc(res.func, res.context);
}

function scanfunc(
node: TSESTree.FunctionDeclaration,
context: RuleContext<string, unknown[]>
): boolean {
const throws = exploreChildren<boolean>(
node,
async (child, parent_, resolve) => {
const try_ = findInParent(child, isTryStatement);
if (try_) {
const catch_ = findInChildren(try_.parent, isCatchClause);
const throw_ = catch_ && findInChildren(catch_, isThrowStatement);
if (throw_) {
resolve(true);
}
return;
}

if (isCallExpression(child) && isIdentifier(child.callee)) {
let throws = false;

if (scannedFunctions.has(getFunctionId(context, child.callee))) {
throws = throwFunctions.has(getFunctionId(context, child.callee));

if (throws) resolve(throws);
return;
}

throws = canFuncThrow(child.callee, context);
if (throws) {
if (node.id) throwFunctions.add(getFunctionId(context, node.id));
resolve(true);
}
} else if (isThrowStatement(child) && node.id) {
throwFunctions.add(getFunctionId(context, node.id));
resolve(true);
}
}
);

if (node.id) {
scannedFunctions.add(getFunctionId(context, node.id));
if (throws) {
throwFunctions.add(getFunctionId(context, node.id));
}
}

return !!throws;
}

export default { name, rule };
56 changes: 56 additions & 0 deletions src/rules/no-unhandled/tests/alias-err.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { throwingFunc } from "@/src/rules/no-unhandled/tests/throwing-func";

const x = 5;
let y = "abc123";
function myFunction() {}
myFunction();
const myErr = new Error();
throw new Error("heyyyy!");
function c() {
a();
}
function a() {
throw new Error("heyyyy!");
}
function b() {
c();
}

try {
b();
} catch (e) {
console.error(e);
}

function d() {
a();
}
function e() {
throw new Error("heyyyy!");
}
function f() {
try {
c();
} catch (e) {
console.error(e);
}
}
function g() {
d();
}

f();

try {
e();
} catch (e) {
console.error(e);
}

function h() {
throwingFunc();
}

throwingFunc();

export {};
67 changes: 67 additions & 0 deletions src/rules/no-unhandled/tests/alias-ok.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { throwingFunc } from "@/src/rules/no-unhandled/tests/throwing-func";

const x = 5;
let y = "abc123";
function myFunction() {}
myFunction();
const myErr = new Error();
throw new Error("heyyyy!");
function c() {
a();
}
function a() {
throw new Error("heyyyy!");
}
function b() {
c();
}

try {
b();
} catch (e) {
console.error(e);
}

function d() {
a();
}
function e() {
throw new Error("heyyyy!");
}
function f() {
try {
c();
} catch (e) {
console.error(e);
}
}
function g() {
d();
}

f();

try {
e();
} catch (e) {
console.error(e);
}

function h() {
try {
throwingFunc();
} catch (e) {
console.error(e);
}
}

h();

try {
throwingFunc();
h();
} catch (e) {
console.error(e);
}

export {};
Loading

0 comments on commit 9f78231

Please sign in to comment.