prometeu-studio/discussion/workflow/plans/PLN-0137-pbs-lsp-remaining-editor-surface.md
bQUARKz 099857b636
implements PLN-0137 (1/7) diagnostic-source
Lock DSC-0066 on Q1-A and Q2-A. Retire AGD-0048 through AGD-0056
into AGD-0069, DEC-0058, and PLN-0137.

Published editor diagnostics use the bound frontend language id as
source. For PBS that is pbs. The stable compiler code stays in code
and is not copied into source. Related locations, phase, and repair
payload stay unpublished.
2026-09-22 08:11:06 +01:00

127 lines
9.3 KiB
Markdown

---
id: PLN-0137
ticket: pbs-lsp-remaining-editor-surface
title: PBS LSP remaining editor surface
status: in_progress
created: 2026-09-22
ref_decisions: [DEC-0058]
tags: [studio, lsp, vscode, compiler-pbs, editor]
---
## Briefing
DEC-0058 locks one PBS LSP wave on top of the editor surface that already ships. Seven steps run in order on `dev/pbs-lsp-remaining-editor-surface`. Each step is one commit. The frontend produces the editorial result. The LSP transports it and does not invent a second policy.
## Objective
Land diagnostic source, physical import document links, folding and selection ranges, full-document formatting, a semantic-token overlay, module-ref completion, and function/method call hierarchy. Leave snapshot cache, type hierarchy, auto-import, and resolve completion out.
## Dependencies
Shipped and unchanged by this plan: request-local analysis, physical definition and references, rename, document symbols, workspace symbols, quick fix (LSN-0073), `PBSSemanticTokenProvider`, and eager completion in `PbsEditorialSupportService`. Spec 23 §8.3 is the only normative doc updated, one paragraph in the commit of the step that introduces that rule.
## Scope
Local to studio LSP and the PBS frontend. Shared compiler entry points do not gain a cache or a new pipeline phase. New LSP capabilities follow the code-action pattern: `FrontendLanguageService` defaults to unsupported, PBS overrides support, `BaselineServerDescription` advertises only that flag, and a missing flag is an empty list.
### Step 1. Diagnostic source
In `CompilerLanguageServiceBridge.toBaselineIssue`, set `BaselineDocumentIssue.source` from `LspProjectContext.languageId`. Keep `code` as the trimmed compiler code, empty when the compiler code is null or blank. Do not special-case `"Prometeu Studio"`. `Lsp4jProtocolMessageMapper.mapDiagnostic` already copies `source` and `code` and must stay without `relatedInformation` or `data`.
Spec 23 §8.3 gains one paragraph: published editor diagnostic `source` is the bound frontend `languageId`; `code` is the stable compiler code or empty; tooling must not copy the code into `source` and must not publish related locations, phase, or a repair payload.
### Step 2. Document links
Add a frontend document-link result: span of a `ModuleRef` plus a physical file target. Default on `FrontendLanguageService` is an empty list and `documentLinksSupported` false. PBS returns a link only when the resolver the compiler already uses yields a regular file. No link for virtual stdlib, assets, docs, or an unresolved module. Do not add a second module resolver.
LSP: baseline message, `documentLinkProvider`, `PrometeuTextDocumentService.documentLink`, mapper. Unsupported stays unadvertised and returns an empty list.
### Step 3. Folding and selection ranges
Frontend produces both lists from the recovered AST when the node has a span: top-level `fn`, `struct`, `service`, `contract`, `enum`, `error`, `callback`, and `host`; their bodies; parameter lists; `Doc` text blocks. Token fallback covers only a brace, parenthesis, or text-block delimiter the tree does not cover. Selection order, inner to outer: identifier, argument or parameter list, block or text block, declaration. Empty when there is nothing. Do not build either list from document symbols.
LSP advertises `foldingRangeProvider` and `selectionRangeProvider` only when the frontend flags are true.
### Step 4. Full-document formatting
Frontend formatter reprints the token stream. It does not reorder declarations, join lines, or split lines to beautify. Indent is four spaces and changes only where brace, parenthesis, or block nesting changes. `Doc` text-block interiors are copied unchanged. A comment stays on the token line it already belongs to. No AST pretty-printer. No range formatting. No on-type formatting. Do not read `.studio/setup.json` or LSN-0033.
LSP advertises `documentFormattingProvider` only.
### Step 5. Semantic-token overlay
Keep `PBSSemanticTokenProvider` as the lexical baseline. After that pass, where the same resolution hover uses names a symbol and an existing `PbsSemanticKind` matches it, replace the weaker key. On resolution failure, a broken file, or a symbol with no existing key, keep the provider token. Add no `PbsSemanticKind` constant. The server already advertises semantic tokens; do not add a second provider.
### Step 6. Module-ref completion
When the completion offset sits inside a `ModuleRef`, return project and stdlib modules the current resolver can already name. Every other offset keeps today's member or general completion. Items stay eager. `CompletionOptions.resolveProvider` stays false. No snippets. No new rank score. No new trigger-character policy beyond what module-ref detection needs inside the existing completion request.
### Step 7. Call hierarchy
Frontend walks `CallExpr` callsites for incoming and outgoing calls of functions and methods. Do not query the references index. A cursor that is not on a callable returns empty. No type hierarchy and no separate host or intrinsic graph.
LSP advertises call hierarchy only. This commit also writes the English lesson, runs `discussion housekeep DSC-0066 --lesson <path>`, and `discussion validate`.
## Non-Goals
- Project snapshot cache, cancellation, and background reanalysis.
- Type hierarchy, contract implementation hierarchy, and a separate host or intrinsic graph.
- `completionItem/resolve`, snippets, and a ranking model.
- Range formatting and on-type formatting.
- Organize imports and a missing-import quick fix.
- `relatedInformation`, compiler phase on the diagnostic, and repair data.
- New semantic-token keys.
- Document links for assets, addressables, docs, or virtual stdlib URIs.
- Reusing document symbols as folding ranges.
- Pushing the branch.
## Execution Method
1. Work on `dev/pbs-lsp-remaining-editor-surface`. Do not commit on `master`.
2. Mark this plan `in_progress` before step 1 code.
3. Implement one step, then run the tests listed for that step.
4. Commit that step before starting the next. Subject: `implements PLN-0137 (k/7) <slug>`.
5. Stage `discussion`, `docs`, `prometeu-compiler`, and `prometeu-lsp` as the step touches them. Do not stage `AGENTS.md`.
6. Spec 23 §8.3 is edited in the same commit as the step whose rule it states.
7. Steps are not reordered and are not parallel. A later step may use the capability flags introduced earlier; it must not reopen a closed step.
8. The seventh commit includes the lesson and housekeep. Earlier commits keep DEC-0058 and this plan in the tree.
Commit slugs:
1. `diagnostic-source`
2. `document-links`
3. `folding-and-selection-ranges`
4. `document-formatting`
5. `semantic-token-overlay`
6. `module-ref-completion`
7. `call-hierarchy`
## Acceptance Criteria
- Step 1: every issue from `analyzeDocument` on a PBS project has `source` equal to `pbs`, `code` is the stable compiler code, and `source` is not that code. No related information is mapped.
- Step 2: a `ModuleRef` that resolves to a regular file becomes one document link on that span. Virtual stdlib and unresolved modules produce no link. The provider is advertised only when supported.
- Step 3: a well-formed declaration, body, parameter list, and `Doc` text block fold from AST spans. An unmatched brace still produces a token fallback range. Selection nests in the decided order. Document symbols are unchanged.
- Step 4: formatting a document does not change `Doc` text-block interiors, does not move a comment off its token line, does not reorder declarations, and only changes indent by four spaces at nesting changes. Range and on-type providers stay off.
- Step 5: an identifier hover can resolve changes to an existing semantic key; a broken file still returns the lexical tokens; `PbsSemanticKind` gains no constant.
- Step 6: completion inside a `ModuleRef` lists resolver-known modules; completion after `.` is unchanged; `resolveProvider` is false.
- Step 7: incoming and outgoing calls report function and method callsites found in the AST. A non-callable cursor is empty. Type hierarchy is not advertised. `discussion validate` passes after housekeep, and the lesson states the seven rules.
## Tests
- `CompilerLanguageServiceBridgeTest` for diagnostic source, and for each new bridge method as it lands.
- `Lsp4jProtocolMessageMapperTest` for capability advertisement of each new provider, and for the absence of range formatting, on-type formatting, resolve, related information, and type hierarchy.
- PBS frontend tests for links, folding, selection, formatting, the token overlay, module-ref completion, and call hierarchy. Include one broken-file case for tokens and one unmatched-delimiter case for folding.
- Do not require a running VS Code instance. Bridge and mapper tests are the protocol gate.
## Affected Artifacts
- `discussion/workflow/agendas/AGD-0069-pbs-lsp-remaining-editor-surface.md`
- `discussion/workflow/decisions/DEC-0058-pbs-lsp-remaining-editor-surface.md`
- `discussion/workflow/plans/PLN-0137-pbs-lsp-remaining-editor-surface.md`
- `discussion/index.ndjson`
- `docs/specs/compiler/23. Compiler Pipeline Entry Points Specification.md`
- `prometeu-compiler/prometeu-frontend-api` (`FrontendLanguageService` and new result types)
- `prometeu-compiler/frontends/prometeu-frontend-pbs` (PBS implementations)
- `prometeu-lsp/prometeu-lsp-v1` (bridge, baseline messages, text document service, mapper)
- Lesson, only in the step 7 commit: `discussion/lessons/DSC-0066-pbs-lsp-remaining-editor-surface/`