@@ -96,7 +96,7 @@ class CommentReferenceParser {
9696 /// ```text
9797 /// <rawCommentReference> ::= <prefix>?<commentReference><suffix>?
9898 ///
99- /// <commentReference> ::= (<packageName> '.')? (<libraryName> '.')? <dartdocIdentifier> ('.' <identifier>)*
99+ /// <commentReference> ::= (<packageName> '.')? (<libraryName> '.')? <dartdocIdentifier> <typeArguments> ('.' <identifier> <typeArguments >)*
100100 /// ```
101101 List <CommentReferenceNode > _parseRawCommentReference () {
102102 var children = < CommentReferenceNode > [];
@@ -124,6 +124,17 @@ class CommentReferenceParser {
124124 } else if (identifierResult.type ==
125125 _IdentifierResultType .parsedIdentifier) {
126126 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+ }
127138 }
128139 if (_atEnd || _thisChar != $dot) {
129140 break ;
@@ -239,6 +250,22 @@ class CommentReferenceParser {
239250 IdentifierNode (codeRef.substring (startIndex, _index)));
240251 }
241252
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+
242269 static const _callableHintSuffix = '()' ;
243270
244271 /// ```text
@@ -270,7 +297,7 @@ class CommentReferenceParser {
270297 if ((_thisChar == $exclamation || _thisChar == $question) && _nextAtEnd) {
271298 return _SuffixParseResult .junk;
272299 }
273- if (_matchBraces ($lparen, $rparen) || _matchBraces ($lt, $gt) ) {
300+ if (_matchBraces ($lparen, $rparen)) {
274301 return _SuffixParseResult .junk;
275302 }
276303
@@ -334,8 +361,10 @@ class CommentReferenceParser {
334361 while (! _atEnd) {
335362 if (_thisChar == startChar) braceCount++ ;
336363 if (_thisChar == endChar) braceCount-- ;
337- ++ _index;
338- if (braceCount == 0 ) return true ;
364+ _index++ ;
365+ if (braceCount == 0 ) {
366+ return true ;
367+ }
339368 }
340369 _index = startIndex;
341370 return false ;
@@ -395,6 +424,32 @@ class _IdentifierParseResult {
395424 _IdentifierParseResult ._(_IdentifierResultType .notIdentifier, null );
396425}
397426
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+
398453enum _SuffixResultType {
399454 junk, // Found known types of junk it is OK to ignore.
400455 missing, // There is no suffix here. Same as EOF as this is a suffix.
@@ -459,3 +514,19 @@ class IdentifierNode extends CommentReferenceNode {
459514 @override
460515 String toString () => 'Identifier["$text "]' ;
461516}
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