#![allow(clippy::expect_used, clippy::unwrap_used, clippy::panic)]
use brink_analyzer::{ImportScope, ShapeInfo, declared_shapes};
use brink_ir::{FileId, HirFile, SymbolManifest};
fn lower(file: FileId, source: &str) -> (HirFile, SymbolManifest) {
let parsed = brink_syntax::parse(source);
let (hir, manifest, diags) = brink_ir::lower(file, &parsed.tree());
assert!(diags.is_empty(), "lowering diagnostics: {diags:?}");
(hir, manifest)
}
const SRC: &str = "\
STRUCT Npc = #{name: string, hp: int}
VAR player = Npc#{name: \"Hero\", hp: 10}
-> DONE
";
#[test]
fn declared_shapes_is_reachable_from_outside_the_crate() {
let file = FileId(0);
let (hir, manifest) = lower(file, SRC);
let (index, index_diags) = brink_analyzer::symbol_index(&[(file, &manifest)]);
assert!(index_diags.is_empty(), "index diagnostics: {index_diags:?}");
let files: &[(FileId, &HirFile)] = &[(file, &hir)];
let shapes = declared_shapes(files, &index);
let scope = ImportScope::new(hir.module.as_ref().map(|m| m.name.clone()), &hir.imports);
let npc: &ShapeInfo = shapes
.resolve("Npc", &scope, &index)
.expect("Npc shape declared");
assert!(npc.has_field("name"));
assert!(npc.has_field("hp"));
assert!(!npc.has_field("mana"), "undeclared field must report false");
assert!(
npc.field_ty("hp").is_some(),
"declared field has a resolvable type slot"
);
assert!(
npc.field_ty("mana").is_none(),
"undeclared field has no type"
);
}
#[test]
fn declared_shapes_is_empty_for_a_project_with_no_structs() {
let file = FileId(0);
let (hir, manifest) = lower(file, "Hello, world.\n-> DONE\n");
let (index, index_diags) = brink_analyzer::symbol_index(&[(file, &manifest)]);
assert!(index_diags.is_empty(), "index diagnostics: {index_diags:?}");
let files: &[(FileId, &HirFile)] = &[(file, &hir)];
let shapes = declared_shapes(files, &index);
assert!(shapes.is_empty());
}