|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 |
|
13 | 13 | #include "clang/AST/DeclObjC.h"
|
| 14 | +#include "swift/AST/ASTContext.h" |
14 | 15 | #include "swift/AST/Decl.h"
|
15 | 16 | #include "swift/AST/Module.h"
|
16 | 17 | #include "swift/AST/ProtocolConformance.h"
|
@@ -218,6 +219,28 @@ void SymbolGraph::recordSuperclassSynthesizedMemberRelationships(Symbol S) {
|
218 | 219 | }
|
219 | 220 | }
|
220 | 221 |
|
| 222 | +bool SymbolGraph::synthesizedMemberIsBestCandidate(const ValueDecl *VD, |
| 223 | + const NominalTypeDecl *Owner) const { |
| 224 | + const auto *FD = dyn_cast<FuncDecl>(VD); |
| 225 | + if (!FD) { |
| 226 | + return true; |
| 227 | + } |
| 228 | + auto *DC = const_cast<DeclContext*>(Owner->getDeclContext()); |
| 229 | + |
| 230 | + ResolvedMemberResult Result = |
| 231 | + resolveValueMember(*DC, Owner->getSelfTypeInContext(), |
| 232 | + FD->getEffectiveFullName()); |
| 233 | + |
| 234 | + const auto ViableCandidates = |
| 235 | + Result.getMemberDecls(InterestedMemberKind::All); |
| 236 | + |
| 237 | + if (ViableCandidates.size() < 2) { |
| 238 | + return true; |
| 239 | + } |
| 240 | + |
| 241 | + return !(Result.hasBestOverload() && Result.getBestOverload() != VD); |
| 242 | +} |
| 243 | + |
221 | 244 | void SymbolGraph::recordConformanceSynthesizedMemberRelationships(Symbol S) {
|
222 | 245 | if (!Walker.Options.EmitSynthesizedMembers) {
|
223 | 246 | return;
|
@@ -264,14 +287,22 @@ void SymbolGraph::recordConformanceSynthesizedMemberRelationships(Symbol S) {
|
264 | 287 | continue;
|
265 | 288 | }
|
266 | 289 |
|
| 290 | + const auto StdlibModule = OwningNominal->getASTContext() |
| 291 | + .getStdlibModule(/*loadIfAbsent=*/true); |
| 292 | + |
267 | 293 | // There can be synthesized members on effectively private protocols
|
268 | 294 | // or things that conform to them. We don't want to include those.
|
269 |
| - if (SynthMember->hasUnderscoredNaming()) { |
| 295 | + if (isImplicitlyPrivate(SynthMember, |
| 296 | + /*IgnoreContext =*/ |
| 297 | + SynthMember->getModuleContext() == StdlibModule)) { |
| 298 | + continue; |
| 299 | + } |
| 300 | + |
| 301 | + if (!synthesizedMemberIsBestCandidate(SynthMember, OwningNominal)) { |
270 | 302 | continue;
|
271 | 303 | }
|
272 | 304 |
|
273 |
| - auto ExtendedSG = |
274 |
| - Walker.getModuleSymbolGraph(OwningNominal->getModuleContext()); |
| 305 | + auto ExtendedSG = Walker.getModuleSymbolGraph(OwningNominal); |
275 | 306 |
|
276 | 307 | Symbol Source(this, SynthMember, OwningNominal);
|
277 | 308 | Symbol Target(this, OwningNominal, nullptr);
|
@@ -501,7 +532,8 @@ SymbolGraph::serializeDeclarationFragments(StringRef Key, Type T,
|
501 | 532 | T->print(Printer, getDeclarationFragmentsPrintOptions());
|
502 | 533 | }
|
503 | 534 |
|
504 |
| -bool SymbolGraph::isImplicitlyPrivate(const ValueDecl *VD) const { |
| 535 | +bool SymbolGraph::isImplicitlyPrivate(const ValueDecl *VD, |
| 536 | + bool IgnoreContext) const { |
505 | 537 | // Don't record unconditionally private declarations
|
506 | 538 | if (VD->isPrivateStdlibDecl(/*treatNonBuiltinProtocolsAsPublic=*/false)) {
|
507 | 539 | return true;
|
@@ -550,15 +582,19 @@ bool SymbolGraph::isImplicitlyPrivate(const ValueDecl *VD) const {
|
550 | 582 | return true;
|
551 | 583 | }
|
552 | 584 |
|
| 585 | + if (IgnoreContext) { |
| 586 | + return false; |
| 587 | + } |
| 588 | + |
553 | 589 | // Check up the parent chain. Anything inside a privately named
|
554 | 590 | // thing is also private. We could be looking at the `B` of `_A.B`.
|
555 | 591 | if (const auto *DC = VD->getDeclContext()) {
|
556 | 592 | if (const auto *Parent = DC->getAsDecl()) {
|
557 | 593 | if (const auto *ParentVD = dyn_cast<ValueDecl>(Parent)) {
|
558 |
| - return isImplicitlyPrivate(ParentVD); |
| 594 | + return isImplicitlyPrivate(ParentVD, IgnoreContext); |
559 | 595 | } else if (const auto *Extension = dyn_cast<ExtensionDecl>(Parent)) {
|
560 | 596 | if (const auto *Nominal = Extension->getExtendedNominal()) {
|
561 |
| - return isImplicitlyPrivate(Nominal); |
| 597 | + return isImplicitlyPrivate(Nominal, IgnoreContext); |
562 | 598 | }
|
563 | 599 | }
|
564 | 600 | }
|
|
0 commit comments