Array f_hphp_get_class_info(CVarRef name) { String className; if (name.isObject()) { className = name.toObject()->o_getClassName(); } else { className = name.toString(); } const ClassInfo *cls = ClassInfo::FindClass(className.data()); if (cls == NULL) { cls = ClassInfo::FindInterface(className.data()); } Array ret; if (cls == NULL) { return ret; } ret.set("name", cls->getName()); ret.set("extension", ""); ret.set("parent", cls->getParentClass()); // interfaces { Array arr = Array::Create(); const ClassInfo::InterfaceMap &interfaces = cls->getInterfaces(); for (ClassInfo::InterfaceMap::const_iterator iter = interfaces.begin(); iter != interfaces.end(); ++iter) { arr.set(*iter, 1); } ret.set("interfaces", arr); } // attributes { int attribute = cls->getAttribute(); ret.set("internal", (bool)(attribute & ClassInfo::IsSystem)); ret.set("abstract", (bool)(attribute & ClassInfo::IsAbstract)); ret.set("interface", (bool)(attribute & ClassInfo::IsInterface)); ret.set("final", (bool)(attribute & ClassInfo::IsFinal)); ret.set("modifiers", get_modifiers(attribute, true)); } // methods { Array arr = Array::Create(); const ClassInfo::MethodVec &methods = cls->getMethodsVec(); for (ClassInfo::MethodVec::const_iterator iter = methods.begin(); iter != methods.end(); ++iter) { ClassInfo::MethodInfo *m = *iter; if ((m->attribute & ClassInfo::IsInherited) == 0) { Array info = Array::Create(); set_method_info(info, m, cls); arr.set(StringUtil::ToLower(m->name), info); } } ret.set("methods", arr); } // properties { Array arr = Array::Create(); const ClassInfo::PropertyMap &properties = cls->getProperties(); for (ClassInfo::PropertyMap::const_iterator iter = properties.begin(); iter != properties.end(); ++iter) { Array info = Array::Create(); set_property_info(info, iter->second, cls); arr.set(iter->first, info); } ret.set("properties", arr); } // constants { Array arr = Array::Create(); const ClassInfo::ConstantMap &constants = cls->getConstants(); for (ClassInfo::ConstantMap::const_iterator iter = constants.begin(); iter != constants.end(); ++iter) { if (iter->second->valueText && *iter->second->valueText) { arr.set(iter->second->name, iter->second->value); } else { arr.set(iter->second->name, get_class_constant(className.data(), iter->second->name)); } } ret.set("constants", arr); } { // source info const char *file = SourceInfo::TheSourceInfo.getClassDeclaringFile(className.data()); if (!file) file = ""; if (file[0] != '/') { ret.set("file", String(RuntimeOption::SourceRoot + file)); } else { ret.set("file", file); } ret.set("line1", 0); ret.set("line2", 0); const char *dc = cls->getDocComment(); if (dc) { ret.set("doc", dc); } else { ret.set("doc", false); } } return ret; }
Array f_hphp_get_class_info(CVarRef name) { String className; if (name.isObject()) { className = name.toObject()->o_getClassName(); } else { className = name.toString(); } const ClassInfo *cls = ClassInfo::FindClass(className); if (cls == NULL) { cls = ClassInfo::FindInterface(className); } if (cls == NULL) { cls = ClassInfo::FindTrait(className); } Array ret; if (cls == NULL) { return ret; } ret.set("name", cls->getName()); ret.set("extension", ""); ret.set("parent", cls->getParentClass()); // interfaces { Array arr = Array::Create(); const ClassInfo::InterfaceVec &interfaces = cls->getInterfacesVec(); for (ClassInfo::InterfaceVec::const_iterator iter = interfaces.begin(); iter != interfaces.end(); ++iter) { arr.set(*iter, 1); } ret.set("interfaces", arr); } // traits { Array arr = Array::Create(); const ClassInfo::TraitVec &traits = cls->getTraitsVec(); for (ClassInfo::TraitVec::const_iterator iter = traits.begin(); iter != traits.end(); ++iter) { arr.set(*iter, 1); } ret.set("traits", arr); } // trait aliases { Array arr = Array::Create(); const ClassInfo::TraitAliasVec &aliases = cls->getTraitAliasesVec(); for (ClassInfo::TraitAliasVec::const_iterator iter = aliases.begin(); iter != aliases.end(); ++iter) { arr.set(iter->first, iter->second); } ret.set("trait_aliases", arr); } // attributes { int attribute = cls->getAttribute(); ret.set("internal", (bool)(attribute & ClassInfo::IsSystem)); ret.set("hphp", (bool)(attribute & ClassInfo::HipHopSpecific)); ret.set("abstract", (bool)(attribute & ClassInfo::IsAbstract)); ret.set("interface", (bool)(attribute & ClassInfo::IsInterface)); ret.set("final", (bool)(attribute & ClassInfo::IsFinal)); ret.set("trait", (bool)(attribute & ClassInfo::IsTrait)); ret.set("modifiers", get_modifiers(attribute, true)); } // methods { Array arr = Array::Create(); const ClassInfo::MethodVec &methods = cls->getMethodsVec(); for (ClassInfo::MethodVec::const_iterator iter = methods.begin(); iter != methods.end(); ++iter) { ClassInfo::MethodInfo *m = *iter; if ((m->attribute & ClassInfo::IsInherited) == 0) { Array info = Array::Create(); set_method_info(info, m, cls); arr.set(StringUtil::ToLower(m->name), info); } } ret.set("methods", arr); } // properties { Array arr = Array::Create(); const ClassInfo::PropertyVec &properties = cls->getPropertiesVec(); for (ClassInfo::PropertyVec::const_iterator iter = properties.begin(); iter != properties.end(); ++iter) { ClassInfo::PropertyInfo *prop = *iter; Array info = Array::Create(); set_property_info(info, prop, cls); arr.set(prop->name, info); } ret.set("properties", arr); } // constants { Array arr = Array::Create(); const ClassInfo::ConstantVec &constants = cls->getConstantsVec(); for (ClassInfo::ConstantVec::const_iterator iter = constants.begin(); iter != constants.end(); ++iter) { ClassInfo::ConstantInfo *info = *iter; if (info->valueText && *info->valueText) { arr.set(info->name, info->getValue()); } else { arr.set(info->name, get_class_constant(className, info->name)); } } ret.set("constants", arr); } { // source info if (!set_source_info(ret, cls->getFile(), cls->getLine1(), cls->getLine2())) { int line = 0; const char *file = SourceInfo::TheSourceInfo. getClassDeclaringFile(className, &line); set_source_info(ret, file, line, line); } set_doc_comment(ret, cls->getDocComment()); } return ret; }