Skip to content

Commit

Permalink
Add new simple operators &&= ||= ?? ??=
Browse files Browse the repository at this point in the history
  • Loading branch information
FreeMasen committed Feb 19, 2024
1 parent cc54e10 commit a1f1dfc
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 38 deletions.
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ edition = "2021"
[dependencies]
hash-chain = "0.3"
log = "0.4"
ress = "0.11"
resast = "0.6.0-alpha.5"
# ress = "0.11"
# resast = "0.6.0-alpha.5"
ress = { path = "../ress" }
resast = { path = "../resast" }
res-regex = "0.1"
tracing = "0.1"

Expand Down
36 changes: 24 additions & 12 deletions src/spanned/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -712,11 +712,9 @@ where
fn parse_import_default_specifier(&mut self) -> Res<DefaultImportSpec<Cow<'b, str>>> {
let start = self.look_ahead_position;
let id = self.parse_ident_name()?;
self.context.lexical_names.declare(
id.slice.source.clone(),
DeclKind::Lex(true),
start,
)?;
self.context
.lexical_names
.declare(id.slice.source.clone(), DeclKind::Lex(true), start)?;
Ok(DefaultImportSpec { id })
}

Expand Down Expand Up @@ -4795,7 +4793,6 @@ where
};
elements.push(ele);
}

}
}
let close_bracket = self.expect_punct(Punct::CloseBracket)?;
Expand Down Expand Up @@ -5070,7 +5067,7 @@ where
&item,
&[
"=", "+=", "-=", "/=", "*=", "**=", "|=", "&=", "~=", "%=", "<<=",
">>=", ">>>=",
">>=", ">>>=", "&&=", "||=", "??=",
],
);
}
Expand All @@ -5080,7 +5077,7 @@ where
&item,
&[
"=", "+=", "-=", "/=", "*=", "**=", "|=", "&=", "~=", "%=", "<<=", ">>=",
">>>=",
">>>=", "&&=", "||=", "??=",
],
);
}
Expand Down Expand Up @@ -5120,6 +5117,9 @@ where
Punct::CaretEqual => Some(AssignOp::XOrEqual(slice.into())),
Punct::AmpersandEqual => Some(AssignOp::AndEqual(slice.into())),
Punct::DoubleAsteriskEqual => Some(AssignOp::PowerOfEqual(slice.into())),
Punct::DoubleAmpersandEqual => Some(AssignOp::DoubleAmpersandEqual(slice.into())),
Punct::DoublePipeEqual => Some(AssignOp::DoublePipeEqual(slice.into())),
Punct::DoubleQuestionMarkEqual => Some(AssignOp::DoubleQuestionmarkEqual(slice.into())),
_ => None,
}
}
Expand Down Expand Up @@ -5658,6 +5658,7 @@ where
log::debug!("left: {:#?} {}", left, self.context.allow_yield);
if op.token.matches_punct(Punct::DoubleAmpersand)
|| op.token.matches_punct(Punct::DoublePipe)
|| op.token.matches_punct(Punct::DoubleQuestionMark)
{
stack.push(Expr::Logical(LogicalExpr {
operator: self.logical_operator(&op).ok_or_else(|| {
Expand Down Expand Up @@ -5692,6 +5693,7 @@ where
.ok_or_else(|| self.op_error("invalid binary operation, too few operators"))?;
if op.token.matches_punct(Punct::DoubleAmpersand)
|| op.token.matches_punct(Punct::DoublePipe)
|| op.token.matches_punct(Punct::DoubleQuestionMark)
{
let operator = self
.logical_operator(&op)
Expand Down Expand Up @@ -5855,6 +5857,7 @@ where
Token::Punct(ref p) => match p {
Punct::DoubleAmpersand => Some(LogicalOp::And(slice.into())),
Punct::DoublePipe => Some(LogicalOp::Or(slice.into())),
Punct::DoubleQuestionMark => Some(LogicalOp::NullishCoalescing(slice.into())),
_ => None,
},
_ => None,
Expand Down Expand Up @@ -6372,7 +6375,7 @@ where
| Punct::Comma
| Punct::Equal
| Punct::CloseBracket => 0,
Punct::DoublePipe => 1,
Punct::DoublePipe | Punct::DoubleQuestionMark => 1,
Punct::DoubleAmpersand => 2,
Punct::Pipe => 3,
Punct::Caret => 4,
Expand Down Expand Up @@ -6668,6 +6671,15 @@ where
|| self.look_ahead.token.matches_punct(Punct::PipeEqual)
|| self.look_ahead.token.matches_punct(Punct::CaretEqual)
|| self.look_ahead.token.matches_punct(Punct::AmpersandEqual)
|| self
.look_ahead
.token
.matches_punct(Punct::DoubleAmpersandEqual)
|| self.look_ahead.token.matches_punct(Punct::DoublePipeEqual)
|| self
.look_ahead
.token
.matches_punct(Punct::DoubleQuestionMarkEqual)
}
/// The keyword `async` is conditional, that means to decided
/// if we are actually at an async function we need to check the
Expand Down Expand Up @@ -6763,8 +6775,8 @@ where
let slice = self.scanner.str_for(&item.span).unwrap();
let contents = match &item.token {
Token::String(lit) => match lit {
ress::tokens::StringLit::Double(inner) => inner.content.clone(),
ress::tokens::StringLit::Single(inner) => inner.content.clone(),
ress::tokens::StringLit::Double(inner) => inner.content,
ress::tokens::StringLit::Single(inner) => inner.content,
},
_ => {
return Err(Error::UnexpectedToken(
Expand Down Expand Up @@ -6821,7 +6833,7 @@ where
// regex will be on 1 line if `validate` is successful
let line = item.location.start.line;
let Token::RegEx(token) = &item.token else {
return self.expected_token_error(item, &["<regex literal>"])
return self.expected_token_error(item, &["<regex literal>"]);
};
let open_slash_pos = Position {
line: line as u32,
Expand Down
69 changes: 45 additions & 24 deletions tests/snippets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1283,8 +1283,8 @@ fn setter_scope() {
fn array_pattern_with_empty_entry() {
use resast::spanned::{
decl::{Decl, VarDecl, VarDecls},
pat::{ArrayPat, ArrayPatPart, Pat},
expr::Expr,
pat::{ArrayPat, ArrayPatPart, Pat},
Ident, ListEntry, Program, ProgramPart, Slice, SourceLocation, VarKind,
};
let js = "let [x,,] = y";
Expand All @@ -1298,35 +1298,36 @@ fn array_pattern_with_empty_entry() {
item: VarDecl {
id: Pat::Array(ArrayPat {
open_bracket: Position::new(1, 5).into(),
elements: vec![ListEntry {
item: Some(ArrayPatPart::Pat(Pat::Ident(Ident {
slice: Slice {
source: Cow::Borrowed("x").into(),
loc: SourceLocation {
start: Position::new(1, 6),
end: Position::new(1, 7)
elements: vec![
ListEntry {
item: Some(ArrayPatPart::Pat(Pat::Ident(Ident {
slice: Slice {
source: Cow::Borrowed("x").into(),
loc: SourceLocation {
start: Position::new(1, 6),
end: Position::new(1, 7)
}
}
}
}))),
comma: Some(Position::new(1, 7).into()),
}, ListEntry {
item: None,
comma: Some(Position::new(1, 8).into()),
}],
}))),
comma: Some(Position::new(1, 7).into()),
},
ListEntry {
item: None,
comma: Some(Position::new(1, 8).into()),
}
],
close_bracket: Position::new(1, 9).into()
}),
eq: Some(Position::new(1, 11).into()),
init: Some(Expr::Ident(
Ident {
slice: Slice {
source: Cow::Borrowed("y").into(),
loc: SourceLocation {
start: Position::new(1, 13),
end: Position::new(1, 14)
}
init: Some(Expr::Ident(Ident {
slice: Slice {
source: Cow::Borrowed("y").into(),
loc: SourceLocation {
start: Position::new(1, 13),
end: Position::new(1, 14)
}
}
)),
})),
},
comma: None
}]
Expand Down Expand Up @@ -1382,6 +1383,26 @@ fn call_args() {
run_spanned_test("call(/.+/, '')", false).unwrap();
}

#[test]
fn and_and_equal() {
run_spanned_test("x &&= false", false).unwrap();
}

#[test]
fn or_or_equal() {
run_spanned_test("x ||= false", false).unwrap();
}

#[test]
fn q_q_equal() {
run_spanned_test("x ??= false", false).unwrap();
}

#[test]
fn nullish_coalesce() {
run_spanned_test("b ?? false", false).unwrap();
}

fn run_test(js: &str, as_mod: bool) -> Result<(), ressa::Error> {
let p = generate_program(js, as_mod);
log::debug!("{:#?}", p);
Expand Down

0 comments on commit a1f1dfc

Please sign in to comment.