diff --git a/.changeset/famous-ants-heal.md b/.changeset/famous-ants-heal.md new file mode 100644 index 0000000000..19408d9633 --- /dev/null +++ b/.changeset/famous-ants-heal.md @@ -0,0 +1,5 @@ +--- +"@nomicfoundation/slang": patch +--- + +parse line breaks without newlines diff --git a/crates/solidity/inputs/language/src/definition.rs b/crates/solidity/inputs/language/src/definition.rs index e0320df567..6f4a24bcb9 100644 --- a/crates/solidity/inputs/language/src/definition.rs +++ b/crates/solidity/inputs/language/src/definition.rs @@ -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, diff --git a/crates/solidity/outputs/cargo/slang_solidity/src/generated/language.rs b/crates/solidity/outputs/cargo/slang_solidity/src/generated/language.rs index a115a3726d..929757bf94 100644 --- a/crates/solidity/outputs/cargo/slang_solidity/src/generated/language.rs +++ b/crates/solidity/outputs/cargo/slang_solidity/src/generated/language.rs @@ -6985,9 +6985,13 @@ impl Language { #[allow(unused_assignments, unused_parens)] fn end_of_line(&self, input: &mut ParserContext<'_>) -> bool { - scan_sequence!( - scan_optional!(input, scan_chars!(input, '\r')), - scan_chars!(input, '\n') + scan_choice!( + input, + scan_chars!(input, '\n'), + scan_sequence!( + scan_chars!(input, '\r'), + scan_optional!(input, scan_chars!(input, '\n')) + ) ) } diff --git a/crates/solidity/outputs/cargo/tests/src/cst_output/generated/SourceUnit.rs b/crates/solidity/outputs/cargo/tests/src/cst_output/generated/SourceUnit.rs index 3e18c332d0..9f81ac60a2 100644 --- a/crates/solidity/outputs/cargo/tests/src/cst_output/generated/SourceUnit.rs +++ b/crates/solidity/outputs/cargo/tests/src/cst_output/generated/SourceUnit.rs @@ -59,6 +59,16 @@ fn everything() -> Result<()> { run("SourceUnit", "everything") } +#[test] +fn line_break_new_line() -> Result<()> { + run("SourceUnit", "line_break_new_line") +} + +#[test] +fn line_break_only() -> Result<()> { + run("SourceUnit", "line_break_only") +} + #[test] fn partial_definition() -> Result<()> { run("SourceUnit", "partial_definition") diff --git a/crates/solidity/outputs/spec/generated/grammar.ebnf b/crates/solidity/outputs/spec/generated/grammar.ebnf index 0ae6a187d5..fd025ce4d0 100644 --- a/crates/solidity/outputs/spec/generated/grammar.ebnf +++ b/crates/solidity/outputs/spec/generated/grammar.ebnf @@ -154,7 +154,7 @@ UsingTarget = TypeName WHITESPACE = (" " | "\t")+; -END_OF_LINE = "\r"? "\n"; +END_OF_LINE = "\n" | ("\r" "\n"?); SINGLE_LINE_COMMENT = "//" (!("\r" "\n"))*; diff --git a/crates/solidity/outputs/spec/generated/public/01-file-structure/06-trivia.md b/crates/solidity/outputs/spec/generated/public/01-file-structure/06-trivia.md index 3c1d2df6b8..97560ccfd8 100644 --- a/crates/solidity/outputs/spec/generated/public/01-file-structure/06-trivia.md +++ b/crates/solidity/outputs/spec/generated/public/01-file-structure/06-trivia.md @@ -14,7 +14,7 @@ ``` -
END_OF_LINE = "\r"? "\n";
+
END_OF_LINE = "\n" | ("\r" "\n"?);
```{ .ebnf #SingleLineComment } diff --git a/crates/solidity/testing/snapshots/cst_output/SourceUnit/line_break_new_line/generated/0.4.11-success.yml b/crates/solidity/testing/snapshots/cst_output/SourceUnit/line_break_new_line/generated/0.4.11-success.yml new file mode 100644 index 0000000000..7369b4b674 --- /dev/null +++ b/crates/solidity/testing/snapshots/cst_output/SourceUnit/line_break_new_line/generated/0.4.11-success.yml @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Source: > + 1 │ // foo │ 0..6 + 2 │ // bar │ 7..13 + +Errors: [] + +Tree: + - (SourceUnit) ► (LeadingTrivia): # "// foo\r\n// bar" (0..14) + - (SingleLineComment): "// foo" # (0..6) + - (EndOfLine): "\r\n" # (6..8) + - (SingleLineComment): "// bar" # (8..14) diff --git a/crates/solidity/testing/snapshots/cst_output/SourceUnit/line_break_new_line/input.sol b/crates/solidity/testing/snapshots/cst_output/SourceUnit/line_break_new_line/input.sol new file mode 100644 index 0000000000..7a9076cdf1 --- /dev/null +++ b/crates/solidity/testing/snapshots/cst_output/SourceUnit/line_break_new_line/input.sol @@ -0,0 +1,2 @@ +// foo +// bar \ No newline at end of file diff --git a/crates/solidity/testing/snapshots/cst_output/SourceUnit/line_break_only/generated/0.4.11-success.yml b/crates/solidity/testing/snapshots/cst_output/SourceUnit/line_break_only/generated/0.4.11-success.yml new file mode 100644 index 0000000000..9e4170eee0 --- /dev/null +++ b/crates/solidity/testing/snapshots/cst_output/SourceUnit/line_break_only/generated/0.4.11-success.yml @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Source: > + 1 │ // foo │ 0..6 + 2 │ // bar │ 7..13 + +Errors: [] + +Tree: + - (SourceUnit) ► (LeadingTrivia): # "// foo\r// bar" (0..13) + - (SingleLineComment): "// foo" # (0..6) + - (EndOfLine): "\r" # (6..7) + - (SingleLineComment): "// bar" # (7..13) diff --git a/crates/solidity/testing/snapshots/cst_output/SourceUnit/line_break_only/input.sol b/crates/solidity/testing/snapshots/cst_output/SourceUnit/line_break_only/input.sol new file mode 100644 index 0000000000..373f32f8a2 --- /dev/null +++ b/crates/solidity/testing/snapshots/cst_output/SourceUnit/line_break_only/input.sol @@ -0,0 +1 @@ +// foo // bar \ No newline at end of file diff --git a/crates/solidity/testing/utils/src/cst_snapshots/mod.rs b/crates/solidity/testing/utils/src/cst_snapshots/mod.rs index 2feb2ff10d..8cd92301c4 100644 --- a/crates/solidity/testing/utils/src/cst_snapshots/mod.rs +++ b/crates/solidity/testing/utils/src/cst_snapshots/mod.rs @@ -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()