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;
}