Skip to content

Commit 144534f

Browse files
committed
fix: handle new lines following each other
1 parent 75819d4 commit 144534f

12 files changed

+32
-43
lines changed

parser/src/lexer/mod.rs

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub struct Lexer<'a> {
6363
peak_mode: bool,
6464

6565
/// Previous token was a Newline token
66-
prev_token_newline: bool,
66+
non_logical_line_state: bool,
6767
/// Cursor at position after the indentation in line
6868
indented: bool,
6969
}
@@ -81,7 +81,7 @@ impl<'a> Lexer<'a> {
8181
next_token_is_dedent: 0,
8282
line_starts: vec![0],
8383
peak_mode: false,
84-
prev_token_newline: true,
84+
non_logical_line_state: true,
8585
indented: false,
8686
}
8787
}
@@ -132,7 +132,9 @@ impl<'a> Lexer<'a> {
132132
return self.next_token();
133133
}
134134

135-
self.prev_token_newline = kind == Kind::NewLine;
135+
if kind != Kind::Comment && kind != Kind::NL {
136+
self.non_logical_line_state = kind == Kind::NewLine;
137+
}
136138
let value = self.parse_token_value(kind, start);
137139
let end = self.current;
138140

@@ -155,12 +157,12 @@ impl<'a> Lexer<'a> {
155157
let nesting = self.nesting;
156158
let start_of_line = self.start_of_line;
157159
let next_token_is_dedent = self.next_token_is_dedent;
158-
let prev_token_newline = self.prev_token_newline;
160+
let prev_token_newline = self.non_logical_line_state;
159161
let indented = self.indented;
160162
self.peak_mode = true;
161163
let token = self.next_token();
162164
self.indented = indented;
163-
self.prev_token_newline = prev_token_newline;
165+
self.non_logical_line_state = prev_token_newline;
164166
self.peak_mode = false;
165167
self.current = current;
166168
self.current_line = current_line;
@@ -527,7 +529,7 @@ impl<'a> Lexer<'a> {
527529
'\n' | '\r' => {
528530
self.current_line += 1;
529531
self.start_of_line = true;
530-
if self.nesting == 0 && (!self.prev_token_newline) {
532+
if self.nesting == 0 && (!self.non_logical_line_state) {
531533
return Ok(Kind::NewLine);
532534
} else {
533535
return Ok(Kind::NL);
@@ -1069,19 +1071,6 @@ impl<'a> Lexer<'a> {
10691071
}
10701072
count
10711073
}
1072-
1073-
// This function is used in test. Not sure to keep it here or not
1074-
#[allow(dead_code)]
1075-
fn to_row_col(&self, source_offset: u32) -> (u32, u32) {
1076-
println!("source_offset: {}", source_offset);
1077-
println!("line_starts: {:?}", self.line_starts);
1078-
let (line_row, line_offset) = match self.line_starts.binary_search(&source_offset) {
1079-
Ok(idx) => (idx, self.line_starts[idx]),
1080-
Err(idx) => (idx - 1, self.line_starts[idx - 1]),
1081-
};
1082-
let line_column = source_offset - line_offset;
1083-
(u32::try_from(line_row).unwrap(), line_column)
1084-
}
10851074
}
10861075

10871076
fn match_whitespace(c: char) -> bool {

parser/src/parser/parser.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ impl<'a> Parser<'a> {
168168

169169
self.prev_token_end = self.cur_token.end;
170170
self.cur_token = token;
171-
if self.cur_kind() == Kind::Comment {
171+
if matches!(self.cur_kind(), Kind::Comment | Kind::NL) {
172172
self.advance();
173173
}
174174
if self.nested_expression_list > 0 {
@@ -4047,7 +4047,7 @@ except *Exception as e:
40474047
let snapshot = format!("{program:#?}");
40484048

40494049
insta::with_settings!({
4050-
description => test_case.clone(),
4050+
description => format!("test file: {}\n{}", $test_file, test_case.clone()),
40514051
omit_expression => true,
40524052
snapshot_path => "../../test_data/output/"
40534053
}, {

parser/test_data/output/enderpy_python_parser__lexer__tests__snapshot_test_lexer@indentation-4.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ description: "if a:\n\n f = c\n\n # Path: test_local.py\n"
1414
16,17: NewLine (None)
1515
17,18: NL (None)
1616
22,43: Comment (Str("# Path: test_local.py"))
17-
43,44: NewLine (None)
17+
43,44: NL (None)
1818
44,44: Dedent (Indent(1))

parser/test_data/output/enderpy_python_parser__lexer__tests__snapshot_test_lexer_and_errors@comments.py.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ description: "# a\n# a\n\n# a\n# b\ndef a(): ... # a\n\ndef b():\n # a\n .
44
input_file: parser/test_data/inputs/comments.py
55
---
66
0,3: Comment (Str("# a"))
7-
3,4: NewLine (None)
7+
3,4: NL (None)
88
4,7: Comment (Str("# a"))
9-
7,8: NewLine (None)
9+
7,8: NL (None)
1010
8,9: NL (None)
1111
9,12: Comment (Str("# a"))
12-
12,13: NewLine (None)
12+
12,13: NL (None)
1313
13,16: Comment (Str("# b"))
14-
16,17: NewLine (None)
14+
16,17: NL (None)
1515
17,20: Def (None)
1616
21,22: Identifier (Str("a"))
1717
22,23: ( (None)

parser/test_data/output/enderpy_python_parser__lexer__tests__snapshot_test_lexer_and_errors@from_import.py.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,6 @@ input_file: parser/test_data/inputs/from_import.py
9595
244,245: Identifier (Str("b"))
9696
245,246: NewLine (None)
9797
246,289: Comment (Str("# TODO(parser): enable after error handling"))
98-
289,290: NewLine (None)
98+
289,290: NL (None)
9999
290,300: Comment (Str("# from ..."))
100-
300,301: NewLine (None)
100+
300,301: NL (None)

parser/test_data/output/enderpy_python_parser__lexer__tests__snapshot_test_lexer_and_errors@functions.py.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ input_file: parser/test_data/inputs/functions.py
6262
327,339: Identifier (Str("ticker_index"))
6363
339,340: NewLine (None)
6464
340,341: NL (None)
65-
341,342: NewLine (None)
65+
341,342: NL (None)
6666
342,342: Dedent (Indent(1))
6767
342,345: Def (None)
6868
346,379: Identifier (Str("_extract_ticker_client_types_data"))

parser/test_data/output/enderpy_python_parser__lexer__tests__snapshot_test_lexer_and_errors@if.py.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ input_file: parser/test_data/inputs/if.py
9898
250,254: Pass (None)
9999
254,255: NewLine (None)
100100
255,256: NL (None)
101-
256,257: NewLine (None)
101+
256,257: NL (None)
102102
257,257: Dedent (Indent(1))
103103
257,259: If (None)
104104
260,261: Identifier (Str("a"))

parser/test_data/output/enderpy_python_parser__lexer__tests__snapshot_test_lexer_and_errors@indentation.py.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ description: "# Unindent does not match any outer indentation level\n# if True:\
44
input_file: parser/test_data/inputs/indentation.py
55
---
66
0,53: Comment (Str("# Unindent does not match any outer indentation level"))
7-
53,54: NewLine (None)
7+
53,54: NL (None)
88
54,64: Comment (Str("# if True:"))
9-
64,65: NewLine (None)
9+
64,65: NL (None)
1010
65,79: Comment (Str("# pass"))
11-
79,80: NewLine (None)
11+
79,80: NL (None)
1212
80,90: Comment (Str("# pass"))
13-
90,91: NewLine (None)
13+
90,91: NL (None)

parser/test_data/output/enderpy_python_parser__lexer__tests__snapshot_test_lexer_and_errors@newlines.py.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ input_file: parser/test_data/inputs/newlines.py
4040
64,65: ] (None)
4141
65,66: NewLine (None)
4242
66,67: NL (None)
43-
67,68: NewLine (None)
43+
67,68: NL (None)
4444
68,71: Def (None)
4545
72,77: Identifier (Str("hello"))
4646
77,78: ( (None)
@@ -56,7 +56,7 @@ input_file: parser/test_data/inputs/newlines.py
5656
96,99: Ellipsis (None)
5757
99,100: NewLine (None)
5858
100,101: NL (None)
59-
101,102: NewLine (None)
59+
101,102: NL (None)
6060
102,107: Class (None)
6161
108,109: Identifier (Str("A"))
6262
109,110: ( (None)

parser/test_data/output/enderpy_python_parser__lexer__tests__snapshot_test_lexer_and_errors@separate_statements.py.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: "# Test case to check that we return correct error when two python
44
input_file: parser/test_data/inputs/separate_statements.py
55
---
66
0,97: Comment (Str("# Test case to check that we return correct error when two python statements are on the same line"))
7-
97,98: NewLine (None)
7+
97,98: NL (None)
88
98,99: NL (None)
99
99,102: Def (None)
1010
103,106: Identifier (Str("foo"))
@@ -38,7 +38,7 @@ input_file: parser/test_data/inputs/separate_statements.py
3838
160,203: Comment (Str("# TODO(parser): enable after error handling"))
3939
203,204: NewLine (None)
4040
208,221: Comment (Str("# x = 1 y = 2"))
41-
221,222: NewLine (None)
41+
221,222: NL (None)
4242
226,232: Return (None)
4343
233,234: Identifier (Str("x"))
4444
235,236: + (None)
@@ -49,4 +49,4 @@ input_file: parser/test_data/inputs/separate_statements.py
4949
240,283: Comment (Str("# TODO(parser): enable after error handling"))
5050
283,284: NewLine (None)
5151
284,298: Comment (Str("# a = 1 b = 2"))
52-
298,299: NewLine (None)
52+
298,299: NL (None)

0 commit comments

Comments
 (0)