* Hash content using AST-aware method (ignores comments, whitespace) * * Falls back to raw content hash when: * - Tree-sitter is unavailable (parser not initialized) * - Analysis returns empty results (no functions/imports detected) * * This ensures consistent hashing b
(content: string, filePath: string)
| 308 | * even if tree-sitter initialization state differs between sessions. |
| 309 | */ |
| 310 | hashContentAST(content: string, filePath: string): string { |
| 311 | try { |
| 312 | const analysis = this.staticAnalyzer.analyze(content, filePath); |
| 313 | |
| 314 | // If analysis returned empty (tree-sitter unavailable or no code), |
| 315 | // fall back to raw content hash for consistency |
| 316 | if (analysis.locations.length === 0 && analysis.imports.length === 0) { |
| 317 | return this.hashContent(content); |
| 318 | } |
| 319 | |
| 320 | const normalized = { |
| 321 | imports: analysis.imports.filter(isLLMImport).sort(), |
| 322 | variables: Array.from(analysis.llmRelatedVariables).sort(), |
| 323 | locations: analysis.locations.map(loc => ({ |
| 324 | line: loc.line, |
| 325 | type: loc.type, |
| 326 | function: loc.function |
| 327 | })).sort((a, b) => a.line - b.line) |
| 328 | }; |
| 329 | return crypto.createHash('sha256').update(JSON.stringify(normalized)).digest('hex'); |
| 330 | } catch (error) { |
| 331 | return this.hashContent(content); |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | // ========================================================================= |
| 336 | // Cache Check |
no test coverage detected