have namespaces work also for calls to record-like constructors.

Signed-off-by: KtorZ <matthias.benkort@gmail.com>
This commit is contained in:
KtorZ 2025-03-16 13:17:05 +01:00
parent 0ed94c18d7
commit 6a4a602391
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
3 changed files with 87 additions and 48 deletions

View File

@ -4,6 +4,7 @@ pub(crate) mod call;
pub(crate) mod field_access; pub(crate) mod field_access;
pub(crate) mod tuple_index; pub(crate) mod tuple_index;
#[derive(Debug)]
pub(crate) enum Chain { pub(crate) enum Chain {
Call(Vec<ParsedCallArg>, Span), Call(Vec<ParsedCallArg>, Span),
FieldAccess(String, Span), FieldAccess(String, Span),

View File

@ -16,6 +16,12 @@ pub fn parser(
.map_with_span(|module, span: ast::Span| (module, span)) .map_with_span(|module, span: ast::Span| (module, span))
.then_ignore(just(Token::Dot)) .then_ignore(just(Token::Dot))
.or_not() .or_not()
.then(
select! {Token::UpName { name } => name}
.map_with_span(|name, span| (name, span))
.then_ignore(just(Token::Dot))
.or_not(),
)
.then(select! {Token::UpName { name } => name}.map_with_span(|name, span| (name, span))) .then(select! {Token::UpName { name } => name}.map_with_span(|name, span| (name, span)))
.then( .then(
choice(( choice((
@ -117,6 +123,12 @@ pub fn parser(
.map_with_span(|module, span| (module, span)) .map_with_span(|module, span| (module, span))
.then_ignore(just(Token::Dot)) .then_ignore(just(Token::Dot))
.or_not() .or_not()
.then(
select! {Token::UpName { name } => name}
.map_with_span(|name, span| (name, span))
.then_ignore(just(Token::Dot))
.or_not(),
)
.then(select! {Token::UpName { name } => name}.map_with_span(|name, span| (name, span))) .then(select! {Token::UpName { name } => name}.map_with_span(|name, span| (name, span)))
.then( .then(
select! {Token::Name {name} => name} select! {Token::Name {name} => name}
@ -157,21 +169,43 @@ pub fn parser(
.delimited_by(just(Token::LeftParen), just(Token::RightParen)), .delimited_by(just(Token::LeftParen), just(Token::RightParen)),
), ),
)) ))
.map_with_span(|((module, (name, n_span)), arguments), span| { .map_with_span(
let fun = if let Some((module, m_span)) = module { |(((module, namespace), (label, label_span)), arguments), span| {
let fun = match (module, namespace) {
(Some((module, module_span)), Some((namespace, namespace_span))) => {
UntypedExpr::FieldAccess { UntypedExpr::FieldAccess {
location: m_span.union(n_span), location: module_span.union(namespace_span).union(label_span),
label: name, label,
container: Box::new(UntypedExpr::FieldAccess {
location: module_span.union(namespace_span),
label: namespace,
container: Box::new(UntypedExpr::Var { container: Box::new(UntypedExpr::Var {
location: m_span, location: module_span,
name: module, name: module,
}), }),
}),
} }
} else {
UntypedExpr::Var {
location: n_span,
name,
} }
(None, Some((namespace, namespace_span))) => UntypedExpr::FieldAccess {
location: namespace_span.union(label_span),
label,
container: Box::new(UntypedExpr::Var {
location: namespace_span,
name: namespace,
}),
},
(Some((module, module_span)), None) => UntypedExpr::FieldAccess {
location: module_span.union(label_span),
label,
container: Box::new(UntypedExpr::Var {
location: module_span,
name: module,
}),
},
(None, None) => UntypedExpr::Var {
location: label_span,
name: label,
},
}; };
UntypedExpr::Call { UntypedExpr::Call {
@ -179,7 +213,8 @@ pub fn parser(
fun: Box::new(fun), fun: Box::new(fun),
location: span, location: span,
} }
}) },
)
} }
#[cfg(test)] #[cfg(test)]

View File

@ -2307,7 +2307,7 @@ fn use_imported_type_as_namespace_for_patterns() {
fn use_type_as_namespace_for_patterns() { fn use_type_as_namespace_for_patterns() {
let dependency = r#" let dependency = r#"
pub type Foo { pub type Foo {
A A { a: Int }
B B
} }
"#; "#;
@ -2317,7 +2317,7 @@ fn use_type_as_namespace_for_patterns() {
fn bar(foo: Foo) { fn bar(foo: Foo) {
when foo is { when foo is {
Foo.A -> True Foo.A { a } -> a > 10
Foo.B -> False Foo.B -> False
} }
} }
@ -2332,7 +2332,7 @@ fn use_type_as_namespace_for_patterns() {
fn use_nested_type_as_namespace_for_patterns() { fn use_nested_type_as_namespace_for_patterns() {
let dependency = r#" let dependency = r#"
pub type Foo { pub type Foo {
A A { a: Int }
B B
} }
"#; "#;
@ -2342,7 +2342,7 @@ fn use_nested_type_as_namespace_for_patterns() {
fn bar(x: Foo) { fn bar(x: Foo) {
when x is { when x is {
foo.Foo.A -> True foo.Foo.A { a } -> a > 10
foo.Foo.B -> False foo.Foo.B -> False
} }
} }
@ -2357,7 +2357,7 @@ fn use_nested_type_as_namespace_for_patterns() {
fn use_opaque_type_as_namespace_for_patterns_fails() { fn use_opaque_type_as_namespace_for_patterns_fails() {
let dependency = r#" let dependency = r#"
pub opaque type Foo { pub opaque type Foo {
A A { a: Int }
B B
} }
"#; "#;
@ -2367,7 +2367,7 @@ fn use_opaque_type_as_namespace_for_patterns_fails() {
fn bar(foo: Foo) { fn bar(foo: Foo) {
when foo is { when foo is {
Foo.A -> True Foo.A { a } -> a > 10
Foo.B -> False Foo.B -> False
} }
} }
@ -2388,7 +2388,7 @@ fn use_opaque_type_as_namespace_for_patterns_fails() {
fn use_wrong_type_as_namespace_for_patterns_fails() { fn use_wrong_type_as_namespace_for_patterns_fails() {
let dependency = r#" let dependency = r#"
pub type Foo { pub type Foo {
A A { a: Int }
B B
} }
@ -2403,7 +2403,7 @@ fn use_wrong_type_as_namespace_for_patterns_fails() {
fn bar(foo: Foo) { fn bar(foo: Foo) {
when foo is { when foo is {
Foo.A -> True Foo.A { .. } -> True
Foo.D -> False Foo.D -> False
} }
} }
@ -2424,7 +2424,7 @@ fn use_wrong_type_as_namespace_for_patterns_fails() {
fn use_type_as_namespace_for_constructors() { fn use_type_as_namespace_for_constructors() {
let dependency = r#" let dependency = r#"
pub type Foo { pub type Foo {
I(Int) I { i: Int }
B(Bool) B(Bool)
} }
"#; "#;
@ -2434,7 +2434,7 @@ fn use_type_as_namespace_for_constructors() {
test my_test() { test my_test() {
and { and {
Foo.I(42) == foo.I(42), Foo.I { i: 42 } == foo.I(42),
foo.B(True) == Foo.B(True), foo.B(True) == Foo.B(True),
} }
} }
@ -2449,7 +2449,7 @@ fn use_type_as_namespace_for_constructors() {
fn use_type_as_nested_namespace_for_constructors() { fn use_type_as_nested_namespace_for_constructors() {
let dependency = r#" let dependency = r#"
pub type Foo { pub type Foo {
I(Int) I { i: Int }
B(Bool) B(Bool)
} }
"#; "#;
@ -2458,7 +2458,8 @@ fn use_type_as_nested_namespace_for_constructors() {
use foo use foo
test my_test() { test my_test() {
trace foo.Foo.I(42) trace foo.Foo.I { i: 42 }
trace foo.Foo.B(False)
Void Void
} }
"#; "#;
@ -2472,7 +2473,7 @@ fn use_type_as_nested_namespace_for_constructors() {
fn use_type_as_nested_namespace_for_constructors_from_multi_level_module() { fn use_type_as_nested_namespace_for_constructors_from_multi_level_module() {
let dependency = r#" let dependency = r#"
pub type Foo { pub type Foo {
I(Int) I { i: Int }
B(Bool) B(Bool)
} }
"#; "#;
@ -2481,7 +2482,8 @@ fn use_type_as_nested_namespace_for_constructors_from_multi_level_module() {
use foo/bar use foo/bar
test my_test() { test my_test() {
trace bar.Foo.I(42) trace bar.Foo.I { i: 42 }
trace bar.Foo.B(True)
Void Void
} }
"#; "#;
@ -2495,7 +2497,7 @@ fn use_type_as_nested_namespace_for_constructors_from_multi_level_module() {
fn use_type_as_nested_namespace_for_constructors_from_module_alias() { fn use_type_as_nested_namespace_for_constructors_from_module_alias() {
let dependency = r#" let dependency = r#"
pub type Foo { pub type Foo {
I(Int) I { i: Int }
B(Bool) B(Bool)
} }
"#; "#;
@ -2504,7 +2506,8 @@ fn use_type_as_nested_namespace_for_constructors_from_module_alias() {
use foo as bar use foo as bar
test my_test() { test my_test() {
trace bar.Foo.I(42) trace bar.Foo.I { i: 42 }
trace bar.Foo.B(True)
Void Void
} }
"#; "#;
@ -2518,7 +2521,7 @@ fn use_type_as_nested_namespace_for_constructors_from_module_alias() {
fn use_type_as_namespace_unknown_constructor() { fn use_type_as_namespace_unknown_constructor() {
let dependency = r#" let dependency = r#"
pub type Foo { pub type Foo {
I(Int) I { i: Int }
B(Bool) B(Bool)
} }
"#; "#;
@ -2527,7 +2530,7 @@ fn use_type_as_namespace_unknown_constructor() {
use foo.{Foo} use foo.{Foo}
test my_test() { test my_test() {
Foo.A == Foo.I(42) Foo.I(42) == Foo.A
} }
"#; "#;
@ -2546,12 +2549,12 @@ fn use_type_as_namespace_unknown_constructor() {
fn use_wrong_type_as_namespace() { fn use_wrong_type_as_namespace() {
let dependency = r#" let dependency = r#"
pub type Foo { pub type Foo {
I(Int) I { i: Int }
B(Bool) B(Bool)
} }
pub type Bar { pub type Bar {
S(String) S { s: String }
L(List<Int>) L(List<Int>)
} }
"#; "#;
@ -2580,12 +2583,12 @@ fn use_wrong_type_as_namespace() {
fn use_wrong_nested_type_as_namespace() { fn use_wrong_nested_type_as_namespace() {
let dependency = r#" let dependency = r#"
pub type Foo { pub type Foo {
I(Int) I { i: Int }
B(Bool) B(Bool)
} }
pub type Bar { pub type Bar {
S(String) S { s: String }
L(List<Int>) L(List<Int>)
} }
"#; "#;
@ -2614,7 +2617,7 @@ fn use_wrong_nested_type_as_namespace() {
fn use_private_type_as_nested_namespace_fails() { fn use_private_type_as_nested_namespace_fails() {
let dependency = r#" let dependency = r#"
type Foo { type Foo {
I(Int) I { i: Int }
B(Bool) B(Bool)
} }
"#; "#;
@ -2623,7 +2626,7 @@ fn use_private_type_as_nested_namespace_fails() {
use foo use foo
test my_test() { test my_test() {
trace foo.Foo.I(42) trace foo.Foo.I { i: 42 }
Void Void
} }
"#; "#;
@ -2643,7 +2646,7 @@ fn use_private_type_as_nested_namespace_fails() {
fn use_opaque_type_as_namespace_for_constructors_fails() { fn use_opaque_type_as_namespace_for_constructors_fails() {
let dependency = r#" let dependency = r#"
pub opaque type Foo { pub opaque type Foo {
I(Int) I { i: Int }
B(Bool) B(Bool)
} }
"#; "#;
@ -2672,7 +2675,7 @@ fn use_opaque_type_as_namespace_for_constructors_fails() {
fn use_opaque_type_as_nested_namespace_for_constructors_fails() { fn use_opaque_type_as_nested_namespace_for_constructors_fails() {
let dependency = r#" let dependency = r#"
pub opaque type Foo { pub opaque type Foo {
I(Int) I { i: Int }
B(Bool) B(Bool)
} }
"#; "#;