Skip to content

Commit

Permalink
fix(tokenizer): enter ident mode when appropriate
Browse files Browse the repository at this point in the history
There was a bug brought up in #54
where the tokenizer incorrectly enters identifier mode after seeing a `when/given`.

This means that `bulloak` failed to scaffold the following:

```tree
Foo
└── It reverts when X.
```

Because it saw a `.` after `when`, even though this is a perfectly valid
tree.

We fix this by checking that `when/given` only make the tokenizer enter
identifier mode if the last processed token was a branching token
(either `Corner` or `Tee` currently).
  • Loading branch information
alexfertel committed Jan 21, 2024
1 parent 8231904 commit 488fb63
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
21 changes: 21 additions & 0 deletions src/syntax/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,27 @@ mod tests {
);
}

// https://github.com/alexfertel/bulloak/issues/54
#[test]
fn parses_top_level_actions() {
assert_eq!(
parse(
r#"Foo
└── It reverts when X."#
)
.unwrap(),
Ast::Root(Root {
contract_name: String::from("Foo"),
span: s(p(0, 1, 1), p(31, 2, 22)),
children: vec![Ast::Action(Action {
title: String::from("It reverts when X."),
span: s(p(4, 2, 1), p(31, 2, 22)),
children: vec![]
})],
})
);
}

#[test]
fn unsanitized_input() {
assert_eq!(
Expand Down
14 changes: 13 additions & 1 deletion src/syntax/tokenizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ pub struct Token {
pub lexeme: String,
}

impl Token {
fn is_branch(&self) -> bool {
match self.kind {
TokenKind::Tee | TokenKind::Corner => true,
TokenKind::Word | TokenKind::When | TokenKind::Given | TokenKind::It => false,
}
}
}

impl fmt::Debug for Token {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
Expand Down Expand Up @@ -329,7 +338,10 @@ impl<'s, T: Borrow<Tokenizer>> TokenizerI<'s, T> {
}
_ => {
let token = self.scan_word()?;
if token.kind == TokenKind::When || token.kind == TokenKind::Given {
let last_is_branch = tokens.last().is_some_and(Token::is_branch);
if last_is_branch
&& (token.kind == TokenKind::When || token.kind == TokenKind::Given)
{
self.enter_identifier_mode();
};
tokens.push(token);
Expand Down

0 comments on commit 488fb63

Please sign in to comment.