add content to lsp roadmaps
This commit is contained in:
parent
c9f844ab61
commit
66f34eeb58
@ -0,0 +1,537 @@
|
|||||||
|
# PR — lsp-base (LSP MVP)
|
||||||
|
|
||||||
|
**Branch:** `pr-08-lsp-mvp`
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Queremos um **LSP mínimo funcional** que já permita trabalhar PBS no VSCode com:
|
||||||
|
|
||||||
|
* erros aparecendo (diagnostics)
|
||||||
|
* navegação básica (goto definition)
|
||||||
|
* visão estrutural (document/workspace symbols)
|
||||||
|
|
||||||
|
Regras-chave (MVP):
|
||||||
|
|
||||||
|
* `didChange` será **full-text**
|
||||||
|
* rebuild será **coarse** (recompila o projeto inteiro) sempre que qualquer arquivo muda
|
||||||
|
* sem incremental analysis ainda
|
||||||
|
* comentários extensivos com exemplos se necessário e em inglês sempre
|
||||||
|
|
||||||
|
Este PR não inclui semantic tokens nem completion (virão nos PRs seguintes).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Alvo (Features)
|
||||||
|
|
||||||
|
### LSP endpoints
|
||||||
|
|
||||||
|
* ✅ `initialize`
|
||||||
|
* ✅ `textDocument/didOpen`
|
||||||
|
* ✅ `textDocument/didChange` (FULL)
|
||||||
|
* ✅ `textDocument/didClose`
|
||||||
|
* ✅ `textDocument/documentSymbol`
|
||||||
|
* ✅ `workspace/symbol`
|
||||||
|
* ✅ `textDocument/definition`
|
||||||
|
* ✅ `textDocument/publishDiagnostics`
|
||||||
|
|
||||||
|
### Modelo de build
|
||||||
|
|
||||||
|
* `AnalysisDb` em memória
|
||||||
|
* `FileDb` (uri → texto)
|
||||||
|
* `rebuild()` recompila **workspace inteiro** e produz um snapshot
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design (como deve funcionar)
|
||||||
|
|
||||||
|
### 1) AnalysisDb: estado e snapshot
|
||||||
|
|
||||||
|
**Objetivo:** separar “estado de arquivos” de “resultado de análise”.
|
||||||
|
|
||||||
|
Estruturas recomendadas:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub struct AnalysisDb {
|
||||||
|
pub file_db: FileDb,
|
||||||
|
pub revision: u64,
|
||||||
|
pub active_rebuild: Option<RebuildHandle>,
|
||||||
|
pub last_good: Option<AnalysisSnapshot>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AnalysisSnapshot {
|
||||||
|
pub diagnostics: Vec<Diagnostic>,
|
||||||
|
pub symbols: SymbolIndex, // index por Project/Module (coarse)
|
||||||
|
pub node_to_symbol: NodeToSymbol, // para definition
|
||||||
|
pub def_index: DefIndex, // opcional se você já tiver
|
||||||
|
pub ast: AstArena, // opcional (mas útil para nodes)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> Observação: use os tipos reais do seu compiler. O importante é ter um “snapshot” único que o LSP consulta.
|
||||||
|
|
||||||
|
### 2) Fluxo de rebuild
|
||||||
|
|
||||||
|
* `didOpen/didChange`:
|
||||||
|
|
||||||
|
* atualizar `file_db` com texto atual
|
||||||
|
* incrementar `revision`
|
||||||
|
* disparar `request_rebuild()` (coalescing)
|
||||||
|
|
||||||
|
* `request_rebuild()`:
|
||||||
|
|
||||||
|
* cancela rebuild anterior se houver
|
||||||
|
* agenda um rebuild assíncrono (tokio task)
|
||||||
|
* no fim, se não estiver cancelado e se `revision` não mudou, grava `last_good` e publica diagnostics
|
||||||
|
|
||||||
|
### 3) Diagnostics
|
||||||
|
|
||||||
|
* O compiler já deve produzir diagnostics com `Span { file, start, end }` em bytes.
|
||||||
|
* Para publicar, converter:
|
||||||
|
|
||||||
|
* `Span` → `lsp_types::Range` via `TextIndex` (já existe do refactor)
|
||||||
|
|
||||||
|
Regra:
|
||||||
|
|
||||||
|
* Diagnóstico sem `Span` (ou span inválido) deve ser **ignorado** ou degradado para range 0..0.
|
||||||
|
|
||||||
|
### 4) Definition
|
||||||
|
|
||||||
|
Ao receber `textDocument/definition`:
|
||||||
|
|
||||||
|
1. converter `Position` → byte offset (com `TextIndex`)
|
||||||
|
2. encontrar `NodeId` no ponto
|
||||||
|
3. resolver `NodeId -> SymbolId` via `node_to_symbol`
|
||||||
|
4. pegar `Symbol.decl_span`
|
||||||
|
5. converter `decl_span` → `Location`
|
||||||
|
|
||||||
|
> Se `NodeId` não existir ou não resolver símbolo: retornar `None`.
|
||||||
|
|
||||||
|
### 5) documentSymbol / workspaceSymbol
|
||||||
|
|
||||||
|
* `documentSymbol`: filtrar símbolos cujo `decl_span.file` == arquivo da request.
|
||||||
|
* `workspaceSymbol`: busca textual simples (contains/case-insensitive) nos nomes de símbolos (coarse) e retorna top N.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tarefas de implementação (checklist técnico)
|
||||||
|
|
||||||
|
### Capabilities em `initialize`
|
||||||
|
|
||||||
|
Declarar no server:
|
||||||
|
|
||||||
|
* `textDocumentSync: Full`
|
||||||
|
* `definitionProvider: true`
|
||||||
|
* `documentSymbolProvider: true`
|
||||||
|
* `workspaceSymbolProvider: true`
|
||||||
|
* `diagnosticProvider`: use publishDiagnostics (push)
|
||||||
|
|
||||||
|
### didOpen
|
||||||
|
|
||||||
|
* upsert texto
|
||||||
|
* request_rebuild
|
||||||
|
|
||||||
|
### didChange (Full)
|
||||||
|
|
||||||
|
* receber texto completo do doc
|
||||||
|
* upsert texto
|
||||||
|
* request_rebuild
|
||||||
|
|
||||||
|
### didClose
|
||||||
|
|
||||||
|
* remover do file_db (ou marcar fechado)
|
||||||
|
* publicar diagnostics vazios para o arquivo fechado
|
||||||
|
|
||||||
|
### Conversions
|
||||||
|
|
||||||
|
* `uri <-> FileId`: FileDb precisa mapear URI para FileId estável.
|
||||||
|
* `Span -> Range`: usar `TextIndex` do texto atual do arquivo.
|
||||||
|
* `Position -> byte`: usar `TextIndex`.
|
||||||
|
|
||||||
|
### Node lookup
|
||||||
|
|
||||||
|
Você precisa de uma função no snapshot (ou util) tipo:
|
||||||
|
|
||||||
|
* `fn node_at(file: FileId, byte: u32) -> Option<NodeId>`
|
||||||
|
|
||||||
|
MVP aceitável:
|
||||||
|
|
||||||
|
* se você ainda não tiver um índice de nodes por span, pode:
|
||||||
|
|
||||||
|
* usar AST arena e fazer busca linear na árvore (aceitável no coarse MVP)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Test Harness (mínimo, mas real)
|
||||||
|
|
||||||
|
### Opção A (preferida): tests com `tower-lsp` client in-process
|
||||||
|
|
||||||
|
Criar um teste `tests/lsp_mvp.rs`:
|
||||||
|
|
||||||
|
* sobe o backend LSP em memória
|
||||||
|
* envia:
|
||||||
|
|
||||||
|
* `initialize`
|
||||||
|
* `didOpen` com um fixture PBS (2 arquivos)
|
||||||
|
* espera `publishDiagnostics` (pode interceptar via `Client` mock)
|
||||||
|
* chama `definition` em uma posição de uso e verifica que retorna `Location` do `decl_span`
|
||||||
|
|
||||||
|
**Aceite:**
|
||||||
|
|
||||||
|
* definition retorna arquivo correto
|
||||||
|
* range bate com span convertido
|
||||||
|
|
||||||
|
### Opção B (mais simples): unit tests nos adaptadores
|
||||||
|
|
||||||
|
Se o harness LSP demorar, pelo menos criar:
|
||||||
|
|
||||||
|
* `span_to_range_uses_utf16()`
|
||||||
|
* `position_to_byte_roundtrip()`
|
||||||
|
* `definition_resolves_to_decl_span()` usando snapshot fake.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checklist de aceite (obrigatório)
|
||||||
|
|
||||||
|
* [ ] `cargo test -q` passa no workspace
|
||||||
|
* [ ] VSCode: abrir arquivo `.pbs` mostra diagnostics (pelo menos 1 erro sintático)
|
||||||
|
* [ ] VSCode: `Go to Definition` funciona para símbolo resolvido
|
||||||
|
* [ ] VSCode: Outline mostra `documentSymbol`
|
||||||
|
* [ ] Mudanças em um arquivo disparam rebuild e atualizam diagnostics
|
||||||
|
* [ ] Unicode: diagnostics não ficam “desalinhados” (teste manual com `ação`/emoji)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fora de escopo (explicitamente)
|
||||||
|
|
||||||
|
* semantic tokens
|
||||||
|
* completion
|
||||||
|
* references/rename
|
||||||
|
* hover/signatureHelp
|
||||||
|
* incremental analysis e cancelation avançada
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# PR — lsp-hightlight-base (Semantic Tokens — lexer-first)
|
||||||
|
|
||||||
|
**Branch:** `pr-12a-lsp-semantic-lexer`
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Queremos **highlight no VSCode via LSP**, sem depender de resolver e sem TextMate.
|
||||||
|
|
||||||
|
Estratégia:
|
||||||
|
|
||||||
|
* Implementar `textDocument/semanticTokens/full`.
|
||||||
|
* Gerar tokens **lexer-first**: comments/strings/numbers/keywords/identifiers.
|
||||||
|
* Converter spans (bytes) para LSP positions (UTF-16) usando `TextIndex`.
|
||||||
|
* comentários extensivos com exemplos se necessário e em inglês sempre
|
||||||
|
|
||||||
|
Isso entrega um highlight “bom o suficiente” e muito estável, mesmo com arquivo com erro de parse.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Alvo (Features)
|
||||||
|
|
||||||
|
* ✅ `textDocument/semanticTokens/full`
|
||||||
|
* ✅ `SemanticTokensLegend` consistente
|
||||||
|
* ✅ tokens derivados do lexer
|
||||||
|
|
||||||
|
Opcional (não obrigatório neste PR):
|
||||||
|
|
||||||
|
* `semanticTokens/range`
|
||||||
|
* `semanticTokens/full/delta`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design
|
||||||
|
|
||||||
|
### 1) Legend fixa
|
||||||
|
|
||||||
|
Escolher um conjunto pequeno de token types:
|
||||||
|
|
||||||
|
* `comment`
|
||||||
|
* `string`
|
||||||
|
* `number`
|
||||||
|
* `keyword`
|
||||||
|
* `operator` (opcional)
|
||||||
|
* `variable` (para identifiers genéricos)
|
||||||
|
|
||||||
|
> Não inventar muitos tipos agora; fácil expandir depois.
|
||||||
|
|
||||||
|
### 2) Fonte de tokens
|
||||||
|
|
||||||
|
Implementar uma função no analysis/compiler layer (ou no lsp crate) que, dado:
|
||||||
|
|
||||||
|
* `FileId`
|
||||||
|
* `text: &str`
|
||||||
|
retorna `Vec<(Span, TokenType, TokenModifiers)>`.
|
||||||
|
|
||||||
|
**Importante:**
|
||||||
|
|
||||||
|
* Spans são em bytes.
|
||||||
|
* Devem ser **não sobrepostos** e preferencialmente em ordem.
|
||||||
|
|
||||||
|
### 3) Conversão para formato LSP (deltas)
|
||||||
|
|
||||||
|
LSP semantic tokens usa encoding em deltas:
|
||||||
|
|
||||||
|
* `deltaLine`, `deltaStartChar`, `length`, `tokenType`, `tokenModifiers`
|
||||||
|
|
||||||
|
Algoritmo:
|
||||||
|
|
||||||
|
1. Converter `Span.start` e `Span.end` em `(line, utf16_col)`.
|
||||||
|
2. Calcular `length` em UTF-16 units para o trecho (start..end).
|
||||||
|
3. Ordenar por `(line, col)`.
|
||||||
|
4. Emitir deltas.
|
||||||
|
|
||||||
|
Regra:
|
||||||
|
|
||||||
|
* Se `Span` cruza linhas, **quebrar** em múltiplos tokens por linha (MVP seguro).
|
||||||
|
|
||||||
|
### 4) Robustez
|
||||||
|
|
||||||
|
* Token inválido (end < start, ou fora do texto) deve ser ignorado.
|
||||||
|
* Se o arquivo não estiver no `FileDb`, retornar tokens vazios.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tarefas de implementação
|
||||||
|
|
||||||
|
### Server capabilities
|
||||||
|
|
||||||
|
No `initialize`, anunciar:
|
||||||
|
|
||||||
|
* `semanticTokensProvider` com:
|
||||||
|
|
||||||
|
* `legend`
|
||||||
|
* `full: true`
|
||||||
|
* `range: false` (por enquanto)
|
||||||
|
|
||||||
|
### Handler
|
||||||
|
|
||||||
|
Implementar `semantic_tokens_full(params)`:
|
||||||
|
|
||||||
|
* pegar `uri`
|
||||||
|
* buscar texto no `file_db`
|
||||||
|
* gerar tokens do lexer
|
||||||
|
* converter com `TextIndex`
|
||||||
|
* retornar `SemanticTokensResult::Tokens`
|
||||||
|
|
||||||
|
### Lexer tokens
|
||||||
|
|
||||||
|
Se você já tem lexer com spans:
|
||||||
|
|
||||||
|
* mapear tokens para os tipos (keyword/string/comment/number/identifier)
|
||||||
|
* keywords: pode ser por enum do token ou por tabela
|
||||||
|
|
||||||
|
Se o lexer não marca keyword vs ident:
|
||||||
|
|
||||||
|
* fallback: parse por string e classifica keywords via `HashSet<&'static str>`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testes
|
||||||
|
|
||||||
|
### Unit tests (obrigatórios)
|
||||||
|
|
||||||
|
1. `semantic_tokens_legend_is_stable()`
|
||||||
|
|
||||||
|
* garante que legend não muda sem intenção.
|
||||||
|
|
||||||
|
2. `semantic_tokens_are_sorted_and_non_negative()`
|
||||||
|
|
||||||
|
* gera tokens em um fixture com 2 linhas
|
||||||
|
* valida que deltas nunca ficam negativos e que ordem é válida.
|
||||||
|
|
||||||
|
3. `semantic_tokens_unicode_length_utf16()`
|
||||||
|
|
||||||
|
* texto com `ação🙂`
|
||||||
|
* valida que `length` corresponde a UTF-16 (emoji conta como 2).
|
||||||
|
|
||||||
|
### Teste manual (aceite)
|
||||||
|
|
||||||
|
* Abrir `.pbs` no VSCode
|
||||||
|
* Verificar:
|
||||||
|
|
||||||
|
* strings e comentários coloridos
|
||||||
|
* keywords coloridas
|
||||||
|
* números coloridos
|
||||||
|
* identifiers coloridos (mesmo que genérico)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checklist de aceite
|
||||||
|
|
||||||
|
* [ ] `cargo test -q` passa
|
||||||
|
* [ ] VSCode: arquivos PBS ficam coloridos via LSP (sem TextMate)
|
||||||
|
* [ ] Unicode não quebra offsets
|
||||||
|
* [ ] Arquivo com erro de parse ainda tem highlight (lexer-first)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fora de escopo
|
||||||
|
|
||||||
|
* semantic tokens semântico (type vs fn vs var) — virá em `PR-12b`
|
||||||
|
* `range`/`delta`
|
||||||
|
* completion
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# PR — lsp-completion-base (Completion mínimo)
|
||||||
|
|
||||||
|
**Branch:** `pr-11a-lsp-completion-min`
|
||||||
|
|
||||||
|
## Briefing
|
||||||
|
|
||||||
|
Queremos autocomplete **mínimo mas útil** para conseguir escrever SDK/ECS em PBS sem fricção.
|
||||||
|
|
||||||
|
Princípio:
|
||||||
|
|
||||||
|
* Não depende de scope facts, nem type facts.
|
||||||
|
* Usa somente:
|
||||||
|
|
||||||
|
* keywords/builtins
|
||||||
|
* símbolos top-level do módulo atual
|
||||||
|
* exports/imports visíveis no projeto (coarse)
|
||||||
|
|
||||||
|
Isso é suficiente para começar a programar e evoluir o LSP depois.
|
||||||
|
|
||||||
|
* comentários extensivos com exemplos se necessário e em inglês sempre
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Alvo (Features)
|
||||||
|
|
||||||
|
* ✅ `textDocument/completion`
|
||||||
|
* ✅ `completionItem/resolve` (opcional; pode retornar item já completo)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design
|
||||||
|
|
||||||
|
### 1) Buckets e ordenação
|
||||||
|
|
||||||
|
Retornar `CompletionList` com itens nesta prioridade:
|
||||||
|
|
||||||
|
1. Keywords (`fn`, `let`, `mutate`, `declare`, `struct`, `storage`, `if`, `else`, `for`, `return`, etc.)
|
||||||
|
2. Builtins/funções globais (ex.: `alloc`, `box`, `unbox`, `range`, etc. — conforme spec do PBS)
|
||||||
|
3. Símbolos do módulo atual (top-level)
|
||||||
|
4. Símbolos “workspace visible” (exports/imports), limitado (ex.: top 200)
|
||||||
|
|
||||||
|
**Regra de ranking simples:**
|
||||||
|
|
||||||
|
* locals (não teremos) > módulo atual > workspace
|
||||||
|
|
||||||
|
### 2) Contexto
|
||||||
|
|
||||||
|
Para completion mínimo, só precisamos:
|
||||||
|
|
||||||
|
* `uri` do documento
|
||||||
|
* `position` (para pegar prefixo)
|
||||||
|
|
||||||
|
Prefixo:
|
||||||
|
|
||||||
|
* converter `Position` -> byte
|
||||||
|
* extrair texto até o cursor e identificar o “token parcial” (regex simples `[A-Za-z_][A-Za-z0-9_]*$`)
|
||||||
|
|
||||||
|
### 3) Fonte dos símbolos
|
||||||
|
|
||||||
|
Usar o `AnalysisSnapshot` (produzido na PR-08) para expor:
|
||||||
|
|
||||||
|
* `fn symbols_in_file(file: FileId) -> Vec<SymbolId>`
|
||||||
|
* `fn symbols_in_module(project: ProjectId, module: ModuleId) -> Vec<SymbolId>`
|
||||||
|
* `fn workspace_symbols() -> impl Iterator<Item = (name, kind, decl_span)>`
|
||||||
|
|
||||||
|
MVP aceitável:
|
||||||
|
|
||||||
|
* `workspace_symbols()` pode ser um vetor “flatten” pré-calculado no snapshot.
|
||||||
|
|
||||||
|
### 4) CompletionItem
|
||||||
|
|
||||||
|
Mapeamento para `CompletionItemKind`:
|
||||||
|
|
||||||
|
* functions -> `FUNCTION`
|
||||||
|
* types -> `CLASS` (ou `STRUCT` se quiser)
|
||||||
|
* modules -> `MODULE`
|
||||||
|
* variables/constants -> `VARIABLE` / `CONSTANT`
|
||||||
|
|
||||||
|
Campos:
|
||||||
|
|
||||||
|
* `label`: nome
|
||||||
|
* `detail`: (opcional) `"fn"/"type"/"module"`
|
||||||
|
* `sortText`: prefixado para impor bucket (ex.: `"1_"`, `"2_"`)
|
||||||
|
* `filterText`: label
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tarefas de implementação
|
||||||
|
|
||||||
|
### Capabilities
|
||||||
|
|
||||||
|
No `initialize`:
|
||||||
|
|
||||||
|
* `completionProvider: { resolveProvider: false, triggerCharacters: [".", ":"]? }`
|
||||||
|
|
||||||
|
> Para completion mínimo, nem precisa trigger chars. Pode deixar default.
|
||||||
|
|
||||||
|
### Handler `completion`
|
||||||
|
|
||||||
|
* buscar texto e `TextIndex`
|
||||||
|
* calcular prefixo
|
||||||
|
* montar lista de candidatos por bucket
|
||||||
|
* filtrar por prefixo (case-sensitive ou insensitive; escolha e documente)
|
||||||
|
* limitar tamanho
|
||||||
|
* retornar `CompletionResponse::List`
|
||||||
|
|
||||||
|
### Builtins/keywords
|
||||||
|
|
||||||
|
Criar tabelas estáticas em `prometeu-lsp`:
|
||||||
|
|
||||||
|
* `static KEYWORDS: &[&str] = ...`
|
||||||
|
* `static BUILTINS: &[&str] = ...`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testes
|
||||||
|
|
||||||
|
### Unit tests (obrigatórios)
|
||||||
|
|
||||||
|
1. `completion_extracts_prefix()`
|
||||||
|
|
||||||
|
* valida regex de prefixo
|
||||||
|
|
||||||
|
2. `completion_includes_keywords()`
|
||||||
|
|
||||||
|
* chama handler com texto vazio e posição 0
|
||||||
|
* garante que `fn` aparece
|
||||||
|
|
||||||
|
3. `completion_filters_by_prefix()`
|
||||||
|
|
||||||
|
* prefixo `"ra"` deve sugerir `range` (se builtin)
|
||||||
|
|
||||||
|
4. (se possível) `completion_includes_module_symbols()`
|
||||||
|
|
||||||
|
* usando snapshot fake ou fixture compilado pela infra da PR-08
|
||||||
|
|
||||||
|
### Teste manual (aceite)
|
||||||
|
|
||||||
|
* Abrir arquivo PBS e digitar `ra` -> aparece `range`
|
||||||
|
* Digitar nome de tipo/fn do SDK -> aparece suggestion
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checklist de aceite
|
||||||
|
|
||||||
|
* [ ] `cargo test -q` passa
|
||||||
|
* [ ] VSCode: autocomplete sugere keywords e builtins
|
||||||
|
* [ ] VSCode: autocomplete sugere símbolos do módulo atual
|
||||||
|
* [ ] Não trava com rebuild coarse
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fora de escopo
|
||||||
|
|
||||||
|
* locals em scope
|
||||||
|
* members (`obj.`)
|
||||||
|
* signatureHelp
|
||||||
|
* hover
|
||||||
@ -0,0 +1,219 @@
|
|||||||
|
# LSP Roadmap — do “base usable” até “LSP completo”
|
||||||
|
|
||||||
|
> Este documento é o mapa incremental pós `lsp-base`, `lsp-hightlight-base`, `lsp-completion-base`.
|
||||||
|
> A ideia é manter o LSP evoluindo sem rework, enquanto SDK/ECS/Packer avançam em paralelo.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estado atual (após os 3 PRs base)
|
||||||
|
|
||||||
|
### ✅ Já temos
|
||||||
|
|
||||||
|
* Diagnostics (publishDiagnostics)
|
||||||
|
* Definition (goto definition)
|
||||||
|
* DocumentSymbol / WorkspaceSymbol
|
||||||
|
* Semantic tokens (lexer-first)
|
||||||
|
* Completion mínimo (keywords/builtins/top-level/module/workspace)
|
||||||
|
|
||||||
|
### ❌ Ainda não temos
|
||||||
|
|
||||||
|
* references / rename
|
||||||
|
* hover / signatureHelp
|
||||||
|
* completion com locals em scope
|
||||||
|
* semantic tokens semântico (type vs fn vs var)
|
||||||
|
* incremental analysis real (por arquivo / cancelation)
|
||||||
|
* debug map pc→span integrado com traps
|
||||||
|
* code actions / formatting
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Próximos PRs recomendados (ordem sugerida)
|
||||||
|
|
||||||
|
## PR-09 — References + Rename (seguro)
|
||||||
|
|
||||||
|
### Objetivo
|
||||||
|
|
||||||
|
Habilitar `references`, `prepareRename`, `rename` com regras de segurança.
|
||||||
|
|
||||||
|
### Pré-requisitos
|
||||||
|
|
||||||
|
* `RefIndex` completo (SymbolId -> usos em spans)
|
||||||
|
* `NodeToSymbol` estável
|
||||||
|
* `TriviaIndex` (comments/strings) para não renomear spans proibidos
|
||||||
|
|
||||||
|
### Regras de segurança
|
||||||
|
|
||||||
|
* Não renomear símbolo não-resolvido
|
||||||
|
* Não renomear em comentário/string
|
||||||
|
* Renomear deve gerar `WorkspaceEdit` apenas para spans válidos
|
||||||
|
|
||||||
|
### Testes
|
||||||
|
|
||||||
|
* Fixture com 2 arquivos: rename atualiza todas as refs
|
||||||
|
* Fixture: rename em comentário não altera nada
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PR-10 — Hover + SignatureHelp
|
||||||
|
|
||||||
|
### Objetivo
|
||||||
|
|
||||||
|
* `hover`: mostrar tipo + docstring (docstring opcional)
|
||||||
|
* `signatureHelp`: para call nodes
|
||||||
|
|
||||||
|
### Pré-requisitos
|
||||||
|
|
||||||
|
* Type facts básicos: `NodeId -> TypeId`
|
||||||
|
* Modelo de assinatura: para functions (params, retorno)
|
||||||
|
|
||||||
|
### Testes
|
||||||
|
|
||||||
|
* Hover em símbolo mostra tipo
|
||||||
|
* SignatureHelp em chamada mostra params
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PR-11b — Completion com locals em scope
|
||||||
|
|
||||||
|
### Objetivo
|
||||||
|
|
||||||
|
Autocomplete útil para código real:
|
||||||
|
|
||||||
|
* locals/params
|
||||||
|
* shadowing correto
|
||||||
|
|
||||||
|
### Pré-requisitos
|
||||||
|
|
||||||
|
* Binder/Scope facts:
|
||||||
|
|
||||||
|
* `Position -> ScopeId`
|
||||||
|
* `ScopeId -> bindings (name -> SymbolId/TypeId)`
|
||||||
|
|
||||||
|
### Testes
|
||||||
|
|
||||||
|
* Dentro de bloco, sugere variável local
|
||||||
|
* Shadowing: sugere a mais interna
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PR-12b — Semantic tokens resolver-backed (semântico)
|
||||||
|
|
||||||
|
### Objetivo
|
||||||
|
|
||||||
|
Melhorar highlight:
|
||||||
|
|
||||||
|
* diferenciar `type` vs `function` vs `variable` vs `parameter` vs `module`
|
||||||
|
|
||||||
|
### Pré-requisitos
|
||||||
|
|
||||||
|
* `NodeAtPosition` confiável
|
||||||
|
* `NodeToSymbol` confiável
|
||||||
|
* `SymbolKind` consistente
|
||||||
|
|
||||||
|
### Testes
|
||||||
|
|
||||||
|
* Identificador de tipo recebe token `type`
|
||||||
|
* Função recebe token `function`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PR-13 — Formatting + Code Actions (opcional)
|
||||||
|
|
||||||
|
### Objetivo
|
||||||
|
|
||||||
|
* `textDocument/formatting` (nem que seja formatter simples/estável)
|
||||||
|
* code actions básicas:
|
||||||
|
|
||||||
|
* organizar imports
|
||||||
|
* criar stub de função/struct
|
||||||
|
|
||||||
|
### Pré-requisitos
|
||||||
|
|
||||||
|
* AST pretty printer (ou formatter incremental)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PR-14 — Incremental analysis + cancelation (de verdade)
|
||||||
|
|
||||||
|
### Objetivo
|
||||||
|
|
||||||
|
Sair do rebuild coarse:
|
||||||
|
|
||||||
|
* recompilar somente arquivo/módulo afetado
|
||||||
|
* cancelamento real de builds longos
|
||||||
|
* snapshots por versão
|
||||||
|
|
||||||
|
### Pré-requisitos
|
||||||
|
|
||||||
|
* Graph de dependências por módulo
|
||||||
|
* Cache de parse/resolve por arquivo
|
||||||
|
* `revision` por doc
|
||||||
|
|
||||||
|
### Testes
|
||||||
|
|
||||||
|
* Editar arquivo A não recompila projeto inteiro
|
||||||
|
* Cancel: digitar rápido não aplica resultados velhos
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PR-15 — Debug map (pc→span) + integração com traps
|
||||||
|
|
||||||
|
### Objetivo
|
||||||
|
|
||||||
|
Quando a VM gerar trap/runtime error:
|
||||||
|
|
||||||
|
* mapear `pc` para `Span`
|
||||||
|
* mostrar erro com localização exata
|
||||||
|
|
||||||
|
### Pré-requisitos
|
||||||
|
|
||||||
|
* SourceMap gerado no backend bytecode
|
||||||
|
* runtime expõe `pc`/contexto
|
||||||
|
|
||||||
|
### Testes
|
||||||
|
|
||||||
|
* programa que gera trap aponta para linha/col corretos
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Backlog adicional (nice to have)
|
||||||
|
|
||||||
|
* `workspace/didChangeWatchedFiles` (reagir a mudanças fora do editor)
|
||||||
|
* `textDocument/codeLens` (ex.: run test / run main)
|
||||||
|
* `textDocument/inlayHint`
|
||||||
|
* `workspace/diagnostic` pull-mode (se quiser)
|
||||||
|
* semanticTokens `range` e `delta` para performance
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Interação com SDK/ECS/Packer
|
||||||
|
|
||||||
|
### Com os 3 PRs base, você já consegue:
|
||||||
|
|
||||||
|
* escrever SDK/ECS em PBS com feedback imediato
|
||||||
|
* navegar rapidamente pelo código
|
||||||
|
* manter arquivos grandes com highlight
|
||||||
|
* usar completion para nomes de APIs
|
||||||
|
|
||||||
|
### Enquanto isso, em paralelo:
|
||||||
|
|
||||||
|
* packer pode evoluir (não depende do LSP)
|
||||||
|
* quando packer estabilizar, podemos adicionar code actions/codelens para “build/pack/run” direto no VSCode
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Definição de “LSP completo” (para Prometeu view-ready)
|
||||||
|
|
||||||
|
Para chamar de "completo" (na sua visão de produto):
|
||||||
|
|
||||||
|
* ✅ diagnostics
|
||||||
|
* ✅ definition
|
||||||
|
* ✅ symbols
|
||||||
|
* ✅ highlight semântico
|
||||||
|
* ✅ completion com scope + members
|
||||||
|
* ✅ hover + signatureHelp
|
||||||
|
* ✅ references + rename
|
||||||
|
* ✅ incremental + cancel
|
||||||
|
* ✅ debug map integrado com traps
|
||||||
|
|
||||||
|
> A ordem acima é incremental por valor percebido e por dependências.
|
||||||
Loading…
x
Reference in New Issue
Block a user