void BuiltinSymbols::ImportExtConstants(AnalysisResultPtr ar, ConstantTablePtr dest, ClassInfo *cls) { ClassInfo::ConstantVec src = cls->getConstantsVec(); for (auto it = src.begin(); it != src.end(); ++it) { // We make an assumption that if the constant is a callback type // (e.g. STDIN, STDOUT, STDERR) then it will return an Object. // And that if it's deferred (SID, PHP_SAPI, etc.) it'll be a String. ClassInfo::ConstantInfo *cinfo = *it; dest->add(cinfo->name.data(), cinfo->isDeferred() ? (cinfo->isCallback() ? Type::Object : Type::String) : typePtrFromDataType(cinfo->getValue().getType(), Type::Variant), ExpressionPtr(), ar, ConstructPtr()); } }
static Array get_class_info(const ClassInfo *cls) { Array ret; CStrRef className = cls->getName(); ret.set(s_name, className); ret.set(s_extension, empty_string); ret.set(s_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(s_interfaces, VarNR(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(s_traits, VarNR(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(s_trait_aliases, VarNR(arr)); } // attributes { int attribute = cls->getAttribute(); if (attribute & ClassInfo::IsSystem) { ret.set(s_internal, true_varNR); } if (attribute & ClassInfo::HipHopSpecific) { ret.set(s_hphp, true_varNR); } if (attribute & ClassInfo::IsFinal) { ret.set(s_final, true_varNR); } if (attribute & ClassInfo::IsAbstract) { ret.set(s_abstract, true_varNR); } if (attribute & ClassInfo::IsInterface) { ret.set(s_interface, true_varNR); } if (attribute & ClassInfo::IsTrait) { ret.set(s_trait, true_varNR); } ret.set(s_modifiers, VarNR(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(s_methods, VarNR(arr)); } // properties { Array arr = Array::Create(); Array arrPriv = 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); if (prop->attribute & ClassInfo::IsPrivate) { assert(prop->owner == cls); arrPriv.set(prop->name, info); } else { arr.set(prop->name, info); } } ret.set(s_properties, VarNR(arr)); ret.set(s_private_properties, VarNR(arrPriv)); } // 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; arr.set(info->name, info->getValue()); } ret.set(s_constants, VarNR(arr)); } { // source info set_source_info(ret, cls->getFile(), cls->getLine1(), cls->getLine2()); set_doc_comment(ret, cls->getDocComment()); } // user attributes { Array arr = Array::Create(); const ClassInfo::UserAttributeVec &userAttrs = cls->getUserAttributeVec(); for (ClassInfo::UserAttributeVec::const_iterator iter = userAttrs.begin(); iter != userAttrs.end(); ++iter) { ClassInfo::UserAttributeInfo *info = *iter; arr.set(info->name, info->getValue()); } ret.set(s_attributes, VarNR(arr)); } 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; }