/* Function: TryToGetBlockComment * * If the iterator is on a line that starts with the opening symbol of a block comment, this function moves the iterator * past the entire comment and returns true. If the comment is a candidate for documentation it will also return it as * a <PossibleDocumentationComment> and mark the symbols as <CommentParsingType.CommentSymbol>. If the * line does not start with an opening comment symbol it will return false and leave the iterator where it is. */ protected bool TryToGetBlockComment(ref LineIterator lineIterator, out PossibleDocumentationComment comment) { TokenIterator firstToken, endOfLine; lineIterator.GetBounds(LineBoundsMode.ExcludeWhitespace, out firstToken, out endOfLine); // Are we on a block comment? TokenIterator lookahead = firstToken; string closingSymbol; if (TryToSkipOpeningBlockCommentSymbol(ref lookahead, out closingSymbol) == false) { comment = null; return(false); } // We are. Create a possible documentation comment. comment = new PossibleDocumentationComment(); comment.Start = lineIterator; // Check if we're on a Javadoc comment, which will be an extra [. if (lookahead.Character == '[') { lookahead.Next(); if (lookahead.FundamentalType != FundamentalType.Symbol) { comment.Javadoc = true; } } // Find the end of the comment, which could be on the same line as the start. var tokenizer = lineIterator.Tokenizer; var lineLookahead = lineIterator; bool hadTrailingDashes = false; for (;;) { TokenIterator closingSymbolIterator; if (tokenizer.FindTokensBetween(closingSymbol, false, firstToken, endOfLine, out closingSymbolIterator) == true) { // Move past the end of the comment regardless of whether it's acceptable for documentation or not lineLookahead.Next(); // Make sure nothing appears after the closing symbol on the line closingSymbolIterator.NextByCharacters(closingSymbol.Length); // We'll allow -- though since some people use --[[ and ]]-- for balance even though the latter is actually the // closing comment symbol followed by a line comment. if (closingSymbolIterator.MatchesAcrossTokens("--")) { hadTrailingDashes = true; closingSymbolIterator.Next(2); } closingSymbolIterator.NextPastWhitespace(); if (closingSymbolIterator.FundamentalType != FundamentalType.LineBreak && closingSymbolIterator.FundamentalType != FundamentalType.Null) { comment = null; } else { comment.End = lineLookahead; } break; } lineLookahead.Next(); // If we're not in bounds that means there was an unclosed comment at the end of the file. Skip it but don't treat // it as a documentation candidate. if (!lookahead.IsInBounds) { comment = null; break; } lineLookahead.GetBounds(LineBoundsMode.ExcludeWhitespace, out firstToken, out endOfLine); } if (comment != null) { // Mark the symbols before returning firstToken = comment.Start.FirstToken(LineBoundsMode.ExcludeWhitespace); lookahead = firstToken; TryToSkipOpeningBlockCommentSymbol(ref lookahead, out closingSymbol); if (comment.Javadoc) { lookahead.Next(); } firstToken.SetCommentParsingTypeBetween(lookahead, CommentParsingType.CommentSymbol); LineIterator lastLine = comment.End; lastLine.Previous(); lastLine.GetBounds(LineBoundsMode.ExcludeWhitespace, out firstToken, out endOfLine); lookahead = endOfLine; if (hadTrailingDashes) { lookahead.Previous(2); } lookahead.PreviousByCharacters(closingSymbol.Length); lookahead.SetCommentParsingTypeBetween(endOfLine, CommentParsingType.CommentSymbol); } // If we made it this far that means we found a comment and can move the line iterator and return true. Whether // that comment was suitable for documentation will be determined by the comment variable, but we are moving the // iterator and returning true either way. lineIterator = lineLookahead; return(true); }
/* Function: TryToGetLineComment * * If the iterator is on a line that starts with a line comment symbol, this function moves the iterator past the entire * comment and returns true. If the comment is a candidate for documentation it will also return it as a * <PossibleDocumentationComment> and mark the symbols as <CommentParsingType.CommentSymbol>. If the * line does not start with a line comment symbol it will return false and leave the iterator where it is. */ protected bool TryToGetLineComment(ref LineIterator lineIterator, out PossibleDocumentationComment comment) { TokenIterator firstToken = lineIterator.FirstToken(LineBoundsMode.ExcludeWhitespace); TokenIterator lookahead = firstToken; // Are we on a line comment? if (TryToSkipLineCommentSymbol(ref lookahead) == false) { comment = null; return(false); } // We are. Create a possible documentation comment. comment = new PossibleDocumentationComment(); comment.Start = lineIterator; // Check if we're a Javadoc/XML comment. We can't tell the difference from just the first line. TokenIterator endOfCommentSymbol = lookahead; if (lookahead.Character == '-') { lookahead.Next(); if (lookahead.FundamentalType != FundamentalType.Symbol) { endOfCommentSymbol = lookahead; comment.Javadoc = true; comment.XML = true; } } // Mark it. firstToken.SetCommentParsingTypeBetween(endOfCommentSymbol, CommentParsingType.CommentSymbol); // Continue to find the rest of the comment lineIterator.Next(); bool hasXMLishLines = false; bool hasNonXMLishLines = false; bool hasMultipleLines = false; while (lineIterator.IsInBounds) { firstToken = lineIterator.FirstToken(LineBoundsMode.ExcludeWhitespace); lookahead = firstToken; if (TryToSkipLineCommentSymbol(ref lookahead) == false) { break; } hasMultipleLines = true; endOfCommentSymbol = lookahead; if (lookahead.Character == '-') { lookahead.Next(); if (lookahead.FundamentalType != FundamentalType.Symbol) { hasXMLishLines = true; endOfCommentSymbol = lookahead; } else { hasNonXMLishLines = true; } } else { hasNonXMLishLines = true; } firstToken.SetCommentParsingTypeBetween(endOfCommentSymbol, CommentParsingType.CommentSymbol); lineIterator.Next(); } comment.End = lineIterator; if (hasMultipleLines && comment.Javadoc) { if (hasXMLishLines && !hasNonXMLishLines) { comment.Javadoc = false; } else if (hasNonXMLishLines) { comment.XML = false; } } return(true); }