Skip to content

Commit a8ecfc9

Browse files
consider requirements of an underscored protocol to also be underscored (#59480)
rdar://94336558
1 parent 45820d3 commit a8ecfc9

File tree

2 files changed

+63
-3
lines changed

2 files changed

+63
-3
lines changed

lib/SymbolGraphGen/SymbolGraph.cpp

+51-1
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,56 @@ SymbolGraph::serializeDeclarationFragments(StringRef Key, Type T,
574574
T->print(Printer, Options);
575575
}
576576

577+
namespace {
578+
579+
/// Returns the first satisfied protocol requirement for the given decl.
580+
const ValueDecl *getProtocolRequirement(const ValueDecl *VD) {
581+
auto reqs = VD->getSatisfiedProtocolRequirements();
582+
583+
if (!reqs.empty())
584+
return reqs.front();
585+
else
586+
return nullptr;
587+
}
588+
589+
/// Returns the protocol that the given decl is a requirement or conformance of, if any.
590+
const ProtocolDecl *getSourceProtocol(const Decl *D) {
591+
const auto *DC = D->getDeclContext();
592+
593+
// First check to see whether it's declared directly in the protocol decl
594+
if (const auto *P = dyn_cast<ProtocolDecl>(DC))
595+
return P;
596+
597+
// Next look at whether it's an extension on a protocol
598+
if (const auto *Extension = dyn_cast<ExtensionDecl>(DC)) {
599+
if (const auto *ExtendedProtocol = Extension->getExtendedProtocolDecl()) {
600+
return ExtendedProtocol;
601+
}
602+
}
603+
604+
// Then check to see whether it's an implementation of a protocol requirement
605+
if (const auto *VD = dyn_cast<ValueDecl>(D)) {
606+
if (const auto *Requirement = getProtocolRequirement(VD)) {
607+
if (const auto *P = dyn_cast<ProtocolDecl>(Requirement->getDeclContext())) {
608+
return P;
609+
}
610+
}
611+
}
612+
613+
// If all those didn't work, there's no protocol to fetch
614+
return nullptr;
615+
}
616+
617+
/// Returns whether the given decl is from a protocol, and that protocol has an underscored name.
618+
bool isFromUnderscoredProtocol(const Decl *D) {
619+
if (const auto *P = getSourceProtocol(D))
620+
return P->hasUnderscoredNaming();
621+
622+
return false;
623+
}
624+
625+
}
626+
577627
bool SymbolGraph::isImplicitlyPrivate(const Decl *D,
578628
bool IgnoreContext) const {
579629
// Don't record unconditionally private declarations
@@ -582,7 +632,7 @@ bool SymbolGraph::isImplicitlyPrivate(const Decl *D,
582632
}
583633

584634
// Don't record effectively internal declarations if specified
585-
if (D->hasUnderscoredNaming()) {
635+
if (D->hasUnderscoredNaming() || isFromUnderscoredProtocol(D)) {
586636
// Some implicit decls from Clang with underscored names sneak in, so throw those out
587637
if (const auto *clangD = D->getClangDecl()) {
588638
if (clangD->isImplicit())

test/SymbolGraph/Symbols/SkipsPublicUnderscore.swift

+12-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ public class SomeClass {
2222

2323
// PUBLIC-NOT: precise:{{.*}}_ProtocolShouldntAppear
2424
// PUBLIC-NOT: precise:{{.*}}PublicProtocol
25+
// PUBLIC-NOT: precise:{{.*}}someHiddenVar
2526
@_show_in_interface
26-
public protocol _ProtocolShouldntAppear {}
27+
public protocol _ProtocolShouldntAppear {
28+
static var someHiddenVar: String { get }
29+
}
2730

2831
// PUBLIC-NOT: _ShouldntAppear
2932
// INTERNAL-DAG: _ShouldntAppear
@@ -46,11 +49,18 @@ public struct _ShouldntAppear: PublicProtocol, _ProtocolShouldntAppear {
4649
// INTERNAL-DAG: InnerInnerShouldntAppear
4750
public struct InnerInnerShouldntAppear {}
4851
}
52+
53+
// INTERNAL-DAG: "precise": "s:21SkipsPublicUnderscore15_ShouldntAppearV13someHiddenVarSSvpZ"
54+
public static var someHiddenVar: String { "someHiddenVar" }
4955
}
5056

5157
// A public type's relationship to an "internal" protocol
5258
// shouldn't cause it to be included.
53-
public struct ShouldAppear: _ProtocolShouldntAppear {}
59+
public struct ShouldAppear {}
60+
61+
extension ShouldAppear: _ProtocolShouldntAppear {
62+
public static var someHiddenVar: String { "someHiddenVar" }
63+
}
5464

5565
public struct PublicOuter {
5666
// Nor should an "internal" type's relationship to a "public" protocol.

0 commit comments

Comments
 (0)