std::vector extractSlots()

in src/RRefs.cpp [225:263]


std::vector<SlotInfo> extractSlots(const ShieldSEXP &classDef) {
  std::unordered_map<grpc::string, SlotInfo> slotsInfos;
  auto defProcessor = [&slotsInfos](const ShieldSEXP &classDef) {
    if (TYPEOF(classDef) != S4SXP) return;
    auto className = stringEltUTF8(R_do_slot(classDef, toSEXP("className")), 0);
    ShieldSEXP slotsList = R_do_slot(classDef, toSEXP("slots"));
    ShieldSEXP slotsNames = Rf_getAttrib(slotsList, R_NamesSymbol);
    for (int i = 0; i < slotsNames.length(); ++i) {
      auto slotName = stringEltUTF8(slotsNames, i);
      auto slotType = stringEltUTF8(VECTOR_ELT(slotsList, i), 0);
      if (slotsInfos.count(slotName) == 0 ||
          RI->R_extends(toSEXP(slotType), toSEXP(slotsInfos[slotName].type), RI->globalEnv) == TRUE) {
        slotsInfos[slotName] = {slotName, slotType, className};
      }
    }
  };

  ShieldSEXP superClassesList = R_do_slot(classDef, toSEXP("contains"));
  std::vector<std::pair<int, grpc::string>> superClasses;
  for (int i = 0; i < superClassesList.length(); ++i) {
    ShieldSEXP superClass = VECTOR_ELT(superClassesList, i);
    auto superClassName = stringEltUTF8(R_do_slot(superClass, toSEXP("superClass")), 0);
    auto distance = asInt(R_do_slot(superClass, toSEXP("distance")));
    superClasses.emplace_back(distance, superClassName);
  }
  std::sort(superClasses.begin(), superClasses.end());

  defProcessor(classDef);
  for (auto& e : superClasses) {
    defProcessor(R_getClassDef(e.second.c_str()));
  }

  std::vector<SlotInfo> result;
  result.reserve(slotsInfos.size());
  for (auto &e : slotsInfos) {
    result.push_back(e.second);
  }
  return result;
}