Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,88 @@
|
||||
use super::checked;
|
||||
use dever::{
|
||||
compiler::{build, emit},
|
||||
syntax::source::Source,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn emission_keeps_only_called_ownership_versions() {
|
||||
let text = "decorate(value: Text, loud: true) (answer: Text) { answer = value + \"!\" }\ndecorate(value: Text, loud: false) (answer: Text) { answer = value + \".\" }\nmain(value: Text, loud: Bool) (answer: Text) { answer = decorate(value + \"hello\", loud) }";
|
||||
let program = checked(text).unwrap();
|
||||
let source = Source::new(0, "case.dever", text.into());
|
||||
let main = program
|
||||
.functions
|
||||
.iter()
|
||||
.position(|function| function.signature.name == "main")
|
||||
.unwrap();
|
||||
let decorate = program
|
||||
.functions
|
||||
.iter()
|
||||
.position(|function| function.signature.name == "decorate")
|
||||
.unwrap();
|
||||
let generated = emit::generate(&program, &[source], &[main].into());
|
||||
assert!(generated.contains(&format!("fn function{decorate}_own0(")));
|
||||
assert!(!generated.contains(&format!("fn function{decorate}(")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn final_record_fields_keep_ownership_across_calls() {
|
||||
let text = "type Packet { path: Text\n values: List<Int> }\nselected(path: \"/echo\", values: List<Int>) (answer: List<Int>) { answer = values }\nselected(path: other, values: List<Int>) (answer: List<Int>) { answer = [] }\nroute(packet: Packet) (answer: List<Int>) { answer = selected(packet.path, packet.values) }\nmain() (answer: List<Int>) { packet = Packet { path = \"/echo\", values = [1, 2, 3] }\n answer = route(packet) }";
|
||||
let program = checked(text).unwrap();
|
||||
let source = Source::new(0, "case.dever", text.into());
|
||||
let index = |name| {
|
||||
program
|
||||
.functions
|
||||
.iter()
|
||||
.position(|function| function.signature.name == name)
|
||||
.unwrap()
|
||||
};
|
||||
let generated = emit::generate(&program, &[source], &[index("main")].into());
|
||||
let selected = index("selected");
|
||||
assert!(generated.contains(&format!("fn function{selected}_own0_own1(")));
|
||||
assert!(!generated.contains(&format!("fn function{selected}(")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn emitted_types_follow_entry_variables_errors_and_nested_fields() {
|
||||
let text = "type Leaf { value: Channel<Int>? }\ntype Box { leaves: List<Leaf> }\ntype Unused { value: AsyncStream<Int> }\nmake() (value: Box) { value = Box { leaves = [] } }\nmain() () { value = make() }\nplain() (answer: Int) { answer = 42 }";
|
||||
let program = checked(text).unwrap();
|
||||
let source = Source::new(0, "case.dever", text.into());
|
||||
for (entry, required) in [("main", true), ("plain", false)] {
|
||||
let index = program
|
||||
.functions
|
||||
.iter()
|
||||
.position(|function| function.signature.name == entry)
|
||||
.unwrap();
|
||||
let functions = program.reachable([index]);
|
||||
assert_eq!(
|
||||
build::runtime_features(&program, &functions).contains(&"task"),
|
||||
required
|
||||
);
|
||||
let generated = emit::generate(&program, std::slice::from_ref(&source), &functions);
|
||||
for (index, definition) in program.definitions.iter().enumerate() {
|
||||
let wanted = required && matches!(definition.name.as_str(), "Leaf" | "Box");
|
||||
assert_eq!(
|
||||
generated.contains(&format!("pub struct Type{index} {{")),
|
||||
wanted,
|
||||
"{entry}: {}",
|
||||
definition.name
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unused_types_are_still_validated_before_emission() {
|
||||
assert_eq!(
|
||||
checked("type Unused { values: Channel<Stream<Int>> }\nmain() () {}")
|
||||
.unwrap_err()
|
||||
.code,
|
||||
"C013"
|
||||
);
|
||||
assert_eq!(
|
||||
checked("type Unused { next: Unused? }\nmain() () {}")
|
||||
.unwrap_err()
|
||||
.code,
|
||||
"C007"
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user