-
Notifications
You must be signed in to change notification settings - Fork 27.1k
feat(language-service): integrate progressive init with pull-based diagnostics #66967
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: main
Are you sure you want to change the base?
feat(language-service): integrate progressive init with pull-based diagnostics #66967
Conversation
Implement support for LSP 3.17 Pull-Based Diagnostics, which allows clients to request diagnostics on-demand rather than receiving them pushed from the server. Key changes: - Add new diagnostics.ts handler with onDocumentDiagnostic and onWorkspaceDiagnostic implementations - Register diagnosticProvider capability in server initialization - Detect client support for pull diagnostics and workspace refresh - Implement result caching with resultId to return unchanged reports when documents haven't been modified - Support fallback to push-based diagnostics when client doesn't support pull diagnostics - Add integration tests for pull-based diagnostics Benefits: - Client controls when diagnostics are computed - Reduced unnecessary diagnostic computations via caching - Better integration with VS Code's diagnostic system - Supports inter-file dependencies for Angular projects
Replace project.refreshDiagnostics() with progressive background processing during project initialization. Open files are now processed in configurable chunks (default: 10) with event loop yields between chunks, keeping the IDE responsive during Angular project startup. Progressive initialization provides: - Immediate feedback: diagnostics appear file-by-file - Responsiveness: event loop not blocked between chunks - Cancellation: stops if project closes or user starts typing
Use promisify(setImmediate) instead of a custom yieldToEventLoop() function for consistency with the existing pattern in session.ts.
…ll-diagnostics-integration
…agnostics When pull-based diagnostics (LSP 3.17) is active, progressive project init now sends a workspace/diagnostic/refresh notification instead of computing and pushing diagnostics for each open file. This avoids wasted computation since the pull-based client would discard pushed diagnostics anyway. Falls back to the chunked push-based approach when pull diagnostics is not supported by the client. Depends on: - PR angular#66700 (Pull-Based Diagnostics) - PR angular#66966 (Progressive Project Initialization)
atscott
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a look at this in conjunction with PR #66966. While I understand the goal of making initialization non-blocking, introducing the initializeProjectProgressively chunking loop and custom cancellation (progressiveInitCancelled) seems redundant with our existing infrastructure, as mentioned in the other PR.
We already have a robust, non-blocking push implementation: sendPendingDiagnostics. It handles event-loop yielding (per-file) and user-typing debounce/cancellation via diagnosticsTimeout.
Instead of maintaining a separate initializeProjectProgressively chunking system, we can just lean on the existing logic:
private enableLanguageServiceForProject(project: ts.server.Project): void {
// ...
this.runGlobalAnalysisForNewlyLoadedProject(project);
if (this.usePullDiagnostics) {
this.connection.languages.diagnostics.refresh();
} else {
// Reuses the existing yielding and debouncing logic instead of blocking!
this.triggerDiagnostics(this.openFiles.getAll(), 'Project initialized');
}
}Could we strip out initializeProjectProgressively and its associated cancellation state, and just use the snippet above? It keeps the server responsive for all clients while reducing complexity.
PR: feat(language-service): integrate progressive init with pull-based diagnostics
Description
Integrates Progressive Project Initialization (#66966) with Pull-Based Diagnostics (#66700) so they work optimally together.
When pull-based diagnostics (LSP 3.17) is active, progressive project initialization now sends a single
workspace/diagnostic/refreshnotification instead of computing and pushing diagnostics for each open file. This eliminates wasted computation since the pull-based client would discard pushed diagnostics anyway.Falls back to the chunked push-based approach when pull diagnostics is not supported by the client.
Problem
Without this integration, when both features are active:
getSemanticDiagnostics) and pushes them viaconnection.sendDiagnostics()textDocument/diagnosticto request them on-demand)Solution
When
usePullDiagnosticsis true, the method:workspace/diagnostic/refreshto the clientThe client then pulls diagnostics on its own schedule, using the pull diagnostics handler which has its own caching via
resultId.Changes
vscode-ng-language-service/server/src/session.tsusePullDiagnosticsininitializeProjectProgressively(), send refresh notification instead of computing diagnosticsDependencies
This PR must be merged AFTER both base PRs:
usePullDiagnosticsflag andworkspace/diagnostic/refresh)initializeProjectProgressively())Testing
Breaking Changes
None
AI Disclosure
This PR was developed using Claude Opus 4 AI assistant under human orchestration and review by @kbrilla.