mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Put UsedDeclEnumerator Back
This abstraction turns out to have hidden dependencies from the dependency verifier. Invert the dependency here and have it use the new enumerators in the DependencyRecorder instead.
This commit is contained in:
@@ -551,24 +551,134 @@ void FrontendSourceFileDepGraphFactory::addAllDefinedDeclsOfAGivenType(
|
||||
// MARK: FrontendSourceFileDepGraphFactory - adding collections of used Decls
|
||||
//==============================================================================
|
||||
|
||||
namespace {
|
||||
/// Extracts uses out of a SourceFile
|
||||
class UsedDeclEnumerator {
|
||||
SourceFile *SF;
|
||||
const DependencyTracker &depTracker;
|
||||
StringRef swiftDeps;
|
||||
|
||||
/// Cache these for efficiency
|
||||
const DependencyKey sourceFileInterface;
|
||||
const DependencyKey sourceFileImplementation;
|
||||
|
||||
const bool includeIntrafileDeps;
|
||||
|
||||
function_ref<void(const DependencyKey &, const DependencyKey &)> createDefUse;
|
||||
|
||||
public:
|
||||
UsedDeclEnumerator(
|
||||
SourceFile *SF, const DependencyTracker &depTracker, StringRef swiftDeps,
|
||||
bool includeIntrafileDeps,
|
||||
function_ref<void(const DependencyKey &, const DependencyKey &)>
|
||||
createDefUse)
|
||||
: SF(SF), depTracker(depTracker), swiftDeps(swiftDeps),
|
||||
sourceFileInterface(DependencyKey::createKeyForWholeSourceFile(
|
||||
DeclAspect::interface, swiftDeps)),
|
||||
sourceFileImplementation(DependencyKey::createKeyForWholeSourceFile(
|
||||
DeclAspect::implementation, swiftDeps)),
|
||||
includeIntrafileDeps(includeIntrafileDeps), createDefUse(createDefUse) {
|
||||
}
|
||||
|
||||
public:
|
||||
void enumerateAllUses() {
|
||||
auto &Ctx = SF->getASTContext();
|
||||
std::unordered_set<std::string> holdersOfCascadingMembers;
|
||||
Ctx.evaluator.enumerateReferencesInFile(SF, [&](const auto &ref) {
|
||||
const auto cascades = ref.cascades;
|
||||
std::string name = ref.name.userFacingName().str();
|
||||
const auto *nominal = ref.subject;
|
||||
using Kind = evaluator::DependencyCollector::Reference::Kind;
|
||||
|
||||
switch (ref.kind) {
|
||||
case Kind::Empty:
|
||||
case Kind::Tombstone:
|
||||
llvm_unreachable("Cannot enumerate dead reference!");
|
||||
case Kind::TopLevel:
|
||||
return enumerateUse<NodeKind::topLevel>("", name, cascades);
|
||||
case Kind::Dynamic:
|
||||
return enumerateUse<NodeKind::dynamicLookup>("", name, cascades);
|
||||
case Kind::PotentialMember: {
|
||||
std::string context = DependencyKey::computeContextForProvidedEntity<
|
||||
NodeKind::potentialMember>(nominal);
|
||||
appendHolderOfCascadingMembers(holdersOfCascadingMembers, nominal,
|
||||
cascades);
|
||||
return enumerateUse<NodeKind::potentialMember>(context, "", cascades);
|
||||
}
|
||||
case Kind::UsedMember: {
|
||||
std::string context =
|
||||
DependencyKey::computeContextForProvidedEntity<NodeKind::member>(
|
||||
nominal);
|
||||
appendHolderOfCascadingMembers(holdersOfCascadingMembers, nominal,
|
||||
cascades);
|
||||
return enumerateUse<NodeKind::member>(context, name, cascades);
|
||||
}
|
||||
}
|
||||
});
|
||||
enumerateExternalUses();
|
||||
enumerateNominalUses(std::move(holdersOfCascadingMembers));
|
||||
}
|
||||
|
||||
private:
|
||||
template <NodeKind kind>
|
||||
void enumerateUse(StringRef context, StringRef name, bool isCascadingUse) {
|
||||
// Assume that what is depended-upon is the interface
|
||||
createDefUse(
|
||||
DependencyKey(kind, DeclAspect::interface, context.str(), name.str()),
|
||||
isCascadingUse ? sourceFileInterface : sourceFileImplementation);
|
||||
}
|
||||
|
||||
void appendHolderOfCascadingMembers(std::unordered_set<std::string> &holders,
|
||||
const NominalTypeDecl *subject,
|
||||
bool isCascading) {
|
||||
bool isPrivate = subject->isPrivateToEnclosingFile();
|
||||
if (isPrivate && !includeIntrafileDeps)
|
||||
return;
|
||||
|
||||
std::string context =
|
||||
DependencyKey::computeContextForProvidedEntity<NodeKind::nominal>(
|
||||
subject);
|
||||
if (isCascading) {
|
||||
holders.insert(context);
|
||||
}
|
||||
}
|
||||
|
||||
void enumerateNominalUses(
|
||||
const std::unordered_set<std::string> &&holdersOfCascadingMembers) {
|
||||
auto &Ctx = SF->getASTContext();
|
||||
Ctx.evaluator.enumerateReferencesInFile(SF, [&](const auto &ref) {
|
||||
const NominalTypeDecl *subject = ref.subject;
|
||||
if (!subject) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isPrivate = subject->isPrivateToEnclosingFile();
|
||||
if (isPrivate && !includeIntrafileDeps) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string context =
|
||||
DependencyKey::computeContextForProvidedEntity<NodeKind::nominal>(
|
||||
subject);
|
||||
const bool isCascadingUse = holdersOfCascadingMembers.count(context) != 0;
|
||||
enumerateUse<NodeKind::nominal>(context, "", isCascadingUse);
|
||||
});
|
||||
}
|
||||
|
||||
void enumerateExternalUses() {
|
||||
// external dependencies always cascade
|
||||
for (StringRef s : depTracker.getDependencies())
|
||||
enumerateUse<NodeKind::externalDepend>("", s, true);
|
||||
}
|
||||
};
|
||||
} // end namespace
|
||||
|
||||
void FrontendSourceFileDepGraphFactory::addAllUsedDecls() {
|
||||
const DependencyKey sourceFileInterface =
|
||||
DependencyKey::createKeyForWholeSourceFile(DeclAspect::interface,
|
||||
swiftDeps);
|
||||
|
||||
const DependencyKey sourceFileImplementation =
|
||||
DependencyKey::createKeyForWholeSourceFile(DeclAspect::implementation,
|
||||
swiftDeps);
|
||||
|
||||
SF->getConfiguredReferencedNameTracker()->enumerateAllUses(
|
||||
includePrivateDeps, depTracker,
|
||||
[&](const fine_grained_dependencies::NodeKind kind, StringRef context,
|
||||
StringRef name, const bool isCascadingUse) {
|
||||
addAUsedDecl(DependencyKey(kind, DeclAspect::interface, context.str(),
|
||||
name.str()),
|
||||
isCascadingUse ? sourceFileInterface
|
||||
: sourceFileImplementation);
|
||||
});
|
||||
UsedDeclEnumerator(SF, depTracker, swiftDeps, includePrivateDeps,
|
||||
[&](const DependencyKey &def, const DependencyKey &use) {
|
||||
addAUsedDecl(def, use);
|
||||
})
|
||||
.enumerateAllUses();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
Reference in New Issue
Block a user