@@ -95,6 +95,12 @@ export interface TokenizeOptions {
95
95
* but the new line should increment the current line for source mapping.
96
96
*/
97
97
escapedString ?: boolean ;
98
+ /**
99
+ * An array of characters that should be considered as leading trivia.
100
+ * Leading trivia are characters that are not important to the developer, and so should not be
101
+ * included in source-map segments. A common example is whitespace.
102
+ */
103
+ leadingTriviaChars ?: string [ ] ;
98
104
}
99
105
100
106
export function tokenize (
@@ -123,11 +129,11 @@ class _Tokenizer {
123
129
private _cursor : CharacterCursor ;
124
130
private _tokenizeIcu : boolean ;
125
131
private _interpolationConfig : InterpolationConfig ;
132
+ private _leadingTriviaCodePoints : number [ ] | undefined ;
126
133
private _currentTokenStart : CharacterCursor | null = null ;
127
134
private _currentTokenType : TokenType | null = null ;
128
135
private _expansionCaseStack : TokenType [ ] = [ ] ;
129
136
private _inInterpolation : boolean = false ;
130
-
131
137
tokens : Token [ ] = [ ] ;
132
138
errors : TokenError [ ] = [ ] ;
133
139
@@ -141,6 +147,8 @@ class _Tokenizer {
141
147
options : TokenizeOptions ) {
142
148
this . _tokenizeIcu = options . tokenizeExpansionForms || false ;
143
149
this . _interpolationConfig = options . interpolationConfig || DEFAULT_INTERPOLATION_CONFIG ;
150
+ this . _leadingTriviaCodePoints =
151
+ options . leadingTriviaChars && options . leadingTriviaChars . map ( c => c . codePointAt ( 0 ) || 0 ) ;
144
152
const range =
145
153
options . range || { endPos : _file . content . length , startPos : 0 , startLine : 0 , startCol : 0 } ;
146
154
this . _cursor = options . escapedString ? new EscapedCharacterCursor ( _file , range ) :
@@ -236,8 +244,9 @@ class _Tokenizer {
236
244
'Programming error - attempted to end a token which has no token type' , null ,
237
245
this . _cursor . getSpan ( this . _currentTokenStart ) ) ;
238
246
}
239
- const token =
240
- new Token ( this . _currentTokenType , parts , this . _cursor . getSpan ( this . _currentTokenStart ) ) ;
247
+ const token = new Token (
248
+ this . _currentTokenType , parts ,
249
+ this . _cursor . getSpan ( this . _currentTokenStart , this . _leadingTriviaCodePoints ) ) ;
241
250
this . tokens . push ( token ) ;
242
251
this . _currentTokenStart = null ;
243
252
this . _currentTokenType = null ;
@@ -772,7 +781,7 @@ interface CharacterCursor {
772
781
/** Advance the cursor by one parsed character. */
773
782
advance ( ) : void ;
774
783
/** Get a span from the marked start point to the current point. */
775
- getSpan ( start ?: this) : ParseSourceSpan ;
784
+ getSpan ( start ?: this, leadingTriviaCodePoints ?: number [ ] ) : ParseSourceSpan ;
776
785
/** Get the parsed characters from the marked start point to the current point. */
777
786
getChars ( start : this) : string ;
778
787
/** The number of characters left before the end of the cursor. */
@@ -831,8 +840,14 @@ class PlainCharacterCursor implements CharacterCursor {
831
840
832
841
init ( ) : void { this . updatePeek ( this . state ) ; }
833
842
834
- getSpan ( start ?: this) : ParseSourceSpan {
843
+ getSpan ( start ?: this, leadingTriviaCodePoints ?: number [ ] ) : ParseSourceSpan {
835
844
start = start || this ;
845
+ if ( leadingTriviaCodePoints ) {
846
+ start = start . clone ( ) as this;
847
+ while ( this . diff ( start ) > 0 && leadingTriviaCodePoints . indexOf ( start . peek ( ) ) !== - 1 ) {
848
+ start . advance ( ) ;
849
+ }
850
+ }
836
851
return new ParseSourceSpan (
837
852
new ParseLocation ( start . file , start . state . offset , start . state . line , start . state . column ) ,
838
853
new ParseLocation ( this . file , this . state . offset , this . state . line , this . state . column ) ) ;
0 commit comments