25 KiB
Prometeu — PR Plan (Arena-Driven) para um LSP Completo
PR-00.X — Reorganização estrutural do workspace (pré–Arena / pré–LSP)
Objetivo macro: separar modelo/ABI, execução, kernel e tooling antes de qualquer refator arena-driven.
Regra de ouro: nenhuma mudança de comportamento. Apenas movimentação de código + ajuste de dependências.
Modelo final alvo:
prometeu-bytecode✅ (fica)prometeu-abi✅ (novo — ex-prometeu-coresem execução)prometeu-vm✅ (novo)prometeu-kernel✅ (novo)prometeu-runtime-desktop✅ (fica)prometeu-compiler✅ (fica)prometeu(CLI) ✅ (fica agregando)
Meta do Nilton / Junie workflow: PRs extremamente prescritivos. A Junie só implementa; você revisa o design antes do código.
Regra de ouro: cada PR abaixo vem com:
- Arquivos/alvos exatos
- Estruturas e assinaturas obrigatórias
- Esquemas JSON (quando aplicável)
- Testes (golden + unit)
- Critérios de aceite “binário” (passou/não passou)
Estado atual (confirmado pelo repo)
Workspace (Archive.zip) tem crates:
prometeu/prometeu-bytecode/prometeu-core/prometeu-compiler/(binsrc/main.rs, deps:serde,serde_json,anyhow,clap, e famíliaoxc_*).
Saída atual existente: symbols.json (schema_version 0), exportando símbolos por projeto, com decl_span em line/col e paths absolutos. (Vamos evoluir isso no PR-07.)
Visão de arquitetura alvo
Camadas
- FileDB: texto, URI/path, line-index, snapshots.
- Lexer/Parser: produz AstArena (NodeId + spans por nó).
- Binder/Resolver: produz SymbolArena + índices (def/ref).
- Typecheck: produz TypeArena + facts (node→type, symbol→type).
- Analysis Export:
analysis.json(full) +symbols.json(leve e estável). - LSP Server: consome
AnalysisDbe responde requests.
IDs padronizados (newtypes)
FileId(u32)NodeId(u32)NameId(u32)(interner)SymbolId(u32)TypeId(u32)ProjectId(u32)ModuleId(u32)
Invariantes
- AST é imutável após construção (normativo na spec PBS).
- Nenhuma fase expõe referências diretas entre nós; apenas IDs.
- IDs externos são aceitos, mas sempre passam por validate/resolve (API checked).
Templates prescritivos para PR (usar em TODAS)
Template de descrição (copiar/colar)
- Motivação:
- Mudança de modelo de dados:
- APIs novas / alteradas:
- Arquivos tocados:
- Testes adicionados/atualizados:
- Riscos & rollback:
- Checklist de aceite (binário):
Regras para Junie (para reduzir vai-e-volta)
-
Não “inventar design”. Se algo não estiver especificado, criar TODO e parar.
-
Não mudar formatação/estilo fora do escopo.
-
Todo novo tipo público precisa de doc-comment curta e exemplo.
-
Toda mudança de JSON precisa:
schema_versionbump (se não for backward)- teste de snapshot
-
Cada PR deve deixar
cargo testverde.
PRs (detalhados)
PR-00 — Infra: crates de análise + lsp (estrutura do workspace)
Branch: pr-00-analysis-lsp-foundations
Decisão travada (LSP)
- Biblioteca escolhida:
tower-lsp - Motivo: reduzir boilerplate, acelerar MVP e minimizar vai-e-volta. Cancelamento/incremental será feito por cima (tasks async + cancel tokens).
Objetivo
Adicionar crates novas sem mexer no pipeline existente.
Entregas obrigatórias
-
Novo crate:
prometeu-analysis/Cargo.toml(library)src/lib.rs
-
Novo crate:
prometeu-lsp/Cargo.toml(bin)src/main.rs
-
Workspace root: ajustar
Cargo.toml(se existir no root) para incluir members.
Dependências (fixas)
-
prometeu-analysis:serde,serde_json -
prometeu-lsp:tower-lsp = "0.20"(ou versão estável atual)tokio(full)prometeu-analysis(path)
Esqueleto obrigatório (prometeu-lsp/src/main.rs)
use tower_lsp::{LspService, Server};
use tokio::sync::RwLock;
use std::sync::Arc;
#[derive(Default)]
struct AnalysisDb {
// FileDB, AstArena, SymbolArena, TypeArena, Diagnostics
}
struct Backend {
db: Arc<RwLock<AnalysisDb>>,
}
#[tower_lsp::async_trait]
impl tower_lsp::LanguageServer for Backend {
async fn initialize(&self, _: tower_lsp::lsp_types::InitializeParams)
-> tower_lsp::jsonrpc::Result<tower_lsp::lsp_types::InitializeResult> {
Ok(tower_lsp::lsp_types::InitializeResult {
capabilities: tower_lsp::lsp_types::ServerCapabilities {
text_document_sync: Some(tower_lsp::lsp_types::TextDocumentSyncCapability::Kind(
tower_lsp::lsp_types::TextDocumentSyncKind::FULL,
)),
// Declaramos capacidades desde já para evitar churn posterior.
definition_provider: Some(true.into()),
document_symbol_provider: Some(true.into()),
workspace_symbol_provider: Some(true.into()),
hover_provider: Some(true.into()),
references_provider: Some(true.into()),
rename_provider: Some(tower_lsp::lsp_types::OneOf::Left(true)),
completion_provider: Some(tower_lsp::lsp_types::CompletionOptions {
resolve_provider: Some(false),
trigger_characters: Some(vec![".".into(), ":".into()]),
..Default::default()
}),
semantic_tokens_provider: Some(
tower_lsp::lsp_types::SemanticTokensServerCapabilities::SemanticTokensOptions(
tower_lsp::lsp_types::SemanticTokensOptions {
legend: tower_lsp::lsp_types::SemanticTokensLegend {
// preenchido no PR-12
token_types: vec![],
token_modifiers: vec![],
},
full: Some(tower_lsp::lsp_types::SemanticTokensFullOptions::Bool(true)),
range: None,
..Default::default()
},
),
),
..Default::default()
},
..Default::default()
})
}
async fn initialized(&self, _: tower_lsp::lsp_types::InitializedParams) {}
}
#[tokio::main]
async fn main() {
let stdin = tokio::io::stdin();
let stdout = tokio::io::stdout();
let (service, socket) = LspService::new(|_| Backend { db: Arc::new(RwLock::new(AnalysisDb::default())) });
Server::new(stdin, stdout, socket).serve(service).await;
}
Contrato exato do AnalysisDb (travado)
Regra: o LSP nunca recalcula segurando
RwLockpor muito tempo. Toda análise pesada roda fora do lock e depois faz swap.
Criar arquivo: prometeu-lsp/src/analysis_db.rs
use std::sync::Arc;
use tokio::sync::RwLock;
use tokio_util::sync::CancellationToken;
use prometeu_analysis::FileDB;
#[derive(Default)]
pub struct AnalysisDb {
pub file_db: FileDB,
// Os campos abaixo serão conectados conforme PR-03/04/05 (podem começar como None)
// pub ast: Option<AstArena>,
// pub symbols: Option<SymbolArena>,
// pub types: Option<TypeArena>,
// pub diagnostics: Vec<Diagnostic>,
/// Incrementa a cada rebuild concluído com sucesso
pub revision: u64,
/// Cancel token do último rebuild em progresso (se houver)
pub active_rebuild: Option<CancellationToken>,
}
pub type SharedDb = Arc<RwLock<AnalysisDb>>;
No main.rs, substituir o AnalysisDb local pelo import acima (ou manter local e delegar, mas sem duplicar).
Modelo de cancelamento e coalescing (travado)
Objetivo: quando chegam múltiplos
didChangeem sequência, cancelar o rebuild anterior e rodar apenas o último.
Adicionar dependência fixa em prometeu-lsp/Cargo.toml:
tokio-util
Criar arquivo: prometeu-lsp/src/rebuild.rs
use tokio_util::sync::CancellationToken;
use crate::analysis_db::SharedDb;
/// Solicita rebuild do projeto (coarse). Cancela rebuild anterior se em progresso.
/// Implementação inicial: apenas cria task e retorna.
pub async fn request_rebuild(db: SharedDb) {
// 1) lock curto: cancelar token anterior e instalar token novo
// 2) spawn task: roda análise fora do lock
// 3) lock curto: se token não cancelado, swap estado + revision++
}
Regras obrigatórias:
-
request_rebuilddeve:- cancelar
active_rebuildanterior (se existir) - instalar um token novo
tokio::spawnuma task de rebuild
- cancelar
-
A task deve checar
token.is_cancelled()em pontos seguros:- antes de começar
- após parsing
- após resolver
- após typecheck
-
O lock (
RwLock) deve ser segurado apenas:- para trocar
active_rebuild - para aplicar o resultado final
- para trocar
Critérios de aceite
cargo build -p prometeu-lspok- LSP inicializa em VS Code/Neovim sem crash
- Nenhuma feature além do declarado
Política fixa de cancelamento e rebuild (tower-lsp)
Objetivo
Garantir que edições rápidas não gerem backlog de análises e evitar race conditions.
Decisão travada
-
Usar
tokio_util::sync::CancellationToken -
Um token por rebuild
-
Qualquer
didChange:- Cancela o rebuild anterior
- Cria novo token
- Agenda nova task de análise
Estruturas obrigatórias
use tokio_util::sync::CancellationToken;
struct AnalysisController {
current: Option<CancellationToken>,
}
Regras
-
Nunca segurar
RwLock<AnalysisDb>durante parsing/resolver/typecheck. -
Fluxo correto:
- Clonar snapshot dos textos (FileDB)
- Soltar lock
- Rodar análise pesada
- Re-adquirir lock e substituir estado
-
Tasks devem checar
token.is_cancelled()entre fases (parse / bind / type).
Critérios de aceite
- Digitar rapidamente não acumula tasks.
- Apenas o último estado publica diagnostics.
Contrato fechado do AnalysisDb (fonte de verdade do LSP)
Objetivo
Eliminar ambiguidade sobre o que vive no estado compartilhado.
Estrutura obrigatória
#[derive(Default)]
pub struct AnalysisDb {
pub files: FileDB,
pub ast: Option<AstArena>,
pub symbols: Option<SymbolArena>,
pub types: Option<TypeArena>,
pub type_facts: Option<TypeFacts>,
pub diagnostics: Vec<Diagnostic>,
}
Regras
-
AnalysisDbnunca armazena estado parcialmente válido. -
Se uma fase falhar:
ast/symbols/typespodem ficarNonediagnosticsdeve estar preenchido
-
LSP handlers não rodam análise: apenas leem
AnalysisDb.
Leitura segura
-
Todos os handlers (
definition,hover,references, etc.) devem:- adquirir
db.read() - lidar com
Option::Noneretornandonull/ resposta vazia
- adquirir
Escrita segura
- Apenas a task de rebuild escreve no
AnalysisDb. - Escrita sempre substitui o estado inteiro (swap lógico).
Critérios de aceite
- Nenhum handler pode panic por
None. - Rebuild substitui estado de forma atômica (do ponto de vista do LSP).
Série PR-00.X — Reestruturação de crates (Arena-Driven + LSP-ready)
Objetivo da série PR-00.X: reorganizar o workspace em crates com fronteiras claras, sem alterar comportamento, preparando o terreno para o Prometeu Arena-Driven (compiler/analysis) e um LSP completo depois.
Novo layout alvo (travado):
prometeu-bytecode(fica)prometeu-abi(novo nome para o atualprometeu-coredepurado) = types + model + protocols (sem execução)prometeu-vm(novo) = execução da VMprometeu-kernel(novo) = OS + FS + syscalls (implementa interface para a VM)prometeu-runtime-desktop(fica) = host desktopprometeu-compiler(fica)prometeu(CLI) (fica)Regra de ouro: 1 PR = 1 fronteira. Nada de mover tudo de uma vez.
Regras para Junie (serie 00.X):
- Não mudar lógica; apenas mover, ajustar imports, e deixar testes verdes.
- Se algo exigir mudança de API pública, criar
TODO(PR-00.Y)e parar.- Sempre manter o workspace compilável a cada PR.
PR-00.1 — Introduzir prometeu-abi (renomear/diluir prometeu-core)
Branch: pr-00-1-prometeu-abi
Objetivo
Criar crate prometeu-abi contendo somente tipos e contratos (types+model+protocols), e manter prometeu-core temporariamente como facade/reexport para não quebrar consumidores.
Passos prescritivos
-
Criar novo crate
crates/prometeu-abi/comsrc/lib.rs. -
Copiar para
prometeu-abi(sem execução):model/*debugger_protocol.rstelemetry.rslog.rs(somente tipos/config; se tiver runtime logger, deixar no core por enquanto)- traits/contratos usados por outros crates (ex.: IDs, enums de eventos)
-
Atualizar dependências dos crates consumidores para apontar para
prometeu-abionde aplicável. -
Manter
prometeu-corecompilando com:pub use prometeu_abi as abi;- reexports temporários de tipos que mudaram de path.
Critérios de aceite
- Workspace compila.
- Nenhum comportamento muda.
prometeu-coreainda existe (temporário).
PR-00.2 — Extrair prometeu-vm do prometeu-core
Branch: pr-00-2-prometeu-vm
Objetivo
Mover virtual_machine/* para crates/prometeu-vm/.
Passos prescritivos
-
Criar crate
crates/prometeu-vm/. -
Mover
crates/prometeu-core/src/virtual_machine/**→crates/prometeu-vm/src/**. -
Ajustar
usepaths em todos os crates. -
Adicionar shim temporário no
prometeu-core(se ainda existir):pub mod virtual_machine { pub use prometeu_vm::*; }
Critérios de aceite
cargo testverde.- runtime desktop ainda roda.
PR-00.3 — Extrair prometeu-kernel (OS + FS + syscalls)
Branch: pr-00-3-prometeu-kernel
Objetivo
Mover prometeu_os/* + fs/* (e qualquer dispatcher de syscalls) para crates/prometeu-kernel/.
Passos prescritivos
-
Criar crate
crates/prometeu-kernel/. -
Mover:
crates/prometeu-core/src/prometeu_os/**→crates/prometeu-kernel/src/**crates/prometeu-core/src/fs/**→crates/prometeu-kernel/src/fs/**
-
Garantir que o kernel depende de:
prometeu-abiprometeu-vm
-
Garantir que a VM chama syscalls via interface implementada pelo kernel.
-
Manter shim temporário no
prometeu-core(se existir):pub mod prometeu_os { pub use prometeu_kernel::*; }
Critérios de aceite
cargo testverde.- Sem mudança comportamental (mesmo conjunto de syscalls e traps).
PR-00.4 — Depurar prometeu-core: remover execução e virar apenas compat layer
Branch: pr-00-4-deprecate-prometeu-core
Objetivo
Eliminar o conteúdo executável restante do prometeu-core, deixando-o como reexport/compat por um curto período.
Passos
-
hardwareefirmware/hubficam onde estiverem por enquanto (podem virar PR-00.5/00.6 se necessário) -
prometeu-corepassa a reexportar:prometeu-abiprometeu-vmprometeu-kernel
Critérios
- Zero imports internos
crate::virtual_machineetc. fora da facade.
PR-00.5 — (Opcional) Extrair prometeu-firmware (hub/boot)
Branch: pr-00-5-prometeu-firmware
Objetivo
Mover firmware/* + prometeu_hub/* para crates/prometeu-firmware/.
Critérios
- runtime desktop depende de
prometeu-firmware.
PR-00.6 — Remover prometeu-core e migrar consumidores
Branch: pr-00-6-remove-prometeu-core
Objetivo
Apagar prometeu-core após migração total.
Critérios
- Nenhum crate depende de
prometeu-core.
PR-01 — FileDB + LineIndex (base do LSP e spans)
Branch: pr-01-filedb
Objetivo
Criar uma base de arquivos com IDs estáveis na sessão e conversão offset<->(line,col).
Arquivos / módulos
prometeu-analysis/src/file_db.rsprometeu-analysis/src/span.rsprometeu-analysis/src/ids.rsprometeu-analysis/src/lib.rs(re-exports)
Estruturas obrigatórias
// prometeu-analysis/src/ids.rs
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize)]
pub struct FileId(pub u32);
// prometeu-analysis/src/span.rs
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct Span {
pub file: FileId,
pub start: u32, // byte offset
pub end: u32, // byte offset, exclusive
}
// prometeu-analysis/src/file_db.rs
pub struct FileDB {
// map uri->id, id->uri/text/line_index
}
pub struct LineIndex {
// stores line start offsets
}
Regras
- Spans são byte offsets UTF-8 (
startinclusive,endexclusive) — alinhado ao Canonical Addenda. LineIndexdeve lidar com(LF). (CRLF pode ser normalizado na entrada.)
APIs obrigatórias
impl FileDB {
pub fn upsert(&mut self, uri: &str, text: String) -> FileId;
pub fn file_id(&self, uri: &str) -> Option<FileId>;
pub fn uri(&self, id: FileId) -> &str;
pub fn text(&self, id: FileId) -> &str;
pub fn line_index(&self, id: FileId) -> &LineIndex;
}
impl LineIndex {
pub fn offset_to_line_col(&self, offset: u32) -> (u32, u32);
pub fn line_col_to_offset(&self, line: u32, col: u32) -> Option<u32>;
}
Testes obrigatórios
-
tests/file_db_line_index.rs(unit)- roundtrip offset->(l,c)->offset
- bordas (start/end, EOF)
Critérios de aceite
- Testes passam.
- Nenhuma mudança no output do
prometeu-compilerainda.
PR-02 — NameInterner (NameId) e eliminação de String no hot path
Branch: pr-02-name-interner
Objetivo
Trocar identificadores em AST/resolver de String para NameId.
Arquivos
prometeu-analysis/src/interner.rs- Ajustar frontend PBS no
prometeu-compiler(ver lista de toques abaixo).
Estruturas obrigatórias
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize)]
pub struct NameId(pub u32);
pub struct NameInterner {
// bidirectional: string->id, id->string
}
APIs obrigatórias
impl NameInterner {
pub fn new() -> Self;
pub fn intern(&mut self, s: &str) -> NameId;
pub fn resolve(&self, id: NameId) -> &str;
}
Regras
- Interner é session-local.
resolvedeve retornar&strestável (armazenarStringinternamente).
Touch points no prometeu-compiler
-
Onde hoje existe
Stringcomo nome de símbolo, token de identifier, etc:- AST nodes de
Ident - Resolver scopes:
HashMap<NameId, _>
- AST nodes de
Testes
- Unit: intern/resolve, dedup
- Golden: manter comportamento de resolver/diags
Critérios de aceite
- Redução de
Stringem estruturas hot (resolver) - Build e testes ok.
PR-03 — AST Arena (NodeId) para PBS
Branch: pr-03-ast-arena
Objetivo
Refatorar o AST PBS (atualmente recursivo) para uma arena Vec com NodeId.
Alvos no repo
prometeu-compiler/src/frontends/pbs/*(localizar AST/parser atuais)
Estruturas obrigatórias
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize)]
pub struct NodeId(pub u32);
pub struct AstArena {
pub nodes: Vec<NodeKind>,
pub spans: Vec<prometeu_analysis::Span>,
pub roots: Vec<NodeId>,
}
pub enum NodeKind {
File { imports: Vec<NodeId>, decls: Vec<NodeId> },
Import { /* ... */ },
FnDecl { name: NameId, /* ... */, body: NodeId },
// ... (conforme canonical AST do PBS)
}
Regras
AstArena::push(kind, span) -> NodeIdsempre faz append.spans.len() == nodes.len()sempre.
APIs obrigatórias
impl AstArena {
pub fn push(&mut self, kind: NodeKind, span: Span) -> NodeId;
pub fn kind(&self, id: NodeId) -> &NodeKind;
pub fn span(&self, id: NodeId) -> Span;
}
Testes obrigatórios
- Parser golden tests: comparar JSON canonical (se você já tem) ou snapshots equivalentes.
- Unit: invariantes (push mantém alinhamento).
Critérios de aceite
- Nenhum
Box<Node>em AST PBS. - Resolver e typechecker passam a consumir NodeId.
PR-04 — SymbolArena + índices (defs/refs) + node→symbol
Branch: pr-04-symbol-arena-index
Objetivo
Criar SymbolArena e índices para features de LSP sem traversal pesado.
Estruturas obrigatórias
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize)]
pub struct SymbolId(pub u32);
pub enum SymbolKind { Type, Value, Service, Function /* etc */ }
pub struct Symbol {
pub name: NameId,
pub kind: SymbolKind,
pub exported: bool,
pub module: ModuleId,
pub decl_span: Span,
}
pub struct SymbolArena { pub symbols: Vec<Symbol> }
pub struct DefIndex { /* HashMap<(ModuleId, NameId, Namespace), SymbolId> */ }
pub struct RefIndex { /* Vec<Vec<Span>> by SymbolId */ }
pub struct NodeToSymbol { /* Vec<Option<SymbolId>> by NodeId */ }
APIs obrigatórias
insert_symbol(...) -> SymbolId(falha se duplicate, com diag E_RESOLVE_DUPLICATE_SYMBOL)record_ref(symbol_id, span)bind_node(node_id, symbol_id)
Testes
- Duplicate symbol
- Undefined identifier
- Visibility violations
- Determinismo (mesma input → mesma ordem IDs, quando possível)
PR-05 — TypeArena + TypeFacts (node→type, symbol→type)
Branch: pr-05-type-arena-facts
Objetivo
Dar base para hover, completion e erros de tipo.
Estruturas obrigatórias
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize)]
pub struct TypeId(pub u32);
pub enum TypeKind {
Primitive { name: NameId },
Struct { sym: SymbolId },
Optional { inner: TypeId },
Result { ok: TypeId, err: TypeId },
Array { inner: TypeId, len: Option<u32> },
// ... conforme v0
}
pub struct TypeArena { pub types: Vec<TypeKind> }
pub struct TypeFacts {
pub node_type: Vec<Option<TypeId>>, // index by NodeId
pub symbol_type: Vec<Option<TypeId>>, // index by SymbolId
}
APIs obrigatórias
intern_type(TypeKind) -> TypeId(dedup opcional; documentar)set_node_type(NodeId, TypeId)set_symbol_type(SymbolId, TypeId)
Testes
- Hover type display snapshots.
PR-06 — Diagnostics canonizados (E_* / W_*)
Branch: pr-06-diagnostics
Objetivo
Diagnósticos estáveis e serializáveis, alinhados ao Canonical Addenda (codes).
Estruturas obrigatórias
pub enum Severity { Error, Warning }
pub struct Diagnostic {
pub severity: Severity,
pub code: String,
pub message: String,
pub span: Span,
pub related: Vec<(String, Span)>,
}
Regras
- Codes conforme Canonical Addenda (E_PARSE_, E_RESOLVE_, E_TYPE_*).
Testes
- Golden diag JSON determinístico.
PR-07 — Export: symbols.json v1 + analysis.json v0
Branch: pr-07-analysis-export
Objetivo
Separar índice leve (symbols.json) e export completo (analysis.json).
Símbolos (novo formato recomendado)
- IMPORTANTE: parar de gravar paths absolutos (usar URI relativo ao projeto quando possível).
symbols.json v1 (schema_version=1):
-
projects[]:-
project(string) -
project_dir(string) (pode ficar absoluto por enquanto) -
symbols[]:symbol_id(u32) OU string estável atual (mantém compat)name(string)kind(string)exported(bool)module_path(string)decl_span:{ file_uri, start:{line,col}, end:{line,col} }
-
analysis.json (schema_version=0):
file_table: [{file_id:u32, uri:string}]symbols: [{symbol_id:u32, name_id:u32, kind, exported, module_id, decl_span}]refs: [{symbol_id:u32, spans:[Span]}]types: [{type_id:u32, kind:...}]facts: { node_type: [...], symbol_type: [...] }diagnostics: [Diagnostic]
Testes
- Snapshot de ambos JSONs.
PR-08 — LSP MVP (diagnostics + symbols + goto definition)
Branch: pr-08-lsp-mvp
Objetivo
LSP funcional mínimo usando AnalysisDb (em memória), recompilando quando arquivo muda.
Features
initializedidOpen/didChange/didClosepublishDiagnosticsdocumentSymbol/workspaceSymboldefinition
Regras
didChange: por enquanto full-text (simplifica)- Rebuild: coarse (projeto inteiro) inicialmente
Testes
- Test harness: abrir doc e pedir definition.
PR-09 — LSP: references + rename
Branch: pr-09-lsp-refs-rename
Objetivo
Baseado em RefIndex e NodeToSymbol.
Features
referencesprepareRenamerename
Regras de segurança
- Não renomear se símbolo não-resolvido.
- Não renomear se span em comentário/string.
PR-10 — LSP: hover + signatureHelp
Branch: pr-10-lsp-hover-sighelp
Features
hover: type + docstring (docstring opcional por enquanto)signatureHelp: para call nodes (se parser já marca)
PR-11 — LSP: completion
Branch: pr-11-lsp-completion
Buckets
- locals em scope (se você tiver scope facts)
- symbols do módulo
- exports importados
- members via type facts
PR-12 — LSP: semantic tokens + highlights
Branch: pr-12-lsp-semantic
PR-13 — LSP: formatting + code actions (opcional)
Branch: pr-13-lsp-actions
PR-14 — Incremental analysis + cancelation
Branch: pr-14-incremental
PR-15 — Debug map (pc→span) + integração com traps
Branch: pr-15-debug-map
Sequência recomendada (travada)
- PR-00.1 (
prometeu-abi+ compat) - PR-00.2 (
prometeu-vm) - PR-00.3 (
prometeu-kernel) - PR-00.4 (depurar
prometeu-core) - PR-00.5 (opcional firmware)
- PR-00.6 (remover core)
Após PR-00.X, iniciar a trilha Arena-Driven (PR-01..PR-07) no compiler/analysis.