Notify the diagnostic system that a file needs fresh diagnostics. Push mode:** Queues the file for the debounced background diagnostic worker and schedules external tool runs. Pull mode:** Only schedules external tool runs (PHPStan, PHPCS, Mago). Native diagnostic computation is deferred until the editor sends a `textDocument/diagnostic` pull request, which triggers [`trigger_diagnostics_for_pu
(&self, uri: String)
| 867 | /// in the background so that completion, hover, and signature help |
| 868 | /// are never blocked. |
| 869 | pub(crate) fn schedule_diagnostics(&self, uri: String) { |
| 870 | // Don't schedule diagnostics before initialization is complete. |
| 871 | // Files opened during startup will be diagnosed once |
| 872 | // `initialized` sets `init_complete` and re-schedules them. |
| 873 | if !self.init_complete.load(Ordering::Acquire) { |
| 874 | return; |
| 875 | } |
| 876 | |
| 877 | let pull_mode = self.supports_pull_diagnostics.load(Ordering::Acquire); |
| 878 | |
| 879 | if pull_mode { |
| 880 | // Invalidate the cached full diagnostics so the next pull |
| 881 | // triggers a fresh computation instead of returning stale |
| 882 | // results. Do NOT remove the resultId — removing it resets |
| 883 | // the ID to 0 (via unwrap_or), which can match a stale |
| 884 | // previousResultId sent by the client and cause the pull |
| 885 | // handler to return "unchanged" with outdated diagnostics. |
| 886 | // The resultId is bumped naturally when assemble_and_push |
| 887 | // caches new results. |
| 888 | self.diag_last_full.lock().remove(&uri); |
| 889 | } |
| 890 | |
| 891 | // Both modes: queue for the debounced background worker. |
| 892 | // In push mode the worker pushes the full assembled set. |
| 893 | // In pull mode the worker pushes only fast diagnostics and |
| 894 | // caches the full set in `diag_last_full` for pull responses. |
| 895 | { |
| 896 | let mut pending = self.diag_pending_uris.lock(); |
| 897 | if !pending.contains(&uri) { |
| 898 | pending.push(uri.clone()); |
| 899 | } |
| 900 | } |
| 901 | self.diag_version.fetch_add(1, Ordering::Release); |
| 902 | self.diag_notify.notify_one(); |
| 903 | |
| 904 | // Both modes: schedule external tool runs. In pull mode the |
| 905 | // external tools still use their own debounce timers because |
| 906 | // they are expensive and the IDE may send many pulls in |
| 907 | // quick succession. |
| 908 | self.schedule_phpstan(uri.clone()); |
| 909 | self.schedule_phpcs(uri.clone()); |
| 910 | self.schedule_mago_lint(uri.clone()); |
| 911 | self.schedule_mago_analyze(uri); |
| 912 | } |
| 913 | |
| 914 | /// Invalidate diagnostics for all open files after a cross-file change. |
| 915 | /// |
no test coverage detected