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);
  }
}
예제 #2
0
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());
  }
}
예제 #3
0
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();
}
예제 #4
0
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;
  }
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}