Use this skill for language service and editor failures.
Include relevant excerpts when reporting or fixing hover, completion, or definition failures.
For large or multi-surface investigations, work as a planned task sequence:
define the current slice, keep one step active, verify it before moving on,
and re-evaluate the next slice after each result. Tell the user what the next
step is after each verified slice. Prefer reduced compiler-level repros before
broad LSP or sample-project coverage, then add editor-level tests only when
request scheduling, workspace loading, or presentation behavior is part of the
bug.
-
Reduce the issue to a minimal source example.
-
Record the exact editor action that fails.
-
Reproduce the request with the headless language-server harness when possible:
dotnet run --project tools/Raven.LanguageServer.Headless/Raven.LanguageServer.Headless.csproj /property:WarningLevel=0
The default run opens samples/projects/efcore-vehicle-costs/src/Api/Main.rvn and simulates hovers for the current EF Core sample. Pass a project directory, source file, and optional target names to narrow the run:
dotnet run --project tools/Raven.LanguageServer.Headless/Raven.LanguageServer.Headless.csproj /property:WarningLevel=0 -- samples/projects/efcore-vehicle-costs samples/projects/efcore-vehicle-costs/src/Api/Main.rvn UseNpgsql
There are three useful replay modes:
dotnet run --project tools/Raven.LanguageServer.Headless/Raven.LanguageServer.Headless.csproj /property:WarningLevel=0 -- samples/projects/efcore-vehicle-costs samples/projects/efcore-vehicle-costs/src/Api/Main.rvn --replay-performance-report --replay-count 10
dotnet run --project tools/Raven.LanguageServer.Headless/Raven.LanguageServer.Headless.csproj /property:WarningLevel=0 -- samples/projects/efcore-vehicle-costs samples/projects/efcore-vehicle-costs/src/Api/Main.rvn --random-hover --random-count 50 --random-seed 1729
dotnet run --project tools/Raven.LanguageServer.Headless/Raven.LanguageServer.Headless.csproj /property:WarningLevel=0 -- samples/projects/efcore-vehicle-costs samples/projects/efcore-vehicle-costs/src/Api/Main.rvn --position 15:29
Use this harness to simulate hover behavior without VS Code, gather timings, and inspect semantic performance counters such as symbol-info fallback, type-info fallback, and bound-node bind fallback.
For edit recovery regressions, use headless edit probes to model the way developers actually reshape code: type an opening wrapper such as func Main() {, later add the closing }, or create func Main() { } and paste existing top-level statements into the body. Compare the first semantic query after the edit with a cold one-shot compilation and with a follow-up edit inside the stabilized owner.
For deterministic regression coverage, use the language-server unit-test hover replay helpers to load inline Raven source, open it through the mock workspace/document store, and orchestrate hovers at exact positions or marker-derived positions.
-
Check the client log to confirm the request lifecycle and parameters.
-
Check the server log to see request handling, failures, or missing symbol results.
-
Correlate the failing request with syntax, symbol lookup, binding, diagnostics behavior, compiler API caching, and language service code.
-
Add focused regression coverage if the failure is fixed in code.
When comparing editor behavior with command-line behavior, use the current
tool split: rvnc / Raven.Compiler is the compiler driver for one-shot
compile and project build repros, while rvn / Raven is for developer
commands such as syntax, pretty dump, and bound-tree views.
-
When hovers, inlays, semantic tokens, and document symbols appear stuck, check whether a full-document/background request started first and failed to complete.
-
Compare client request start/complete events with logs/raven-lsp.log and logs/raven-lsp-performance.txt.
-
Use the headless harness for hover and inlay ranges to separate compiler cold-path cost from VS Code scheduling.
-
For CPU traces, profile the built headless apphost directly rather than dotnet run; profiling dotnet run mostly captures CLI/MSBuild startup and wait frames. Use a bounded trace with rundown enabled so method symbols are preserved and the profiler stops cleanly:
dotnet build tools/Raven.LanguageServer.Headless/Raven.LanguageServer.Headless.csproj --property WarningLevel=0 --no-restore
dotnet trace collect --duration 00:00:12 --format speedscope \
-o /tmp/raven-traces/<scenario>.nettrace \
-- tools/Raven.LanguageServer.Headless/bin/Debug/net10.0/Raven.LanguageServer.Headless \
<project-dir> <source-file> <target-symbol> <headless-options>
dotnet trace report /tmp/raven-traces/<scenario>.nettrace topN --number 80
Avoid open-ended dotnet trace collect -- <headless-app> for these short LSP probes; EventPipe shutdown can leave the target waiting even after the app prints its results. If Asynkron Profiler is used, run it against the built apphost as well, and guard direct collection with a watchdog if the scenario previously showed EventPipe shutdown issues. Keep the raw headless timing output alongside the trace, because short scenarios can be dominated by startup, sleeps, and idle waits in aggregate profiler views.
-
When investigating hangs, compare the same project with editor inlays enabled and disabled. A project that loads without inlays but stalls with inlays points to request pressure or inlay-triggered cold semantic binding, not necessarily a broken compiler answer.
-
When investigating stale or surprising diagnostics, compare compiler diagnostics without source-code analyzers against diagnostics with analyzers enabled. This keeps binder/compiler diagnostics distinct from analyzer diagnostics and avoids chasing analyzer behavior as a binder regression.
-
When isolating analyzer performance, disable expensive built-in analyzers per project with RavenDisabledAnalyzers before changing compiler or LSP scheduling. Analyzer names may use the short analyzer type name, for example UnusedVariableAnalyzer.
-
For analyzer diagnostic delays, inspect workspace analyzer events as well as LSP request timings. Raven's analyzer driver should behave like a Roslyn-style scheduler: one cold full document walk is acceptable, but analyzers should be registered as narrow stateless actions so later edits can invalidate and rerun only affected syntax or symbol scopes.
-
If analyzer diagnostics disappear while analyzer work is skipped, canceled, or
failed, treat that as a diagnostic-lane bug. Background analyzer failures
should preserve the previous valid analyzer diagnostics and requeue work
instead of publishing an empty diagnostic set.
-
When a code-action request stalls, check whether a code-fix provider recomputed diagnostics or diagnostics-with-analyzers. Code fixes should use the diagnostics supplied by CodeFixContext; asking workspace or semantic-model diagnostic APIs from a code action can force broad binding and analyzer execution.
-
If a request is slow because public semantic APIs force broad binding, fix the compiler path. If a request blocks newer interactive work, fix LSP scheduling/cancellation without duplicating compiler semantics.
-
Treat structural edits that change executable ownership, such as wrapping top-level statements in func Main, as first-class recovery cases. Verify that changed-owner detection identifies the source-level owner and that later body-only edits can reuse unaffected semantic state.
-
For inlay flicker or disappearing hints, check whether the server returned an empty result while semantic access was busy. Prefer returning cached results for the same document version and range-filtering them over clearing the editor UI.
-
Treat large full-document inlay requests as background presentation work: they should prefer cached or available compiler state and avoid cold expensive binding fallbacks. Small full-document, precise, or visible-range inlay requests may trigger the authoritative compiler bind when needed.
-
Do not eagerly build tooltip markdown for full-document inlay responses. Full-document responses should prioritize correct labels and source-applicable edits; focused range requests can include richer tooltip content.
-
For slow inlays, separate three costs: semantic model materialization, binding needed for missing symbols/types, and presentation formatting such as type-name qualification. Fix broad metadata lookup or formatting costs before suppressing annotations.
-
For cross-file responsiveness issues, test adding a new .rvn file that declares a symbol and immediately hovering a reference to that symbol in another document. This exposes whether project snapshot updates and background diagnostics are blocking interactive semantic queries.
-
When request timings show high gateWait but low semantic work, fix request scheduling or gate ownership before optimizing binders.
-
When timings show low gate wait but high semantic/binding work, reduce the compiler path: prefer sound binder-owned caches, narrower binding, metadata lookup shortcuts, or incremental reuse.