@@ -96,7 +96,7 @@ class CommentReferenceParser {
96
96
/// ```text
97
97
/// <rawCommentReference> ::= <prefix>?<commentReference><suffix>?
98
98
///
99
- /// <commentReference> ::= (<packageName> '.')? (<libraryName> '.')? <dartdocIdentifier> ('.' <identifier>)*
99
+ /// <commentReference> ::= (<packageName> '.')? (<libraryName> '.')? <dartdocIdentifier> <typeArguments> ('.' <identifier> <typeArguments >)*
100
100
/// ```
101
101
List <CommentReferenceNode > _parseRawCommentReference () {
102
102
var children = < CommentReferenceNode > [];
@@ -124,6 +124,17 @@ class CommentReferenceParser {
124
124
} else if (identifierResult.type ==
125
125
_IdentifierResultType .parsedIdentifier) {
126
126
children.add (identifierResult.node);
127
+ var typeVariablesResult = _parseTypeVariables ();
128
+ if (typeVariablesResult.type == _TypeVariablesResultType .endOfFile) {
129
+ break ;
130
+ } else if (typeVariablesResult.type ==
131
+ _TypeVariablesResultType .notTypeVariables) {
132
+ // Do nothing, _index has not moved.
133
+ ;
134
+ } else if (typeVariablesResult.type ==
135
+ _TypeVariablesResultType .parsedTypeVariables) {
136
+ children.add (typeVariablesResult.node);
137
+ }
127
138
}
128
139
if (_atEnd || _thisChar != $dot) {
129
140
break ;
@@ -239,6 +250,22 @@ class CommentReferenceParser {
239
250
IdentifierNode (codeRef.substring (startIndex, _index)));
240
251
}
241
252
253
+ /// Parse a list of type variables (arguments or parameters).
254
+ ///
255
+ /// Dartdoc isolates these where present and potentially valid, but we don't
256
+ /// break them down.
257
+ _TypeVariablesParseResult _parseTypeVariables () {
258
+ if (_atEnd) {
259
+ return _TypeVariablesParseResult .endOfFile;
260
+ }
261
+ var startIndex = _index;
262
+ if (_matchBraces ($lt, $gt)) {
263
+ return _TypeVariablesParseResult .ok (
264
+ TypeVariablesNode (codeRef.substring (startIndex + 1 , _index - 1 )));
265
+ }
266
+ return _TypeVariablesParseResult .notIdentifier;
267
+ }
268
+
242
269
static const _callableHintSuffix = '()' ;
243
270
244
271
/// ```text
@@ -270,7 +297,7 @@ class CommentReferenceParser {
270
297
if ((_thisChar == $exclamation || _thisChar == $question) && _nextAtEnd) {
271
298
return _SuffixParseResult .junk;
272
299
}
273
- if (_matchBraces ($lparen, $rparen) || _matchBraces ($lt, $gt) ) {
300
+ if (_matchBraces ($lparen, $rparen)) {
274
301
return _SuffixParseResult .junk;
275
302
}
276
303
@@ -334,8 +361,10 @@ class CommentReferenceParser {
334
361
while (! _atEnd) {
335
362
if (_thisChar == startChar) braceCount++ ;
336
363
if (_thisChar == endChar) braceCount-- ;
337
- ++ _index;
338
- if (braceCount == 0 ) return true ;
364
+ _index++ ;
365
+ if (braceCount == 0 ) {
366
+ return true ;
367
+ }
339
368
}
340
369
_index = startIndex;
341
370
return false ;
@@ -395,6 +424,32 @@ class _IdentifierParseResult {
395
424
_IdentifierParseResult ._(_IdentifierResultType .notIdentifier, null );
396
425
}
397
426
427
+ enum _TypeVariablesResultType {
428
+ endOfFile, // Found end of file instead of the beginning of a list of type
429
+ // variables.
430
+ notTypeVariables, // Found something, but it isn't type variables.
431
+ parsedTypeVariables, // Found type variables.
432
+ }
433
+
434
+ class _TypeVariablesParseResult {
435
+ final _TypeVariablesResultType type;
436
+
437
+ final TypeVariablesNode node;
438
+
439
+ const _TypeVariablesParseResult ._(this .type, this .node);
440
+
441
+ factory _TypeVariablesParseResult .ok (TypeVariablesNode node) =>
442
+ _TypeVariablesParseResult ._(
443
+ _TypeVariablesResultType .parsedTypeVariables, node);
444
+
445
+ static const _TypeVariablesParseResult endOfFile =
446
+ _TypeVariablesParseResult ._(_TypeVariablesResultType .endOfFile, null );
447
+
448
+ static const _TypeVariablesParseResult notIdentifier =
449
+ _TypeVariablesParseResult ._(
450
+ _TypeVariablesResultType .notTypeVariables, null );
451
+ }
452
+
398
453
enum _SuffixResultType {
399
454
junk, // Found known types of junk it is OK to ignore.
400
455
missing, // There is no suffix here. Same as EOF as this is a suffix.
@@ -459,3 +514,19 @@ class IdentifierNode extends CommentReferenceNode {
459
514
@override
460
515
String toString () => 'Identifier["$text "]' ;
461
516
}
517
+
518
+ /// Represents one or more type variables, may be
519
+ /// comma separated.
520
+ class TypeVariablesNode extends CommentReferenceNode {
521
+ @override
522
+
523
+ /// Note that this will contain commas, spaces, and other text, as
524
+ /// generally type variables are a form of junk that comment references
525
+ /// should ignore.
526
+ final String text;
527
+
528
+ TypeVariablesNode (this .text);
529
+
530
+ @override
531
+ String toString () => 'TypeVariablesNode["$text "]' ;
532
+ }
0 commit comments