Skip to content

Commit

Permalink
parse line breaks without newlines (#854)
Browse files Browse the repository at this point in the history
  • Loading branch information
OmarTawfik authored Feb 28, 2024
1 parent 0c54cc3 commit 4b8970b
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/famous-ants-heal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nomicfoundation/slang": patch
---

parse line breaks without newlines
3 changes: 2 additions & 1 deletion crates/solidity/inputs/language/src/definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,8 @@ codegen_language_macros::compile!(Language(
),
Trivia(
name = EndOfLine,
scanner = Sequence([Optional(Atom("\r")), Atom("\n")])
scanner =
Choice([Atom("\n"), Sequence([Atom("\r"), Optional(Atom("\n"))])])
),
Trivia(
name = SingleLineComment,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/solidity/outputs/cargo/tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

mod cst_output;
mod doc_examples;
mod trivia;
47 changes: 47 additions & 0 deletions crates/solidity/outputs/cargo/tests/src/trivia.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use anyhow::Result;
use semver::Version;
use slang_solidity::cst::Node;
use slang_solidity::kinds::{RuleKind, TokenKind};
use slang_solidity::language::Language;

#[test]
fn end_of_line() -> Result<()> {
// Only one is valid as a single token:
compare_end_of_lines("\r", &["\r"])?;
compare_end_of_lines("\n", &["\n"])?;

// Two of the same are two tokens:
compare_end_of_lines("\n\n", &["\n", "\n"])?;
compare_end_of_lines("\r\r", &["\r", "\r"])?;

// A carriage return followed by a newline is one token, but the opposite is not:
compare_end_of_lines("\r\n", &["\r\n"])?;
compare_end_of_lines("\n\r", &["\n", "\r"])?;

Ok(())
}

fn compare_end_of_lines(input: &str, expected: &[&str]) -> Result<()> {
let version = Version::parse("0.8.0")?;
let language = &Language::new(version)?;

let output = language.parse(RuleKind::SourceUnit, input);
assert!(output.is_valid());

let actual = output
.create_tree_cursor()
.filter_map(|node| match node {
Node::Rule(_) => None,

Node::Token(token) => {
assert_eq!(token.kind, TokenKind::EndOfLine);
Some(token.text.to_owned())
}
})
.collect::<Vec<_>>();

let expected = expected.to_vec();
assert_eq!(actual, expected);

Ok(())
}
2 changes: 1 addition & 1 deletion crates/solidity/outputs/spec/generated/grammar.ebnf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crates/solidity/testing/utils/src/cst_snapshots/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ fn write_source(w: &mut String, source: &str) -> Result<()> {
return Ok(());
}

// "lines()" only handles "\n", so let's normalize all line endings:
let source = source.replace("\r\n", "\n").replace('\r', "\n");

let line_data = source
.lines()
.enumerate()
Expand Down

0 comments on commit 4b8970b

Please sign in to comment.