Skip to content

Commit 66fb806

Browse files
committed
ModulePrinting: For decls without doc-comment, we print the doc-comment associated with their conformances, if any.
Inspired by rdar://24409720
1 parent 5d99f7a commit 66fb806

File tree

7 files changed

+74
-9
lines changed

7 files changed

+74
-9
lines changed

include/swift/AST/ASTPrinter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace swift {
2929
class Pattern;
3030
class ExtensionDecl;
3131
class NominalTypeDecl;
32+
class ValueDecl;
3233
struct PrintOptions;
3334

3435
/// Describes the context in which a name is being printed, which
@@ -253,6 +254,7 @@ class ASTPrinter {
253254

254255
/// To sanitize a malformed utf8 string to a well-formed one.
255256
static std::string sanitizeUtf8(StringRef Text);
257+
static ValueDecl* findConformancesWithDocComment(ValueDecl *VD);
256258
static bool printTypeInterface(Type Ty, DeclContext *DC, std::string &Result);
257259
static bool printTypeInterface(Type Ty, DeclContext *DC, llvm::raw_ostream &Out);
258260

include/swift/AST/PrintOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,10 @@ struct PrintOptions {
243243
BothAlways,
244244
};
245245

246+
/// Whether to print the doc-comment from the conformance if a member decl
247+
/// has no associated doc-comment by itself.
248+
bool ElevateDocCommentFromConformance = false;
249+
246250
/// Whether to print the content of an extension decl inside the type decl where it
247251
/// extends from.
248252
std::function<bool(const ExtensionDecl *)> printExtensionContentAsMembers =
@@ -322,6 +326,7 @@ struct PrintOptions {
322326
result.SkipDeinit = true;
323327
result.ExcludeAttrList.push_back(DAK_WarnUnusedResult);
324328
result.EmptyLineBetweenMembers = true;
329+
result.ElevateDocCommentFromConformance = true;
325330
return result;
326331
}
327332

include/swift/IDE/ModuleInterfacePrinting.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ typedef OptionSet<ModuleTraversal> ModuleTraversalOptions;
4343
ArrayRef<StringRef> collectModuleGroups(ModuleDecl *M,
4444
std::vector<StringRef> &Scratch);
4545

46-
void printModuleInterface(ModuleDecl *M,
46+
void printModuleInterface(ModuleDecl *M, Optional<StringRef> Group,
4747
ModuleTraversalOptions TraversalOptions,
4848
ASTPrinter &Printer, const PrintOptions &Options,
4949
const bool PrintSynthesizedExtensions);

lib/AST/ASTPrinter.cpp

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "llvm/Support/raw_ostream.h"
4747
#include "llvm/Support/SaveAndRestore.h"
4848
#include <algorithm>
49+
#include <queue>
4950

5051
using namespace swift;
5152
namespace swift {
@@ -708,6 +709,24 @@ std::string ASTPrinter::sanitizeUtf8(StringRef Text) {
708709
return Builder.str();
709710
}
710711

712+
ValueDecl* ASTPrinter::findConformancesWithDocComment(ValueDecl *VD) {
713+
assert(VD->getRawComment().isEmpty());
714+
std::queue<ValueDecl*> AllConformances;
715+
AllConformances.push(VD);
716+
while(!AllConformances.empty()) {
717+
auto *VD = AllConformances.front();
718+
AllConformances.pop();
719+
if (VD->getRawComment().isEmpty()) {
720+
for (auto *Req : VD->getSatisfiedProtocolRequirements()) {
721+
AllConformances.push(Req);
722+
}
723+
} else {
724+
return VD;
725+
}
726+
}
727+
return nullptr;
728+
}
729+
711730
bool ASTPrinter::printTypeInterface(Type Ty, DeclContext *DC,
712731
llvm::raw_ostream &OS) {
713732
if (!Ty)
@@ -969,11 +988,7 @@ class PrintAST : public ASTVisitor<PrintAST> {
969988
}
970989
}
971990

972-
void printSwiftDocumentationComment(const Decl *D) {
973-
auto RC = D->getRawComment();
974-
if (RC.isEmpty())
975-
return;
976-
991+
void printRawComment(RawComment RC) {
977992
indent();
978993

979994
SmallVector<StringRef, 8> Lines;
@@ -991,6 +1006,23 @@ class PrintAST : public ASTVisitor<PrintAST> {
9911006
}
9921007
}
9931008

1009+
void printSwiftDocumentationComment(const Decl *D) {
1010+
auto RC = D->getRawComment();
1011+
if (RC.isEmpty() && !Options.ElevateDocCommentFromConformance)
1012+
return;
1013+
1014+
if (RC.isEmpty()) {
1015+
if (auto *VD = dyn_cast<ValueDecl>(D)) {
1016+
if (auto *Req = ASTPrinter::findConformancesWithDocComment(
1017+
const_cast<ValueDecl*>(VD))) {
1018+
printRawComment(Req->getRawComment());
1019+
}
1020+
}
1021+
} else {
1022+
printRawComment(RC);
1023+
}
1024+
}
1025+
9941026
void printDocumentationComment(const Decl *D) {
9951027
if (!Options.PrintDocumentationComments)
9961028
return;

lib/IDE/ModuleInterfacePrinting.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,13 @@ getUnderlyingClangModuleForImport(ImportDecl *Import) {
145145
return nullptr;
146146
}
147147

148-
void swift::ide::printModuleInterface(Module *M,
148+
void swift::ide::printModuleInterface(Module *M, Optional<StringRef> Group,
149149
ModuleTraversalOptions TraversalOptions,
150150
ASTPrinter &Printer,
151151
const PrintOptions &Options,
152152
const bool PrintSynthesizedExtensions) {
153-
printSubmoduleInterface(M, M->getName().str(), ArrayRef<StringRef>(),
153+
printSubmoduleInterface(M, M->getName().str(),
154+
Group.hasValue() ? Group.getValue() : ArrayRef<StringRef>(),
154155
TraversalOptions, Printer, Options,
155156
PrintSynthesizedExtensions);
156157
}

test/IDE/print_swift_module.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: rm -rf %t && mkdir %t
2+
// RUN: %target-swift-frontend -emit-module-path %t/print_swift_module.swiftmodule -emit-module-doc -emit-module-doc-path %t/print_swift_module.swiftdoc %s
3+
// RUN: %target-swift-ide-test -print-module -print-interface -no-empty-line-between-members -module-to-print=print_swift_module -I %t -source-filename=%s > %t.syn.txt
4+
// RUN: FileCheck %s -check-prefix=CHECK1 < %t.syn.txt
5+
6+
public protocol P1 {
7+
/// foo1 comment from P1
8+
func foo1()
9+
/// foo2 comment from P1
10+
func foo2()
11+
}
12+
public class C1 : P1 {
13+
public func foo1() {
14+
}
15+
/// foo2 comment from C1
16+
public func foo2() {
17+
}
18+
}
19+
20+
// CHECK1: public class C1 : P1 {
21+
// CHECK1-NEXT: /// foo1 comment from P1
22+
// CHECK1-NEXT: public func foo1()
23+
// CHECK1-NEXT: /// foo2 comment from C1
24+
// CHECK1-NEXT: public func foo2()
25+
// CHECK1-NEXT: }

tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ static bool getModuleInterfaceInfo(ASTContext &Ctx, StringRef ModuleName,
676676
SmallString<128> Text;
677677
llvm::raw_svector_ostream OS(Text);
678678
AnnotatingPrinter Printer(OS);
679-
printModuleInterface(M, TraversalOptions, Printer, Options, false);
679+
printModuleInterface(M, None, TraversalOptions, Printer, Options, false);
680680

681681
Info.Text = OS.str();
682682
Info.TopEntities = std::move(Printer.TopEntities);

0 commit comments

Comments
 (0)