feat: replace heuristic Big-O analyzer with structured complexity util#42
Conversation
Summary by BeetleThis PR refactors the Big-O complexity analysis system in the QuillBot Discord bot by replacing a heuristic regex-based estimator with a structured, production-grade 📁 File Changes Summary (Consolidated across all commits):
Total Changes: 5 files changed, +473 additions, -156 deletions 🗺️ Walkthrough:graph TD
A["User Input: Code Block"] --> B["parseCodeBlock & parseCodeCommandInput"]
B --> C["analyzeComplexity Utility"]
C --> D["stripDecorators"]
D --> E["loopDepthProfile"]
E --> F["Loop Analysis"]
F --> G["Complexity Ranking"]
C --> H["findFunctions"]
H --> I["analyzeRecursion"]
I --> J["Recursion Classification"]
J --> K["Memoization Detection"]
K --> G
G --> L["Determine Final Complexity"]
L --> M["Calculate Confidence"]
M --> N["Generate Indicators & Reasoning"]
N --> O["EmbedBuilder"]
O --> P["Discord Message Response"]
🎯 Key Changes:
📊 Impact Assessment:
⚙️ SettingsSeverity Threshold: 📖 User Guide
|
|
|
||
| try { | ||
| if (!code?.trim()) { | ||
| if (!code.trim()) { |
There was a problem hiding this comment.
The code calls .trim() on code which is typed as string | undefined, but the optional chaining operator (?.) was removed. This will throw a runtime error if code is undefined at this point.
Confidence: 5/5
Suggested Fix
| if (!code.trim()) { | |
| if (!code?.trim()) { | |
The optional chaining operator (?.) safely handles the case where code might be undefined, preventing a "Cannot read property 'trim' of undefined" runtime error.
Prompt for AI
Copy this prompt to your AI IDE to fix this issue locally:
In src/commands/code/complexity.ts around line 93, the code calls .trim() on the
variable `code` which is typed as `string | undefined`. The original code used optional
chaining (`code?.trim()`) to safely handle the undefined case, but this was removed
during refactoring. Restore the optional chaining operator to prevent runtime errors
when code is undefined.
There was a problem hiding this comment.
there is already check for that 😭
There was a problem hiding this comment.
@calebephrem I encountered an error while generating a response. Please try again.
| function matchBrace(str: string, openIndex: number): number { | ||
| let depth = 0; | ||
| for (let i = openIndex; i < str.length; i++) { | ||
| const ch = str.charAt(i); | ||
| if (ch === "{") depth++; | ||
| else if (ch === "}") { | ||
| depth--; | ||
| if (depth === 0) return i; | ||
| } | ||
| } | ||
| return -1; | ||
| } |
There was a problem hiding this comment.
The matchBrace function doesn't validate that openIndex is within valid bounds. If called with a negative index or an index >= str.length, the function behavior becomes unpredictable. While JavaScript's string indexing is forgiving, this could lead to subtle bugs if the function is called with invalid indices from other parts of the code.
Confidence: 4/5
Suggested Fix
| function matchBrace(str: string, openIndex: number): number { | |
| let depth = 0; | |
| for (let i = openIndex; i < str.length; i++) { | |
| const ch = str.charAt(i); | |
| if (ch === "{") depth++; | |
| else if (ch === "}") { | |
| depth--; | |
| if (depth === 0) return i; | |
| } | |
| } | |
| return -1; | |
| } | |
| function matchBrace(str: string, openIndex: number): number { | |
| if (openIndex < 0 || openIndex >= str.length) return -1; | |
| let depth = 0; | |
| for (let i = openIndex; i < str.length; i++) { | |
| const ch = str.charAt(i); | |
| if (ch === "{") depth++; | |
| else if (ch === "}") { | |
| depth--; | |
| if (depth === 0) return i; | |
| } | |
| return -1; | |
| } | |
Add bounds validation at the start of the function to ensure openIndex is within the valid range [0, str.length).
Prompt for AI
Copy this prompt to your AI IDE to fix this issue locally:
In src/utils/analyzeComplexity.ts around line 33, add bounds validation to the
matchBrace function to ensure openIndex is within valid range [0, str.length).
This prevents undefined behavior if the function is called with invalid indices.
📍 This suggestion applies to lines 33-44
| function matchParen(str: string, openIndex: number): number { | ||
| let depth = 0; | ||
| for (let i = openIndex; i < str.length; i++) { | ||
| const ch = str.charAt(i); | ||
| if (ch === "(") depth++; | ||
| else if (ch === ")") { | ||
| depth--; | ||
| if (depth === 0) return i; | ||
| } | ||
| } | ||
| return -1; | ||
| } |
There was a problem hiding this comment.
Similar to matchBrace, the matchParen function lacks bounds validation for the openIndex parameter. This could cause issues if called with invalid indices, leading to unpredictable behavior or incorrect results.
Confidence: 4/5
Suggested Fix
| function matchParen(str: string, openIndex: number): number { | |
| let depth = 0; | |
| for (let i = openIndex; i < str.length; i++) { | |
| const ch = str.charAt(i); | |
| if (ch === "(") depth++; | |
| else if (ch === ")") { | |
| depth--; | |
| if (depth === 0) return i; | |
| } | |
| } | |
| return -1; | |
| } | |
| function matchParen(str: string, openIndex: number): number { | |
| if (openIndex < 0 || openIndex >= str.length) return -1; | |
| let depth = 0; | |
| for (let i = openIndex; i < str.length; i++) { | |
| const ch = str.charAt(i); | |
| if (ch === "(") depth++; | |
| else if (ch === ")") { | |
| depth--; | |
| if (depth === 0) return i; | |
| } | |
| return -1; | |
| } | |
Add bounds validation at the start of the function to ensure openIndex is within the valid range [0, str.length).
Prompt for AI
Copy this prompt to your AI IDE to fix this issue locally:
In src/utils/analyzeComplexity.ts around line 47, add bounds validation to the
matchParen function to ensure openIndex is within valid range [0, str.length).
This prevents undefined behavior if the function is called with invalid indices.
📍 This suggestion applies to lines 47-58
|
Note Linting checks passed successfully 🎉 All formatting and code quality checks are clean. You're good to merge 🚀 |
What does this PR do?
Explain here what you changed and why. Doesn't need to be long, just enough
for a reviewer to understand the change without reading every line of
diff. If it was a bug fix, briefly describe what was broken. Delete this paragraph and replace it with your description.
Closes
Type of change(s)
Checklist
bun run typecheckornpm run typecheckcompletes without errorsfix: ...,feat: ...,chore: ...)console.logor debug codeScreenshots / recordings (if applicable)