@@ -93,7 +93,7 @@ class CommentReferenceParser {
93
93
/// ```text
94
94
/// <rawCommentReference> ::= <prefix>?<commentReference><suffix>?
95
95
///
96
- /// <commentReference> ::= (<packageName> '.')? (<libraryName> '.')? <dartdocIdentifier> ('.' <identifier>)*
96
+ /// <commentReference> ::= (<packageName> '.')? (<libraryName> '.')? <dartdocIdentifier> <typeParameters> ('.' <identifier> <typeParameters >)*
97
97
/// ```
98
98
List <CommentReferenceNode > _parseRawCommentReference () {
99
99
var children = < CommentReferenceNode > [];
@@ -121,6 +121,17 @@ class CommentReferenceParser {
121
121
} else if (identifierResult.type ==
122
122
_IdentifierResultType .parsedIdentifier) {
123
123
children.add (identifierResult.node);
124
+ var typeParametersResult = _parseTypeParameters ();
125
+ if (typeParametersResult.type == _TypeParametersResultType .endOfFile) {
126
+ break ;
127
+ } else if (typeParametersResult.type ==
128
+ _TypeParametersResultType .notTypeParameters) {
129
+ // Do nothing, _index has not moved.
130
+ ;
131
+ } else if (typeParametersResult.type ==
132
+ _TypeParametersResultType .parsedTypeParameters) {
133
+ children.add (typeParametersResult.node);
134
+ }
124
135
}
125
136
if (_atEnd || _thisChar != $dot) {
126
137
break ;
@@ -236,6 +247,22 @@ class CommentReferenceParser {
236
247
IdentifierNode (codeRef.substring (startIndex, _index)));
237
248
}
238
249
250
+ /// Parse a list of type parameters.
251
+ ///
252
+ /// Dartdoc isolates these where present and potentially valid, but we don't
253
+ /// break them down.
254
+ _TypeParametersParseResult _parseTypeParameters () {
255
+ if (_atEnd) {
256
+ return _TypeParametersParseResult .endOfFile;
257
+ }
258
+ var startIndex = _index;
259
+ if (_matchBraces ($lt, $gt)) {
260
+ return _TypeParametersParseResult .ok (
261
+ TypeParametersNode (codeRef.substring (startIndex + 1 , _index - 1 )));
262
+ }
263
+ return _TypeParametersParseResult .notIdentifier;
264
+ }
265
+
239
266
static const _callableHintSuffix = '()' ;
240
267
241
268
/// ```text
@@ -267,7 +294,7 @@ class CommentReferenceParser {
267
294
if ((_thisChar == $exclamation || _thisChar == $question) && _nextAtEnd) {
268
295
return _SuffixParseResult .junk;
269
296
}
270
- if (_matchBraces ($lparen, $rparen) || _matchBraces ($lt, $gt) ) {
297
+ if (_matchBraces ($lparen, $rparen)) {
271
298
return _SuffixParseResult .junk;
272
299
}
273
300
@@ -331,8 +358,10 @@ class CommentReferenceParser {
331
358
while (! _atEnd) {
332
359
if (_thisChar == startChar) braceCount++ ;
333
360
if (_thisChar == endChar) braceCount-- ;
334
- ++ _index;
335
- if (braceCount == 0 ) return true ;
361
+ _index++ ;
362
+ if (braceCount == 0 ) {
363
+ return true ;
364
+ }
336
365
}
337
366
_index = startIndex;
338
367
return false ;
@@ -392,6 +421,32 @@ class _IdentifierParseResult {
392
421
_IdentifierParseResult ._(_IdentifierResultType .notIdentifier, null );
393
422
}
394
423
424
+ enum _TypeParametersResultType {
425
+ endOfFile, // Found end of file instead of the beginning of a list of type
426
+ // parameters.
427
+ notTypeParameters, // Found something, but it isn't type parameters.
428
+ parsedTypeParameters, // Found type parameters.
429
+ }
430
+
431
+ class _TypeParametersParseResult {
432
+ final _TypeParametersResultType type;
433
+
434
+ final TypeParametersNode node;
435
+
436
+ const _TypeParametersParseResult ._(this .type, this .node);
437
+
438
+ factory _TypeParametersParseResult .ok (TypeParametersNode node) =>
439
+ _TypeParametersParseResult ._(
440
+ _TypeParametersResultType .parsedTypeParameters, node);
441
+
442
+ static const _TypeParametersParseResult endOfFile =
443
+ _TypeParametersParseResult ._(_TypeParametersResultType .endOfFile, null );
444
+
445
+ static const _TypeParametersParseResult notIdentifier =
446
+ _TypeParametersParseResult ._(
447
+ _TypeParametersResultType .notTypeParameters, null );
448
+ }
449
+
395
450
enum _SuffixResultType {
396
451
junk, // Found known types of junk it is OK to ignore.
397
452
missing, // There is no suffix here. Same as EOF as this is a suffix.
@@ -456,3 +511,19 @@ class IdentifierNode extends CommentReferenceNode {
456
511
@override
457
512
String toString () => 'Identifier["$text "]' ;
458
513
}
514
+
515
+ /// Represents one or more type parameters, may be
516
+ /// comma separated.
517
+ class TypeParametersNode extends CommentReferenceNode {
518
+ @override
519
+
520
+ /// Note that this will contain commas, spaces, and other text, as
521
+ /// generally type parameters are a form of junk that comment references
522
+ /// should ignore.
523
+ final String text;
524
+
525
+ TypeParametersNode (this .text);
526
+
527
+ @override
528
+ String toString () => 'TypeParametersNode["$text "]' ;
529
+ }
0 commit comments