[display] honor request-provided file contents#12979
Open
kLabz wants to merge 2 commits into
Open
Conversation
…idated caches Unsaved editor buffers arrive as 'contents' in display requests (haxe-language-server sends them on every hover), but all three server cache layers validate freshness by disk mtime only, which does not change while the user types: - parse_file serves the cached disk parse on mtime match without consulting com.file_contents (and dms_per_file could cache a contents-parse keyed by disk mtime, poisoning later requests); - check_module deems the module clean (mtime unchanged), so the stale typed module is served and the display position is either never visited (empty hover) or resolved against old content (wrong-symbol hover); - check_display_file types the cached c_decls directly with no freshness validation at all. haxe-language-server sends server/invalidate on each edit, which evicts these caches and usually hides the problem. But nothing invalidates again when a compilation or a diagnostics run re-populates them from disk: with unsaved edits still pending, the next display request is answered from the freshly cached disk state instead of the buffer. Fix: request contents take priority. parse_file bypasses the parse cache (and skips caching) for files with provided contents; check_module compares the contents-parse against the cached declarations (not gated by NoFileSystemCheck — no file system involved); check_display_file re-parses and falls back to fresh typing when the declarations differ (needed even with the check_module fix: a display module already loaded fresh this request hits module_lut directly, skipping the hook). Regression test: cases/UnsavedContentsStale — hover carrying newer contents after a compile with no invalidate in between. Unfixed, it resolves the offset against the stale disk parse and returns the type of the identifier that previously occupied it (Int from the old `aaa` instead of String from the new `bbb`).
Two optimizations over the previous commit, measured on a pathological 351KB / 3000-decl display file (typical files are 10-30x smaller); without them the freshness checks re-parsed the buffer at every check site on every hover (~180ms at this size). - displayJson drops request contents that are byte-identical to the on-disk file (the common case: hover with no unsaved edits). The mtime-validated caches then stay fully usable. Clean-buffer hover: 35ms vs 33ms unfixed — the fix-attributable cost is one file read + string compare (~1ms even at this size); the ~22ms both pay over the 13ms no-contents baseline is JSON payload decode of the contents string, which pre-exists. - context_cache grows a tmp_parse_cache (cleared per request alongside tmp_binary_cache): the contents-parse is computed once and shared by check_module, check_display_file and module typing instead of re-parsing at each site. Dirty-buffer hover (unsaved edits pending): ~100ms at this size = one parse + full fresh display typing — the price of a correct answer where the unfixed server returned a wrong-symbol result.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Unsaved editor buffers arrive as 'contents' in display requests (haxe language server sends them on every hover), but all three server cache layers validated freshness by disk
mtimeonly, which does not change while the user types:parse_fileserves the cached disk parse onmtimematch without consultingcom.file_contents(anddms_per_filecould cache acontents-parsekeyed by diskmtime, poisoning later requests);check_moduledeems the module clean (mtimeunchanged), so the stale typed module is served and the display position is never visited (empty hover) or resolved against old content (wrong-symbol hover);check_display_filetypes the cachedc_declsdirectly with no freshness validation at all.Haxe language server sends
server/invalidateon each edit, which evicts these caches and usually hides the problem. But nothing invalidates again when a compilation or a diagnostics run re-populates them from disk: with unsaved edits still pending, the next display request is answered from the freshly cached disk state instead of the buffer.