Exemplo n.º 1
0
 std::unique_ptr<ExtensionInfoMap>
 collectSynthesizedExtensionInfoForProtocol(MergeGroupVector &AllGroups) {
   std::unique_ptr<ExtensionInfoMap> InfoMap(new ExtensionInfoMap());
   ExtensionMergeInfoMap MergeInfoMap;
   for (auto *E : Target->getExtensions()) {
     if (!Options.shouldPrint(E))
       continue;
     auto Pair = isApplicable(E, /*Synthesized*/false);
     if (Pair.first) {
       InfoMap->insert({E, Pair.first});
       MergeInfoMap.insert({E, Pair.second});
     }
   }
   populateMergeGroup(*InfoMap, MergeInfoMap, AllGroups,
                      /*AllowMergeWithDefBody*/false);
   std::sort(AllGroups.begin(), AllGroups.end());
   for (auto &Group : AllGroups) {
     Group.sortMembers();
   }
   return InfoMap;
 }
Exemplo n.º 2
0
 void populateMergeGroup(ExtensionInfoMap &InfoMap,
                         ExtensionMergeInfoMap &MergeInfoMap,
                         MergeGroupVector &Results,
                         bool AllowMergeWithDefBody) {
   for (auto &Pair : InfoMap) {
     ExtensionDecl *ED = Pair.first;
     ExtensionMergeInfo &MergeInfo = MergeInfoMap[ED];
     SynthesizedExtensionInfo &ExtInfo = InfoMap[ED];
     auto Found = std::find_if(Results.begin(), Results.end(),
       [&](ExtensionMergeGroup &Group) {
         return MergeInfo == MergeInfoMap[Group.Members.front()->Ext];
       });
     if (Found == Results.end()) {
       Results.push_back({&ExtInfo,
         (unsigned)MergeInfo.Requirements.size(),
         MergeInfo.InheritsCount,
         AllowMergeWithDefBody && MergeInfo.isMergeableWithTypeDef()});
     } else {
       Found->Members.push_back(&ExtInfo);
     }
   }
 }
Exemplo n.º 3
0
  std::unique_ptr<ExtensionInfoMap>
  collectSynthesizedExtensionInfo(MergeGroupVector &AllGroups) {
    if (isa<ProtocolDecl>(Target)) {
      return collectSynthesizedExtensionInfoForProtocol(AllGroups);
    }
    std::unique_ptr<ExtensionInfoMap> InfoMap(new ExtensionInfoMap());
    ExtensionMergeInfoMap MergeInfoMap;
    std::vector<NominalTypeDecl*> Unhandled;

    auto handleExtension = [&](ExtensionDecl *E, bool Synthesized,
                               ExtensionDecl *EnablingE,
                               NormalProtocolConformance *Conf) {
      if (Options.shouldPrint(E)) {
        auto Pair = isApplicable(E, Synthesized, EnablingE, Conf);
        if (Pair.first) {
          InfoMap->insert({E, Pair.first});
          MergeInfoMap.insert({E, Pair.second});
        }
      }
    };

    for (auto *Conf : Target->getLocalConformances()) {
      Unhandled.push_back(Conf->getProtocol());
    }
    if (auto *CD = dyn_cast<ClassDecl>(Target)) {
      if (auto Super = CD->getSuperclassDecl())
        Unhandled.push_back(Super);
    }
    while (!Unhandled.empty()) {
      NominalTypeDecl* Back = Unhandled.back();
      Unhandled.pop_back();
      for (ExtensionDecl *E : Back->getExtensions()) {
        handleExtension(E, true, nullptr, nullptr);
      }
      for (auto *Conf : Back->getLocalConformances()) {
        Unhandled.push_back(Conf->getProtocol());
      }
      if (auto *CD = dyn_cast<ClassDecl>(Back)) {
        if (auto Super = CD->getSuperclass())
          Unhandled.push_back(Super->getAnyNominal());
      }
    }

    // Merge with actual extensions.
    for (auto *EnablingE : Target->getExtensions()) {
      handleExtension(EnablingE, false, nullptr, nullptr);
      for (auto *Conf : EnablingE->getLocalConformances()) {
        for (auto E : Conf->getProtocol()->getExtensions())
          handleExtension(E, true, EnablingE, Conf->getRootNormalConformance());
      }
    }

    populateMergeGroup(*InfoMap, MergeInfoMap, AllGroups,
                       /*AllowMergeWithDefBody*/true);

    std::sort(AllGroups.begin(), AllGroups.end());
    for (auto &Group : AllGroups) {
      Group.removeUnfavored(Target);
      Group.sortMembers();
    }
    AllGroups.erase(std::remove_if(AllGroups.begin(), AllGroups.end(),
      [](ExtensionMergeGroup &Group) { return Group.Members.empty(); }),
                    AllGroups.end());

    return InfoMap;
  }