Skip to content

Commit 892dd45

Browse files
committed
SymbolGraph: Fixes for noncopyable generics and some small cleanups
1 parent a535948 commit 892dd45

File tree

8 files changed

+62
-43
lines changed

8 files changed

+62
-43
lines changed

lib/SymbolGraphGen/Edge.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,11 @@ void Edge::serialize(llvm::json::OStream &OS) const {
4747
SmallVector<Requirement, 4> FilteredRequirements;
4848
filterGenericRequirements(
4949
ConformanceExtension->getGenericRequirements(),
50-
ConformanceExtension->getExtendedNominal()
51-
->getDeclContext()->getSelfNominalTypeDecl(),
50+
ConformanceExtension->getExtendedProtocolDecl(),
5251
FilteredRequirements);
5352
if (!FilteredRequirements.empty()) {
5453
OS.attributeArray("swiftConstraints", [&](){
55-
for (const auto &Req :
56-
ConformanceExtension->getGenericRequirements()) {
54+
for (const auto &Req : FilteredRequirements) {
5755
::serialize(Req, OS);
5856
}
5957
});

lib/SymbolGraphGen/JSON.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ swift::symbolgraphgen::filterGenericParams(
216216
}
217217
}
218218

219+
// FIXME: This is wrong. We should instead compute the new requirements of a
220+
// member declaration by comparing against the generic signature of its
221+
// parent, with getRequirementsNotSatisfiedBy().
219222
static bool containsParams(swift::Type Ty, llvm::ArrayRef<const swift::GenericTypeParamType*> Others) {
220223
return Ty.findIf([&](swift::Type T) -> bool {
221224
if (auto AT = T->getAs<swift::ArchetypeType>()) {
@@ -232,20 +235,23 @@ static bool containsParams(swift::Type Ty, llvm::ArrayRef<const swift::GenericTy
232235

233236
void swift::symbolgraphgen::filterGenericRequirements(
234237
ArrayRef<Requirement> Requirements,
235-
const NominalTypeDecl *Self,
238+
const ProtocolDecl *Self,
236239
SmallVectorImpl<Requirement> &FilteredRequirements,
237240
SubstitutionMap SubMap,
238241
ArrayRef<const GenericTypeParamType *> FilteredParams) {
239242

240243
for (const auto &Req : Requirements) {
244+
// FIXME: We're just dropping "Self: AnyObject", etc.
241245
if (Req.getKind() == RequirementKind::Layout) {
242246
continue;
243247
}
244248
// extension /* protocol */ Q {
245249
// func foo() {}
246250
// }
247251
// ignore Self : Q, obvious
248-
if (Req.getSecondType()->getAnyNominal() == Self) {
252+
if (Self &&
253+
Req.getKind() == RequirementKind::Conformance &&
254+
Req.getProtocolDecl() == Self) {
249255
continue;
250256
}
251257

@@ -274,21 +280,31 @@ void swift::symbolgraphgen::filterGenericRequirements(
274280
void
275281
swift::symbolgraphgen::filterGenericRequirements(const ExtensionDecl *Extension,
276282
SmallVectorImpl<Requirement> &FilteredRequirements) {
277-
for (const auto &Req : Extension->getGenericRequirements()) {
278-
if (Req.getKind() == RequirementKind::Layout) {
279-
continue;
280-
}
283+
auto Sig = Extension->getGenericSignature();
284+
if (!Sig)
285+
return;
281286

282-
if (!isa<ProtocolDecl>(Extension->getExtendedNominal()) &&
283-
Req.getFirstType()->isEqual(Extension->getExtendedType())) {
287+
SmallVector<Requirement, 2> Reqs;
288+
SmallVector<InverseRequirement, 2> InverseReqs;
289+
Sig->getRequirementsWithInverses(Reqs, InverseReqs);
290+
// FIXME(noncopyable_generics): Do something with InverseReqs, or just use
291+
// getRequirements() above and update the tests.
292+
293+
for (const auto &Req : Reqs) {
294+
if (Req.getKind() == RequirementKind::Layout) {
284295
continue;
285296
}
286297

287298
// extension /* protocol */ Q
288299
// ignore Self : Q, obvious
289-
if (Req.getSecondType()->isEqual(Extension->getExtendedType())) {
290-
continue;
300+
if (auto *Proto = Extension->getExtendedProtocolDecl()) {
301+
if (Req.getKind() == RequirementKind::Conformance &&
302+
Req.getFirstType()->isEqual(Extension->getSelfInterfaceType()) &&
303+
Req.getProtocolDecl() == Proto) {
304+
continue;
305+
}
291306
}
307+
292308
FilteredRequirements.push_back(Req);
293309
}
294310
}

lib/SymbolGraphGen/JSON.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void filterGenericParams(
5353
/// Filter generic requirements on an extension that aren't relevant
5454
/// for documentation.
5555
void filterGenericRequirements(
56-
ArrayRef<Requirement> Requirements, const NominalTypeDecl *Self,
56+
ArrayRef<Requirement> Requirements, const ProtocolDecl *Self,
5757
SmallVectorImpl<Requirement> &FilteredRequirements,
5858
SubstitutionMap SubMap = {},
5959
ArrayRef<const GenericTypeParamType *> FilteredParams = {});

lib/SymbolGraphGen/Symbol.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,12 +516,18 @@ void Symbol::serializeSwiftGenericMixin(llvm::json::OStream &OS) const {
516516
filterGenericParams(Generics.getGenericParams(), FilteredParams,
517517
SubMap);
518518

519-
const auto *Self = dyn_cast<NominalTypeDecl>(D);
519+
const auto *Self = dyn_cast<ProtocolDecl>(D);
520520
if (!Self) {
521-
Self = D->getDeclContext()->getSelfNominalTypeDecl();
521+
Self = D->getDeclContext()->getSelfProtocolDecl();
522522
}
523523

524-
filterGenericRequirements(Generics.getRequirements(), Self,
524+
SmallVector<Requirement, 2> Reqs;
525+
SmallVector<InverseRequirement, 2> InverseReqs;
526+
Generics->getRequirementsWithInverses(Reqs, InverseReqs);
527+
// FIXME(noncopyable_generics): Do something with InverseReqs, or just use
528+
// getRequirements() above and update the tests.
529+
530+
filterGenericRequirements(Reqs, Self,
525531
FilteredRequirements, SubMap, FilteredParams);
526532

527533
if (FilteredParams.empty() && FilteredRequirements.empty()) {

lib/SymbolGraphGen/SymbolGraph.cpp

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ SymbolGraph::isRequirementOrDefaultImplementation(const ValueDecl *VD) const {
164164
// or a freestanding implementation from a protocol extension without
165165
// a corresponding requirement.
166166

167-
auto *Proto = dyn_cast_or_null<ProtocolDecl>(DC->getSelfNominalTypeDecl());
167+
auto *Proto = DC->getSelfProtocolDecl();
168168
if (!Proto) {
169169
return false;
170170
}
@@ -185,7 +185,8 @@ SymbolGraph::isRequirementOrDefaultImplementation(const ValueDecl *VD) const {
185185
if (FoundRequirementMemberNamed(VD->getName(), Proto)) {
186186
return true;
187187
}
188-
for (auto *Inherited : Proto->getInheritedProtocols()) {
188+
189+
for (auto *Inherited : Proto->getAllInheritedProtocols()) {
189190
if (FoundRequirementMemberNamed(VD->getName(), Inherited)) {
190191
return true;
191192
}
@@ -396,23 +397,18 @@ void SymbolGraph::recordConformanceSynthesizedMemberRelationships(Symbol S) {
396397

397398
void
398399
SymbolGraph::recordInheritanceRelationships(Symbol S) {
399-
const auto VD = S.getLocalSymbolDecl();
400-
if (const auto *NTD = dyn_cast<NominalTypeDecl>(VD)) {
401-
for (const auto &InheritanceLoc : NTD->getInherited().getEntries()) {
402-
auto Ty = InheritanceLoc.getType();
403-
if (!Ty) {
404-
continue;
405-
}
406-
auto *InheritedTypeDecl =
407-
dyn_cast_or_null<ClassDecl>(Ty->getAnyNominal());
408-
if (!InheritedTypeDecl) {
409-
continue;
410-
}
400+
const auto D = S.getLocalSymbolDecl();
411401

412-
recordEdge(Symbol(this, NTD, nullptr),
413-
Symbol(this, InheritedTypeDecl, nullptr),
414-
RelationshipKind::InheritsFrom());
415-
}
402+
ClassDecl *Super = nullptr;
403+
if (auto *CD = dyn_cast<ClassDecl>(D))
404+
Super = CD->getSuperclassDecl();
405+
else if (auto *PD = dyn_cast<ProtocolDecl>(D))
406+
Super = PD->getSuperclassDecl();
407+
408+
if (Super) {
409+
recordEdge(Symbol(this, cast<ValueDecl>(D), nullptr),
410+
Symbol(this, Super, nullptr),
411+
RelationshipKind::InheritsFrom());
416412
}
417413
}
418414

@@ -457,7 +453,7 @@ void SymbolGraph::recordDefaultImplementationRelationships(Symbol S) {
457453
if (const auto *Extension = dyn_cast<ExtensionDecl>(VD->getDeclContext())) {
458454
if (const auto *ExtendedProtocol = Extension->getExtendedProtocolDecl()) {
459455
HandleProtocol(ExtendedProtocol);
460-
for (const auto *Inherited : ExtendedProtocol->getInheritedProtocols()) {
456+
for (const auto *Inherited : ExtendedProtocol->getAllInheritedProtocols()) {
461457
HandleProtocol(Inherited);
462458
}
463459
}
@@ -493,11 +489,19 @@ void SymbolGraph::recordConformanceRelationships(Symbol S) {
493489
if (const auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
494490
if (auto *PD = dyn_cast<ProtocolDecl>(NTD)) {
495491
for (auto *inherited : PD->getAllInheritedProtocols()) {
492+
// FIXME(noncopyable_generics): Figure out what we want here.
493+
if (inherited->getInvertibleProtocolKind())
494+
continue;
495+
496496
recordEdge(S, Symbol(this, inherited, nullptr),
497497
RelationshipKind::ConformsTo(), nullptr);
498498
}
499499
} else {
500500
for (const auto *Conformance : NTD->getAllConformances()) {
501+
// FIXME(noncopyable_generics): Figure out what we want here.
502+
if (Conformance->getProtocol()->getInvertibleProtocolKind())
503+
continue;
504+
501505
// Check to make sure that this conformance wasn't declared via an
502506
// unconditionally-unavailable extension. If so, don't add that to the graph.
503507
if (const auto *ED = dyn_cast_or_null<ExtensionDecl>(Conformance->getDeclContext())) {
@@ -778,6 +782,7 @@ bool SymbolGraph::isImplicitlyPrivate(const Decl *D,
778782
return false;
779783
}
780784

785+
/// FIXME: This should use AvailableAttr::isUnavailable() or similar.
781786
bool SymbolGraph::isUnconditionallyUnavailableOnAllPlatforms(const Decl *D) const {
782787
return llvm::any_of(D->getAttrs(), [](const auto *Attr) {
783788
if (const auto *AvAttr = dyn_cast<AvailableAttr>(Attr)) {

test/SymbolGraph/Symbols/Mixins/Generics/Arguments.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
// RUN: %target-swift-symbolgraph-extract -module-name Arguments -I %t -pretty-print -output-dir %t
44
// RUN: %FileCheck %s --input-file %t/Arguments.symbols.json
55

6-
// XFAIL: noncopyable_generics
7-
86
public struct MyStruct<T> {
97
public var x: T
108
public init(x: T) {

test/SymbolGraph/Symbols/SkipProtocolImplementations.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@
3636
// COUNT-COUNT-3: sourceOrigin
3737
// COUNT-NOT: sourceOrigin
3838

39-
// XFAIL: noncopyable_generics
40-
4139
public protocol SomeProtocol {
4240
/// Base docs
4341
func someFunc()

test/SymbolGraph/Symbols/SkipsPublicUnderscore.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
// RUN: %target-swift-symbolgraph-extract -module-name SkipsPublicUnderscore -I %t -pretty-print -output-dir %t -minimum-access-level private
1010
// RUN: %FileCheck %s --input-file %t/SkipsPublicUnderscore.symbols.json --check-prefix PRIVATE
1111

12-
// XFAIL: noncopyable_generics
13-
1412
public protocol PublicProtocol {}
1513

1614
public class SomeClass {

0 commit comments

Comments
 (0)