Call hierarchy walks CallExpr nodes for functions and methods. It does not use the references index. A cursor that is not on a callable is empty, and type hierarchy stays unadvertised. Housekeep DSC-0066 with LSN-0074.
71 lines
5.9 KiB
Markdown
71 lines
5.9 KiB
Markdown
---
|
|
id: LSN-0074
|
|
ticket: pbs-lsp-remaining-editor-surface
|
|
title: PBS remaining editor surface is frontend-owned and transported by the LSP
|
|
created: 2026-09-22
|
|
tags: [studio, lsp, vscode, compiler-pbs, editor]
|
|
---
|
|
|
|
# PBS remaining editor surface is frontend-owned and transported by the LSP
|
|
|
|
## Original Problem
|
|
|
|
Nine open LSP agendas still described formatting, imports, semantic tokens, snapshots, completion, folding, diagnostics, document links, and call hierarchy as if none of that surface existed. By the time those agendas were still open, the server already advertised hover, completion, signature help, definition, references, outline, workspace symbols, rename, quick fix, and full semantic tokens. Each request still rebuilt analysis. References and rename had already shipped without a snapshot cache. There was no diagnostic whose meaning was "this name is not imported."
|
|
|
|
Treating the nine agendas as nine decisions would have reimplemented finished work and locked stale premises.
|
|
|
|
## Consolidated Decision
|
|
|
|
`DEC-0058` retired that split. One plan, `PLN-0137`, landed seven steps. The frontend produces the editorial result. The LSP transports it and does not invent a second policy. A missing capability is not advertised and returns an empty list, not a protocol error.
|
|
|
|
The wave explicitly does not add a project snapshot cache, type hierarchy, `completionItem/resolve`, snippets, a ranking score, range or on-type formatting, organize imports, a missing-import quick fix, `relatedInformation`, or a new semantic-token key.
|
|
|
|
1. Published editor diagnostic `source` is the bound frontend `languageId`. For PBS that is `pbs`. `code` stays the stable compiler code. The code is not copied into `source`.
|
|
2. A document link covers only the span of a `ModuleRef` whose module assembly already resolved to a regular file. Virtual stdlib and unresolved modules produce no link.
|
|
3. Folding comes from recovered spans of the listed declarations, their bodies, parameter lists, and `Doc` text blocks. A brace, parenthesis, or text block the tree does not cover still folds, including an unmatched opener through the end of the text. Selection grows outward from identifier, to argument or parameter list, to block or `Doc` text block, to declaration.
|
|
4. Formatting is full-document only. It reprints the token stream, indents by four spaces where brace or parenthesis nesting changes, leaves `Doc` text-block interiors untouched, and does not reorder declarations or move comments off their line.
|
|
5. Semantic tokens keep `PBSSemanticTokenProvider` as the baseline. Hover resolution may replace an identifier token only when an existing `PbsSemanticKind` matches the symbol. Failure, a broken file, or a symbol with no existing key keeps the baseline token.
|
|
6. Completion inside a `ModuleRef` lists project and stdlib modules the current resolver can already name. Every other offset keeps the existing member or general completion. Items stay eager and `resolveProvider` stays false.
|
|
7. Call hierarchy walks `CallExpr` nodes for functions and methods. It does not use the references index. A cursor that is not on a callable is empty. Type hierarchy is not advertised.
|
|
|
|
## Final Implementation
|
|
|
|
`CompilerLanguageServiceBridge` reads `LspProjectContext.languageId` into `BaselineDocumentIssue.source`. Document links read the physical module map that module assembly already built; stdlib files under `/virtual/stdlib` are not regular files, so they are not links. Folding, selection, and formatting reparse the open buffer with the existing lexer and parser. They do not require a successful project analysis. The semantic-token overlay runs only when editorial context is available and otherwise returns the provider tokens, including when project discovery fails. Module completion labels are the project modules from that same physical map plus the modules `ResourceStdlibEnvironmentResolver` can already resolve. Call hierarchy collects function, method, and constructor declarations from the recovered AST and matches `CallExpr` callees by name and call shape.
|
|
|
|
Spec 23 §8.3 states each of these rules. The nine earlier agendas, `AGD-0048` through `AGD-0056`, were abandoned and are not normative.
|
|
|
|
## Examples
|
|
|
|
A project import `@app:a` that resolves to `src/a/source.pbs` is one document link on that module-reference span. `@sdk:log` is not, because the stdlib file is virtual.
|
|
|
|
```pbs
|
|
fn helper() -> int { return 1; }
|
|
fn main() -> int { return helper; }
|
|
```
|
|
|
|
The use of `helper` without a call is an identifier in the lexical pass. Hover resolves it as a function, so the overlay key is `pbs-function`. A local such as `value` has no existing key, so it stays `pbs-identifier`.
|
|
|
|
```pbs
|
|
fn helper() -> int { return 1; }
|
|
fn main() -> int { return helper(); }
|
|
```
|
|
|
|
Prepare on `main` returns that function. Outgoing calls include `helper`. Incoming calls of `helper` include `main`. A cursor on a struct name returns no item.
|
|
|
|
## Common Pitfalls
|
|
|
|
- Do not copy the diagnostic code into `source`. The editor then shows the code twice and loses the language id.
|
|
- Do not build document links to `/virtual/stdlib`. Definition already refuses that destination.
|
|
- Do not treat document symbols as folding ranges. Outline and folding are different payloads.
|
|
- Do not pretty-print from the AST. Comments and `Doc` text-block interiors are not fully modeled as trivia on the tree.
|
|
- Do not add `pbs-local`, `pbs-parameter`, or `pbs-field` in the overlay. Those symbols stay on the baseline token until a later decision adds the key.
|
|
- Do not implement call hierarchy by inverting the references index. A reference is a use of a name, not a call.
|
|
- Do not start a snapshot cache because a later feature feels slow. This wave deliberately kept request-local analysis.
|
|
|
|
## References
|
|
|
|
- `DEC-0058` and `PLN-0137`, removed by housekeeping after this lesson
|
|
- `docs/specs/compiler/23. Compiler Pipeline Entry Points Specification.md` §8.3
|
|
- Earlier surface: `LSN-0068`, `LSN-0069`, `LSN-0070`, `LSN-0071`, `LSN-0072`, `LSN-0073`
|
|
- Abandoned agendas: `AGD-0048` through `AGD-0056`
|