Skip to content

Commit 3ed457a

Browse files
committed
[Sema] Move getDocCommentProvidingDecl and getCascadingDocComment from AST to Sema
This allows use to re-use logic from Sema in those requests. This commit just moves functions around and does not change any functionality.
1 parent 45e9534 commit 3ed457a

File tree

10 files changed

+256
-246
lines changed

10 files changed

+256
-246
lines changed

include/swift/AST/Comment.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,6 @@ class DocComment {
9696
DocComment *getSingleDocComment(swift::markup::MarkupContext &Context,
9797
const Decl *D);
9898

99-
/// Get the declaration that actually provides a doc comment for another.
100-
const Decl *getDocCommentProvidingDecl(const Decl *D);
101-
102-
/// Attempt to get a doc comment from the declaration, or other inherited
103-
/// sources, like from base classes or protocols.
104-
DocComment *getCascadingDocComment(swift::markup::MarkupContext &MC,
105-
const Decl *D);
106-
10799
/// Extract comments parts from the given Markup node.
108100
swift::markup::CommentParts
109101
extractCommentParts(swift::markup::MarkupContext &MC,

include/swift/AST/Decl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,9 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
12021202

12031203
std::optional<unsigned> getSourceOrder() const;
12041204

1205+
/// Get the declaration that actually provides a doc comment for another.
1206+
const Decl *getDocCommentProvidingDecl() const;
1207+
12051208
/// \returns The brief comment attached to this declaration, or the brief
12061209
/// comment attached to the comment providing decl.
12071210
StringRef getSemanticBriefComment() const;

include/swift/AST/PrintOptions.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -734,13 +734,6 @@ struct PrintOptions {
734734
return CurrentPrintabilityChecker->shouldPrint(P, *this);
735735
}
736736

737-
/// Retrieve the print options that are suitable to print the testable interface.
738-
static PrintOptions printTestableInterface(bool printFullConvention) {
739-
PrintOptions result = printInterface(printFullConvention);
740-
result.AccessFilter = AccessLevel::Internal;
741-
return result;
742-
}
743-
744737
/// Retrieve the print options that are suitable to print interface for a
745738
/// swift file.
746739
static PrintOptions printSwiftFileInterface(bool printFullConvention) {

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ class PrintAST : public ASTVisitor<PrintAST> {
743743

744744
void printSwiftDocumentationComment(const Decl *D) {
745745
if (Options.CascadeDocComment)
746-
D = getDocCommentProvidingDecl(D);
746+
D = D->getDocCommentProvidingDecl();
747747
if (!D)
748748
return;
749749
auto RC = D->getRawComment();

lib/AST/DocComment.cpp

Lines changed: 0 additions & 226 deletions
Original file line numberDiff line numberDiff line change
@@ -391,229 +391,3 @@ DocComment *swift::getSingleDocComment(swift::markup::MarkupContext &MC,
391391
return nullptr;
392392
return DocComment::create(D, MC, RC);
393393
}
394-
395-
namespace {
396-
/// Helper class for finding the comment providing decl for either a brief or
397-
/// raw comment.
398-
template <typename Result>
399-
class CommentProviderFinder final {
400-
using ResultWithDecl = std::pair<Result, const Decl *>;
401-
using VisitFnTy = std::optional<Result> (*)(const Decl *);
402-
403-
VisitFnTy VisitFn;
404-
405-
public:
406-
CommentProviderFinder(VisitFnTy visitFn) : VisitFn(visitFn) {}
407-
408-
private:
409-
std::optional<ResultWithDecl> visit(const Decl *D) {
410-
// Adapt the provided visitor function to also return the decl.
411-
if (auto result = VisitFn(D))
412-
return {{*result, D}};
413-
return std::nullopt;
414-
}
415-
416-
std::optional<ResultWithDecl> findOverriddenDecl(const ValueDecl *VD) {
417-
// Only applies to class member.
418-
if (!VD->getDeclContext()->getSelfClassDecl())
419-
return std::nullopt;
420-
421-
while (auto *baseDecl = VD->getOverriddenDecl()) {
422-
if (auto result = visit(baseDecl))
423-
return result;
424-
425-
VD = baseDecl;
426-
}
427-
return std::nullopt;
428-
}
429-
430-
/// Check if there is an inherited protocol that has a default implementation
431-
/// of `VD` with a doc comment.
432-
std::optional<ResultWithDecl> findDefaultProvidedDecl(const ValueDecl *VD) {
433-
NominalTypeDecl *nominalType =
434-
dyn_cast_or_null<NominalTypeDecl>(VD->getDeclContext()->getAsDecl());
435-
if (!nominalType) {
436-
nominalType = VD->getDeclContext()->getExtendedProtocolDecl();
437-
}
438-
if (!nominalType)
439-
return std::nullopt;
440-
441-
SmallVector<ValueDecl *, 2> members;
442-
nominalType->lookupQualified(nominalType, DeclNameRef(VD->getName()),
443-
VD->getLoc(), NLOptions::NL_ProtocolMembers,
444-
members);
445-
446-
std::optional<ResultWithDecl> result;
447-
Type vdComparisonTy = VD->getInterfaceType();
448-
if (!vdComparisonTy) {
449-
return std::nullopt;
450-
}
451-
if (auto fnTy = vdComparisonTy->getAs<AnyFunctionType>()) {
452-
// Strip off the 'Self' parameter.
453-
vdComparisonTy = fnTy->getResult();
454-
}
455-
456-
for (auto *member : members) {
457-
if (isa<AbstractFunctionDecl>(member) || isa<AbstractStorageDecl>(member)) {
458-
if (VD->isStatic() != member->isStatic()) {
459-
continue;
460-
}
461-
Type memberComparisonTy = member->getInterfaceType();
462-
if (!memberComparisonTy) {
463-
continue;
464-
}
465-
if (auto fnTy = memberComparisonTy->getAs<AnyFunctionType>()) {
466-
// Strip off the 'Self' parameter.
467-
memberComparisonTy = fnTy->getResult();
468-
}
469-
if (!vdComparisonTy->matches(memberComparisonTy, TypeMatchFlags::AllowOverride)) {
470-
continue;
471-
}
472-
}
473-
auto newResult = visit(member);
474-
if (!newResult)
475-
continue;
476-
477-
if (result) {
478-
// Found two or more decls with doc-comment.
479-
return std::nullopt;
480-
}
481-
result = newResult;
482-
}
483-
return result;
484-
}
485-
486-
std::optional<ResultWithDecl> findRequirementDecl(const ValueDecl *VD) {
487-
std::queue<const ValueDecl *> requirements;
488-
while (true) {
489-
for (auto *req : VD->getSatisfiedProtocolRequirements()) {
490-
if (auto result = visit(req))
491-
return result;
492-
493-
requirements.push(req);
494-
}
495-
if (requirements.empty())
496-
return std::nullopt;
497-
498-
VD = requirements.front();
499-
requirements.pop();
500-
}
501-
}
502-
503-
public:
504-
std::optional<ResultWithDecl> findCommentProvider(const Decl *D) {
505-
if (auto result = visit(D))
506-
return result;
507-
508-
auto *VD = dyn_cast<ValueDecl>(D);
509-
if (!VD)
510-
return std::nullopt;
511-
512-
if (auto result = findOverriddenDecl(VD))
513-
return result;
514-
515-
if (auto result = findRequirementDecl(VD))
516-
return result;
517-
518-
if (auto result = findDefaultProvidedDecl(VD))
519-
return result;
520-
521-
return std::nullopt;
522-
}
523-
};
524-
} // end anonymous namespace
525-
526-
const Decl *swift::getDocCommentProvidingDecl(const Decl *D) {
527-
// Search for the first decl we see with a non-empty raw comment.
528-
auto finder = CommentProviderFinder<RawComment>(
529-
[](const Decl *D) -> std::optional<RawComment> {
530-
auto comment = D->getRawComment();
531-
if (comment.isEmpty())
532-
return std::nullopt;
533-
return comment;
534-
});
535-
536-
auto result = finder.findCommentProvider(D);
537-
return result ? result->second : nullptr;
538-
}
539-
540-
DocComment *swift::getCascadingDocComment(swift::markup::MarkupContext &MC,
541-
const Decl *D) {
542-
auto *docD = getDocCommentProvidingDecl(D);
543-
if (!docD)
544-
return nullptr;
545-
546-
auto *doc = getSingleDocComment(MC, docD);
547-
assert(doc && "getDocCommentProvidingDecl() returned decl with no comment");
548-
549-
// If the doc-comment is inherited from other decl, add a note about it.
550-
if (docD != D) {
551-
doc->setDecl(D);
552-
if (auto baseD = docD->getDeclContext()->getSelfNominalTypeDecl()) {
553-
doc->addInheritanceNote(MC, baseD);
554-
555-
// If the doc is inherited from protocol requirement, associate the
556-
// requirement with the doc-comment.
557-
// FIXME: This is to keep the old behavior.
558-
if (isa<ProtocolDecl>(baseD))
559-
doc->setDecl(docD);
560-
}
561-
}
562-
563-
return doc;
564-
}
565-
566-
/// Retrieve the brief comment for a given decl \p D, without attempting to
567-
/// walk any requirements or overrides.
568-
static std::optional<StringRef> getDirectBriefComment(const Decl *D) {
569-
if (!D->canHaveComment())
570-
return std::nullopt;
571-
572-
auto *ModuleDC = D->getDeclContext()->getModuleScopeContext();
573-
auto &Ctx = ModuleDC->getASTContext();
574-
575-
// If we expect the comment to be in the swiftdoc, check for it if we loaded a
576-
// swiftdoc. If missing from the swiftdoc, we know it will not be in the
577-
// swiftsourceinfo either, so we can bail early.
578-
if (auto *Unit = dyn_cast<FileUnit>(ModuleDC)) {
579-
if (Unit->hasLoadedSwiftDoc()) {
580-
auto target = getDocCommentSerializationTargetFor(D);
581-
if (target == DocCommentSerializationTarget::SwiftDocAndSourceInfo) {
582-
auto C = Unit->getCommentForDecl(D);
583-
if (!C)
584-
return std::nullopt;
585-
586-
return C->Brief;
587-
}
588-
}
589-
}
590-
591-
// Otherwise, parse the brief from the raw comment itself. This will look into
592-
// the swiftsourceinfo if needed.
593-
auto RC = D->getRawComment();
594-
if (RC.isEmpty())
595-
return std::nullopt;
596-
597-
SmallString<256> BriefStr;
598-
llvm::raw_svector_ostream OS(BriefStr);
599-
printBriefComment(RC, OS);
600-
return Ctx.AllocateCopy(BriefStr.str());
601-
}
602-
603-
StringRef SemanticBriefCommentRequest::evaluate(Evaluator &evaluator,
604-
const Decl *D) const {
605-
// Perform a walk over the potential providers of the brief comment,
606-
// retrieving the first one we come across.
607-
CommentProviderFinder<StringRef> finder(getDirectBriefComment);
608-
auto result = finder.findCommentProvider(D);
609-
return result ? result->first : StringRef();
610-
}
611-
612-
StringRef Decl::getSemanticBriefComment() const {
613-
if (!this->canHaveComment())
614-
return StringRef();
615-
616-
auto &eval = getASTContext().evaluator;
617-
return evaluateOrDefault(eval, SemanticBriefCommentRequest{this},
618-
StringRef());
619-
}

lib/IDE/CommentConversion.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,32 @@ std::string ide::extractPlainTextFromComment(const StringRef Text) {
469469
return getLineListFromComment(SourceMgr, MC, Text).str();
470470
}
471471

472+
static DocComment *getCascadingDocComment(swift::markup::MarkupContext &MC,
473+
const Decl *D) {
474+
auto *docD = D->getDocCommentProvidingDecl();
475+
if (!docD)
476+
return nullptr;
477+
478+
auto *doc = getSingleDocComment(MC, docD);
479+
assert(doc && "getDocCommentProvidingDecl() returned decl with no comment");
480+
481+
// If the doc-comment is inherited from other decl, add a note about it.
482+
if (docD != D) {
483+
doc->setDecl(D);
484+
if (auto baseD = docD->getDeclContext()->getSelfNominalTypeDecl()) {
485+
doc->addInheritanceNote(MC, baseD);
486+
487+
// If the doc is inherited from protocol requirement, associate the
488+
// requirement with the doc-comment.
489+
// FIXME: This is to keep the old behavior.
490+
if (isa<ProtocolDecl>(baseD))
491+
doc->setDecl(docD);
492+
}
493+
}
494+
495+
return doc;
496+
}
497+
472498
bool ide::getDocumentationCommentAsXML(const Decl *D, raw_ostream &OS,
473499
TypeOrExtensionDecl SynthesizedTarget) {
474500
auto MaybeClangNode = D->getClangNode();
@@ -519,7 +545,7 @@ bool ide::getRawDocumentationComment(const Decl *D, raw_ostream &OS) {
519545
return true;
520546
}
521547

522-
const Decl *docD = getDocCommentProvidingDecl(D);
548+
const Decl *docD = D->getDocCommentProvidingDecl();
523549
if (!docD) {
524550
return false;
525551
}

lib/Sema/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
add_swift_host_library(swiftSema STATIC
33
AssociatedTypeInference.cpp
44
BuilderTransform.cpp
5+
Comment.cpp
56
CSApply.cpp
67
CSBindings.cpp
78
CSSyntacticElement.cpp

0 commit comments

Comments
 (0)