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()); } }
void Module::setSpecification(const ObjectType& parent, const ObjectType& child) { if (!parent.typeTemplate().isVirtual()) { Log::error("Cannot forward ",parent," to ",child," because ",parent.typeTemplate(), " is not virtual "); } const ObjectType* parentPtr = new ObjectType(parent); _automaticSpecifications.insert(std::make_pair(parentPtr, child)); }
void Module::setSpecification(const ObjectType& parent, const ObjectType& child) { if (!parent.typeTemplate().isVirtual()) { Log::error("Cannot forward ",parent," to ",child," because ",parent.typeTemplate().name(), " is not virtual "); } const ObjectType* parentPtr = new ObjectType(parent); _automaticSpecifications.insert(std::make_pair(parentPtr, child)); auto it = _specializers.find(const_cast<ObjectTypeTemplate*>(&parent.typeTemplate())); if (it == _specializers.end()) { _specializers.emplace(std::piecewise_construct, std::make_tuple(const_cast<ObjectTypeTemplate* >(&parent.typeTemplate())), std::make_tuple(parent, child)); } else { it->second.forward(parent, child); } }
ObjectType Module::specifyLocally(const ObjectType& parent) const { ObjectType type; ObjectType rangeBegin(parent.typeTemplate()); for(SpecificationMap::const_iterator it = _automaticSpecifications.lower_bound(&rangeBegin); it != _automaticSpecifications.end() && it->first->typeTemplate() == parent.typeTemplate(); ++it) { if(parent.extendsDirectly(*(it->first))) { type = it->second; type.importParameters(parent); break; } } return type; }
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::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; }
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; }
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(); }