prometeu-studio/discussion/workflow/decisions/DEC-0058-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

79 lines
6.6 KiB
Markdown

---
id: DEC-0058
ticket: pbs-lsp-remaining-editor-surface
title: PBS LSP remaining editor surface
status: accepted
created: 2026-09-22
ref_agenda: AGD-0069
tags: [studio, lsp, vscode, compiler-pbs, editor]
---
## Context
AGD-0069 consolidou AGD-0048 a AGD-0056. Essas agendas foram aposentadas e não são normativas. O usuário travou Q1-A e Q2-A em 2026-09-22.
O LSP já anuncia hover, completion, signature help, definition, references, document symbols, workspace symbols, rename, quick fix e semantic tokens full. Cada pedido reconstrói a análise. Definition, references e rename só devolvem arquivo físico. Quick fix é um `WorkspaceEdit` produzido pelo frontend, casado por code e range, sem remediação dentro do diagnóstico. `PBSSemanticTokenProvider` já classifica o documento a partir do lexer. Completion já cobre membro depois de `.` e o contexto geral, com documentação no próprio item e sem `resolve`.
O que falta é a superfície desta decision. O campo `source` do diagnóstico publicado está errado: hoje recebe o code estável, ou `"Prometeu Studio"` quando o code vem vazio.
## Decision
A discussão DSC-0066 tem uma decision e um plan. O plan executa sete passos, nesta ordem, um commit cada, na branch `dev/pbs-lsp-remaining-editor-surface`. Lesson e housekeep acontecem só no commit do último passo. Não há push nesta decision.
O frontend produz o resultado editorial. O LSP transporta. O LSP MUST NOT inventar reparo, link, range, formatação, token ou chamada que o frontend não devolveu. Capacidade ausente MUST NOT ser anunciada e MUST devolver lista vazia, não erro de protocolo.
### 1. Diagnostic source
O `source` de um diagnóstico editorial publicado MUST ser o `languageId` do `LspProjectContext` daquele pedido. Numa sessão PBS esse valor é `pbs`. O `code` MUST continuar o code estável do diagnóstico do compilador, vazio quando o compilador não tem code. O LSP MUST NOT copiar o code para `source`. O LSP MUST NOT publicar `relatedInformation`, fase do compilador ou payload de reparo nesse diagnóstico.
### 2. Document links
O servidor MUST anunciar `documentLink` só para esta capacidade. Cada link MUST cobrir o span do `ModuleRef` de um import cujo destino o resolver atual já entrega como arquivo físico regular. Sem arquivo físico, MUST NOT haver link. Stdlib virtual, asset, addressable, doc e URI sintético MUST NOT ser alvo. O link MUST NOT substituir definition.
### 3. Folding e selection range
O servidor MUST anunciar folding range e selection range. Range de declaração top-level (`fn`, `struct`, `service`, `contract`, `enum`, `error`, `callback`, `host`), corpo, lista de parâmetros e text block `Doc` MUST vir do span da árvore recuperada quando o nó existe. Chave, parêntese ou text block que a árvore não cobre MUST usar fallback de token. Selection, do interno para o externo, MUST ser: identificador, lista de argumento ou parâmetro, bloco ou text block, declaração. Sem range, a resposta MUST ser lista vazia. Document symbols MUST NOT ser reutilizados como folding.
### 4. Formatting
O servidor MUST anunciar formatting só de documento inteiro. Range formatting e on-type formatting MUST NOT ser anunciados. O formatter MUST reimprimir o token stream. MUST NOT reordenar declarações. MUST NOT juntar ou partir linhas para embelezar. Indentação MUST ser 4 espaços, aplicada só onde o aninhamento de chaves, parênteses ou bloco muda. O interior de text block `Doc` MUST permanecer intocado. Comentário MUST permanecer na linha do token a que já estava preso. Pretty-printer de AST MUST NOT ser o formatter. `LSN-0033` MUST NOT definir esse estilo.
### 5. Overlay semântico
`PBSSemanticTokenProvider` MUST continuar sendo a base lexical. Onde a mesma resolução usada pelo hover nomeia o símbolo e existe um `PbsSemanticKind` para esse símbolo, o token MUST trocar o kind fraco por esse kind existente. Falha de resolução, arquivo quebrado ou símbolo sem kind existente MUST manter o token que o provider emitiu. Esta onda MUST NOT criar key nova de semantic token.
### 6. Completion de module ref
Com o cursor dentro de um `ModuleRef`, completion MUST oferecer módulos de projeto e de stdlib que o resolver atual já sabe nomear. Fora de `ModuleRef`, o completion atual MUST permanecer. A resposta MUST continuar eager. `resolveProvider` MUST continuar falso. Snippets e score novo de ranking MUST NOT entrar.
### 7. Call hierarchy
O servidor MUST anunciar call hierarchy para função e método. Incoming e outgoing MUST ser uma caminhada de callsite na AST. O índice de references MUST NOT ser tratado como grafo de chamadas. Cursor que não está num callable MUST devolver vazio. Type hierarchy, implementações de contract e grafo separado de host ou intrinsic MUST NOT entrar.
### Fora desta decision
Esta decision MUST NOT pedir cache de snapshot, cancelamento, reanálise em background, organize imports, quick fix de import faltando, `completionItem/resolve`, formatting por range ou on-type, `relatedInformation`, ou links que não sejam o `ModuleRef` físico do passo 2.
## Rationale
Q1-A mantém os sete passos porque cada um cobre um buraco real e o piso já está implementado. Q2-A isola o estilo no formatter para ele não vazar para os outros passos. Cache deixou de ser pré-requisito quando references e rename saíram em análise local ao pedido. Auto-import não tem diagnóstico cujo significado seja "nome não importado". Type hierarchy não compartilha modelo com call hierarchy.
## Implications
Os passos 2, 3, 4 e 7 acrescentam capacidade anunciada. Os passos 1, 5 e 6 corrigem ou estendem capacidade que o servidor já anuncia. Nenhum passo reabre o contrato de quick fix nem o de definition física. Spec 23 §8.3 ganha o parágrafo do passo no commit daquele passo, não antes.
## Propagation Targets
- specs: `docs/specs/compiler/23. Compiler Pipeline Entry Points Specification.md` §8.3, um parágrafo por passo, no commit desse passo.
- plans: um plan de DSC-0066 com os sete passos e um commit cada.
- code: `prometeu-compiler` onde o frontend produz o resultado; `prometeu-lsp` onde o protocolo transporta. `source` do diagnóstico usa `LspProjectContext.languageId`.
- tests: bridge e, quando a capacidade é nova, o anúncio no mapper. Arquivo quebrado continua coberto em token e folding.
- docs: nenhum outro. A lesson em inglês só no housekeep do último passo.
## References
- Agenda: AGD-0069
- Discussões aposentadas: DSC-0045 a DSC-0053, AGD-0048 a AGD-0056
- Spec: `docs/specs/compiler/23. Compiler Pipeline Entry Points Specification.md` §8.3
- Lessons de piso: LSN-0068, LSN-0069, LSN-0070, LSN-0071, LSN-0072, LSN-0073