-
Notifications
You must be signed in to change notification settings - Fork 192
JS-946 Implement direct TypeScript program caching #5921
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Latest Changes Summary1. Global Source File Content Cache with Lazy Loading
2. Global TSConfig Content Cache
3. Refactored
|
Updates - November 19, 2025Module Resolution FixFixed failing test "jsonParse does not resolve imports, createProgram does" by adding proper module resolution defaults:
Root cause: Without these defaults, TypeScript falls back to Classic module resolution which doesn't support:
This ensures modern module resolution works correctly for all analysis runs. Global SourceFile CacheImplemented a significant performance optimization by adding a global cache for parsed TypeScript SourceFile ASTs: Architecture:
Benefits:
API (in getCachedSourceFile(fileName, scriptTarget, contentHash): ts.SourceFile | undefined
setCachedSourceFile(fileName, scriptTarget, contentHash, sourceFile): void
invalidateCachedSourceFile(fileName): void
clearSourceFileContentCache(): void // Now clears both content and parsed cachesDesign Decision - Per-Target Caching: We cache SourceFiles per
Rationale for keeping target-specific caching:
See detailed rationale in the code comments. If profiling shows diverse targets are common, we can simplify to target-agnostic caching (always use ESNext) with minimal impact. Config File DiagnosticsAdded support for tsconfig parsing diagnostics:
TSConfig Cache EnhancementUpdated tsconfig cache structure to track missing files:
Test Updates
DocumentationAdded
Status: ✅ All 13 tests passing, TypeScript compilation successful Commit: a3addf9 - "Add module resolution defaults and global SourceFile cache" |
d98064d to
b22519f
Compare
266c555 to
1b5a26d
Compare
|
🤖 Claude Code Investigation Update I'm continuing to debug the backslash-reference test issue. Initial findings:
Currently investigating |
a071859 to
2b7d5cb
Compare
636b9e4 to
88dcae3
Compare
|




JS-946
JS-946
Summary
This PR replaces typescript-eslint's internal program creation with direct TypeScript program management, giving full control over
CompilerHostand enabling efficient program caching with incremental updates for SonarLint analysis.Core Objectives
Architecture
New Components
1. IncrementalCompilerHost (
packages/jsts/src/program/incrementalCompilerHost.ts)CompilerHostimplementation for TypeScript programs2. ProgramCacheManager (
packages/jsts/src/program/programCacheManager.ts)Hybrid LRU + WeakMap caching strategy:
3. Program Creation Functions (
packages/jsts/src/program/program.ts)extractCompilerOptions(): Parses tsconfig.json with properextendsresolution (including from node_modules)mergeCompilerOptions(): Merges all discovered tsconfig compiler optionscreateOrGetCachedProgramForFile(): Main entry point for program cachingModified Components
4. analyzeWithWatchProgram (
packages/jsts/src/analysis/projectAnalysis/analyzeWithWatchProgram.ts)Complete rewrite of SonarLint analysis flow:
files/include/exclude)ts.Programto typescript-eslint (nottsConfigsarray)5. Simplified TSConfig Discovery (
packages/jsts/src/analysis/projectAnalysis/tsconfigCache.ts,file-stores/tsconfigs.ts)Removed (~80 lines):
Kept:
TypeScript Program Type: SemanticDiagnosticsBuilderProgram
Why This Choice
The implementation uses
ts.createSemanticDiagnosticsBuilderProgram(). I think this appears to be a good fit because:createProgram()SemanticDiagnosticsBuilder✅EmitAndSemanticDiagnosticsBuilderIncrementalProgram.tsbuildinfo)* Requires disk I/O for
.tsbuildinfofilesAdvantages:
Incremental behavior:
Trade-offs with alternatives:
createProgram()- Simpler but no incremental updates (parses everything each time)EmitAndSemanticDiagnosticsBuilder- Higher memory for emit tracking we don't useIncrementalProgram- Lower memory but requires.tsbuildinfodisk I/O (problematic for concurrent IDE instances)All program types provide identical type checker APIs - the difference is in update efficiency, not functionality.
Key Features
1. Per-File Caching Strategy
Instead of creating programs containing all requested files, we:
Example:
This allows multiple smaller, focused programs to coexist rather than requiring large programs containing all files.
2. Incremental Updates with Content Change Detection
3. Compiler Options Merging
This approach:
extends(including fromnode_moduleslike@tsconfig/node16)Analysis Flow
Expected Performance Characteristics
These are estimates that should be validated with real-world usage.
Memory Profile
Typical SonarLint session (10 cached programs):
Benefits
Breaking Changes
Removed APIs
Cache.getTsConfigForInputFile()- No longer neededCache.getTsConfigMapForInputFile()- Removed BFS logicCache.clearFileToTsConfigCache()- Not applicableTsConfigStore.getTsConfigForInputFile()- Not used anymoreTest Updates Needed
Test file
packages/jsts/tests/analysis/tsconfigs.test.tsneeds updates as it tests the removed file-to-tsconfig mapping functionality.Testing
Main source code compiles successfully:
Test files have compilation errors due to removed APIs (need updates).
Future Improvements
maxSizeconfigurable via settings