Skip to content

Commit 892fdd9

Browse files
srawlinsCommit Queue
authored and
Commit Queue
committed
Move all comment-parsing code into pkg/analyzer
I did not change the content of the functions, except the following: * modernized some variable declarations with `var`. * added periods to the end of comments. * privatized most methods. Work towards #50702 Change-Id: I4d63d3ee847316b58fa76c12558767c0825027a9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/315243 Reviewed-by: Paul Berry <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Samuel Rawlins <[email protected]>
1 parent 9803ffe commit 892fdd9

File tree

3 files changed

+292
-392
lines changed

3 files changed

+292
-392
lines changed

pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart

-286
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,8 @@ import 'util.dart'
126126
show
127127
findNonZeroLengthToken,
128128
findPreviousNonZeroLengthToken,
129-
isLetter,
130-
isLetterOrDigit,
131129
isOneOf,
132130
isOneOfOrEof,
133-
isWhitespace,
134131
optional;
135132

136133
/// An event generating parser of Dart programs. This parser expects all tokens
@@ -9422,289 +9419,6 @@ class Parser {
94229419
return dartdoc;
94239420
}
94249421

9425-
/// Parse the comment references in a sequence of comment tokens
9426-
/// where [dartdoc] (not null) is the first token in the sequence.
9427-
/// Return the number of comment references parsed.
9428-
int parseCommentReferences(Token dartdoc) {
9429-
return dartdoc.lexeme.startsWith('///')
9430-
? parseReferencesInSingleLineComments(dartdoc)
9431-
: parseReferencesInMultiLineComment(dartdoc);
9432-
}
9433-
9434-
/// Parse the comment references in a multi-line comment token.
9435-
/// Return the number of comment references parsed.
9436-
int parseReferencesInMultiLineComment(Token multiLineDoc) {
9437-
String comment = multiLineDoc.lexeme;
9438-
assert(comment.startsWith('/**'));
9439-
int count = 0;
9440-
int length = comment.length;
9441-
int start = 3;
9442-
bool inCodeBlock = false;
9443-
int codeBlock = comment.indexOf('```', /* start = */ 3);
9444-
if (codeBlock == -1) {
9445-
codeBlock = length;
9446-
}
9447-
while (start < length) {
9448-
if (isWhitespace(comment.codeUnitAt(start))) {
9449-
++start;
9450-
continue;
9451-
}
9452-
int end = comment.indexOf('\n', start);
9453-
if (end == -1) {
9454-
end = length;
9455-
}
9456-
if (codeBlock < end) {
9457-
inCodeBlock = !inCodeBlock;
9458-
codeBlock = comment.indexOf('```', end);
9459-
if (codeBlock == -1) {
9460-
codeBlock = length;
9461-
}
9462-
}
9463-
if (!inCodeBlock && !comment.startsWith('* ', start)) {
9464-
count += parseCommentReferencesInText(multiLineDoc, start, end);
9465-
}
9466-
start = end + 1;
9467-
}
9468-
return count;
9469-
}
9470-
9471-
/// Parse the comment references in a sequence of single line comment tokens
9472-
/// where [token] is the first comment token in the sequence.
9473-
/// Return the number of comment references parsed.
9474-
int parseReferencesInSingleLineComments(Token? token) {
9475-
int count = 0;
9476-
bool inCodeBlock = false;
9477-
while (token != null && !token.isEof) {
9478-
String comment = token.lexeme;
9479-
if (comment.startsWith('///')) {
9480-
if (comment.indexOf('```', /* start = */ 3) != -1) {
9481-
inCodeBlock = !inCodeBlock;
9482-
}
9483-
if (!inCodeBlock) {
9484-
bool parseReferences;
9485-
if (comment.startsWith('/// ')) {
9486-
String? previousComment = token.previous?.lexeme;
9487-
parseReferences = previousComment != null &&
9488-
previousComment.startsWith('///') &&
9489-
previousComment.trim().length > 3;
9490-
} else {
9491-
parseReferences = true;
9492-
}
9493-
if (parseReferences) {
9494-
count += parseCommentReferencesInText(
9495-
token, /* start = */ 3, comment.length);
9496-
}
9497-
}
9498-
}
9499-
token = token.next;
9500-
}
9501-
return count;
9502-
}
9503-
9504-
/// Parse the comment references in the text between [start] inclusive
9505-
/// and [end] exclusive. Return a count indicating how many were parsed.
9506-
int parseCommentReferencesInText(Token commentToken, int start, int end) {
9507-
String comment = commentToken.lexeme;
9508-
int count = 0;
9509-
int index = start;
9510-
while (index < end) {
9511-
int ch = comment.codeUnitAt(index);
9512-
if (ch == 0x5B /* `[` */) {
9513-
++index;
9514-
if (index < end && comment.codeUnitAt(index) == 0x3A /* `:` */) {
9515-
// Skip old-style code block.
9516-
index = comment.indexOf(':]', index + 1) + 1;
9517-
if (index == 0 || index > end) {
9518-
break;
9519-
}
9520-
} else {
9521-
int referenceStart = index;
9522-
index = comment.indexOf(']', index);
9523-
if (index == -1 || index >= end) {
9524-
// Recovery: terminating ']' is not typed yet.
9525-
index = findReferenceEnd(comment, referenceStart, end);
9526-
}
9527-
if (ch != 0x27 /* `'` */ && ch != 0x22 /* `"` */) {
9528-
if (isLinkText(comment, index)) {
9529-
// TODO(brianwilkerson) Handle the case where there's a library
9530-
// URI in the link text.
9531-
} else {
9532-
listener.handleCommentReferenceText(
9533-
comment.substring(referenceStart, index),
9534-
commentToken.charOffset + referenceStart);
9535-
++count;
9536-
}
9537-
}
9538-
}
9539-
} else if (ch == 0x60 /* '`' */) {
9540-
// Skip inline code block if there is both starting '`' and ending '`'
9541-
int endCodeBlock = comment.indexOf('`', index + 1);
9542-
if (endCodeBlock != -1 && endCodeBlock < end) {
9543-
index = endCodeBlock;
9544-
}
9545-
}
9546-
++index;
9547-
}
9548-
return count;
9549-
}
9550-
9551-
/// Given a comment reference without a closing `]`,
9552-
/// search for a possible place where `]` should be.
9553-
int findReferenceEnd(String comment, int index, int end) {
9554-
// Find the end of the identifier if there is one
9555-
if (index >= end || !isLetter(comment.codeUnitAt(index))) {
9556-
return index;
9557-
}
9558-
while (index < end && isLetterOrDigit(comment.codeUnitAt(index))) {
9559-
++index;
9560-
}
9561-
9562-
// Check for a trailing `.`
9563-
if (index >= end || comment.codeUnitAt(index) != 0x2E /* `.` */) {
9564-
return index;
9565-
}
9566-
++index;
9567-
9568-
// Find end of the identifier after the `.`
9569-
if (index >= end || !isLetter(comment.codeUnitAt(index))) {
9570-
return index;
9571-
}
9572-
++index;
9573-
while (index < end && isLetterOrDigit(comment.codeUnitAt(index))) {
9574-
++index;
9575-
}
9576-
return index;
9577-
}
9578-
9579-
/// Parse the tokens in a single comment reference and generate either a
9580-
/// `handleCommentReference` or `handleNoCommentReference` event.
9581-
/// Return `true` if a comment reference was successfully parsed.
9582-
bool parseOneCommentReference(Token token, int referenceOffset) {
9583-
Token begin = token;
9584-
Token? newKeyword = null;
9585-
if (optional('new', token)) {
9586-
newKeyword = token;
9587-
token = token.next!;
9588-
}
9589-
Token? firstToken, firstPeriod, secondToken, secondPeriod;
9590-
if (token.isIdentifier && optional('.', token.next!)) {
9591-
secondToken = token;
9592-
secondPeriod = token.next!;
9593-
if (secondPeriod.next!.isIdentifier &&
9594-
optional('.', secondPeriod.next!.next!)) {
9595-
firstToken = secondToken;
9596-
firstPeriod = secondPeriod;
9597-
secondToken = secondPeriod.next!;
9598-
secondPeriod = secondToken.next!;
9599-
}
9600-
Token identifier = secondPeriod.next!;
9601-
if (identifier.kind == KEYWORD_TOKEN && optional('new', identifier)) {
9602-
// Treat `new` after `.` is as an identifier so that it can represent an
9603-
// unnamed constructor. This support is separate from the
9604-
// constructor-tearoffs feature.
9605-
rewriter.replaceTokenFollowing(
9606-
secondPeriod,
9607-
new StringToken(TokenType.IDENTIFIER, identifier.lexeme,
9608-
identifier.charOffset));
9609-
}
9610-
token = secondPeriod.next!;
9611-
}
9612-
if (token.isEof) {
9613-
// Recovery: Insert a synthetic identifier for code completion
9614-
token = rewriter.insertSyntheticIdentifier(
9615-
secondPeriod ?? newKeyword ?? syntheticPreviousToken(token));
9616-
if (begin == token.next!) {
9617-
begin = token;
9618-
}
9619-
}
9620-
Token? operatorKeyword = null;
9621-
if (optional('operator', token)) {
9622-
operatorKeyword = token;
9623-
token = token.next!;
9624-
}
9625-
if (token.isUserDefinableOperator) {
9626-
if (token.next!.isEof) {
9627-
parseOneCommentReferenceRest(begin, referenceOffset, newKeyword,
9628-
firstToken, firstPeriod, secondToken, secondPeriod, token);
9629-
return true;
9630-
}
9631-
} else {
9632-
token = operatorKeyword ?? token;
9633-
if (token.next!.isEof) {
9634-
if (token.isIdentifier) {
9635-
parseOneCommentReferenceRest(begin, referenceOffset, newKeyword,
9636-
firstToken, firstPeriod, secondToken, secondPeriod, token);
9637-
return true;
9638-
}
9639-
Keyword? keyword = token.keyword;
9640-
if (newKeyword == null &&
9641-
secondToken == null &&
9642-
(keyword == Keyword.THIS ||
9643-
keyword == Keyword.NULL ||
9644-
keyword == Keyword.TRUE ||
9645-
keyword == Keyword.FALSE)) {
9646-
// TODO(brianwilkerson) If we want to support this we will need to
9647-
// extend the definition of CommentReference to take an expression
9648-
// rather than an identifier. For now we just ignore it to reduce the
9649-
// number of errors produced, but that's probably not a valid long
9650-
// term approach.
9651-
}
9652-
}
9653-
}
9654-
listener.handleNoCommentReference();
9655-
return false;
9656-
}
9657-
9658-
void parseOneCommentReferenceRest(
9659-
Token begin,
9660-
int referenceOffset,
9661-
Token? newKeyword,
9662-
Token? firstToken,
9663-
Token? firstPeriod,
9664-
Token? secondToken,
9665-
Token? secondPeriod,
9666-
Token identifierOrOperator) {
9667-
// Adjust the token offsets to match the enclosing comment token.
9668-
Token token = begin;
9669-
do {
9670-
token.offset += referenceOffset;
9671-
token = token.next!;
9672-
} while (!token.isEof);
9673-
9674-
listener.handleCommentReference(newKeyword, firstToken, firstPeriod,
9675-
secondToken, secondPeriod, identifierOrOperator);
9676-
}
9677-
9678-
/// Given that we have just found bracketed text within the given [comment],
9679-
/// look to see whether that text is (a) followed by a parenthesized link
9680-
/// address, (b) followed by a colon, or (c) followed by optional whitespace
9681-
/// and another square bracket. The [rightIndex] is the index of the right
9682-
/// bracket. Return `true` if the bracketed text is followed by a link
9683-
/// address.
9684-
///
9685-
/// This method uses the syntax described by the
9686-
/// <a href="http://daringfireball.net/projects/markdown/syntax">markdown</a>
9687-
/// project.
9688-
bool isLinkText(String comment, int rightIndex) {
9689-
int length = comment.length;
9690-
int index = rightIndex + 1;
9691-
if (index >= length) {
9692-
return false;
9693-
}
9694-
int ch = comment.codeUnitAt(index);
9695-
if (ch == 0x28 || ch == 0x3A) {
9696-
return true;
9697-
}
9698-
while (isWhitespace(ch)) {
9699-
index = index + 1;
9700-
if (index >= length) {
9701-
return false;
9702-
}
9703-
ch = comment.codeUnitAt(index);
9704-
}
9705-
return ch == 0x5B;
9706-
}
9707-
97089422
/// pattern ::= logicalOrPattern
97099423
/// logicalOrPattern ::= logicalOrPattern ( '|' logicalAndPattern )?
97109424
/// logicalAndPattern ::= logicalAndPattern ( '&' relationalPattern )?

0 commit comments

Comments
 (0)