Add few more test cases for the parser and type-checker.

This commit is contained in:
KtorZ 2024-06-13 15:26:07 +02:00 committed by Lucas
parent aeb079334e
commit 00d1927dad
4 changed files with 209 additions and 4 deletions

View File

@ -1,12 +1,10 @@
use chumsky::prelude::*; use super::block;
use crate::{ use crate::{
ast, ast,
expr::UntypedExpr, expr::UntypedExpr,
parser::{annotation, error::ParseError, pattern, token::Token}, parser::{annotation, error::ParseError, pattern, token::Token},
}; };
use chumsky::prelude::*;
use super::block;
pub fn parser<'a>( pub fn parser<'a>(
sequence: Recursive<'a, Token, UntypedExpr, ParseError>, sequence: Recursive<'a, Token, UntypedExpr, ParseError>,
@ -133,4 +131,30 @@ mod tests {
"# "#
); );
} }
#[test]
fn if_soft_cast_discard_assign() {
assert_expr!(
r#"
if foo() is Foo {
todo
} else {
todo
}
"#
);
}
#[test]
fn if_soft_cast_not_var_condition() {
assert_expr!(
r#"
if foo() is Foo { a }: Foo {
todo
} else {
todo
}
"#
);
}
} }

View File

@ -0,0 +1,59 @@
---
source: crates/aiken-lang/src/parser/expr/if_else.rs
description: "Code:\n\nif foo() is Foo {\n todo\n} else {\n todo\n}\n"
---
If {
location: 0..42,
branches: [
IfBranch {
condition: Call {
arguments: [],
fun: Var {
location: 3..6,
name: "foo",
},
location: 3..8,
},
body: Trace {
kind: Todo,
location: 20..24,
then: ErrorTerm {
location: 20..24,
},
text: String {
location: 20..24,
value: "aiken::todo",
},
},
is: Some(
AssignmentPattern {
pattern: Discard {
name: "_",
location: 12..15,
},
annotation: Some(
Constructor {
location: 12..15,
module: None,
name: "Foo",
arguments: [],
},
),
location: 12..15,
},
),
location: 3..26,
},
],
final_else: Trace {
kind: Todo,
location: 36..40,
then: ErrorTerm {
location: 36..40,
},
text: String {
location: 36..40,
value: "aiken::todo",
},
},
}

View File

@ -0,0 +1,76 @@
---
source: crates/aiken-lang/src/parser/expr/if_else.rs
description: "Code:\n\nif foo() is Foo { a }: Foo {\n todo\n} else {\n todo\n}\n"
---
If {
location: 0..53,
branches: [
IfBranch {
condition: Call {
arguments: [],
fun: Var {
location: 3..6,
name: "foo",
},
location: 3..8,
},
body: Trace {
kind: Todo,
location: 31..35,
then: ErrorTerm {
location: 31..35,
},
text: String {
location: 31..35,
value: "aiken::todo",
},
},
is: Some(
AssignmentPattern {
pattern: Constructor {
is_record: true,
location: 12..21,
name: "Foo",
arguments: [
CallArg {
label: Some(
"a",
),
location: 18..19,
value: Var {
location: 18..19,
name: "a",
},
},
],
module: None,
constructor: (),
spread_location: None,
tipo: (),
},
annotation: Some(
Constructor {
location: 23..26,
module: None,
name: "Foo",
arguments: [],
},
),
location: 12..26,
},
),
location: 3..37,
},
],
final_else: Trace {
kind: Todo,
location: 47..51,
then: ErrorTerm {
location: 47..51,
},
text: String {
location: 47..51,
value: "aiken::todo",
},
},
}

View File

@ -2653,6 +2653,52 @@ fn if_soft_cast_no_scope_leak() {
)) ))
} }
#[test]
fn if_soft_cast_no_scope_leak_2() {
let source_code = r#"
pub type Foo {
a: Int
}
pub fn foo(foo: Data) -> Int {
if foo is Foo { a }: Foo {
a
} else {
a
}
}
"#;
assert!(matches!(
check_validator(parse(source_code)),
Err((_, Error::UnknownVariable { name, .. })) if name == "a"
))
}
#[test]
fn if_soft_cast_unused_pattern() {
let source_code = r#"
pub type Foo {
a: Int
}
pub fn foo(foo: Data) -> Int {
if foo is Foo { a }: Foo {
1
} else {
0
}
}
"#;
let (warnings, _ast) = dbg!(check(parse(source_code))).unwrap();
assert!(matches!(
warnings[0],
Warning::UnusedVariable { ref name, .. } if name == "a"
))
}
#[test] #[test]
fn if_soft_cast_not_data() { fn if_soft_cast_not_data() {
let source_code = r#" let source_code = r#"