@@ -10,6 +10,8 @@ pub struct Lexer<'a> {
10
10
start : Vec < u32 > ,
11
11
error : Vec < LexError > ,
12
12
offset : usize ,
13
+ /// we store line ending counts outside of SyntaxKind because of the u16 represenation of SyntaxKind
14
+ line_ending_counts : Vec < usize > ,
13
15
}
14
16
15
17
impl < ' a > Lexer < ' a > {
@@ -21,6 +23,7 @@ impl<'a> Lexer<'a> {
21
23
start : Vec :: new ( ) ,
22
24
error : Vec :: new ( ) ,
23
25
offset : 0 ,
26
+ line_ending_counts : Vec :: new ( ) ,
24
27
}
25
28
}
26
29
@@ -32,21 +35,35 @@ impl<'a> Lexer<'a> {
32
35
}
33
36
34
37
// Add EOF token
35
- self . push ( SyntaxKind :: EOF , 0 , None ) ;
38
+ self . push ( SyntaxKind :: EOF , 0 , None , None ) ;
36
39
37
40
Lexed {
38
41
text : self . text ,
39
42
kind : self . kind ,
40
43
start : self . start ,
41
44
error : self . error ,
45
+ line_ending_counts : self . line_ending_counts ,
42
46
}
43
47
}
44
48
45
- fn push ( & mut self , kind : SyntaxKind , len : usize , err : Option < & str > ) {
49
+ fn push (
50
+ & mut self ,
51
+ kind : SyntaxKind ,
52
+ len : usize ,
53
+ err : Option < & str > ,
54
+ line_ending_count : Option < usize > ,
55
+ ) {
46
56
self . kind . push ( kind) ;
47
57
self . start . push ( self . offset as u32 ) ;
48
58
self . offset += len;
49
59
60
+ assert ! (
61
+ kind != SyntaxKind :: LINE_ENDING || line_ending_count. is_some( ) ,
62
+ "Line ending token must have a line ending count"
63
+ ) ;
64
+
65
+ self . line_ending_counts . push ( line_ending_count. unwrap_or ( 0 ) ) ;
66
+
50
67
if let Some ( err) = err {
51
68
let token = ( self . kind . len ( ) - 1 ) as u32 ;
52
69
let msg = err. to_owned ( ) ;
@@ -56,6 +73,7 @@ impl<'a> Lexer<'a> {
56
73
57
74
fn extend_token ( & mut self , kind : & pgt_tokenizer:: TokenKind , token_text : & str ) {
58
75
let mut err = "" ;
76
+ let mut line_ending_count = None ;
59
77
60
78
let syntax_kind = {
61
79
match kind {
@@ -68,8 +86,10 @@ impl<'a> Lexer<'a> {
68
86
}
69
87
pgt_tokenizer:: TokenKind :: Space => SyntaxKind :: SPACE ,
70
88
pgt_tokenizer:: TokenKind :: Tab => SyntaxKind :: TAB ,
71
- pgt_tokenizer:: TokenKind :: Newline => SyntaxKind :: NEWLINE ,
72
- pgt_tokenizer:: TokenKind :: CarriageReturn => SyntaxKind :: CARRIAGE_RETURN ,
89
+ pgt_tokenizer:: TokenKind :: LineEnding { count } => {
90
+ line_ending_count = Some ( * count) ;
91
+ SyntaxKind :: LINE_ENDING
92
+ }
73
93
pgt_tokenizer:: TokenKind :: VerticalTab => SyntaxKind :: VERTICAL_TAB ,
74
94
pgt_tokenizer:: TokenKind :: FormFeed => SyntaxKind :: FORM_FEED ,
75
95
pgt_tokenizer:: TokenKind :: Ident => {
@@ -121,7 +141,7 @@ impl<'a> Lexer<'a> {
121
141
} ;
122
142
123
143
let err = if err. is_empty ( ) { None } else { Some ( err) } ;
124
- self . push ( syntax_kind, token_text. len ( ) , err) ;
144
+ self . push ( syntax_kind, token_text. len ( ) , err, line_ending_count ) ;
125
145
}
126
146
127
147
fn extend_literal ( & mut self , len : usize , kind : & pgt_tokenizer:: LiteralKind ) {
@@ -182,6 +202,6 @@ impl<'a> Lexer<'a> {
182
202
} ;
183
203
184
204
let err = if err. is_empty ( ) { None } else { Some ( err) } ;
185
- self . push ( syntax_kind, len, err) ;
205
+ self . push ( syntax_kind, len, err, None ) ;
186
206
}
187
207
}
0 commit comments