void FunctionStatement::getInfo(ClassInfo::MethodInfo &info) const { int attr = m_ref ? ClassInfo::IsReference : ClassInfo::IsNothing; if (m_hasCallToGetArgs) attr |= ClassInfo::VariableArguments; info.attribute = (ClassInfo::Attribute)attr; info.name = m_name.c_str(); info.file = m_loc.file; info.line1 = m_loc.line0; info.line2 = m_loc.line1; if (!m_docComment.empty()) { info.docComment = m_docComment.c_str(); } info.invokeFn = NULL; info.invokeFailedFn = NULL; DummyVariableEnvironment env; for (vector<ParameterPtr>::const_iterator it = m_params.begin(); it != m_params.end(); ++it) { ClassInfo::ParameterInfo *pi = new ClassInfo::ParameterInfo; (*it)->getInfo(*pi, env); info.parameters.push_back(pi); } for (map<string, ExpressionPtr>::const_iterator it = m_staticStmts.begin(); it != m_staticStmts.end(); ++it) { ClassInfo::ConstantInfo *ci = new ClassInfo::ConstantInfo; ci->name = it->first.c_str(); ci->valueLen = 12; ci->valueText = "unsupported"; if (it->second) { ci->setValue(it->second->eval(env)); } info.staticVariables.push_back(ci); } }
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()); } }
Cell lookupCnsHelper(const TypedValue* tv, StringData* nm, bool error) { assert(tv->m_type == KindOfUninit); // Deferred constants such as SID if (UNLIKELY(tv->m_data.pref != nullptr)) { ClassInfo::ConstantInfo* ci = (ClassInfo::ConstantInfo*)(void*)tv->m_data.pref; Cell *cns = const_cast<Variant&>(ci->getDeferredValue()).asTypedValue(); if (LIKELY(cns->m_type != KindOfUninit)) { Cell c1; cellDup(*cns, c1); return c1; } } Cell *cns = nullptr; if (UNLIKELY(TargetCache::s_constants().get() != nullptr)) { cns = TargetCache::s_constants()->nvGet(nm); } if (!cns) { cns = Unit::loadCns(const_cast<StringData*>(nm)); } if (LIKELY(cns != nullptr)) { Cell c1; c1.m_type = cns->m_type; c1.m_data = cns->m_data; return c1; } // Undefined constants if (error) { raise_error("Undefined constant '%s'", nm->data()); } else { raise_notice(Strings::UNDEFINED_CONSTANT, nm->data(), nm->data()); Cell c1; c1.m_data.pstr = const_cast<StringData*>(nm); c1.m_type = KindOfStaticString; return c1; } not_reached(); }
Array lookupDefinedConstants(bool categorize /*= false */) { assert(s_stringDataMap); Array usr(RDS::s_constants()); Array sys; for (StringDataMap::const_iterator it = s_stringDataMap->begin(); it != s_stringDataMap->end(); ++it) { if (it->second.bound()) { Array *tbl = (categorize && RDS::isPersistentHandle(it->second.handle())) ? &sys : &usr; auto& tv = *it->second; if (tv.m_type != KindOfUninit) { StrNR key(const_cast<StringData*>(to_sdata(it->first))); tbl->set(key, tvAsVariant(&tv), true); } else if (tv.m_data.pref) { StrNR key(const_cast<StringData*>(to_sdata(it->first))); ClassInfo::ConstantInfo* ci = (ClassInfo::ConstantInfo*)(void*)tv.m_data.pref; auto cns = ci->getDeferredValue(); if (cns.isInitialized()) { tbl->set(key, cns, true); } } } } if (categorize) { Array ret; ret.set(s_user, usr); ret.set(s_Core, sys); return ret; } else { return usr; } }
Array StringData::GetConstants() { // Return an array of all defined constants. assert(s_stringDataMap); Array a(Transl::TargetCache::s_constants); for (StringDataMap::const_iterator it = s_stringDataMap->begin(); it != s_stringDataMap->end(); ++it) { if (it->second) { TypedValue& tv = Transl::TargetCache::handleToRef<TypedValue>(it->second); if (tv.m_type != KindOfUninit) { StrNR key(const_cast<StringData*>(it->first)); a.set(key, tvAsVariant(&tv), true); } else if (tv.m_data.pref) { StrNR key(const_cast<StringData*>(it->first)); ClassInfo::ConstantInfo* ci = (ClassInfo::ConstantInfo*)(void*)tv.m_data.pref; a.set(key, ci->getDeferredValue(), true); } } } return a; }
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; }