luau-syntax 0.732.0

Luau lexer, parser, AST, CST, and source utilities
Documentation
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(),
        })
    }
}