static void AddSuggestions(std::vector<String>& matches, const String& word, const String& pword, bool withFields, const Value& value) { String prefix; if (!pword.IsEmpty()) prefix = pword + "."; if (value.IsObjectType<Dictionary>()) { Dictionary::Ptr dict = value; ObjectLock olock(dict); for (const Dictionary::Pair& kv : dict) { AddSuggestion(matches, word, prefix + kv.first); } } if (value.IsObjectType<Namespace>()) { Namespace::Ptr ns = value; ObjectLock olock(ns); for (const Namespace::Pair& kv : ns) { AddSuggestion(matches, word, prefix + kv.first); } } if (withFields) { Type::Ptr type = value.GetReflectionType(); for (int i = 0; i < type->GetFieldCount(); i++) { Field field = type->GetFieldInfo(i); AddSuggestion(matches, word, prefix + field.Name); } while (type) { Object::Ptr prototype = type->GetPrototype(); Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(prototype); if (dict) { ObjectLock olock(dict); for (const Dictionary::Pair& kv : dict) { AddSuggestion(matches, word, prefix + kv.first); } } type = type->GetBaseType(); } } }
Value icinga::GetPrototypeField(const Value& context, const String& field, bool not_found_error, const DebugInfo& debugInfo) { Type::Ptr ctype = context.GetReflectionType(); Type::Ptr type = ctype; do { Object::Ptr object = type->GetPrototype(); if (object && object->HasOwnField(field)) return object->GetFieldByName(field, false, debugInfo); type = type->GetBaseType(); } while (type); if (not_found_error) BOOST_THROW_EXCEPTION(ScriptError("Invalid field access (for value of type '" + ctype->GetName() + "'): '" + field + "'", debugInfo)); else return Empty; }