[wip] on demand program diagnostics population
- Store information about file explaining diagnostics to be generated only when program diagnsotics are asked. We store this already if its the diagnostic while we are creating program graph, We now store other compiler options errors that explain file include reasons as well as lazy diagnostics to be generated and then actually populate it when program diagnostics are queried
- In diagnostic explaining the reason why file is in program, we are caching details as well as related info that can be reused when there are multiple diagnostics for same file. The cache is cleared after population of program diagnostics is complete so doesnt stay beyond the computation of these diagnostics
Probably fixes
- https://github.com/microsoft/TypeScript/issues/58011
- https://github.com/typescript-eslint/typescript-eslint/issues/1192
- https://github.com/microsoft/TypeScript/issues/58274
@typescript-bot pack this
Starting jobs; this comment will be updated as builds start and complete.
| Command | Status | Results |
|---|---|---|
pack this |
✅ Started | ✅ Results |
Hey @sheetalkamat, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:
{
"devDependencies": {
"typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/161598/artifacts?artifactName=tgz&fileId=3F3D97042F3CD53F19137FD5481087CF59977AC9681B5F1C2DEDE0CAE6673D6E02&fileName=/typescript-5.5.0-insiders.20240502.tgz"
}
}
and then running npm install.
There is also a playground for this build and an npm module you can use via "typescript": "npm:@typescript-deploys/[email protected]".;
@sheetalkamat I am experiencing an error with these changes in my project when using getCombinedCodeFix:
TypeError: Cannot read properties of undefined (reading 'push')
at addLazyProgramDiagnosticExplainingFile (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:126723:41)
at checkSourceFilesBelongToPath (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:126142:11)
at ../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:124558:37
at getCommonSourceDirectory (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:117872:53)
at Object.getCommonSourceDirectory2 [as getCommonSourceDirectory] (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:124553:31)
at getDeclarationEmitOutputFilePath (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:20116:119)
at getOutputPathsFor (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:117787:96)
at transformRoot (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:115914:62)
at transformation (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:117457:14)
at transformRoot (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:117480:71)
at transformNodes (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:117465:70)
at getDeclarationDiagnostics (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:115644:18)
at ../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:125420:14
at runWithCancellationToken (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:125122:14)
at getDeclarationDiagnosticsForFileNoCache (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:125418:12)
at getAndCacheDiagnostics (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:125429:20)
at getDeclarationDiagnosticsWorker (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:125415:12)
at getDeclarationDiagnosticsForFile (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:125438:48)
at getDiagnosticsHelper (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:125070:44)
at Object.getDeclarationDiagnostics2 [as getDeclarationDiagnostics] (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:125108:14)
at getDiagnostics (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:151176:18)
at eachDiagnostic (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:151162:23)
at Object.getAllCodeActions (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:154119:5)
at Object.getAllFixes (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:151148:65)
at Object.getCombinedCodeFix (../../node_modules/.pnpm/@[email protected]/node_modules/@ts-morph/common/dist/typescript.js:149433:31)
Unfortunately I am not exactly sure how to reproduce this issue outside of my codebase, but it seems there is some code path that calls addLazyProgramDiagnosticExplainingFile (which calls push on lazyProgramDiagnosticExplainingFile assuming it is defined) after updateAndGetProgramDiagnostics is called, which sets it to undefined.
Here is the call stack that hits updateAndGetProgramDiagnostics which sets the array to undefined before the above call stack:
updateAndGetProgramDiagnostics
getProgramDiagnostics
getSemanticDiagnosticsForFile
getDiagnosticsHelper
Object.getSemanticDiagnostics
getDiagnostics
eachDiagnostic
getAllCodeActions
Object.getAllFixes
Object.getCombinedCodeFix
This is occurring in 5.5.2
In codeFixProvider.ts#getDiagnostics I see we are getting semantic diagnostics before getting declaration diagnostics. As you can see in the stack traces above, the code path which sets lazyProgramDiagnosticExplainingFile to undefined is reached while getting semantic diagnostics while the code path which attempts to push to it is reached while getting declaration diagnostics. The change to get declaration diagnostics after semantic diagnostics came from this commit.
My hunch is that in order to reproduce this issue you'd need to request code fixes for a file that has both semantic diagnostics AND declaration diagnostics. The error doesn't occur if I set "declaration": false and "composite": false in my tsconfig.json because that causes this if-statement to evaluate to false and skip declaration diagnostics.
Please send the tsserver log so we can investigate
Ok I have the repro .. will look into this