prometeu-studio/discussion/workflow/agendas/AGD-0069-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

11 KiB

id ticket title status created resolved decision tags
AGD-0069 pbs-lsp-remaining-editor-surface PBS LSP Remaining Editor Surface accepted 2026-09-22
studio
lsp
vscode
compiler-pbs
editor

Pain

Domain owner: studio

Nove agendas de LSP (AGD-0048 a AGD-0056, discussões DSC-0045 a DSC-0053) continuavam abertas como se cada tema partisse do zero. O servidor já anuncia hover, completion, signature help, definition, references, document symbols, workspace symbols, rename, quick fix e semantic tokens. Várias perguntas dessas agendas já foram respondidas pelo código, ou pedem trabalho cuja premissa deixou de existir. Decidir uma a uma repetiria debate vencido e produziria nove decisions para uma superfície só.

Context

Esta agenda substitui, sem herdar o texto como normativo:

Agenda aposentada Discussão O que o código já fez com o tema
AGD-0048 formatting DSC-0045 Não há documentFormattingProvider, rangeFormatting nem onTypeFormatting.
AGD-0049 import assistance DSC-0046 Não há auto-import nem organize imports. Imports existem como ImportDecl / ModuleRef.
AGD-0050 semantic tokens DSC-0047 Tokens full-document já saem de PBSSemanticTokenProvider.
AGD-0051 cache e snapshots DSC-0048 Cada pedido reconstrói análise. References e rename já existem sem cache.
AGD-0052 completion depth DSC-0049 Completion já existe, eager, gatilho ., resolveProvider falso.
AGD-0053 folding e selection DSC-0050 Não há folding nem selection range. Outline não é folding.
AGD-0054 diagnostics UX DSC-0051 Diagnóstico já publica range, severity, message e code. Quick fix já casa code + range.
AGD-0055 document links DSC-0052 Não há documentLinkProvider. Definition já recusa alvo que não seja arquivo físico.
AGD-0056 call e type hierarchy DSC-0053 Não há call hierarchy nem type hierarchy. References não são grafo de chamadas.

O que o initialize anuncia hoje, em Lsp4jProtocolMessageMapper: sync full, hover, completion, signature help, definition, references, document symbol, workspace symbol, rename com prepare, code action só quickfix, semantic tokens full. Nada além disso.

Fatos que esta agenda trata como fechados, porque o código já os fixou:

  1. Análise de LSP é local ao pedido. CompilerLanguageServiceBridge.analyzeDocument monta um AnalysisSnapshot novo com overlay do documento aberto. Não há cache de projeto, cancelamento nem reanálise em background. References, rename e workspace symbols já foram entregues em cima desse modelo. Cache não é pré-requisito de mais nenhuma feature desta onda.
  2. Semantic tokens não estão por fazer. PBSSemanticTokenProvider lexa o arquivo, classifica token léxico direto e classifica identificador por token vizinho, mapa de declaração do próprio arquivo e kinds importados da stdlib. A legenda é PbsSemanticKind. Não existem keys de field, local ou parameter. Arquivo quebrado continua tokenizável porque o lexer não depende do sucesso semântico.
  3. Completion não está por fazer. PbsEditorialSupportService.completion faz duas coisas: se o token anterior é ., membros do tipo; senão keywords, parâmetros, locals, símbolos importados e top-level do arquivo. Documentação volta no próprio item. Não há snippets, não há completionItem/resolve, não há score de ranking.
  4. Diagnóstico não carrega remediação. Spec 23 §8.3 e o quick fix já entregue exigem que o reparo não seja campo do diagnóstico nem venha de parse da mensagem. O mapper copia range, severity, message e code. O campo source está errado: toBaselineIssue grava o code estável também em source (ou "Prometeu Studio" quando o code vem vazio). Não há relatedInformation.
  5. Não há um code de diagnóstico cujo significado seja "nome não importado". Os codes de nome não resolvido que existem são casos pontuais (E_SEM_CONST_UNRESOLVED_REFERENCE, E_SEM_APPLY_UNRESOLVED_OVERLOAD, E_SEM_ASSIGN_TARGET_UNRESOLVED, E_SEM_EXEC_LOWERING_UNRESOLVED_CALLEE). Inserir import em cima deles mistura typo com import faltando.
  6. Definition, references e rename só apontam arquivo físico. Alvo virtual de stdlib não é destino de navegação.
  7. A política de indentação em LSN-0033 pertence ao editor embutido removido. Não é estilo canônico de PBS e não manda no formatter do LSP.
  8. Outline, workspace symbols, rename e quick fix não absorvem folding, links, hierarquia nem organize imports.

Fora desta onda, de propósito:

  • cache de snapshot, cancelamento e reanálise em background;
  • type hierarchy, implementações de contract e grafo de host/intrinsic como feature separada;
  • completionItem/resolve, snippets e modelo de ranking;
  • formatting por range ou on-type;
  • organize imports e quick fix de import faltando;
  • relatedInformation, fase do compilador dentro do diagnóstico, e campo de remediação;
  • keys novas de semantic token;
  • links para assets, addressables, docs ou URI virtual de stdlib.

Open Questions

  • Q1. Qual pacote o plano único executa? Travada em 2026-09-22: A.

    • A. Os sete passos da recomendação, nesta ordem, um commit cada. Inclui formatter e call hierarchy.
    • B. Os mesmos passos sem o 7 (call hierarchy fica fora).
    • C. Os mesmos passos sem o 4 (formatter fica fora até existir estilo aceito).
    • D. Só os passos que não escolhem estilo nem grafo novo: 1, 2, 3 e 6.
  • Q2. Se o passo 4 entrar, qual estilo o formatter aplica? Travada em 2026-09-22: A.

    • A. Reimpressão do token stream. Não reordena declarações. Não junta nem parte linhas para embelezar. Indentação de 4 espaços só onde o aninhamento de chaves, parênteses ou bloco muda. Interior de text block Doc intocado. Comentário permanece na linha do token a que já estava preso. Documento inteiro apenas.
    • B. Não travar estilo. O passo 4 sai do plano mesmo se Q1 escolher A ou B.

Options

Option A - Uma onda, um plano, commits por passo

  • Approach: Uma decision e um plan. O plan copia os passos abaixo que Q1/Q2 deixarem vivos. Cada passo é um commit na mesma branch. Lesson e housekeep só depois do último passo.
  • Pro: O código atual vira o piso. Tema vencido não vira decision. A série continua um commit por entrega, sem nove discussões.
  • Con: Formatter e call hierarchy ainda são maiores que links ou o rótulo de source.
  • Maintainability: Forte se cada passo não reabrir cache, type hierarchy ou auto-import.

Option B - Só o que já não tem escolha de produto

  • Approach: Mesma discussão única, mas o plano fica em diagnóstico source, document links físicos, folding/selection e completion de module ref.
  • Pro: Evita travar estilo e evita um grafo de chamadas novo.
  • Con: Formatting e call hierarchy continuam sem dono depois de aposentar as agendas velhas.
  • Maintainability: Boa, e menor.

Tradeoffs

Juntar as nove agendas num plano só é seguro porque o piso já está no código. O risco é enfiar de volta, como "passo pequeno", cache, contrato novo de diagnóstico ou auto-import. Esses três não cabem: o primeiro perdeu a premissa, o segundo quebra o quick fix já aceito, o terceiro não tem diagnóstico estável para se pendurar.

Formatter é o único passo que ainda escolhe estilo. Por isso ele é um passo isolado: recusar Q2 tira só esse commit. Call hierarchy não pode reusar o índice de references; references são usos da mesma identidade, não chamadas. Ou entra como caminhada de CallExpr no último commit, ou fica de fora.

Recommendation

Aceitar Option A com Q1-A e Q2-A.

Forma do plano, obrigatória:

  • uma decision e um plan desta discussão;
  • branch dev/pbs-lsp-remaining-editor-surface, não uma branch por passo e não commit em master;
  • cada passo vivo vira um commit implements PLN-NNNN (k/N) <slug>;
  • sem push;
  • spec 23 §8.3 só ganha parágrafo do passo que a superfície realmente passa a anunciar;
  • lesson e discussion housekeep só no commit do último passo.

Passos, nesta ordem. Passo que Q1 ou Q2 tirar não é renumerado no meio da implementação: o plan lista só os que sobreviverem, em ordem.

  1. Diagnostic source. source passa a ser o language id do frontend (pbs). code continua o code estável. Sem relatedInformation, sem fase, sem data de reparo.
  2. Document links. Link só no span do ModuleRef de um import cujo destino já resolve para arquivo físico regular. Sem destino físico, sem link. Stdlib virtual, asset e doc ficam de fora.
  3. Folding e selection range. Span de AST quando a árvore recuperada tem o nó: declaração top-level (fn, struct, service, contract, enum, error, callback, host), corpo, lista de parâmetros e text block Doc. Fallback de token só para chave, parêntese ou text block que a árvore não cobre. Selection, do interno para o externo: identificador, lista de argumento ou parâmetro, bloco ou text block, declaração. Lista vazia quando não houver range. Não reutilizar document symbols.
  4. Formatting de documento inteiro. Só se Q2 travar estilo. Sem range e sem on-type. Preserva comentário e interior de text block Doc. Não é pretty-printer de AST.
  5. Overlay semântico em cima do token atual. Não substituir PBSSemanticTokenProvider. Onde a mesma resolução de hover já nomeia o símbolo, trocar o kind fraco por um PbsSemanticKind que já existe. Falha, arquivo quebrado ou símbolo desconhecido mantém o token de hoje. Nenhuma key nova.
  6. Completion de module ref. No cursor dentro de ModuleRef, candidatos que o resolver atual já sabe nomear, módulo de projeto e stdlib. Continua eager. resolveProvider continua falso. Sem snippets e sem score novo. Fora de module ref, o completion atual não muda.
  7. Call hierarchy. Incoming e outgoing de função e método por caminhada de callsite na AST, não pelo índice de references. Cursor que não é callable devolve vazio. Sem type hierarchy e sem cache.

Discussion

As agendas AGD-0048 a AGD-0056 foram aposentadas a pedido, neste consolidado, antes de qualquer accept. O texto delas não é decisão. A CLI discussion não tem comando de abandon; a aposentadoria ficou no índice e no frontmatter, com a lacuna registrada para um comando futuro.

Não aceitar esta agenda até Q1 e Q2 terem resposta explícita. A recomendação é o pacote, não um convite para preencher o resto na implementação.

Resolution

Q1-A e Q2-A travados pelo usuário em 2026-09-22. O pacote da recomendação é a escolha que a decision torna normativa.

Next Step

Decision aceita e plan desta discussão. Implementar os sete passos em série, um commit cada.