diff --git a/checker/src/synthesis/expressions.rs b/checker/src/synthesis/expressions.rs index 2e3b5798..2658a345 100644 --- a/checker/src/synthesis/expressions.rs +++ b/checker/src/synthesis/expressions.rs @@ -989,7 +989,7 @@ pub(super) fn synthesise_expression( Expression::Comment { on, .. } => { return synthesise_expression(on, environment, checking_data, expecting); } - Expression::ParenthesizedExpression(inner_expression, _) => Instance::RValue( + Expression::Parenthesised(inner_expression, _) => Instance::RValue( synthesise_multiple_expression(inner_expression, environment, checking_data, expecting), ), Expression::ClassExpression(class) => Instance::RValue(synthesise_class_declaration( diff --git a/parser/src/expressions/assignments.rs b/parser/src/expressions/assignments.rs index 8757a59f..f83cd777 100644 --- a/parser/src/expressions/assignments.rs +++ b/parser/src/expressions/assignments.rs @@ -104,7 +104,7 @@ impl TryFrom for VariableOrPropertyAccess { Ok(Self::Index { indexer, position, indexee }) } // Yah weird. Recursion is fine - Expression::ParenthesizedExpression(inner, _) => { + Expression::Parenthesised(inner, _) => { if let MultipleExpression::Single(expression) = *inner { TryFrom::try_from(expression) } else { diff --git a/parser/src/expressions/mod.rs b/parser/src/expressions/mod.rs index fdc87145..aed1e3c3 100644 --- a/parser/src/expressions/mod.rs +++ b/parser/src/expressions/mod.rs @@ -70,7 +70,7 @@ pub enum Expression { ArrayLiteral(Vec, Span), ObjectLiteral(ObjectLiteral), TemplateLiteral(TemplateLiteral), - ParenthesizedExpression(Box, Span), + Parenthesised(Box, Span), // Regular operations: BinaryOperation { lhs: Box, @@ -308,10 +308,7 @@ impl Expression { reader.advance(1); let parenthesize_expression = MultipleExpression::from_reader(reader)?; let end = reader.expect(')')?; - Expression::ParenthesizedExpression( - Box::new(parenthesize_expression), - start.union(end), - ) + Expression::Parenthesised(Box::new(parenthesize_expression), start.union(end)) } } else if reader.starts_with('<') { let is_generic_arguments = reader.after_brackets().starts_with('('); @@ -1024,7 +1021,7 @@ impl Expression { | Self::RegexLiteral { .. } | Self::ArrayLiteral(..) | Self::TemplateLiteral(..) - | Self::ParenthesizedExpression(..) + | Self::Parenthesised(..) | Self::JSXRoot(..) | Self::ExpressionFunction(..) | Self::Null(..) @@ -1361,7 +1358,7 @@ impl Expression { } } } - Self::ParenthesizedExpression(expr, _) => { + Self::Parenthesised(expr, _) => { // TODO more expressions could be considered for parenthesis elision if matches!(&**expr, MultipleExpression::Single(inner) if inner.get_precedence() == PARENTHESIZED_EXPRESSION_AND_LITERAL_PRECEDENCE) { @@ -1402,7 +1399,19 @@ impl Expression { } Self::ConstructorCall { constructor, type_arguments, arguments, .. } => { buf.push_str("new "); + // let requires_parenthesis = !matches!( + // &**constructor, + // Expression::VariableReference(..) + // | Expression::PropertyAccess { .. } + // | Expression::Parenthesised(..) + // ); + // if requires_parenthesis { + // buf.push('('); + // } constructor.to_string_from_buffer(buf, options, local); + // if requires_parenthesis { + // buf.push(')'); + // } if let (true, Some(type_arguments)) = (options.include_type_annotations, type_arguments) { @@ -1533,7 +1542,22 @@ impl Expression { Self::TemplateLiteral(template_literal) => { // Doing here because of tag precedence if let Some(tag) = &template_literal.tag { + // TODO ConstructorCall should not be here + let requires_parenthesis = !matches!( + &**tag, + Expression::VariableReference(..) + | Expression::PropertyAccess { .. } + | Expression::Parenthesised(..) + | Expression::FunctionCall { .. } + | Expression::ConstructorCall { .. } + ); + if requires_parenthesis { + buf.push('('); + } tag.to_string_using_precedence(buf, options, local, local2); + if requires_parenthesis { + buf.push(')'); + } } buf.push('`'); for (static_part, dynamic_part) in &template_literal.parts { @@ -2014,7 +2038,7 @@ impl Expression { pub fn build_iife(block: Block) -> Self { let position = block.get_position(); Expression::FunctionCall { - function: Expression::ParenthesizedExpression( + function: Expression::Parenthesised( Box::new( Expression::ArrowFunction(ArrowFunction { // TODO maybe async @@ -2046,7 +2070,7 @@ impl Expression { #[must_use] pub fn is_iife(&self) -> Option<&ExpressionOrBlock> { if let Expression::FunctionCall { arguments, function, .. } = self { - if let (true, Expression::ParenthesizedExpression(expression, _)) = + if let (true, Expression::Parenthesised(expression, _)) = (arguments.is_empty(), &**function) { if let MultipleExpression::Single(Expression::ArrowFunction(function)) = @@ -2062,7 +2086,7 @@ impl Expression { /// Recurses to find first non parenthesized expression #[must_use] pub fn get_non_parenthesized(&self) -> &Self { - if let Expression::ParenthesizedExpression(inner_multiple_expr, _) = self { + if let Expression::Parenthesised(inner_multiple_expr, _) = self { if let MultipleExpression::Single(expr) = &**inner_multiple_expr { expr.get_non_parenthesized() } else { @@ -2237,7 +2261,7 @@ mod tests { // Can't match 45 here assert_matches_ast!( "(45)", - ParenthesizedExpression( + Parenthesised( Deref @ MultipleExpression::Single(NumberLiteral( NumberRepresentation::Number { .. }, span!(1, 3), @@ -2257,7 +2281,7 @@ mod tests { fn multiple_expression() { assert_matches_ast!( "(45,2)", - ParenthesizedExpression( + Parenthesised( Deref @ MultipleExpression::Multiple { lhs: Deref @ MultipleExpression::Single(NumberLiteral( diff --git a/parser/src/expressions/template_literal.rs b/parser/src/expressions/template_literal.rs index b6b1ad82..4fce8e09 100644 --- a/parser/src/expressions/template_literal.rs +++ b/parser/src/expressions/template_literal.rs @@ -81,7 +81,19 @@ impl ASTNode for TemplateLiteral { local: crate::LocalToStringInformation, ) { if let Some(tag) = &self.tag { + let requires_parenthesis = !matches!( + &**tag, + Expression::VariableReference(..) + | Expression::PropertyAccess { .. } + | Expression::Parenthesised(..) + ); + if requires_parenthesis { + buf.push('('); + } tag.to_string_from_buffer(buf, options, local); + if requires_parenthesis { + buf.push(')'); + } } buf.push('`'); for (static_part, dynamic_part) in &self.parts { diff --git a/parser/src/lexer.rs b/parser/src/lexer.rs index cef5fd57..bca1c9b7 100644 --- a/parser/src/lexer.rs +++ b/parser/src/lexer.rs @@ -697,30 +697,22 @@ impl<'a> Lexer<'a> { {} chr => { let num_slice = ¤t[..idx]; - let number = crate::number::NumberRepresentation::from_str(num_slice); - let number = number.unwrap(); - let length = idx as u32; - self.head += length; - return Ok((number, length)); - // if is_number_delimiter(chr) { - // // Note not = as don't want to include chr - - // if num_slice.trim_end() == "." - // || num_slice.ends_with(['x', 'X', 'o', 'O', '_', '-']) - // || (!matches!(state, NumberLiteralType::HexadecimalLiteral) - // && num_slice.ends_with(['e', 'E', 'b', 'B'])) - // { - // // (LexingErrors::UnexpectedEndToNumberLiteral) - // return Err(()) - // } - // } else { - // // (LexingErrors::UnexpectedEndToNumberLiteral) - // return Err(()) - // } + return match crate::number::NumberRepresentation::from_str(num_slice) { + Ok(number) => { + let length = idx as u32; + self.head += length; + Ok((number, length)) + } + Err(_) => Err(ParseError::new( + ParseErrors::InvalidNumber, + self.get_start().with_length(idx), + )), + }; } } } + // Fix if don't find end let number = crate::number::NumberRepresentation::from_str(current).expect("bad number"); let length = current.len() as u32; self.head += length; @@ -785,10 +777,14 @@ impl<'a> Lexer<'a> { .unwrap_or(current.len()); let regex_flags = ¤t[regex_end..first_non_char]; - - let invalid_flag = regex_flags.chars().any(|chr| !matches!(chr, 'd' | 'g' | 'i' | 'm' | 's' | 'u' | 'y')); + + let invalid_flag = + regex_flags.chars().any(|chr| !matches!(chr, 'd' | 'g' | 'i' | 'm' | 's' | 'u' | 'y')); if invalid_flag { - Err(ParseError::new(ParseErrors::InvalidRegexFlag, self.get_start().with_length(regex_flags.len()))) + Err(ParseError::new( + ParseErrors::InvalidRegexFlag, + self.get_start().with_length(regex_flags.len()), + )) } else { self.head += regex_flags.len() as u32; Ok((regex, regex_flags))