From 4d134ec92818ef0ac49088e13c1125a6013a22f7 Mon Sep 17 00:00:00 2001 From: willeand Date: Tue, 4 Jun 2024 13:45:40 -0700 Subject: [PATCH] creates a switch statement code smell detection. 1.0 --- output/data.json | 2 +- package.json | 4 +++ src/badSwitch.ts | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ src/extension.ts | 5 ++++ 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 src/badSwitch.ts diff --git a/output/data.json b/output/data.json index 02a7603..1dc1244 100644 --- a/output/data.json +++ b/output/data.json @@ -1 +1 @@ -{"12":["Code Smell: Consider refactoring to reduce method length"],"30":["Code smell found: Long Parameters in method public static int addNumbers (int a, int b, int c, int d){"],"38":["Code Smell: Consider refactoring to reduce method length"]} \ No newline at end of file +{"69":["Similar logic found in switch cases based on character usage","Similar logic found in switch cases based on character usage","Similar logic found in switch cases based on character usage"],"92":["Similar logic found in switch cases based on character usage","Similar logic found in switch cases based on character usage"]} \ No newline at end of file diff --git a/package.json b/package.json index a83a227..dc0f576 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,10 @@ { "command": "extension.createJSON", "title": "createJSON" + }, + { + "command": "extension.badSwitch", + "title": "badSwitch" } ], "menus": { diff --git a/src/badSwitch.ts b/src/badSwitch.ts new file mode 100644 index 0000000..38eac7a --- /dev/null +++ b/src/badSwitch.ts @@ -0,0 +1,66 @@ +import * as vscode from 'vscode'; + +export function badSwitch(myMap: Map) { + let editor = vscode.window.activeTextEditor; + if (!editor) { + vscode.window.showErrorMessage('No active text editor.'); + return myMap; // Early return if no editor + } + + let text = editor.document.getText(); + // Regex to match Java switch statements + let switchRegex = /switch\s*\(([^)]+)\)\s*{([^}]*)}/g; + let match; + while ((match = switchRegex.exec(text))) { + let switchCases = match[2].split('case').slice(1); + if (switchCases.length >= 3) { + let lineIndex = editor.document.positionAt(match.index).line; + let errorMessage = `Code smell found: Switch statement with ${switchCases.length} cases`; + if (!myMap.has(lineIndex)) { + myMap.set(lineIndex, [errorMessage]); + } else { + myMap.get(lineIndex)?.push(errorMessage); + } + + // Initialize character array for each case + let charArrays: number[][] = []; + for (let i = 0; i < switchCases.length; i++) { + let caseCharArray = new Array(26).fill(0); + let caseLines = switchCases[i].split('\n').map(line => line.trim().toLowerCase()); + for (let line of caseLines) { + for (let char of line) { + if (char >= 'a' && char <= 'z') { + let index = char.charCodeAt(0) - 'a'.charCodeAt(0); + caseCharArray[index]++; + } + } + } + charArrays.push(caseCharArray); + } + + // Compare each case to every other case at least once + for (let i = 0; i < charArrays.length; i++) { + for (let j = i + 1; j < charArrays.length; j++) { + let similarity = calculateSimilarity(charArrays[i], charArrays[j]); + if (similarity >= 0.8) { // Adjust similarity threshold as needed + let similarLogicMessage = `Similar logic found in switch cases based on character usage`; + if (!myMap.get(lineIndex)?.includes(similarLogicMessage)) { + myMap.get(lineIndex)?.push(similarLogicMessage); + } + break; // Exit inner loop if similar logic found + } + } + } + } + } + + return myMap; +} + +function calculateSimilarity(arr1: number[], arr2: number[]): number { + let similarity = 0; + for (let i = 0; i < 26; i++) { + similarity += Math.min(arr1[i], arr2[i]); + } + return similarity / arr1.reduce((a, b) => a + b, 0); // Normalize by total characters in the first case +} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 2777ef8..aace195 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -13,6 +13,7 @@ import { findLowercaseEnums } from './findLowercaseEnums'; import { findConstantCap} from './findConstantCap'; import { longMethod } from './longMethod'; import { longParameters } from './longParameters'; +import { badSwitch } from './badSwitch'; const myMap: Map = new Map(); const filePath = 'C:\\Users\\Will\\Desktop\\cw\\gradeFast-1.0\\output\\data.json'; @@ -58,6 +59,10 @@ export function activate(context: vscode.ExtensionContext) { longParameters(myMap); } ); + const disposable9 = vscode.commands.registerCommand('extension.badSwitch', () => { + badSwitch(myMap); + } ); + const commentController = vscode.comments.createCommentController('comment-sample', 'Comment API Sample'); context.subscriptions.push(commentController);