152 lines
3.3 KiB
Rust
152 lines
3.3 KiB
Rust
|
#![cfg(test)]
|
||
|
|
||
|
#[macro_use]
|
||
|
use super::*;
|
||
|
use crate::util::quick_ast;
|
||
|
|
||
|
macro_rules! values_in_table {
|
||
|
//TODO multiple values
|
||
|
($source:expr, $single_value:expr) => {
|
||
|
{
|
||
|
let mut symbol_table = SymbolTable::new();
|
||
|
let ast = quick_ast($source);
|
||
|
symbol_table.add_top_level_symbols(&ast).unwrap();
|
||
|
match symbol_table.lookup_by_fqsn($single_value) {
|
||
|
Some(_spec) => (),
|
||
|
None => panic!(),
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn basic_symbol_table() {
|
||
|
values_in_table! { "let a = 10; fn b() { 20 }", &fqsn!("b"; tr) }
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn no_duplicates() {
|
||
|
let source = r#"
|
||
|
fn a() { 1 }
|
||
|
fn b() { 2 }
|
||
|
fn a() { 3 }
|
||
|
"#;
|
||
|
let mut symbol_table = SymbolTable::new();
|
||
|
let ast = quick_ast(source);
|
||
|
let output = symbol_table.add_top_level_symbols(&ast).unwrap_err();
|
||
|
assert!(output.contains("Duplicate"))
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn no_duplicates_2() {
|
||
|
let source = r#"
|
||
|
let a = 20;
|
||
|
let q = 39;
|
||
|
let a = 30;
|
||
|
"#;
|
||
|
let mut symbol_table = SymbolTable::new();
|
||
|
let ast = quick_ast(source);
|
||
|
let output = symbol_table.add_top_level_symbols(&ast).unwrap_err();
|
||
|
assert!(output.contains("Duplicate"))
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn no_duplicates_3() {
|
||
|
let source = r#"
|
||
|
fn a() {
|
||
|
let a = 20
|
||
|
let b = 40
|
||
|
a + b
|
||
|
}
|
||
|
|
||
|
fn q() {
|
||
|
let x = 30
|
||
|
let x = 33
|
||
|
}
|
||
|
"#;
|
||
|
let mut symbol_table = SymbolTable::new();
|
||
|
let ast = quick_ast(source);
|
||
|
let output = symbol_table.add_top_level_symbols(&ast).unwrap_err();
|
||
|
assert!(output.contains("Duplicate"))
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn dont_falsely_detect_duplicates() {
|
||
|
let source = r#"
|
||
|
let a = 20;
|
||
|
fn some_func() {
|
||
|
let a = 40;
|
||
|
77
|
||
|
}
|
||
|
let q = 39;
|
||
|
"#;
|
||
|
let mut symbol_table = SymbolTable::new();
|
||
|
let ast = quick_ast(source);
|
||
|
symbol_table.add_top_level_symbols(&ast).unwrap();
|
||
|
assert!(symbol_table.lookup_by_fqsn(&fqsn!["a"; tr]).is_some());
|
||
|
assert!(symbol_table.lookup_by_fqsn(&fqsn!["some_func"; fn, "a";tr]).is_some());
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn enclosing_scopes() {
|
||
|
let source = r#"
|
||
|
fn outer_func(x) {
|
||
|
fn inner_func(arg) {
|
||
|
arg
|
||
|
}
|
||
|
x + inner_func(x)
|
||
|
}"#;
|
||
|
let mut symbol_table = SymbolTable::new();
|
||
|
let ast = quick_ast(source);
|
||
|
symbol_table.add_top_level_symbols(&ast).unwrap();
|
||
|
assert!(symbol_table.lookup_by_fqsn(&fqsn!("outer_func"; tr)).is_some());
|
||
|
assert!(symbol_table.lookup_by_fqsn(&fqsn!("outer_func"; fn, "inner_func"; tr)).is_some());
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn enclosing_scopes_2() {
|
||
|
let source = r#"
|
||
|
fn outer_func(x) {
|
||
|
fn inner_func(arg) {
|
||
|
arg
|
||
|
}
|
||
|
|
||
|
fn second_inner_func() {
|
||
|
fn another_inner_func() {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inner_func(x)
|
||
|
}"#;
|
||
|
let mut symbol_table = SymbolTable::new();
|
||
|
let ast = quick_ast(source);
|
||
|
symbol_table.add_top_level_symbols(&ast).unwrap();
|
||
|
assert!(symbol_table.lookup_by_fqsn(&fqsn!("outer_func"; tr)).is_some());
|
||
|
assert!(symbol_table.lookup_by_fqsn(&fqsn!("outer_func"; fn, "inner_func"; tr)).is_some());
|
||
|
assert!(symbol_table.lookup_by_fqsn(&fqsn!("outer_func"; fn, "second_inner_func"; tr)).is_some());
|
||
|
assert!(symbol_table.lookup_by_fqsn(&fqsn!("outer_func"; fn, "second_inner_func"; fn, "another_inner_func"; tr)).is_some());
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn enclosing_scopes_3() {
|
||
|
let source = r#"
|
||
|
fn outer_func(x) {
|
||
|
fn inner_func(arg) {
|
||
|
arg
|
||
|
}
|
||
|
|
||
|
fn second_inner_func() {
|
||
|
fn another_inner_func() {
|
||
|
}
|
||
|
fn another_inner_func() {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inner_func(x)
|
||
|
}"#;
|
||
|
let mut symbol_table = SymbolTable::new();
|
||
|
let ast = quick_ast(source);
|
||
|
let output = symbol_table.add_top_level_symbols(&ast).unwrap_err();
|
||
|
assert!(output.contains("Duplicate"))
|
||
|
}
|