rename IgnoreRedefinition to AllowOverride
[hiphop-php.git] / hphp / runtime / base / class_info.h
blob88195f71766f2b15e66f9cb9616ec8da0302d4e9
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_CLASS_INFO_H_
18 #define incl_HPHP_CLASS_INFO_H_
20 #include "hphp/runtime/base/types.h"
21 #include "hphp/runtime/base/complex_types.h"
22 #include "hphp/util/mutex.h"
23 #include "hphp/util/case_insensitive.h"
25 namespace HPHP {
26 ///////////////////////////////////////////////////////////////////////////////
28 class ClassInfoHook;
30 /**
31 * Though called "ClassInfo", we consider global scope as a virtual "class".
32 * Therefore, this is the place we store meta information of both global
33 * functions and class methods and properties.
35 class ClassInfo {
36 public:
37 enum Attribute { // class prop func method param
38 IsOverride = (1 << 0), // x
39 IsRedeclared = (1 << 1), // x x
40 IsVolatile = (1 << 2), // x x
42 IsInterface = (1 << 3), // x
43 IsClosure = (1 << 3), // x x
44 IsAbstract = (1 << 4), // x x
45 IsFinal = (1 << 5), // x x
47 IsPublic = (1 << 6), // x x
48 IsProtected = (1 << 7), // x x
49 IsPrivate = (1 << 8), // x x
50 IsStatic = (1 << 9), // x x
51 // FIXME (#2163116): IsCppAbstract = (1 << 10) in idl/base.php
52 IsInherited = (1 << 10), // x
53 HasCall = IsPublic, // x
54 HasCallStatic = IsProtected,// x
55 AllowOverride = IsPrivate, // x
56 IsReference = (1 << 11), // x x x
57 IsConstructor = (1 << 12), // x
59 // need a non-zero number for const char * maps
60 IsNothing = (1 << 13),
62 HasDocComment = (1 << 14), // x x
63 IsLazyInit = (1 << 15), // x
64 HasGeneratorAsBody = (1 << 15), // x x
65 HipHopSpecific = (1 << 16), // x x
67 VariableArguments = (1 << 17), // x x
68 RefVariableArguments = (1 << 18), // x x
69 MixedVariableArguments = (1 << 19), // x x
71 FunctionIsFoldable = (1 << 20), // x
72 NoEffect = (1 << 21), // x
73 NoInjection = (1 << 22), // x x
74 HasOptFunction = (1 << 23), // x
75 AllowIntercept = (1 << 24), // x x
76 NoProfile = (1 << 25), // x x
77 ContextSensitive = (1 << 26), // x
78 NoDefaultSweep = (1 << 27), // x
79 IsSystem = (1 << 28), // x x
81 IsTrait = (1 << 29), // x
82 UsesTraits = (1 << 30), // x
83 HasAliasedMethods = (1u << 31),// x
84 NeedsActRec = (1u << 31),// x x
87 class ConstantInfo {
88 public:
89 ConstantInfo();
91 String name;
92 unsigned int valueLen;
93 const char *valueText;
94 const void* callback;
96 CVarRef getDeferredValue() const;
97 Variant getValue() const;
98 bool isDeferred() const { return deferred; }
99 bool isCallback() const { return callback != nullptr; }
100 void setValue(CVarRef value);
101 void setStaticValue(CVarRef value);
103 bool isDynamic() const {
104 return deferred;
106 private:
107 bool deferred;
108 Variant value;
109 std::string svalue; // serialized, only used by eval
112 class UserAttributeInfo {
113 public:
114 UserAttributeInfo();
116 String name;
118 Variant getValue() const;
119 void setStaticValue(CVarRef value);
121 private:
122 Variant value;
125 struct ParameterInfo {
126 ~ParameterInfo();
127 Attribute attribute;
128 DataType argType; // hinted arg type
129 const char *name;
130 const char *type; // hinted type string
131 const char *value; // serialized default value
132 int64_t valueLen;
133 const char *valueText; // original PHP code
134 int64_t valueTextLen;
135 std::vector<const UserAttributeInfo *> userAttrs;
138 struct MethodInfo {
139 MethodInfo() : docComment(nullptr) {}
140 explicit MethodInfo(const char **&p);
141 ~MethodInfo();
142 MethodInfo *getDeclared();
143 Attribute attribute;
144 int volatile_redec_offset;
145 String name;
147 std::vector<const ParameterInfo *> parameters;
148 std::vector<const ConstantInfo *> staticVariables;
149 std::vector<const UserAttributeInfo *> userAttrs;
151 const char *docComment;
152 const char *file;
153 int line1;
154 int line2;
155 DataType returnType;
158 class PropertyInfo {
159 public:
160 PropertyInfo() : docComment(nullptr) {}
161 Attribute attribute;
162 String name;
163 DataType type;
164 const char *docComment;
165 const ClassInfo *owner;
168 typedef StringIMap<ClassInfo *> ClassMap;
169 typedef std::vector<String> ClassVec;
170 typedef StringISet InterfaceSet;
171 typedef std::vector<String> InterfaceVec;
172 typedef StringISet TraitSet;
173 typedef std::vector<String> TraitVec;
174 typedef StringIMap<MethodInfo *> MethodMap;
175 typedef std::vector<MethodInfo *> MethodVec;
176 typedef StringMap<PropertyInfo *> PropertyMap;
177 typedef std::vector<PropertyInfo *> PropertyVec;
178 typedef StringMap<ConstantInfo *> ConstantMap;
179 typedef std::vector<ConstantInfo *> ConstantVec;
180 typedef std::vector<UserAttributeInfo *> UserAttributeVec;
181 typedef std::vector<std::pair<String, String> > TraitAliasVec;
183 public:
185 * Load everything.
187 static void Load();
190 * Return a list of PHP library functions.
192 static Array GetSystemFunctions();
195 * Return a list of user defined functions.
197 static Array GetUserFunctions();
200 * Locate one function.
202 static const MethodInfo *FindSystemFunction(CStrRef name);
203 static const MethodInfo *FindFunction(CStrRef name);
206 * Return a list of declared classes.
208 static Array GetClasses() { return GetClassLike(IsInterface|IsTrait, 0); }
211 * Locate one class.
213 static const ClassInfo *FindClass(CStrRef name);
216 * Locate one system class.
218 static const ClassInfo *FindSystemClass(CStrRef name);
221 * Return a list of declared interfaces.
223 static Array GetInterfaces() { return GetClassLike(IsInterface, IsInterface); }
226 * Return a list of declared traits.
228 static Array GetTraits() { return GetClassLike(IsTrait, IsTrait); }
231 * Locate one interface.
233 static const ClassInfo *FindInterface(CStrRef name);
236 * Locate one system interface.
238 static const ClassInfo *FindSystemInterface(CStrRef name);
241 * Locate one trait.
243 static const ClassInfo *FindTrait(CStrRef name);
246 * Locate one system trait.
248 static const ClassInfo *FindSystemTrait(CStrRef name);
251 * Locate either a class, interface, or trait.
253 static const ClassInfo *FindClassInterfaceOrTrait(CStrRef name);
256 * Locate either a system class, system interface, or system trait.
258 static const ClassInfo *FindSystemClassInterfaceOrTrait(CStrRef name);
261 * Get all statically known constants
263 static Array GetConstants();
266 * Get all statically known system constants
268 static Array GetSystemConstants();
269 static void InitializeSystemConstants();
272 * Return all methods a class has, including the ones on base classes and
273 * interfaces.
274 * type: 0: unknown; 1: class; 2: interface
276 static bool GetClassMethods(MethodVec &ret, CStrRef classname, int type = 0);
277 static bool GetClassMethods(MethodVec &ret, const ClassInfo *classInfo);
280 * Read user attributes in from the class map.
282 static void ReadUserAttributes(const char **&p,
283 std::vector<const UserAttributeInfo*> &attrs);
286 * Return lists of names for auto-complete purposes.
288 static void GetClassSymbolNames(CArrRef names, bool interface, bool trait,
289 std::vector<String> &classes,
290 std::vector<String> *clsMethods,
291 std::vector<String> *clsProperties,
292 std::vector<String> *clsConstants);
293 static void GetSymbolNames(std::vector<String> &classes,
294 std::vector<String> &functions,
295 std::vector<String> &constants,
296 std::vector<String> *clsMethods,
297 std::vector<String> *clsProperties,
298 std::vector<String> *clsConstants);
300 static void SetHook(ClassInfoHook *hook) { s_hook = hook; }
302 static Variant GetVariant(DataType type, const void *addr) {
303 switch (type) {
304 case KindOfBoolean:
305 return *(bool*)addr;
306 case KindOfInt64:
307 return *(int64_t*)addr;
308 case KindOfDouble:
309 return *(double*)addr;
310 case KindOfString:
311 return *(String*)addr;
312 case KindOfArray:
313 return *(Array*)addr;
314 case KindOfObject:
315 return *(Object*)addr;
316 default:
317 assert(false);
318 return uninit_null();
322 public:
323 ClassInfo() : m_cdec_offset(0), m_docComment(nullptr) {}
324 virtual ~ClassInfo() {}
326 inline const ClassInfo *checkCurrent() const {
327 assert(!(m_attribute & IsRedeclared));
328 return this;
331 Attribute getAttribute() const { return checkCurrent()->m_attribute;}
332 const char *getFile() const { return checkCurrent()->m_file;}
333 int getLine1() const { return checkCurrent()->m_line1;}
334 int getLine2() const { return checkCurrent()->m_line2;}
335 virtual const ClassInfo* getCurrentOrNull() const { return this; }
336 virtual CStrRef getName() const { return m_name;}
337 const char *getDocComment() const { return m_docComment; }
339 virtual void postInit();
342 * Parents of this class.
344 virtual CStrRef getParentClass() const = 0;
345 const ClassInfo *getParentClassInfo() const;
346 virtual const InterfaceSet &getInterfaces() const = 0;
347 virtual const InterfaceVec &getInterfacesVec() const = 0;
348 virtual const TraitSet &getTraits() const = 0;
349 virtual const TraitVec &getTraitsVec() const = 0;
350 virtual const TraitAliasVec &getTraitAliasesVec() const = 0;
353 * Method functions.
355 virtual const MethodMap &getMethods() const = 0; // non-recursively
356 virtual const MethodVec &getMethodsVec() const = 0; // non-recursively
357 MethodInfo *getMethodInfo(CStrRef name) const;
358 MethodInfo *hasMethod(CStrRef name,
359 ClassInfo *&classInfo,
360 bool interfaces = false) const;
363 * Property functions.
365 virtual const PropertyMap &getProperties() const = 0; // non-recursively
366 virtual const PropertyVec &getPropertiesVec() const = 0; // non-recursively
369 * Constant functions.
371 virtual const ConstantMap &getConstants() const = 0;
372 virtual const ConstantVec &getConstantsVec() const = 0;
374 virtual const UserAttributeVec &getUserAttributeVec() const = 0;
376 static ClassInfo *GetSystem() { return s_systemFuncs; }
377 static const ClassMap GetClassesMap() { return s_class_like; }
379 protected:
380 static bool s_loaded; // whether class map is loaded
381 static ClassInfo *s_systemFuncs; // all system functions
383 static ClassInfoHook *s_hook;
385 Attribute m_attribute;
386 int m_cdec_offset;
387 String m_name;
388 const char *m_file;
389 int m_line1;
390 int m_line2;
391 const char *m_docComment;
393 private:
394 static ClassMap s_class_like; // all classes, interfaces and traits
395 static Array GetClassLike(unsigned mask, unsigned value);
396 const ClassInfo *getDeclared() const;
400 * Stores info about a class that appears once in the codebase.
402 class ClassInfoUnique : public ClassInfo {
403 public:
406 * Read one class's information from specified map pointer and move it.
408 explicit ClassInfoUnique(const char **&p);
409 virtual ~ClassInfoUnique();
411 // implementing ClassInfo
412 CStrRef getParentClass() const { return m_parent;}
413 const ClassInfo *getParentClassInfo() const;
414 const InterfaceSet &getInterfaces() const { return m_interfaces;}
415 const InterfaceVec &getInterfacesVec() const { return m_interfacesVec;}
416 const TraitSet &getTraits() const { return m_traits;}
417 const TraitVec &getTraitsVec() const { return m_traitsVec;}
418 const TraitAliasVec &getTraitAliasesVec() const { return m_traitAliasesVec;}
419 const MethodMap &getMethods() const { return m_methods;}
420 const MethodVec &getMethodsVec() const { return m_methodsVec;}
421 const PropertyMap &getProperties() const { return m_properties;}
422 const PropertyVec &getPropertiesVec() const { return m_propertiesVec;}
423 const ConstantMap &getConstants() const { return m_constants;}
424 const ConstantVec &getConstantsVec() const { return m_constantsVec;}
425 const UserAttributeVec &getUserAttributeVec() const { return m_userAttrVec;}
427 virtual void postInit();
429 private:
430 String m_parent; // parent class name
431 const ClassInfo *m_parentInfo; // parent class info (or null)
432 InterfaceSet m_interfaces; // all interfaces
433 InterfaceVec m_interfacesVec; // all interfaces in declaration order
434 TraitSet m_traits; // all used traits
435 TraitVec m_traitsVec; // all used traits
436 TraitAliasVec m_traitAliasesVec; // all trait aliases
437 MethodMap m_methods; // all methods
438 MethodVec m_methodsVec; // all methods in declaration order
439 PropertyMap m_properties; // all properties
440 PropertyVec m_propertiesVec; // all properties in declaration order
441 ConstantMap m_constants; // all constants
442 ConstantVec m_constantsVec; // all constants in declaration order
443 UserAttributeVec m_userAttrVec;
447 * Interface for a hook into class info for eval. This way I can avoid
448 * a dependency on eval.
450 class ClassInfoHook {
451 public:
452 virtual ~ClassInfoHook() {};
453 virtual Array getUserFunctions() const = 0;
454 virtual Array getClasses() const = 0;
455 virtual Array getInterfaces() const = 0;
456 virtual Array getTraits() const = 0;
457 virtual Array getConstants() const = 0;
458 virtual const ClassInfo::MethodInfo *findFunction(CStrRef name) const = 0;
459 virtual const ClassInfo *findClassLike(CStrRef name) const = 0;
460 virtual const ClassInfo::ConstantInfo *findConstant(CStrRef name) const = 0;
463 ///////////////////////////////////////////////////////////////////////////////
466 #endif // incl_HPHP_CLASS_INFO_H_