Skip to content

Commit

Permalink
Merge pull request #101 from Fee0/optional-puncts
Browse files Browse the repository at this point in the history
Disambiguate optional chaining operator from ternary operator
  • Loading branch information
FreeMasen authored Apr 27, 2024
2 parents ea32cf0 + 1f65b9b commit ec107a2
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/tokenizer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,13 @@ impl<'a> Tokenizer<'a> {
self.gen_punct(Punct::DoubleQuestionMark)
} else if self.look_ahead_byte_matches('.') {
self.stream.skip_bytes(1);
self.gen_punct(Punct::QuestionMarkDot)
if self.stream.at_decimal() {
// floating point numbers can be defined with a leading period: ".123"
self.stream.skip_back(1);
self.gen_punct(Punct::QuestionMark)
} else {
self.gen_punct(Punct::QuestionMarkDot)
}
} else {
self.gen_punct(Punct::QuestionMark)
}
Expand Down
124 changes: 124 additions & 0 deletions tests/snippets/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use ress::prelude::StringLit::Single;
use ress::prelude::*;
use ress::tokens::InnerString;

#[test]
fn vue_number_error() {
Expand Down Expand Up @@ -336,6 +338,128 @@ fn regex_spaces() {
}
}

#[test]
fn nullish_coalescing_assignment() {
let js = r"a??=b";
compare(
js,
&[
Token::Ident(Ident::from("a")),
Token::Punct(Punct::DoubleQuestionMarkEqual),
Token::Ident(Ident::from("b")),
Token::EoF,
],
)
}

#[test]
fn logical_or_assignment() {
let js = r"a||=b";
compare(
js,
&[
Token::Ident(Ident::from("a")),
Token::Punct(Punct::DoublePipeEqual),
Token::Ident(Ident::from("b")),
Token::EoF,
],
)
}

#[test]
fn logical_and_assignment() {
let js = r"a&&=b";
compare(
js,
&[
Token::Ident(Ident::from("a")),
Token::Punct(Punct::DoubleAmpersandEqual),
Token::Ident(Ident::from("b")),
Token::EoF,
],
)
}

#[test]
fn nullish_coalescing() {
let js = r#"a??b"#;
compare(
js,
&[
Token::Ident(Ident::from("a")),
Token::Punct(Punct::DoubleQuestionMark),
Token::Ident(Ident::from("b")),
Token::EoF,
],
)
}

#[test]
fn optional_chaining1() {
let js = r#"a?.b"#;
compare(
js,
&[
Token::Ident(Ident::from("a")),
Token::Punct(Punct::QuestionMarkDot),
Token::Ident(Ident::from("b")),
Token::EoF,
],
)
}

#[test]
fn optional_chaining2() {
let js = r#"a?.()"#;
compare(
js,
&[
Token::Ident(Ident::from("a")),
Token::Punct(Punct::QuestionMarkDot),
Token::Punct(Punct::OpenParen),
Token::Punct(Punct::CloseParen),
Token::EoF,
],
)
}

#[test]
fn optional_chaining3() {
let js = r#"a?.['b']"#;
compare(
js,
&[
Token::Ident(Ident::from("a")),
Token::Punct(Punct::QuestionMarkDot),
Token::Punct(Punct::OpenBracket),
Token::String(Single(InnerString {
content: "b",
contains_octal_escape: false,
})),
Token::Punct(Punct::CloseBracket),
Token::EoF,
],
)
}

#[test]
fn optional_chaining4() {
let js = r#"a==b?.123:.321"#;
compare(
js,
&[
Token::Ident(Ident::from("a")),
Token::Punct(Punct::DoubleEqual),
Token::Ident(Ident::from("b")),
Token::Punct(Punct::QuestionMark),
Token::Number(Number::from(".123")),
Token::Punct(Punct::Colon),
Token::Number(Number::from(".321")),
Token::EoF,
],
)
}

#[test]
fn regex_out_of_order() {
pretty_env_logger::try_init().ok();
Expand Down

0 comments on commit ec107a2

Please sign in to comment.