--- 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