summaryrefslogtreecommitdiff
path: root/src/syntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/syntax')
-rw-r--r--src/syntax/ast.rs6
-rw-r--r--src/syntax/parser.rs15
2 files changed, 17 insertions, 4 deletions
diff --git a/src/syntax/ast.rs b/src/syntax/ast.rs
index 4119802e..e492297a 100644
--- a/src/syntax/ast.rs
+++ b/src/syntax/ast.rs
@@ -1570,7 +1570,7 @@ pub enum Param {
/// A named parameter with a default value: `draw: false`.
Named(Named),
/// An argument sink: `..args`.
- Sink(Ident),
+ Sink(Option<Ident>),
}
impl AstNode for Param {
@@ -1578,7 +1578,7 @@ impl AstNode for Param {
match node.kind() {
SyntaxKind::Ident => node.cast().map(Self::Pos),
SyntaxKind::Named => node.cast().map(Self::Named),
- SyntaxKind::Spread => node.cast_first_match().map(Self::Sink),
+ SyntaxKind::Spread => Some(Self::Sink(node.cast_first_match())),
_ => Option::None,
}
}
@@ -1587,7 +1587,7 @@ impl AstNode for Param {
match self {
Self::Pos(v) => v.as_untyped(),
Self::Named(v) => v.as_untyped(),
- Self::Sink(v) => v.as_untyped(),
+ Self::Sink(_) => self.as_untyped(),
}
}
}
diff --git a/src/syntax/parser.rs b/src/syntax/parser.rs
index 42183f3a..7c05eebc 100644
--- a/src/syntax/parser.rs
+++ b/src/syntax/parser.rs
@@ -1069,6 +1069,7 @@ fn validate_dict(p: &mut Parser, m: Marker) {
}
fn validate_params(p: &mut Parser, m: Marker) {
+ let mut used_spread = false;
let mut used = HashSet::new();
for child in p.post_process(m) {
match child.kind() {
@@ -1086,12 +1087,24 @@ fn validate_params(p: &mut Parser, m: Marker) {
}
SyntaxKind::Spread => {
let Some(within) = child.children_mut().last_mut() else { continue };
- if within.kind() != SyntaxKind::Ident {
+ if used_spread {
+ child.convert_to_error("only one argument sink is allowed");
+ continue;
+ }
+ used_spread = true;
+ if within.kind() == SyntaxKind::Dots {
+ continue;
+ } else if within.kind() != SyntaxKind::Ident {
within.convert_to_error(eco_format!(
"expected identifier, found {}",
within.kind().name(),
));
child.make_erroneous();
+ continue;
+ }
+ if !used.insert(within.text().clone()) {
+ within.convert_to_error("duplicate parameter");
+ child.make_erroneous();
}
}
SyntaxKind::LeftParen | SyntaxKind::RightParen | SyntaxKind::Comma => {}