intellify
Version:
Detect JavaScript & TypeScript errors and make codes more optimized.
213 lines (160 loc) ⢠8.29 kB
JavaScript
import readline from 'readline';
import chalk from 'chalk';
import path from 'path';
import { fixComments } from '../analyzers/code.js';
import fs from 'fs';
export async function promptFix(results, projectPath) {
if (results.syntaxErrors.length === 0 &&
results.unusedPackages.length === 0 &&
results.unusedVariables.length === 0 &&
(!results.comments || results.comments.length === 0)) {
console.log(chalk.green.bold('⨠Your project looks clean! No issues found.'));
return;
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const ask = (question) => {
return new Promise((resolve) => {
rl.question(question, (answer) => {
resolve(answer.trim().toLowerCase());
});
});
};
console.log(chalk.cyan.bold('\nš§ Would you like to optimize your codebase?'));
const optimize = await ask('š¬ (yes/no): ');
if (optimize === 'yes' || optimize === 'y') {
console.log(chalk.cyan('\nš§ Starting optimization process...'));
if (results.comments && results.comments.length > 0) {
console.log(chalk.cyan('\nš¬ Would you like to remove comments?'));
const removeComments = await ask('š¬ (yes/no): ');
if (removeComments === 'yes' || removeComments === 'y') {
console.log(chalk.cyan('\nš¬ Attempting to remove comments...'));
const commentsByFile = {};
results.comments.forEach(comment => {
if (!commentsByFile[comment.file]) {
commentsByFile[comment.file] = [];
}
commentsByFile[comment.file].push(comment);
});
let totalRemoved = 0;
let totalSkipped = 0;
for (const [file, comments] of Object.entries(commentsByFile)) {
try {
const code = fs.readFileSync(file, 'utf-8');
const result = fixComments(code, comments);
fs.writeFileSync(file, result.code, 'utf-8');
totalRemoved += result.stats.removed;
totalSkipped += result.stats.skipped;
if (result.stats.skipped > 0) {
console.log(` Skipped ${result.stats.skipped} comment${result.stats.skipped !== 1 ? 's' : ''} in ${path.basename(file)} (potential syntax issue)`);
}
} catch (error) {
console.error(` Error processing ${path.basename(file)}: ${error.message}`);
totalSkipped += comments.length;
}
}
if (totalSkipped > 0) {
console.log(chalk.yellow(`ā ļø Skipped ${totalSkipped} comments due to potential syntax issues or batch failure.`));
}
if (totalRemoved > 0) {
console.log(chalk.green(`ā
Successfully removed ${totalRemoved} comments.`));
}
}
}
if (results.unusedVariables && results.unusedVariables.length > 0) {
console.log(chalk.cyan('\nš Would you like to remove unused variables and imports?'));
const removeUnused = await ask('š¬ (yes/no): ');
if (removeUnused === 'yes' || removeUnused === 'y') {
console.log(chalk.cyan('\nš Attempting to remove unused variables and imports...'));
const unusedByFile = {};
results.unusedVariables.forEach(item => {
if (!unusedByFile[item.file]) {
unusedByFile[item.file] = [];
}
unusedByFile[item.file].push(item);
});
let totalRemoved = 0;
let totalSkipped = 0;
for (const [file, items] of Object.entries(unusedByFile)) {
try {
const fileContent = fs.readFileSync(file, 'utf-8');
const lines = fileContent.split('\n');
const removals = [];
items.forEach(item => {
try {
if (item.type === 'variable') {
const lineIndex = item.line - 1;
const line = lines[lineIndex];
if (line.includes(`let ${item.name}`) || line.includes(`var ${item.name}`) || line.includes(`const ${item.name}`)) {
if (line.trim().startsWith('let') || line.trim().startsWith('var') || line.trim().startsWith('const')) {
if (!line.includes(',')) {
removals.push({ line: lineIndex, content: line });
} else {
console.log(chalk.yellow(` ā ļø Skipped complex variable declaration: ${item.name} in ${path.basename(file)}:${item.line}`));
totalSkipped++;
}
} else {
console.log(chalk.yellow(` ā ļø Skipped variable in complex context: ${item.name} in ${path.basename(file)}:${item.line}`));
totalSkipped++;
}
} else {
console.log(chalk.yellow(` ā ļø Variable declaration not found as expected: ${item.name} in ${path.basename(file)}:${item.line}`));
totalSkipped++;
}
} else if (item.type === 'import' || item.type === 'require') {
const lineIndex = item.line - 1;
const line = lines[lineIndex];
if (item.type === 'import' && line.includes(`import ${item.name}`) ||
line.includes(`import { ${item.name}`) ||
line.includes(`import {${item.name}`)) {
if (line.includes(',')) {
console.log(chalk.yellow(` ā ļø Skipped complex import statement: ${item.name} in ${path.basename(file)}:${item.line}`));
totalSkipped++;
} else {
removals.push({ line: lineIndex, content: line });
}
} else if (item.type === 'require' && line.includes(`= require('${item.source}')`)) {
removals.push({ line: lineIndex, content: line });
} else {
console.log(chalk.yellow(` ā ļø Import/require statement not found as expected: ${item.name} in ${path.basename(file)}:${item.line}`));
totalSkipped++;
}
} else {
console.log(chalk.yellow(` ā ļø Unknown item type: ${item.type} for ${item.name} in ${path.basename(file)}:${item.line}`));
totalSkipped++;
}
} catch (itemError) {
console.error(` Error processing item ${item.name} in ${path.basename(file)}: ${itemError.message}`);
totalSkipped++;
}
});
if (removals.length > 0) {
removals.sort((a, b) => b.line - a.line);
for (const removal of removals) {
lines.splice(removal.line, 1);
totalRemoved++;
}
fs.writeFileSync(file, lines.join('\n'), 'utf-8');
console.log(chalk.green(` ā
Removed ${removals.length} unused items from ${path.basename(file)}`));
}
} catch (fileError) {
console.error(` Error processing file ${path.basename(file)}: ${fileError.message}`);
totalSkipped += items.length;
}
}
if (totalSkipped > 0) {
console.log(chalk.yellow(`ā ļø Skipped ${totalSkipped} unused items due to complexity or potential syntax issues.`));
}
if (totalRemoved > 0) {
console.log(chalk.green(`ā
Successfully removed ${totalRemoved} unused items.`));
}
}
}
console.log(chalk.green('\nā
All selected optimizations have been applied!'));
console.log(chalk.cyan.bold('š Your codebase is now faster and cleaner.'));
}
rl.close();
}
export default promptFix;