@@ -93,7 +93,7 @@ class CommentReferenceParser {
9393 /// ```text
9494 /// <rawCommentReference> ::= <prefix>?<commentReference><suffix>?
9595 ///
96- /// <commentReference> ::= (<packageName> '.')? (<libraryName> '.')? <dartdocIdentifier> ('.' <identifier>)*
96+ /// <commentReference> ::= (<packageName> '.')? (<libraryName> '.')? <dartdocIdentifier> <typeParameters> ('.' <identifier> <typeParameters >)*
9797 /// ```
9898 List <CommentReferenceNode > _parseRawCommentReference () {
9999 var children = < CommentReferenceNode > [];
@@ -121,6 +121,17 @@ class CommentReferenceParser {
121121 } else if (identifierResult.type ==
122122 _IdentifierResultType .parsedIdentifier) {
123123 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+ }
124135 }
125136 if (_atEnd || _thisChar != $dot) {
126137 break ;
@@ -236,6 +247,22 @@ class CommentReferenceParser {
236247 IdentifierNode (codeRef.substring (startIndex, _index)));
237248 }
238249
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+
239266 static const _callableHintSuffix = '()' ;
240267
241268 /// ```text
@@ -267,7 +294,7 @@ class CommentReferenceParser {
267294 if ((_thisChar == $exclamation || _thisChar == $question) && _nextAtEnd) {
268295 return _SuffixParseResult .junk;
269296 }
270- if (_matchBraces ($lparen, $rparen) || _matchBraces ($lt, $gt) ) {
297+ if (_matchBraces ($lparen, $rparen)) {
271298 return _SuffixParseResult .junk;
272299 }
273300
@@ -331,8 +358,10 @@ class CommentReferenceParser {
331358 while (! _atEnd) {
332359 if (_thisChar == startChar) braceCount++ ;
333360 if (_thisChar == endChar) braceCount-- ;
334- ++ _index;
335- if (braceCount == 0 ) return true ;
361+ _index++ ;
362+ if (braceCount == 0 ) {
363+ return true ;
364+ }
336365 }
337366 _index = startIndex;
338367 return false ;
@@ -392,6 +421,32 @@ class _IdentifierParseResult {
392421 _IdentifierParseResult ._(_IdentifierResultType .notIdentifier, null );
393422}
394423
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+
395450enum _SuffixResultType {
396451 junk, // Found known types of junk it is OK to ignore.
397452 missing, // There is no suffix here. Same as EOF as this is a suffix.
@@ -456,3 +511,19 @@ class IdentifierNode extends CommentReferenceNode {
456511 @override
457512 String toString () => 'Identifier["$text "]' ;
458513}
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