void Module::addParsersRecursive(Object &object, const ObjectType &type, const Module &fromModule, const ObjectType &lastType) const { //Building the father list std::list<ObjectType> fathers; ObjectType currentType = type; while(currentType.typeTemplate() != lastType.typeTemplate() && !currentType.isNull()) { fathers.push_front(currentType); currentType = fromModule.getFather(currentType); } //Adding the fathers' parsers for(ObjectType father : fathers) { object.setType(father); const Module* module = handler(father); if(module!=nullptr) { Parser* parser = module->getParser(father, object, fromModule); object.addParser(parser); } } //Type specification ObjectType specification = specify(object.type()); if(!specification.isNull()) { addParsersRecursive(object, specification, fromModule, object.type()); } }
ObjectType Module::specify(const ObjectType &parent) const { ObjectType child = specifyLocally(parent); if(child.isNull()) { for(const Module* module : reverse(_importedModules)) { child = module->specify(parent); if(!child.isNull()) return child; } } return child; }
ObjectType Module::specify(const ObjectType &parent) const { if (!parent.typeTemplate().isVirtual()) { return ObjectType(); } ObjectType child = specifyLocally(parent); if(child.isNull()) { for(const Module* importedModule : _importedModulesChain) { child = importedModule->specifyLocally(parent); if(!child.isNull()) break; } } return child; }
bool Module::isExtension(const ObjectType& child, const ObjectType& parent) const { if(child.extendsDirectly(parent)) return true; ObjectType father = getFather(child); if(!father.isNull()) return isExtension(father, parent); return false; }
void Module::addParsers(Object &object, const ObjectType &type) const { //Building the father list ObjectType currentType = type; ObjectType lastType; while (!currentType.isNull()) { std::list<ObjectType> fathers; while(currentType.typeTemplate() != lastType.typeTemplate() && !currentType.isNull()) { fathers.push_front(currentType); currentType = currentType.parent(); } //Adding the fathers' parsers for(ObjectType father : fathers) { object.setType(father); Parser* parser = father.parseOrGetParser(static_cast<ParsingOption&>(object)); object.addParser(parser); } //Type specification lastType= object.type(); currentType = specify(lastType); } const auto& parsers = object._parsers; if (std::any_of(parsers.begin(), parsers.end(), [](const std::unique_ptr<Parser>& parser) { if (parser) { return parser->needTailParsing(); } else { return false; } })) { object.parse(); }; }
ObjectType Module::getFather(const ObjectType &child) const { //Searching locally auto it = _extensions.find(&child.typeTemplate()); if(it != _extensions.end()) { ObjectType father = (it->second)(child); if(!father.isNull()) { return father; } } //Searching in imported modules for(const Module* module: reverse(_importedModules)) { ObjectType father = module->getFather(child); if(!father.isNull()) { return father; } } return ObjectType(); }
ObjectType Module::specifyLocally(const ObjectType& parent) const { auto it = _specializers.find(const_cast<ObjectTypeTemplate*>(&parent.typeTemplate())); if (it == _specializers.end()) { return ObjectType(); } ObjectType type = it->second.specialize(parent); if (!type.isNull()) { type.importParameters(parent); } return type; }