Skip to content

Commit

Permalink
SymbolGraph: Fixes for noncopyable generics and some small cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
slavapestov committed Mar 1, 2024
1 parent a535948 commit 892dd45
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 43 deletions.
6 changes: 2 additions & 4 deletions lib/SymbolGraphGen/Edge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,11 @@ void Edge::serialize(llvm::json::OStream &OS) const {
SmallVector<Requirement, 4> FilteredRequirements;
filterGenericRequirements(
ConformanceExtension->getGenericRequirements(),
ConformanceExtension->getExtendedNominal()
->getDeclContext()->getSelfNominalTypeDecl(),
ConformanceExtension->getExtendedProtocolDecl(),
FilteredRequirements);
if (!FilteredRequirements.empty()) {
OS.attributeArray("swiftConstraints", [&](){
for (const auto &Req :
ConformanceExtension->getGenericRequirements()) {
for (const auto &Req : FilteredRequirements) {
::serialize(Req, OS);
}
});
Expand Down
36 changes: 26 additions & 10 deletions lib/SymbolGraphGen/JSON.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ swift::symbolgraphgen::filterGenericParams(
}
}

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

void swift::symbolgraphgen::filterGenericRequirements(
ArrayRef<Requirement> Requirements,
const NominalTypeDecl *Self,
const ProtocolDecl *Self,
SmallVectorImpl<Requirement> &FilteredRequirements,
SubstitutionMap SubMap,
ArrayRef<const GenericTypeParamType *> FilteredParams) {

for (const auto &Req : Requirements) {
// FIXME: We're just dropping "Self: AnyObject", etc.
if (Req.getKind() == RequirementKind::Layout) {
continue;
}
// extension /* protocol */ Q {
// func foo() {}
// }
// ignore Self : Q, obvious
if (Req.getSecondType()->getAnyNominal() == Self) {
if (Self &&
Req.getKind() == RequirementKind::Conformance &&
Req.getProtocolDecl() == Self) {
continue;
}

Expand Down Expand Up @@ -274,21 +280,31 @@ void swift::symbolgraphgen::filterGenericRequirements(
void
swift::symbolgraphgen::filterGenericRequirements(const ExtensionDecl *Extension,
SmallVectorImpl<Requirement> &FilteredRequirements) {
for (const auto &Req : Extension->getGenericRequirements()) {
if (Req.getKind() == RequirementKind::Layout) {
continue;
}
auto Sig = Extension->getGenericSignature();
if (!Sig)
return;

if (!isa<ProtocolDecl>(Extension->getExtendedNominal()) &&
Req.getFirstType()->isEqual(Extension->getExtendedType())) {
SmallVector<Requirement, 2> Reqs;
SmallVector<InverseRequirement, 2> InverseReqs;
Sig->getRequirementsWithInverses(Reqs, InverseReqs);
// FIXME(noncopyable_generics): Do something with InverseReqs, or just use
// getRequirements() above and update the tests.

for (const auto &Req : Reqs) {
if (Req.getKind() == RequirementKind::Layout) {
continue;
}

// extension /* protocol */ Q
// ignore Self : Q, obvious
if (Req.getSecondType()->isEqual(Extension->getExtendedType())) {
continue;
if (auto *Proto = Extension->getExtendedProtocolDecl()) {
if (Req.getKind() == RequirementKind::Conformance &&
Req.getFirstType()->isEqual(Extension->getSelfInterfaceType()) &&
Req.getProtocolDecl() == Proto) {
continue;
}
}

FilteredRequirements.push_back(Req);
}
}
2 changes: 1 addition & 1 deletion lib/SymbolGraphGen/JSON.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void filterGenericParams(
/// Filter generic requirements on an extension that aren't relevant
/// for documentation.
void filterGenericRequirements(
ArrayRef<Requirement> Requirements, const NominalTypeDecl *Self,
ArrayRef<Requirement> Requirements, const ProtocolDecl *Self,
SmallVectorImpl<Requirement> &FilteredRequirements,
SubstitutionMap SubMap = {},
ArrayRef<const GenericTypeParamType *> FilteredParams = {});
Expand Down
12 changes: 9 additions & 3 deletions lib/SymbolGraphGen/Symbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,12 +516,18 @@ void Symbol::serializeSwiftGenericMixin(llvm::json::OStream &OS) const {
filterGenericParams(Generics.getGenericParams(), FilteredParams,
SubMap);

const auto *Self = dyn_cast<NominalTypeDecl>(D);
const auto *Self = dyn_cast<ProtocolDecl>(D);
if (!Self) {
Self = D->getDeclContext()->getSelfNominalTypeDecl();
Self = D->getDeclContext()->getSelfProtocolDecl();
}

filterGenericRequirements(Generics.getRequirements(), Self,
SmallVector<Requirement, 2> Reqs;
SmallVector<InverseRequirement, 2> InverseReqs;
Generics->getRequirementsWithInverses(Reqs, InverseReqs);
// FIXME(noncopyable_generics): Do something with InverseReqs, or just use
// getRequirements() above and update the tests.

filterGenericRequirements(Reqs, Self,
FilteredRequirements, SubMap, FilteredParams);

if (FilteredParams.empty() && FilteredRequirements.empty()) {
Expand Down
43 changes: 24 additions & 19 deletions lib/SymbolGraphGen/SymbolGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ SymbolGraph::isRequirementOrDefaultImplementation(const ValueDecl *VD) const {
// or a freestanding implementation from a protocol extension without
// a corresponding requirement.

auto *Proto = dyn_cast_or_null<ProtocolDecl>(DC->getSelfNominalTypeDecl());
auto *Proto = DC->getSelfProtocolDecl();
if (!Proto) {
return false;
}
Expand All @@ -185,7 +185,8 @@ SymbolGraph::isRequirementOrDefaultImplementation(const ValueDecl *VD) const {
if (FoundRequirementMemberNamed(VD->getName(), Proto)) {
return true;
}
for (auto *Inherited : Proto->getInheritedProtocols()) {

for (auto *Inherited : Proto->getAllInheritedProtocols()) {
if (FoundRequirementMemberNamed(VD->getName(), Inherited)) {
return true;
}
Expand Down Expand Up @@ -396,23 +397,18 @@ void SymbolGraph::recordConformanceSynthesizedMemberRelationships(Symbol S) {

void
SymbolGraph::recordInheritanceRelationships(Symbol S) {
const auto VD = S.getLocalSymbolDecl();
if (const auto *NTD = dyn_cast<NominalTypeDecl>(VD)) {
for (const auto &InheritanceLoc : NTD->getInherited().getEntries()) {
auto Ty = InheritanceLoc.getType();
if (!Ty) {
continue;
}
auto *InheritedTypeDecl =
dyn_cast_or_null<ClassDecl>(Ty->getAnyNominal());
if (!InheritedTypeDecl) {
continue;
}
const auto D = S.getLocalSymbolDecl();

recordEdge(Symbol(this, NTD, nullptr),
Symbol(this, InheritedTypeDecl, nullptr),
RelationshipKind::InheritsFrom());
}
ClassDecl *Super = nullptr;
if (auto *CD = dyn_cast<ClassDecl>(D))
Super = CD->getSuperclassDecl();
else if (auto *PD = dyn_cast<ProtocolDecl>(D))
Super = PD->getSuperclassDecl();

if (Super) {
recordEdge(Symbol(this, cast<ValueDecl>(D), nullptr),
Symbol(this, Super, nullptr),
RelationshipKind::InheritsFrom());
}
}

Expand Down Expand Up @@ -457,7 +453,7 @@ void SymbolGraph::recordDefaultImplementationRelationships(Symbol S) {
if (const auto *Extension = dyn_cast<ExtensionDecl>(VD->getDeclContext())) {
if (const auto *ExtendedProtocol = Extension->getExtendedProtocolDecl()) {
HandleProtocol(ExtendedProtocol);
for (const auto *Inherited : ExtendedProtocol->getInheritedProtocols()) {
for (const auto *Inherited : ExtendedProtocol->getAllInheritedProtocols()) {
HandleProtocol(Inherited);
}
}
Expand Down Expand Up @@ -493,11 +489,19 @@ void SymbolGraph::recordConformanceRelationships(Symbol S) {
if (const auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
if (auto *PD = dyn_cast<ProtocolDecl>(NTD)) {
for (auto *inherited : PD->getAllInheritedProtocols()) {
// FIXME(noncopyable_generics): Figure out what we want here.
if (inherited->getInvertibleProtocolKind())
continue;

recordEdge(S, Symbol(this, inherited, nullptr),
RelationshipKind::ConformsTo(), nullptr);
}
} else {
for (const auto *Conformance : NTD->getAllConformances()) {
// FIXME(noncopyable_generics): Figure out what we want here.
if (Conformance->getProtocol()->getInvertibleProtocolKind())
continue;

// Check to make sure that this conformance wasn't declared via an
// unconditionally-unavailable extension. If so, don't add that to the graph.
if (const auto *ED = dyn_cast_or_null<ExtensionDecl>(Conformance->getDeclContext())) {
Expand Down Expand Up @@ -778,6 +782,7 @@ bool SymbolGraph::isImplicitlyPrivate(const Decl *D,
return false;
}

/// FIXME: This should use AvailableAttr::isUnavailable() or similar.
bool SymbolGraph::isUnconditionallyUnavailableOnAllPlatforms(const Decl *D) const {
return llvm::any_of(D->getAttrs(), [](const auto *Attr) {
if (const auto *AvAttr = dyn_cast<AvailableAttr>(Attr)) {
Expand Down
2 changes: 0 additions & 2 deletions test/SymbolGraph/Symbols/Mixins/Generics/Arguments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// RUN: %target-swift-symbolgraph-extract -module-name Arguments -I %t -pretty-print -output-dir %t
// RUN: %FileCheck %s --input-file %t/Arguments.symbols.json

// XFAIL: noncopyable_generics

public struct MyStruct<T> {
public var x: T
public init(x: T) {
Expand Down
2 changes: 0 additions & 2 deletions test/SymbolGraph/Symbols/SkipProtocolImplementations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@
// COUNT-COUNT-3: sourceOrigin
// COUNT-NOT: sourceOrigin

// XFAIL: noncopyable_generics

public protocol SomeProtocol {
/// Base docs
func someFunc()
Expand Down
2 changes: 0 additions & 2 deletions test/SymbolGraph/Symbols/SkipsPublicUnderscore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
// RUN: %target-swift-symbolgraph-extract -module-name SkipsPublicUnderscore -I %t -pretty-print -output-dir %t -minimum-access-level private
// RUN: %FileCheck %s --input-file %t/SkipsPublicUnderscore.symbols.json --check-prefix PRIVATE

// XFAIL: noncopyable_generics

public protocol PublicProtocol {}

public class SomeClass {
Expand Down

0 comments on commit 892dd45

Please sign in to comment.