void RawCommentList::addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator) { if (RC.isInvalid()) return; // Check if the comments are not in source order. while (!Comments.empty() && !SourceMgr.isBeforeInTranslationUnit(Comments.back()->getLocStart(), RC.getLocStart())) { // If they are, just pop a few last comments that don't fit. // This happens if an \#include directive contains comments. Comments.pop_back(); } // Ordinary comments are not interesting for us. if (RC.isOrdinary()) return; // If this is the first Doxygen comment, save it (because there isn't // anything to merge it with). if (Comments.empty()) { Comments.push_back(new (Allocator) RawComment(RC)); return; } const RawComment &C1 = *Comments.back(); const RawComment &C2 = RC; // Merge comments only if there is only whitespace between them. // Can't merge trailing and non-trailing comments unless the second is // non-trailing ordinary in the same column, as in the case: // int x; // documents x // // more text // versus: // int x; // documents x // int y; // documents y // or: // int x; // documents x // // documents y // int y; // Merge comments if they are on same or consecutive lines. if ((C1.isTrailingComment() == C2.isTrailingComment() || (C1.isTrailingComment() && !C2.isTrailingComment() && isOrdinaryKind(C2.getKind()) && commentsStartOnSameColumn(SourceMgr, C1, C2))) && onlyWhitespaceBetween(SourceMgr, C1.getLocEnd(), C2.getLocStart(), /*MaxNewlinesAllowed=*/1)) { SourceRange MergedRange(C1.getLocStart(), C2.getLocEnd()); *Comments.back() = RawComment(SourceMgr, MergedRange, true, RC.isParseAllComments()); } else { Comments.push_back(new (Allocator) RawComment(RC)); } }
static Optional<DocComment *> getAnyBaseClassDocComment(swift::markup::MarkupContext &MC, const ClassDecl *CD, const Decl *D) { RawComment RC; if (const auto *VD = dyn_cast<ValueDecl>(D)) { const auto *BaseDecl = VD->getOverriddenDecl(); while (BaseDecl) { RC = BaseDecl->getRawComment(); if (!RC.isEmpty()) { swift::markup::LineList LL = MC.getLineList(RC); auto *Doc = swift::markup::parseDocument(MC, LL); auto Parts = extractCommentParts(MC, Doc); SmallString<48> RawCascadeText; llvm::raw_svector_ostream OS(RawCascadeText); OS << "This documentation comment was inherited from "; auto *Text = swift::markup::Text::create(MC, MC.allocateCopy(OS.str())); auto BaseClass = BaseDecl->getDeclContext()->getAsClassOrClassExtensionContext(); auto *BaseClassMonospace = swift::markup::Code::create(MC, MC.allocateCopy(BaseClass->getNameStr())); auto *Period = swift::markup::Text::create(MC, "."); auto *Para = swift::markup::Paragraph::create(MC, { Text, BaseClassMonospace, Period }); auto CascadeNote = swift::markup::NoteField::create(MC, {Para}); SmallVector<const swift::markup::MarkupASTNode *, 8> BodyNodes { Parts.BodyNodes.begin(), Parts.BodyNodes.end() }; BodyNodes.push_back(CascadeNote); Parts.BodyNodes = MC.allocateCopy(llvm::makeArrayRef(BodyNodes)); return new (MC) DocComment(D, Doc, Parts); } BaseDecl = BaseDecl->getOverriddenDecl(); } } return None; }
void RawCommentList::addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator) { if (RC.isInvalid()) return; // Check if the comments are not in source order. while (!Comments.empty() && !SourceMgr.isBeforeInTranslationUnit( Comments.back()->getSourceRange().getBegin(), RC.getSourceRange().getBegin())) { // If they are, just pop a few last comments that don't fit. // This happens if an \#include directive contains comments. Comments.pop_back(); } if (OnlyWhitespaceSeen) { if (!onlyWhitespaceBetweenComments(SourceMgr, LastComment, RC)) OnlyWhitespaceSeen = false; } LastComment = RC; // Ordinary comments are not interesting for us. if (RC.isOrdinary()) return; // If this is the first Doxygen comment, save it (because there isn't // anything to merge it with). if (Comments.empty()) { Comments.push_back(new (Allocator) RawComment(RC)); OnlyWhitespaceSeen = true; return; } const RawComment &C1 = *Comments.back(); const RawComment &C2 = RC; // Merge comments only if there is only whitespace between them. // Can't merge trailing and non-trailing comments. // Merge trailing comments if they are on same or consecutive lines. if (OnlyWhitespaceSeen && (C1.isTrailingComment() == C2.isTrailingComment()) && (!C1.isTrailingComment() || C1.getEndLine(SourceMgr) + 1 >= C2.getBeginLine(SourceMgr))) { SourceRange MergedRange(C1.getSourceRange().getBegin(), C2.getSourceRange().getEnd()); *Comments.back() = RawComment(SourceMgr, MergedRange, true); } else Comments.push_back(new (Allocator) RawComment(RC)); OnlyWhitespaceSeen = true; }