-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from surenpoghosian/antipatterns
[antipatterns] add support for more antipatterns
- Loading branch information
Showing
9 changed files
with
133 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
dist/ | ||
dist/Analyzers/ | ||
node_modules/ | ||
.node_modules/ | ||
built/* | ||
|
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { BasePattern } from './BasePattern'; | ||
import { Hint } from '../Reports/Hint'; | ||
|
||
export class CodeSmellPattern extends BasePattern { | ||
analyze(content: string): Hint[] { | ||
const hints: Hint[] = []; | ||
|
||
// Deep Nesting | ||
const deepNestingRegex = /if\s*\([^\)]+\)\s*\{[^]*(if\s*\([^\)]+\)\s*\{[^]*(if\s*\([^\)]+\)\s*\{[^]*\})\})\}/g; | ||
let match: RegExpExecArray | null; | ||
while ((match = deepNestingRegex.exec(content)) !== null) { | ||
hints.push(new Hint(`Possible deep nesting detected. Consider refactoring.`)); | ||
} | ||
|
||
// Long Methods | ||
const methodRegex = /(?:public|private|protected|static)?\s*(?:async\s+)?(?:function)?\s*\w+\(.*?\)\s*\{[^]*?\}/g; | ||
while ((match = methodRegex.exec(content)) !== null) { | ||
const methodBody = match[0]; | ||
const lineCount = methodBody.split('\n').length; | ||
if (lineCount > 50) { // Threshold can be adjusted | ||
hints.push(new Hint(`Possible long method detected with ${lineCount} lines. Consider refactoring.`)); | ||
} | ||
} | ||
|
||
return hints; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { BasePattern } from './BasePattern'; | ||
import { Hint } from '../Reports/Hint'; | ||
import * as ts from 'typescript'; | ||
|
||
export class GodObjectASTPattern extends BasePattern { | ||
analyze(content: string): Hint[] { | ||
const hints: Hint[] = []; | ||
const sourceFile = ts.createSourceFile('file.ts', content, ts.ScriptTarget.Latest, true); | ||
|
||
function analyzeNode(node: ts.Node) { | ||
if (ts.isClassDeclaration(node) && node.members.length > 20) { // Threshold can be adjusted | ||
const className = node.name ? node.name.getText() : 'Unnamed Class'; | ||
hints.push(new Hint(`Possible God Object detected: ${className} has too many members.`)); | ||
} | ||
node.forEachChild(analyzeNode); | ||
} | ||
|
||
analyzeNode(sourceFile); | ||
|
||
return hints; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { BasePattern } from './BasePattern'; | ||
import { Hint } from '../Reports/Hint'; | ||
|
||
export class GodObjectPattern extends BasePattern { | ||
analyze(content: string): Hint[] { | ||
const hints: Hint[] = []; | ||
const classRegex = /class\s+\w+\s*\{[^]*?\}/g; | ||
const methodRegex = /(?:public|private|protected|static)?\s*(?:async\s+)?(?:function)?\s*\w+\(.*?\)\s*\{[^]*?\}/g; | ||
const propertyRegex = /(?:public|private|protected|static)?\s*(?:async\s+)?\w+\s*:\s*\w+\s*;/g; | ||
|
||
let match: RegExpExecArray | null; | ||
while ((match = classRegex.exec(content)) !== null) { | ||
const classBody = match[0]; | ||
const methodCount = (classBody.match(methodRegex) || []).length; | ||
const propertyCount = (classBody.match(propertyRegex) || []).length; | ||
|
||
if (methodCount > 10 || propertyCount > 10) { // Threshold can be adjusted | ||
hints.push(new Hint(`Possible God Object detected: Class has ${methodCount} methods and ${propertyCount} properties.`)); | ||
} | ||
} | ||
|
||
return hints; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { BasePattern } from './BasePattern'; | ||
import { Hint } from '../Reports/Hint'; | ||
|
||
export class MagicNumbersPattern extends BasePattern { | ||
analyze(content: string): Hint[] { | ||
const hints: Hint[] = []; | ||
const magicNumberRegex = /\b\d+\b/g; | ||
const allowedNumbers = new Set([0, 1]); // Add more allowed numbers if necessary | ||
|
||
let match: RegExpExecArray | null; | ||
while ((match = magicNumberRegex.exec(content)) !== null) { | ||
const number = parseInt(match[0], 10); | ||
if (!allowedNumbers.has(number)) { | ||
hints.push(new Hint(`Possible Magic Number detected: "${number}" should be replaced with a named constant.`)); | ||
} | ||
} | ||
|
||
return hints; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { BasePattern } from './BasePattern'; | ||
import { Hint } from '../Reports/Hint'; | ||
|
||
export class ShotgunSurgeryPattern extends BasePattern { | ||
analyze(content: string): Hint[] { | ||
const hints: Hint[] = []; | ||
const methodOrPropertyRegex = /\b\w+\b/g; | ||
const occurrences = new Map<string, number>(); | ||
|
||
let match: RegExpExecArray | null; | ||
while ((match = methodOrPropertyRegex.exec(content)) !== null) { | ||
const name = match[0]; | ||
occurrences.set(name, (occurrences.get(name) || 0) + 1); | ||
} | ||
|
||
occurrences.forEach((count, name) => { | ||
if (count > 5) { // Threshold can be adjusted | ||
hints.push(new Hint(`Possible Shotgun Surgery detected: "${name}" is modified in ${count} places.`)); | ||
} | ||
}); | ||
|
||
return hints; | ||
} | ||
} |