@@ -177,8 +177,9 @@ class MustachioParser {
177
177
_index += 2 ;
178
178
179
179
var key = template.substring (startIndex, endIndex);
180
- return _TagParseResult .ok (
181
- Partial (key, span: _sourceFile.span (tagStartIndex, _index)));
180
+ var keySpan = _sourceFile.span (startIndex, endIndex);
181
+ return _TagParseResult .ok (Partial (key,
182
+ span: _sourceFile.span (tagStartIndex, _index), keySpan: keySpan));
182
183
}
183
184
184
185
/// Tries to parse a section tag at [_index] .
@@ -208,20 +209,30 @@ class MustachioParser {
208
209
// inside the section, are the children of the [three] section. The
209
210
// [three] section is the singular child node of the [two] section, and
210
211
// the [two] section is the singular child of the [one] section.
211
- var section =
212
- Section ([parsedKey.names.last], children, invert: invert, span: span);
213
- for (var sectionKey in parsedKey.names.reversed.skip (1 )) {
212
+ var lastName = parsedKey.names.last;
213
+ var keySpanEndOffset = parsedKey.span.end.offset;
214
+ var lastNameSpan = _sourceFile.span (
215
+ keySpanEndOffset - lastName.length, keySpanEndOffset);
216
+ var section = Section ([lastName], children,
217
+ invert: invert, span: span, keySpan: lastNameSpan);
218
+ //for (var sectionKey in parsedKey.names.reversed.skip(1)) {
219
+ for (var i = parsedKey.names.length - 2 ; i >= 0 ; i-- ) {
220
+ var sectionKey = parsedKey.names[i];
221
+ // To find the start offset of the ith name, take the length of all of
222
+ // the names 0 through `i - 1` re-joined with '.', and a final '.' at
223
+ // the end.
224
+ var sectionKeyStartOffset = parsedKey.span.start.offset +
225
+ (i == 0 ? 0 : parsedKey.names.take (i).join ('.' ).length + 1 );
226
+ var keySpan = _sourceFile.span (
227
+ sectionKeyStartOffset, sectionKeyStartOffset + sectionKey.length);
214
228
section = Section ([sectionKey], [section],
215
- invert: false ,
216
- // TODO(srawlins): It may not make sense to use [span] here; we
217
- // might want to do the work to find the span of [sectionKey].
218
- span: span);
229
+ invert: false , span: span, keySpan: keySpan);
219
230
}
220
231
return _TagParseResult .ok (section);
221
232
}
222
233
223
- return _TagParseResult .ok (
224
- Section (parsedKey.names, children, invert: invert, span: span));
234
+ return _TagParseResult .ok (Section (parsedKey.names, children,
235
+ invert: invert, span: span, keySpan : parsedKey. span));
225
236
}
226
237
227
238
/// Tries to parse an end tag at [_index] .
@@ -257,8 +268,9 @@ class MustachioParser {
257
268
return _TagParseResult .endOfFile;
258
269
}
259
270
271
+ var span = _sourceFile.span (tagStartIndex, _index);
260
272
return _TagParseResult .ok (Variable (parsedKey.names,
261
- escape: escape, span: _sourceFile. span (tagStartIndex, _index) ));
273
+ escape: escape, span: span, keySpan : parsedKey.span ));
262
274
}
263
275
264
276
/// Tries to parse a key at [_index] .
@@ -289,6 +301,7 @@ class MustachioParser {
289
301
}
290
302
291
303
var key = template.substring (startIndex, _index);
304
+ var span = _sourceFile.span (startIndex, _index);
292
305
293
306
if (key.length > 1 &&
294
307
(key.codeUnitAt (0 ) == $dot || key.codeUnitAt (key.length - 1 ) == $dot)) {
@@ -306,7 +319,7 @@ class MustachioParser {
306
319
if (escape) {
307
320
if (char0 == $rbrace && char1 == $rbrace) {
308
321
_index += 2 ;
309
- return _KeyParseResult (_KeyParseResultType .parsedKey, key);
322
+ return _KeyParseResult (_KeyParseResultType .parsedKey, key, span : span );
310
323
} else {
311
324
return _KeyParseResult .notKey;
312
325
}
@@ -318,7 +331,7 @@ class MustachioParser {
318
331
var char2 = _nextNextChar;
319
332
if (char0 == $rbrace && char1 == $rbrace && char2 == $rbrace) {
320
333
_index += 3 ;
321
- return _KeyParseResult (_KeyParseResultType .parsedKey, key);
334
+ return _KeyParseResult (_KeyParseResultType .parsedKey, key, span : span );
322
335
} else {
323
336
return _KeyParseResult .notKey;
324
337
}
@@ -391,7 +404,10 @@ class Variable implements MustachioNode {
391
404
@override
392
405
final SourceSpan span;
393
406
394
- Variable (this .key, {@required this .escape, @required this .span});
407
+ final SourceSpan keySpan;
408
+
409
+ Variable (this .key,
410
+ {@required this .escape, @required this .span, @required this .keySpan});
395
411
396
412
@override
397
413
String toString () => 'Variable[$key , escape=$escape ]' ;
@@ -410,8 +426,10 @@ class Section implements MustachioNode {
410
426
@override
411
427
final SourceSpan span;
412
428
429
+ final SourceSpan keySpan;
430
+
413
431
Section (this .key, this .children,
414
- {@required this .invert, @required this .span});
432
+ {@required this .invert, @required this .span, @required this .keySpan });
415
433
416
434
@override
417
435
String toString () => 'Section[$key , invert=$invert ]' ;
@@ -425,7 +443,9 @@ class Partial implements MustachioNode {
425
443
@override
426
444
final SourceSpan span;
427
445
428
- Partial (this .key, {@required this .span});
446
+ final SourceSpan keySpan;
447
+
448
+ Partial (this .key, {@required this .span, @required this .keySpan});
429
449
}
430
450
431
451
/// An enumeration of types of tag parse results.
@@ -490,13 +510,18 @@ class _KeyParseResult {
490
510
491
511
final List <String > names;
492
512
493
- const _KeyParseResult ._(this .type, this .names);
513
+ /// The source span from where this key was parsed, if this represents a
514
+ /// parsed key, othwerwise `null` .
515
+ final SourceSpan /*?*/ span;
516
+
517
+ const _KeyParseResult ._(this .type, this .names, {this .span});
494
518
495
- factory _KeyParseResult (_KeyParseResultType type, String key) {
519
+ factory _KeyParseResult (_KeyParseResultType type, String key,
520
+ {@required SourceSpan span}) {
496
521
if (key == '.' ) {
497
- return _KeyParseResult ._(type, [key]);
522
+ return _KeyParseResult ._(type, [key], span : span );
498
523
} else {
499
- return _KeyParseResult ._(type, key.split ('.' ));
524
+ return _KeyParseResult ._(type, key.split ('.' ), span : span );
500
525
}
501
526
}
502
527
0 commit comments