2 +----------------------------------------------------------------------+
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_TYPE_H_
18 #define incl_HPHP_TYPE_H_
20 #include <compiler/hphp.h>
21 #include <util/json.h>
22 #include <util/case_insensitive.h>
23 #include <runtime/base/types.h>
28 struct ProgramOptions
;
29 int process(const ProgramOptions
&);
32 ///////////////////////////////////////////////////////////////////////////////
35 DECLARE_BOOST_TYPES(Expression
);
36 DECLARE_BOOST_TYPES(AnalysisResult
);
37 DECLARE_BOOST_TYPES(Type
);
38 DECLARE_BOOST_TYPES(BlockScope
);
39 DECLARE_BOOST_TYPES(ClassScope
);
41 class Type
: public JSON::CodeError::ISerializable
,
42 public JSON::DocTarget::ISerializable
{
43 friend class ::TestCodeRun
;
44 friend class ::TestCodeError
;
48 static const KindOf KindOfVoid
= 0x0001;
49 static const KindOf KindOfBoolean
= 0x0002;
50 static const KindOf KindOfInt32
= 0x0010;
51 static const KindOf KindOfInt64
= 0x0020;
52 static const KindOf KindOfDouble
= 0x0040;
53 static const KindOf KindOfString
= 0x0080;
54 static const KindOf KindOfArray
= 0x0100;
55 static const KindOf KindOfObject
= 0x0200; // with classname
56 static const KindOf KindOfVariant
= 0xFFFF;
58 /* This bit tells coerce that if the other type
59 is already one of the specified types, it wont
61 eg $a['foo'] = <whatever>
62 If $a is already known to be string or array, it stays that way.
63 If we coerce to Sequence, however, it would become Sequence, and
66 static const KindOf KindOfAuto
= 0x0400;
68 static const KindOf KindOfInteger
= (KindOf
)(KindOfInt64
| KindOfInt32
);
69 static const KindOf KindOfNumeric
= (KindOf
)(KindOfDouble
| KindOfInteger
);
70 static const KindOf KindOfPrimitive
= (KindOf
)(KindOfNumeric
| KindOfString
);
71 static const KindOf KindOfPlusOperand
= (KindOf
)(KindOfNumeric
| KindOfArray
);
72 static const KindOf KindOfSequence
= (KindOf
)(KindOfString
| KindOfArray
);
74 static const KindOf KindOfAutoSequence
= (KindOf
)(KindOfAuto
|
76 static const KindOf KindOfAutoObject
= (KindOf
)(KindOfAuto
| KindOfObject
);
78 static const KindOf KindOfSome
= (KindOf
)0x7FFE;
79 static const KindOf KindOfAny
= (KindOf
)0x7FFF;
81 * Inferred types: types that a variable or a constant is sure to be.
84 static TypePtr Boolean
;
87 static TypePtr Double
;
88 static TypePtr String
;
90 static TypePtr Object
;
91 static TypePtr Variant
;
93 static TypePtr Numeric
;
94 static TypePtr PlusOperand
;
95 static TypePtr Primitive
;
96 static TypePtr Sequence
;
98 static TypePtr AutoSequence
;
99 static TypePtr AutoObject
;
104 typedef hphp_string_imap
<TypePtr
> TypePtrMap
;
105 static const TypePtrMap
&GetTypeHintTypes();
108 * Uncertain types: types that are ambiguous yet.
110 static TypePtr
CreateObjectType(const std::string
&classname
);
113 * For inferred, return static type objects; for uncertain, create new
116 static TypePtr
GetType(KindOf kindOf
,
117 const std::string
&clsname
= "");
120 * Whether a type can be used as another type.
122 static bool IsLegalCast(AnalysisResultConstPtr ar
, TypePtr from
, TypePtr to
);
125 * Find the intersection between two sets of types.
127 static TypePtr
Intersection(AnalysisResultConstPtr ar
,
128 TypePtr from
, TypePtr to
);
131 * Whether or not this type is mapped to type Variant
134 static bool IsMappedToVariant(TypePtr t
);
137 * Whether or not a cast is needed during code generation.
139 static bool IsCastNeeded(AnalysisResultConstPtr ar
, TypePtr from
, TypePtr to
);
142 * When a variable's type is t1, and it's used as t2, do we need to
143 * coerce variable's type? Normally, if t2 can be legally casted to t1,
144 * this returns false.
146 static bool IsCoercionNeeded(AnalysisResultConstPtr ar
,
147 TypePtr t1
, TypePtr t2
);
150 * When a variable is assigned with two types, what type a variable
153 static TypePtr
Coerce(AnalysisResultConstPtr ar
,
154 TypePtr type1
, TypePtr type2
);
155 static TypePtr
Union(AnalysisResultConstPtr ar
, TypePtr type1
, TypePtr type2
);
158 * When two types have been inferred for an expression, what type
161 static TypePtr
Inferred(AnalysisResultConstPtr ar
,
162 TypePtr type1
, TypePtr type2
);
165 * When two object types have been inferred for an expression, what type
168 static TypePtr
InferredObject(AnalysisResultConstPtr ar
,
173 * Whether or not two types are the same.
175 static bool SameType(TypePtr type1
, TypePtr type2
);
178 * Return true if SameType(type1,type2) or if type1 and type2
179 * are objects and type1 derives from type2.
181 static bool SubType(AnalysisResultConstPtr ar
, TypePtr type1
, TypePtr type2
);
184 * Testing type conversion for constants.
186 static bool IsExactType(KindOf kindOf
);
188 static bool HasFastCastMethod(TypePtr t
);
191 * Returns the name of the method used to fast cast from
194 static std::string
GetFastCastMethod(
195 TypePtr dst
, bool allowRef
, bool forConst
);
198 Type(KindOf kindOf
, const std::string
&name
);
204 explicit Type(KindOf kindOf
);
205 bool is(KindOf kindOf
) const { return m_kindOf
== kindOf
;}
206 bool isExactType() const { return IsExactType(m_kindOf
); }
207 bool mustBe(KindOf kindOf
) const { return !(m_kindOf
& ~kindOf
); }
208 bool couldBe(KindOf kindOf
) const { return m_kindOf
& kindOf
; }
209 bool isSubsetOf(TypePtr t
) const {
210 return m_kindOf
!= t
->m_kindOf
&& mustBe(t
->m_kindOf
);
212 KindOf
getKindOf() const { return m_kindOf
;}
213 bool isInteger() const;
214 bool isStandardObject() const;
215 bool isSpecificObject() const;
216 bool isNonConvertibleType() const; // other types cannot convert to them
217 bool isPrimitive() const {
218 return IsExactType(m_kindOf
) && (m_kindOf
<= KindOfDouble
) &&
219 (m_kindOf
!= KindOfVoid
);
221 bool isNoObjectInvolved() const;
222 const std::string
&getName() const { return m_name
;}
223 static TypePtr
combinedArithmeticType(TypePtr t1
, TypePtr t2
);
225 ClassScopePtr
getClass(AnalysisResultConstPtr ar
,
226 BlockScopeRawPtr scope
) const;
228 DataType
getDataType() const;
229 DataType
getHhvmDataType() const;
232 * Type hint names in PHP.
234 std::string
getPHPName();
239 std::string
toString() const;
240 static void Dump(TypePtr type
, const char *fmt
= "%s");
241 static void Dump(ExpressionPtr exp
);
244 * Implements JSON::CodeError::ISerializable.
246 virtual void serialize(JSON::CodeError::OutputStream
&out
) const;
249 * Implements JSON::DocTarget::ISerializable.
251 virtual void serialize(JSON::DocTarget::OutputStream
&out
) const;
254 * For stats reporting.
256 void count(std::map
<std::string
, int> &counts
);
259 * Must not be invoked concurrently
261 static void InitTypeHintMap();
265 * Must not be invoked concurrently
267 static void ResetTypeHintTypes();
269 static TypePtrMap s_TypeHintTypes
;
271 const KindOf m_kindOf
;
272 const std::string m_name
;
275 ///////////////////////////////////////////////////////////////////////////////
277 #endif // incl_HPHP_TYPE_H_