use super::*;
#[derive(Clone, Copy)]
pub(in crate::parser) struct Binding<'ast> {
pub(in crate::parser) name: AstName<'ast>,
pub(in crate::parser) name_location: Location,
pub(in crate::parser) annotation: Option<Type<'ast>>,
pub(in crate::parser) colon_position: Position,
pub(in crate::parser) is_const: bool,
}
pub(in crate::parser) struct ParsedBindingList<'ast> {
pub(in crate::parser) variadic: bool,
pub(in crate::parser) vararg_location: Location,
pub(in crate::parser) vararg_annotation: Option<TypePack<'ast>>,
pub(in crate::parser) vararg_annotation_colon: Position,
}
impl<'ast> Parser<'_, 'ast, '_, '_> {
pub(in crate::parser) fn parse_binding(&mut self, is_const: bool) -> Result<Binding<'ast>> {
let (name, name_location) = match self.current {
Token::Ident(name) => {
let location = self.current_token_location();
self.advance();
(name, location)
}
_ => {
let location = self.current_token_location();
self.report_parse_error(self.variable_name_error());
(self.name_error, location)
}
};
let colon_position = if self.cst.enabled() && self.current.kind() == TokenKind::Colon {
self.current_position()
} else {
Position::missing()
};
let annotation = self.parse_optional_type_annotation()?;
Ok(Binding {
name,
name_location,
annotation,
colon_position,
is_const,
})
}
pub(in crate::parser) fn parse_binding_list_into(
&mut self,
bindings: &mut TempVector<Binding<'ast>>,
allow_vararg: bool,
commas: &mut TempVector<Position>,
is_const: bool,
) -> Result<ParsedBindingList<'ast>> {
loop {
if self.current.kind() == TokenKind::Ellipsis && allow_vararg {
let vararg_location = self.current_token_location();
self.advance();
let mut vararg_annotation_colon = Position::missing();
let vararg_annotation = if self.current.kind() == TokenKind::Colon {
if self.cst.enabled() {
vararg_annotation_colon = self.current_position();
}
self.advance();
Some(self.parse_variadic_argument_type_pack()?)
} else {
None
};
return Ok(ParsedBindingList {
variadic: true,
vararg_location,
vararg_annotation,
vararg_annotation_colon,
});
}
bindings.push_back(self.parse_binding(is_const)?);
if self.current.kind() != TokenKind::Comma {
break;
}
if self.cst.enabled() {
commas.push_back(self.current_position());
}
self.advance();
}
Ok(ParsedBindingList {
variadic: false,
vararg_location: Location::zero(),
vararg_annotation: None,
vararg_annotation_colon: Position::missing(),
})
}
}