prometeu-runtime/docs/specs/pbs/files/PRs para Junie.md
2026-03-24 13:40:24 +00:00

24 KiB
Raw Blame History

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-core sem 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:

  1. Arquivos/alvos exatos
  2. Estruturas e assinaturas obrigatórias
  3. Esquemas JSON (quando aplicável)
  4. Testes (golden + unit)
  5. 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/ (bin src/main.rs, deps: serde, serde_json, anyhow, clap, e família oxc_*).

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

  1. FileDB: texto, URI/path, line-index, snapshots.
  2. Lexer/Parser: produz AstArena (NodeId + spans por nó).
  3. Binder/Resolver: produz SymbolArena + índices (def/ref).
  4. Typecheck: produz TypeArena + facts (node→type, symbol→type).
  5. Analysis Export: analysis.json (full) + symbols.json (leve e estável).
  6. LSP Server: consome AnalysisDb e 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)

  1. Não “inventar design”. Se algo não estiver especificado, criar TODO e parar.

  2. Não mudar formatação/estilo fora do escopo.

  3. Todo novo tipo público precisa de doc-comment curta e exemplo.

  4. Toda mudança de JSON precisa:

    • schema_version bump (se não for backward)
    • teste de snapshot
  5. Cada PR deve deixar cargo test verde.


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

  1. Novo crate: prometeu-analysis/

    • Cargo.toml (library)
    • src/lib.rs
  2. Novo crate: prometeu-lsp/

    • Cargo.toml (bin)
    • src/main.rs
  3. 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 RwLock por 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 didChange em 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:

  1. request_rebuild deve:

    • cancelar active_rebuild anterior (se existir)
    • instalar um token novo
    • tokio::spawn uma task de rebuild
  2. A task deve checar token.is_cancelled() em pontos seguros:

    • antes de começar
    • após parsing
    • após resolver
    • após typecheck
  3. O lock (RwLock) deve ser segurado apenas:

    • para trocar active_rebuild
    • para aplicar o resultado final

Critérios de aceite

  • cargo build -p prometeu-lsp ok
  • 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:

    1. Cancela o rebuild anterior
    2. Cria novo token
    3. 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:

    1. Clonar snapshot dos textos (FileDB)
    2. Soltar lock
    3. Rodar análise pesada
    4. 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

  • AnalysisDb nunca armazena estado parcialmente válido.

  • Se uma fase falhar:

    • ast/symbols/types podem ficar None
    • diagnostics deve 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::None retornando null / resposta vazia

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 atual prometeu-core depurado) = types + model + protocols (sem execução)
  • prometeu-vm (novo) = execução da VM
  • prometeu-kernel (novo) = OS + FS + syscalls (implementa interface para a VM)
  • prometeu-runtime-desktop (fica) = host desktop
  • prometeu-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):

  1. Não mudar lógica; apenas mover, ajustar imports, e deixar testes verdes.
  2. Se algo exigir mudança de API pública, criar TODO(PR-00.Y) e parar.
  3. Sempre manter o workspace compilável a cada PR.

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

  1. Criar crate crates/prometeu-kernel/.

  2. Mover:

    • crates/prometeu-core/src/prometeu_os/**crates/prometeu-kernel/src/**
    • crates/prometeu-core/src/fs/**crates/prometeu-kernel/src/fs/**
  3. Garantir que o kernel depende de:

    • prometeu-abi
    • prometeu-vm
  4. Garantir que a VM chama syscalls via interface implementada pelo kernel.

  5. Manter shim temporário no prometeu-core (se existir): pub mod prometeu_os { pub use prometeu_kernel::*; }

Critérios de aceite

  • cargo test verde.
  • 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

  • hardware e firmware/hub ficam onde estiverem por enquanto (podem virar PR-00.5/00.6 se necessário)

  • prometeu-core passa a reexportar:

    • prometeu-abi
    • prometeu-vm
    • prometeu-kernel

Critérios

  • Zero imports internos crate::virtual_machine etc. 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.rs
  • prometeu-analysis/src/span.rs
  • prometeu-analysis/src/ids.rs
  • prometeu-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 (start inclusive, end exclusive) — alinhado ao Canonical Addenda.
  • LineIndex deve 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-compiler ainda.

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.
  • resolve deve retornar &str estável (armazenar String internamente).

Touch points no prometeu-compiler

  • Onde hoje existe String como nome de símbolo, token de identifier, etc:

    • AST nodes de Ident
    • Resolver scopes: HashMap<NameId, _>

Testes

  • Unit: intern/resolve, dedup
  • Golden: manter comportamento de resolver/diags

Critérios de aceite

  • Redução de String em 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) -> NodeId sempre 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

  • initialize
  • didOpen/didChange/didClose
  • publishDiagnostics
  • documentSymbol / workspaceSymbol
  • definition

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

  • references
  • prepareRename
  • rename

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)

  1. PR-00.1 (prometeu-abi + compat)
  2. PR-00.2 (prometeu-vm)
  3. PR-00.3 (prometeu-kernel)
  4. PR-00.4 (depurar prometeu-core)
  5. PR-00.5 (opcional firmware)
  6. PR-00.6 (remover core)

Após PR-00.X, iniciar a trilha Arena-Driven (PR-01..PR-07) no compiler/analysis.