mod declarations;
mod function_types;
mod match_;
mod object_types;
mod params;
mod types;
use hermes_ast::node::{Node, RecordExpression, RecordExpressionProperties};
use hermes_ast::node_child::{NodeList, NodeMetadata};
use hermes_support::location::SMLoc;
use crate::js::JSParserImpl;
use crate::lexer::GrammarContext;
use crate::token_kinds::{ord, TokenKind};
impl<'gc, 'ast, 'ctx, 'a> JSParserImpl<'gc, 'ast, 'ctx, 'a> {
pub(in crate::js) fn check_record_expression_flow(
&self,
expr: &Node<'gc>,
) -> bool {
if !self.check(TokenKind::l_brace)
|| self.lexer.is_new_line_before_current_token()
{
return false;
}
if let Node::Identifier(ident) = expr {
let name = self.gc.ctx().atom_table.bytes(ident.name.get());
if name.is_empty() || (name[0] >= b'a' && name[0] <= b'z') {
return false;
}
return true;
}
matches!(expr, Node::MemberExpression(_))
}
pub(in crate::js) fn parse_record_expression_flow(
&mut self,
start_loc: SMLoc,
constructor: &'gc Node<'gc>,
type_args: Option<&'gc Node<'gc>>,
) -> Option<&'gc Node<'gc>> {
debug_assert!(self.check(TokenKind::l_brace));
let properties_start_loc = self.advance(GrammarContext::AllowRegExp).start;
let mut elem_list: Vec<&'gc Node<'gc>> = Vec::new();
if !self.parse_object_properties(&mut elem_list) {
return None;
}
let end_loc = self.cur_range().end;
if !self.eat_at(
TokenKind::r_brace,
GrammarContext::AllowDiv,
" at end of record expression '{...'",
Some("location of '{'"),
properties_start_loc,
) {
return None;
}
let props_node = Node::RecordExpressionProperties(
RecordExpressionProperties::new(
NodeMetadata::new(self.dummy_range()),
NodeList::from_iter(self.gc, elem_list),
),
);
let properties =
self.set_location(properties_start_loc, end_loc, props_node);
let node = Node::RecordExpression(RecordExpression::new(
NodeMetadata::new(self.dummy_range()),
constructor,
type_args,
properties,
));
Some(self.set_location(start_loc, end_loc, node))
}
}
pub(super) fn can_follow_variance_keyword_flow(
opt_token_kind: Option<TokenKind>,
) -> bool {
let Some(kind) = opt_token_kind else {
return false;
};
if ord(kind) > ord(TokenKind::_first_resword)
&& ord(kind) < ord(TokenKind::_last_resword)
{
return true;
}
matches!(
kind,
TokenKind::identifier
| TokenKind::private_identifier
| TokenKind::string_literal
| TokenKind::numeric_literal
| TokenKind::bigint_literal
| TokenKind::l_square
)
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[allow(dead_code)] pub(super) enum TypeAliasKind {
None,
Declare,
Opaque,
DeclareOpaque,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub(super) enum AllowAnonFunctionType {
No,
Yes,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub(super) enum AllowTypedArrowFunction {
No,
Yes,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub(super) enum CoverTypedParameters {
No,
Yes,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[allow(dead_code)] pub(super) enum AllowProtoProperty {
No,
Yes,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[allow(dead_code)] pub(super) enum AllowStaticProperty {
No,
Yes,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub(super) enum AllowSpreadProperty {
No,
Yes,
}