@@ -53,14 +53,21 @@ class NominalTypeConformanceCollector : public ASTWalker {
5353 }
5454
5555 PreWalkAction walkToDeclPre (Decl *D) override {
56- if (auto *NTD = llvm::dyn_cast<NominalTypeDecl>(D))
57- if (!isa<ProtocolDecl>(NTD))
56+ auto *NTD = llvm::dyn_cast<NominalTypeDecl>(D);
57+ if (!NTD)
58+ if (auto *ETD = dyn_cast<ExtensionDecl>(D))
59+ NTD = ETD->getExtendedNominal ();
60+ if (NTD)
61+ if (!isa<ProtocolDecl>(NTD) && CheckedDecls.insert (NTD).second )
5862 for (auto &Protocol : NTD->getAllProtocols ())
5963 if (Protocol->getAttrs ().hasAttribute <ExtractConstantsFromMembersAttr>() ||
6064 Protocols.count (Protocol->getName ().str ().str ()) != 0 )
6165 ConformanceTypeDecls.push_back (NTD);
6266 return Action::Continue ();
6367 }
68+
69+ private:
70+ std::unordered_set<NominalTypeDecl *> CheckedDecls;
6471};
6572
6673std::string toFullyQualifiedTypeNameString (const swift::Type &Type) {
@@ -463,37 +470,52 @@ extractEnumCases(NominalTypeDecl *Decl) {
463470 return llvm::None;
464471}
465472
466- ConstValueTypeInfo
467- ConstantValueInfoRequest::evaluate (Evaluator &Evaluator,
468- NominalTypeDecl *Decl) const {
469- // Use 'getStoredProperties' to get lowered lazy and wrapped properties
470- auto StoredProperties = Decl->getStoredProperties ();
471- std::unordered_set<VarDecl *> StoredPropertiesSet (StoredProperties.begin (),
472- StoredProperties.end ());
473+ ConstValueTypeInfo ConstantValueInfoRequest::evaluate (
474+ Evaluator &Evaluator, NominalTypeDecl *Decl,
475+ llvm::PointerUnion<const SourceFile *, ModuleDecl *> extractionScope)
476+ const {
477+
478+ auto shouldExtract = [&](DeclContext *decl) {
479+ if (auto SF = extractionScope.dyn_cast <const SourceFile *>())
480+ return decl->getOutermostParentSourceFile () == SF;
481+ return decl->getParentModule () == extractionScope.get <ModuleDecl *>();
482+ };
473483
474484 std::vector<ConstValueTypePropertyInfo> Properties;
475- for (auto Property : StoredProperties) {
476- Properties.push_back (extractTypePropertyInfo (Property));
477- }
485+ llvm::Optional<std::vector<EnumElementDeclValue>> EnumCases;
478486
479- for (auto Member : Decl->getMembers ()) {
480- auto *VD = dyn_cast<VarDecl>(Member);
481- // Ignore plain stored properties collected above,
482- // instead gather up remaining static and computed properties.
483- if (!VD || StoredPropertiesSet.count (VD))
484- continue ;
485- Properties.push_back (extractTypePropertyInfo (VD));
487+ if (shouldExtract (Decl)) {
488+ // Use 'getStoredProperties' to get lowered lazy and wrapped properties
489+ auto StoredProperties = Decl->getStoredProperties ();
490+ std::unordered_set<VarDecl *> StoredPropertiesSet (StoredProperties.begin (),
491+ StoredProperties.end ());
492+ for (auto Property : StoredProperties) {
493+ Properties.push_back (extractTypePropertyInfo (Property));
494+ }
495+
496+ for (auto Member : Decl->getMembers ()) {
497+ auto *VD = dyn_cast<VarDecl>(Member);
498+ // Ignore plain stored properties collected above,
499+ // instead gather up remaining static and computed properties.
500+ if (!VD || StoredPropertiesSet.count (VD))
501+ continue ;
502+ Properties.push_back (extractTypePropertyInfo (VD));
503+ }
504+
505+ EnumCases = extractEnumCases (Decl);
486506 }
487507
488508 for (auto Extension: Decl->getExtensions ()) {
489- for (auto Member : Extension->getMembers ()) {
490- if (auto *VD = dyn_cast<VarDecl>(Member)) {
491- Properties.push_back (extractTypePropertyInfo (VD));
509+ if (shouldExtract (Extension)) {
510+ for (auto Member : Extension->getMembers ()) {
511+ if (auto *VD = dyn_cast<VarDecl>(Member)) {
512+ Properties.push_back (extractTypePropertyInfo (VD));
513+ }
492514 }
493515 }
494516 }
495517
496- return ConstValueTypeInfo{Decl, Properties, extractEnumCases (Decl) };
518+ return ConstValueTypeInfo{Decl, Properties, EnumCases };
497519}
498520
499521std::vector<ConstValueTypeInfo>
@@ -507,7 +529,8 @@ gatherConstValuesForModule(const std::unordered_set<std::string> &Protocols,
507529 Module->walk (ConformanceCollector);
508530 for (auto *CD : ConformanceDecls)
509531 Result.emplace_back (evaluateOrDefault (CD->getASTContext ().evaluator ,
510- ConstantValueInfoRequest{CD}, {}));
532+ ConstantValueInfoRequest{CD, Module},
533+ {}));
511534 return Result;
512535}
513536
@@ -523,8 +546,8 @@ gatherConstValuesForPrimary(const std::unordered_set<std::string> &Protocols,
523546 D->walk (ConformanceCollector);
524547
525548 for (auto *CD : ConformanceDecls)
526- Result.emplace_back (evaluateOrDefault (CD-> getASTContext (). evaluator ,
527- ConstantValueInfoRequest{CD}, {}));
549+ Result.emplace_back (evaluateOrDefault (
550+ CD-> getASTContext (). evaluator , ConstantValueInfoRequest{CD, SF }, {}));
528551 return Result;
529552}
530553
0 commit comments