yog_script_analyze/typeck/
content.rs1use yog_ids::{Format, script_problem};
7
8use super::Checker;
9use crate::ast::{Decl, DeclKind, Name};
10
11pub fn content_path(name: &str) -> String {
14 yog_codegen::snake(name)
15}
16
17impl Checker<'_, '_, '_> {
18 pub(super) fn content_decl(&mut self, word: &str, name: &Name, body: &[Decl]) {
21 if word == yog_ids::kind::RECIPE {
23 return;
24 }
25 let Some(format) = Format::ALL.iter().find(|f| f.noun() == word) else {
26 return;
27 };
28 let file = format.file(&content_path(&name.text));
29 for d in body {
30 if let DeclKind::Prop(p) = &d.kind {
31 self.expr(&p.value);
32 self.report.error(
33 script_problem::CONTENT_PROPERTY,
34 p.name.span,
35 format!(
36 "`{}` is said in `{file}`: a `{word}` declaration holds only its behaviour",
37 p.name.text
38 ),
39 );
40 }
41 }
42 let Some(content) = &self.content else {
43 return;
44 };
45 let path = content_path(&name.text);
46 let found = content
47 .iter()
48 .any(|(kind, id)| kind == word && yog_ids::split(id).1 == path);
49 if !found {
50 self.report.error(
51 script_problem::NO_CONTENT_FILE,
52 name.span,
53 format!(
54 "no `{file}` under `{}/`: `{word} {}` is its behaviour",
55 yog_ids::project::CONTENT,
56 name.text
57 ),
58 );
59 }
60 }
61}