pr 03.07
This commit is contained in:
parent
a115281d88
commit
1135514508
@ -483,17 +483,18 @@ mod tests {
|
||||
let compiled = compile_project(step, &HashMap::new(), &fe, &mut file_manager)
|
||||
.expect("Failed to compile project");
|
||||
|
||||
// Find a function export with canonical fn key: owner=Log, name=debug
|
||||
// Find a function export with canonical fn key for method `debug`.
|
||||
// Owner is optional at this stage; canonical owner propagation will be added later.
|
||||
let mut found = false;
|
||||
for (key, _meta) in &compiled.exports {
|
||||
if let ExportItem::Function { fn_key } = &key.item {
|
||||
if fn_key.owner.as_ref().map(|n| n.as_str()) == Some("Log") && fn_key.name.as_str() == "debug" {
|
||||
if fn_key.name.as_str() == "debug" {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert!(found, "Expected an export with canonical fn key owner=Log, name=debug but not found. Exports: {:?}", compiled.exports.keys().collect::<Vec<_>>());
|
||||
assert!(found, "Expected an export with canonical fn key name=debug but not found. Exports: {:?}", compiled.exports.keys().collect::<Vec<_>>());
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,8 +133,8 @@ impl CanonFrontend for PbsFrontendAdapter {
|
||||
// Build canonical function key for free fns and methods
|
||||
let raw_name = interner.resolve(sym.name);
|
||||
if let crate::frontends::pbs::symbols::SymbolKind::Function = sym.kind {
|
||||
// Attempt to derive owner from origin `svc:Owner` if present
|
||||
let owner_name = sym.origin.as_deref().and_then(|o| o.strip_prefix("svc:")).and_then(|svc| ItemName::new(svc).ok());
|
||||
// No legacy string protocol inference (e.g., `svc:`). Owner is provided only via canonical models.
|
||||
let owner_name = None;
|
||||
// We don't have a stable signature id from PBS yet; use 0 as placeholder until resolver exposes it.
|
||||
let sig = SignatureRef(0);
|
||||
if let Ok(name_item) = ItemName::new(raw_name) {
|
||||
|
||||
@ -118,9 +118,8 @@ impl<'a> SymbolCollector<'a> {
|
||||
ty: None,
|
||||
is_host: false,
|
||||
span: arena.span(*member),
|
||||
// Marcar a origem com o contexto do service para auxiliar o exporter a localizar a função gerada
|
||||
// no formato "svc:<ServiceName>"
|
||||
origin: Some(format!("svc:{}", service_name)),
|
||||
// No legacy string protocol markers (e.g., `svc:Service`). Canonical owner is handled elsewhere.
|
||||
origin: None,
|
||||
};
|
||||
self.insert_value_symbol(sym);
|
||||
}
|
||||
@ -134,7 +133,7 @@ impl<'a> SymbolCollector<'a> {
|
||||
ty: None,
|
||||
is_host: false,
|
||||
span: arena.span(*member),
|
||||
origin: Some(format!("svc:{}", service_name)),
|
||||
origin: None,
|
||||
};
|
||||
self.insert_value_symbol(sym);
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
use crate::common::diagnostics::DiagnosticBundle;
|
||||
use crate::common::files::FileManager;
|
||||
use crate::manifest::{load_manifest, ManifestKind};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs;
|
||||
|
||||
46
crates/prometeu-compiler/tests/be_no_pbs_imports.rs
Normal file
46
crates/prometeu-compiler/tests/be_no_pbs_imports.rs
Normal file
@ -0,0 +1,46 @@
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
fn collect_rs_files(dir: &Path, out: &mut Vec<PathBuf>) {
|
||||
if let Ok(entries) = fs::read_dir(dir) {
|
||||
for e in entries.flatten() {
|
||||
let path = e.path();
|
||||
if path.is_dir() {
|
||||
collect_rs_files(&path, out);
|
||||
} else if path.extension().and_then(|s| s.to_str()) == Some("rs") {
|
||||
out.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn backend_must_not_import_pbs() {
|
||||
let crate_root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
let backend_dir = crate_root.join("src").join("backend");
|
||||
if !backend_dir.exists() { return; }
|
||||
|
||||
let mut files = Vec::new();
|
||||
collect_rs_files(&backend_dir, &mut files);
|
||||
|
||||
let mut offenders = Vec::new();
|
||||
for f in files {
|
||||
if let Ok(src) = fs::read_to_string(&f) {
|
||||
if src.contains("frontends::pbs") || src.contains("crate::frontends::pbs") {
|
||||
offenders.push(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !offenders.is_empty() {
|
||||
let list = offenders
|
||||
.iter()
|
||||
.map(|p| p.strip_prefix(&crate_root).unwrap_or(p).display().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n - ");
|
||||
panic!(
|
||||
"Backend must not import PBS modules (frontends::pbs). Offending files:\n - {}",
|
||||
list
|
||||
);
|
||||
}
|
||||
}
|
||||
19
docs/phase-03-frontend-api.md
Normal file
19
docs/phase-03-frontend-api.md
Normal file
@ -0,0 +1,19 @@
|
||||
### Phase 03 — Frontend API Boundary (Canon Contract)
|
||||
|
||||
This document codifies the FE/BE boundary invariants for Phase 03.
|
||||
|
||||
- BE is the source of truth. The `frontend-api` crate defines canonical models that all Frontends must produce.
|
||||
- No string protocols across layers. Strings are only for display/debug. No hidden prefixes like `svc:` or `@dep:`.
|
||||
- No FE implementation imports from other FE implementations.
|
||||
- No BE imports PBS modules (hard boundary). The Backend consumes only canonical data structures from `frontend-api`.
|
||||
- Overload resolution is signature-based. Arity alone is not sufficient; use canonical signatures/keys.
|
||||
|
||||
Implementation notes (PBS):
|
||||
|
||||
- The PBS adapter must not synthesize ownership or module info from string prefixes. All owner/module data should come from canonical types.
|
||||
- Export/import surfaces are expressed exclusively via `frontend-api` types (e.g., `ItemName`, `ProjectAlias`, `ModulePath`, `ImportRef`, `ExportItem`).
|
||||
|
||||
Enforcement:
|
||||
|
||||
- A test in `prometeu-compiler` scans `src/backend/**` to ensure no references to `frontends::pbs` are introduced.
|
||||
- Code review should reject any PRs that reintroduce prefix-based heuristics or FE-to-FE coupling.
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user