Skip to content

Commit

Permalink
Added regex for check module.exports
Browse files Browse the repository at this point in the history
  • Loading branch information
Denisoed committed Jun 3, 2024
1 parent a5310a9 commit 4a7291b
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 12 deletions.
8 changes: 8 additions & 0 deletions example/files/1.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,11 @@ function foo() {
function bar() {
console.log('Hello world!');
}

function bar1() {
console.log('Hello world!');
}

module.exports = {
foo
};
8 changes: 7 additions & 1 deletion example/files/2.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
const { foo } = require('./1.js');

function test1() {
console.log('Hello world!');
console.log('I feel like I let you down.');
}

function test2() {
console.log('Use test2 function to test dead code.');
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dead-code-checker",
"version": "1.0.0",
"version": "1.0.1",
"description": "Dead Code Checker is a tool for finding dead code in your JavaScript or TypeScript project. It helps to ensure a cleaner and more maintainable code base.",
"license": "MIT",
"repository": "https://github.com/denisoed/dead-code-checker",
Expand Down
33 changes: 23 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class DeadCodeChecker {
private deadMap: Record<string, IDeadCodeInfo> = {};
private deadCodeFound: boolean = false;
private reportList: IDeadCodeReport[] = [];
private usedOnlyResult: Set<string> = new Set();
private usedOnlyReturn: Set<string> = new Set();

constructor(filesPath: string, params?: IDeadCodeParams) {
this.params = params;
Expand Down Expand Up @@ -59,11 +59,20 @@ class DeadCodeChecker {
);
}

private saveUsedOnlyReturn(content: string) {
const matches = content.split(',') || [];
matches.forEach(method => {
method = method.trim().replace(':', '');
this.usedOnlyReturn.add(method);
});
}

private getDeclaredNames(fileContent: string) {
const functionRegex = /\bfunction\s+([a-zA-Z0-9_]+)\s*\(/g;
const arrowFunctionRegex = /\bconst\s+([a-zA-Z0-9_]+)\s*=\s*\(/g;
const methodRegex = /([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*{/g;
const onlyInReturnRegex = /\breturn\s*{([^}]*)}/g;
const onlyModuleExportsRegex = /\bmodule\.exports\s*=\s*{([^}]*)}/g;
const variableRegex = /\b(?:const|let|var)\s+([a-zA-Z0-9_]+)\s*=?/g;

const declaredNames: { name: string; line: number }[] = [];
Expand Down Expand Up @@ -93,12 +102,11 @@ class DeadCodeChecker {
});

while ((match = onlyInReturnRegex.exec(fileContent)) !== null) {
const returnContent = match[1];
const returnMatches = returnContent.split(',') || [];
returnMatches.forEach(method => {
method = method.trim().replace(':', '');
this.usedOnlyResult.add(method);
});
this.saveUsedOnlyReturn(match[1]);
}

while ((match = onlyModuleExportsRegex.exec(fileContent)) !== null) {
this.saveUsedOnlyReturn(match[1]);
}

return declaredNames;
Expand All @@ -108,6 +116,10 @@ class DeadCodeChecker {
return fileContent.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, '');
}

private removeText(fileContent: string) {
return fileContent.replace(/(['"])(?:(?=(\\?))\2.)*?\1/g, '');
}

private displayReport() {
this.reportList.forEach(report => {
console.log(
Expand Down Expand Up @@ -140,10 +152,11 @@ class DeadCodeChecker {
const allFiles = this.getAllFiles(this.filesPath);
for (const filePath of allFiles) {
const fileContent = fs.readFileSync(filePath, 'utf8');
const cleanedContent = this.removeComments(fileContent);
const withoutComments = this.removeComments(fileContent);
const withoutTexts = this.removeText(withoutComments);
Object.keys(this.deadMap).forEach(name => {
const usageRegex = new RegExp(`\\b${name}\\b`, 'g');
const matches = cleanedContent.match(usageRegex);
const matches = withoutTexts.match(usageRegex);
if (matches) {
this.deadMap[name].count += matches.length;
}
Expand All @@ -155,7 +168,7 @@ class DeadCodeChecker {
for (const name of Object.keys(this.deadMap)) {
const occurrences = this.deadMap[name];
const isOnlyInReturn =
occurrences.count === 2 && this.usedOnlyResult.has(name);
occurrences.count === 2 && this.usedOnlyReturn.has(name);
if (occurrences.count === 1 || isOnlyInReturn) {
this.deadCodeFound = true;
occurrences.declaredIn.forEach(decl => {
Expand Down

0 comments on commit 4a7291b

Please sign in to comment.