Skip to content

Commit d4f704b

Browse files
committed
ASTPrinter: Add pre and post callbacks for printing synthesized extensions and call them.
This is necessary for jump to synthesized extensions in IDE.
1 parent d4ece4b commit d4f704b

File tree

6 files changed

+72
-20
lines changed

6 files changed

+72
-20
lines changed

include/swift/AST/ASTPrinter.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ namespace swift {
2525
class TypeDecl;
2626
class Type;
2727
class Pattern;
28+
class ExtensionDecl;
29+
class NominalTypeDecl;
2830
struct PrintOptions;
2931

3032
/// Describes the context in which a name is being printed, which
@@ -45,6 +47,7 @@ class ASTPrinter {
4547
unsigned PendingNewlines = 0;
4648
const Decl *PendingDeclPreCallback = nullptr;
4749
const Decl *PendingDeclLocCallback = nullptr;
50+
const NominalTypeDecl *SynthesizeTarget = nullptr;
4851

4952
void printTextImpl(StringRef Text);
5053

@@ -74,6 +77,14 @@ class ASTPrinter {
7477
/// Called when printing the referenced name of a module.
7578
virtual void printModuleRef(ModuleEntity Mod, Identifier Name);
7679

80+
/// Called before printing a synthesized extesion.
81+
virtual void printSynthesizedExtensionPre(const ExtensionDecl *ED,
82+
const NominalTypeDecl *NTD) {}
83+
84+
/// Called after printing a synthesized extension.
85+
virtual void printSynthesizedExtensionPost(const ExtensionDecl *ED,
86+
const NominalTypeDecl *NTD) {}
87+
7788
// Helper functions.
7889

7990
ASTPrinter &operator<<(StringRef Text) {
@@ -93,6 +104,10 @@ class ASTPrinter {
93104
CurrentIndentation = NumSpaces;
94105
}
95106

107+
void setSynthesizedTarget(NominalTypeDecl *Target) {
108+
SynthesizeTarget = Target;
109+
}
110+
96111
void printNewline() {
97112
PendingNewlines++;
98113
}

include/swift/AST/PrintOptions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ struct PrintOptions {
257257

258258
void initArchetypeTransformerForSynthesizedExtensions(NominalTypeDecl *D);
259259

260+
bool isPrintingSynthesizedExtension();
261+
260262
void clearArchetypeTransformerForSynthesizedExtensions();
261263

262264
/// Retrieve the print options that are suitable to print the testable interface.

lib/AST/ASTPrinter.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ void PrintOptions::initArchetypeTransformerForSynthesizedExtensions(NominalTypeD
217217
SynthesizedTarget = D;
218218
}
219219

220+
bool PrintOptions::isPrintingSynthesizedExtension() {
221+
return pTransformer && SynthesizedTarget;
222+
}
223+
220224
void PrintOptions::clearArchetypeTransformerForSynthesizedExtensions() {
221225
pTransformer = nullptr;
222226
SynthesizedTarget = nullptr;
@@ -301,7 +305,10 @@ void ASTPrinter::printTextImpl(StringRef Text) {
301305
PendingDeclLocCallback = nullptr;
302306

303307
if (PreD) {
304-
printDeclPre(PreD);
308+
if (SynthesizeTarget && PreD->getKind() == DeclKind::Extension)
309+
printSynthesizedExtensionPre(cast<ExtensionDecl>(PreD), SynthesizeTarget);
310+
else
311+
printDeclPre(PreD);
305312
}
306313
if (LocD) {
307314
printDeclLoc(LocD);
@@ -636,9 +643,19 @@ class PrintAST : public ASTVisitor<PrintAST> {
636643
if (!shouldPrint(D, true))
637644
return false;
638645

646+
bool Synthesize = Options.isPrintingSynthesizedExtension() &&
647+
D->getKind() == DeclKind::Extension;
648+
if (Synthesize)
649+
Printer.setSynthesizedTarget(Options.SynthesizedTarget);
639650
Printer.callPrintDeclPre(D);
640651
ASTVisitor::visit(D);
641-
Printer.printDeclPost(D);
652+
if (Synthesize) {
653+
Printer.setSynthesizedTarget(nullptr);
654+
Printer.printSynthesizedExtensionPost(cast<ExtensionDecl>(D),
655+
Options.SynthesizedTarget);
656+
} else {
657+
Printer.printDeclPost(D);
658+
}
642659
return true;
643660
}
644661

@@ -1415,6 +1432,8 @@ void PrintAST::visitImportDecl(ImportDecl *decl) {
14151432
}
14161433

14171434
void PrintAST::printSynthesizedExtension(NominalTypeDecl* Decl, ExtensionDecl* ExtDecl) {
1435+
Printer << "/// Synthesized extension from " <<
1436+
ExtDecl->getExtendedType()->getAnyNominal()->getName().str() << "\n";
14181437
printDocumentationComment(ExtDecl);
14191438
printAttributes(ExtDecl);
14201439
Printer << "extension ";

lib/IDE/ModuleInterfacePrinting.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ class ClangCommentPrinter : public ASTPrinter {
6868
void printModuleRef(ModuleEntity Mod, Identifier Name) override {
6969
return OtherPrinter.printModuleRef(Mod, Name);
7070
}
71+
void printSynthesizedExtensionPre(const ExtensionDecl *ED,
72+
const NominalTypeDecl *NTD) override {
73+
return OtherPrinter.printSynthesizedExtensionPre(ED, NTD);
74+
}
75+
76+
void printSynthesizedExtensionPost(const ExtensionDecl *ED,
77+
const NominalTypeDecl *NTD) override {
78+
return OtherPrinter.printSynthesizedExtensionPost(ED, NTD);
79+
}
7180

7281
// Prints regular comments of the header the clang node comes from, until
7382
// the location of the node. Keeps track of the comments that were printed
@@ -435,9 +444,6 @@ void swift::ide::printSubmoduleInterface(
435444
if (!shouldPrint(ET, AdjustedOptions))
436445
continue;
437446
Printer << "\n";
438-
Printer << "/// Synthesized extension from ";
439-
ET->getExtendedTypeLoc().getType().print(Printer, AdjustedOptions);
440-
Printer << "\n";
441447
ET->print(Printer, AdjustedOptions);
442448
Printer << "\n";
443449
}

test/IDE/print_synthesized_extensions.swift

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: rm -rf %t && mkdir %t
22
// RUN: %target-swift-frontend -emit-module-path %t/print_synthesized_extensions.swiftmodule %s
3-
// RUN: %target-swift-ide-test -print-module -synthesize-extension -print-interface -module-to-print=print_synthesized_extensions -I %t -source-filename=%s | FileCheck %s
3+
// RUN: %target-swift-ide-test -print-module -annotate-print -synthesize-extension -print-interface -module-to-print=print_synthesized_extensions -I %t -source-filename=%s | FileCheck %s
44

55
public protocol P1{
66
associatedtype T1
@@ -47,24 +47,24 @@ public struct S1<T> : P1, P2 {
4747
}
4848
}
4949

50-
// CHECK: /// Synthesized extension from P2
50+
// CHECK: <synthesized>/// Synthesized extension from P2
5151
// CHECK: extension S1 where T : P2 {
52-
// CHECK: public func p2member()
53-
// CHECK: }
52+
// CHECK: <decl:Func>public func <loc>p2member()</loc></decl>
53+
// CHECK: }</synthesized>
5454

55-
// CHECK: /// Synthesized extension from P1
55+
// CHECK: <synthesized>/// Synthesized extension from P1
5656
// CHECK: extension S1 where T : P2 {
57-
// CHECK: public func ef1(t: T)
58-
// CHECK: public func ef2(t: S2)
59-
// CHECK: }
57+
// CHECK: <decl:Func>public func <loc>ef1(t: T)</loc></decl>
58+
// CHECK: <decl:Func>public func <loc>ef2(t: <ref:Struct>S2</ref>)</loc></decl>
59+
// CHECK: }</synthesized>
6060

61-
// CHECK: /// Synthesized extension from P1
61+
// CHECK: <synthesized>/// Synthesized extension from P1
6262
// CHECK: extension S1 where T == P2, S2 : P3 {
63-
// CHECK: public func ef3(t: P2)
64-
// CHECK: public func ef4(t: P2)
65-
// CHECK: }
63+
// CHECK: <decl:Func>public func <loc>ef3(t: <ref:Protocol>P2</ref>)</loc></decl>
64+
// CHECK: <decl:Func>public func <loc>ef4(t: <ref:Protocol>P2</ref>)</loc></decl>
65+
// CHECK: }</synthesized>
6666

67-
// CHECK: /// Synthesized extension from P1
67+
// CHECK: <synthesized>/// Synthesized extension from P1
6868
// CHECK: extension S1 where S2 : P3 {
69-
// CHECK: public func ef5(t: S2)
70-
// CHECK: }
69+
// CHECK: <decl:Func>public func <loc>ef5(t: <ref:Struct>S2</ref>)</loc></decl>
70+
// CHECK: }</synthesized>

tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,16 @@ class AnnotatingPrinter : public StreamPrinter {
15711571
OS << "</decl>";
15721572
}
15731573

1574+
void printSynthesizedExtensionPre(const ExtensionDecl *ED,
1575+
const NominalTypeDecl *NTD) override {
1576+
OS << "<synthesized>";
1577+
}
1578+
1579+
void printSynthesizedExtensionPost(const ExtensionDecl *ED,
1580+
const NominalTypeDecl *NTD) override {
1581+
OS << "</synthesized>";
1582+
}
1583+
15741584
void printTypeRef(const TypeDecl *TD, Identifier Name) override {
15751585
OS << "<ref:" << Decl::getKindName(TD->getKind()) << '>';
15761586
StreamPrinter::printTypeRef(TD, Name);

0 commit comments

Comments
 (0)