Allow parameter promotion in constructors
[hiphop-php.git] / hphp / compiler / parser / parser.h
blobc5752aad37e1f29b5dee81a7144bc68b66ec4195
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 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_COMPILER_PARSER_H_
18 #define incl_HPHP_COMPILER_PARSER_H_
20 #include "hphp/runtime/base/util/exceptions.h"
21 #include "hphp/util/parser/parser.h"
22 #include "hphp/compiler/construct.h"
23 #include "hphp/compiler/option.h"
24 #include "hphp/compiler/type_annotation.h"
25 #include "hphp/compiler/expression/scalar_expression.h"
27 #ifdef HPHP_PARSER_NS
28 #undef HPHP_PARSER_NS
29 #endif
30 #define HPHP_PARSER_NS Compiler
32 #ifdef HPHP_PARSER_ERROR
33 #undef HPHP_PARSER_ERROR
34 #endif
35 #define HPHP_PARSER_ERROR(fmt, p, args...) \
36 do { \
37 if (HPHP::Option::WholeProgram) { \
38 HPHP::Logger::Error(fmt " %s", ##args, (p)->getMessage(true).c_str()); \
39 } \
40 throw HPHP::ParseTimeFatalException((p)->file(), (p)->line1(), \
41 fmt, ##args); \
42 } while (0)
45 namespace HPHP {
46 ///////////////////////////////////////////////////////////////////////////////
48 DECLARE_BOOST_TYPES(Expression);
49 DECLARE_BOOST_TYPES(Statement);
50 DECLARE_BOOST_TYPES(StatementList);
51 DECLARE_BOOST_TYPES(Location);
52 DECLARE_BOOST_TYPES(AnalysisResult);
53 DECLARE_BOOST_TYPES(BlockScope);
54 DECLARE_BOOST_TYPES(TypeAnnotation);
56 namespace Compiler {
57 ///////////////////////////////////////////////////////////////////////////////
58 // scanner
60 class Token : public ScannerToken {
61 public:
62 ExpressionPtr exp;
63 StatementPtr stmt;
64 TypeAnnotationPtr typeAnnotation;
66 Token &operator+(const char *str) {
67 m_text += str;
68 return *this;
70 Token &operator+(const Token &token) {
71 m_num += token.m_num;
72 m_text += token.m_text;
73 return *this;
75 Token *operator->() {
76 return this;
78 void operator=(int num) {
79 m_num = num;
81 void operator=(Token &other) {
82 ScannerToken::operator=(other);
83 exp = other.exp;
84 stmt = other.stmt;
85 typeAnnotation = other.typeAnnotation;
87 void reset() {
88 exp.reset();
89 stmt.reset();
90 typeAnnotation.reset();
91 ScannerToken::reset();
93 const std::string typeAnnotationName() {
94 return (typeAnnotation) ? typeAnnotation->fullName() : "";
98 ///////////////////////////////////////////////////////////////////////////////
100 DECLARE_BOOST_TYPES(Parser);
101 class Parser : public ParserBase {
102 public:
103 static StatementListPtr ParseString(CStrRef input, AnalysisResultPtr ar,
104 const char *fileName = nullptr,
105 bool lambdaMode = false);
107 public:
108 Parser(Scanner &scanner, const char *fileName,
109 AnalysisResultPtr ar, int fileSize = 0);
111 // implementing ParserBase
112 virtual bool parseImpl();
113 bool parse();
114 virtual void error(const char* fmt, ...) ATTRIBUTE_PRINTF(2,3);
115 virtual bool enableXHP();
116 virtual bool enableFinallyStatement();
117 IMPLEMENT_XHP_ATTRIBUTES;
119 virtual void fatal(Location *loc, const char *msg);
120 std::string errString();
122 // result
123 StatementListPtr getTree() const { return m_tree;}
125 // parser handlers
126 void initParseTree();
127 void finiParseTree();
128 void onHaltCompiler();
129 void onName(Token &out, Token &name, NameKind kind);
130 void onVariable(Token &out, Token *exprs, Token &var, Token *value,
131 bool constant = false,
132 const std::string &docComment = "");
133 void onStaticVariable(Token &out, Token *exprs, Token &var, Token *value);
134 void onClassVariableModifer(Token &mod) {}
135 void onClassVariableStart(Token &out, Token *modifiers, Token &decl,
136 Token *type);
137 void onClassVariable(Token &out, Token *exprs, Token &var, Token *value);
138 void onClassConstant(Token &out, Token *exprs, Token &var, Token &value);
139 void onSimpleVariable(Token &out, Token &var);
140 void onSynthesizedVariable(Token &out, Token &var) {
141 onSimpleVariable(out, var);
143 void onDynamicVariable(Token &out, Token &expr, bool encap);
144 void onIndirectRef(Token &out, Token &refCount, Token &var);
145 void onStaticMember(Token &out, Token &cls, Token &name);
146 void onRefDim(Token &out, Token &var, Token &offset);
147 void onCallParam(Token &out, Token *params, Token &expr, bool ref);
148 void onCall(Token &out, bool dynamic, Token &name, Token &params,
149 Token *cls, bool fromCompiler = false);
150 void onEncapsList(Token &out, int type, Token &list);
151 void addEncap(Token &out, Token *list, Token &expr, int type);
152 void encapRefDim(Token &out, Token &var, Token &offset);
153 void encapObjProp(Token &out, Token &var, Token &name);
154 void encapArray(Token &out, Token &var, Token &expr);
155 void onConstantValue(Token &out, Token &constant);
156 void onScalar(Token &out, int type, Token &scalar);
157 void onExprListElem(Token &out, Token *exprs, Token &expr);
159 void onObjectProperty(Token &out, Token &base, Token &prop);
160 void onObjectMethodCall(Token &out, Token &base, Token &prop, Token &params);
162 void onListAssignment(Token &out, Token &vars, Token *expr,
163 bool rhsFirst = false);
164 void onAListVar(Token &out, Token *list, Token *var);
165 void onAListSub(Token &out, Token *list, Token &sublist);
166 void onAssign(Token &out, Token &var, Token &expr, bool ref,
167 bool rhsFirst = false);
168 void onAssignNew(Token &out, Token &var, Token &name, Token &args);
169 void onNewObject(Token &out, Token &name, Token &args);
170 void onUnaryOpExp(Token &out, Token &operand, int op, bool front);
171 void onBinaryOpExp(Token &out, Token &operand1, Token &operand2, int op);
172 void onQOp(Token &out, Token &exprCond, Token *expYes, Token &expNo);
173 void onArray(Token &out, Token &pairs, int op = T_ARRAY);
174 void onArrayPair(Token &out, Token *pairs, Token *name, Token &value,
175 bool ref);
176 void onEmptyCollection(Token &out);
177 void onCollectionPair(Token &out, Token *pairs, Token *name, Token &value);
178 void onUserAttribute(Token &out, Token *attrList, Token &name, Token &value);
179 void onClassConst(Token &out, Token &cls, Token &name, bool text);
180 void fixStaticVars();
181 void onFunctionStart(Token &name, bool doPushComment = true);
182 void onFunction(Token &out, Token *modifier, Token &ret, Token &ref,
183 Token &name, Token &params, Token &stmt, Token *attr);
184 void onParam(Token &out, Token *params, Token &type, Token &var,
185 bool ref, Token *defValue, Token *attr, Token *modifiers);
186 void onClassStart(int type, Token &name);
187 void onClass(Token &out, int type, Token &name, Token &base,
188 Token &baseInterface, Token &stmt, Token *attr);
189 void onInterface(Token &out, Token &name, Token &base, Token &stmt,
190 Token *attr);
191 void onInterfaceName(Token &out, Token *names, Token &name);
192 void onTraitUse(Token &out, Token &traits, Token &rules);
193 void onTraitName(Token &out, Token *names, Token &name);
194 void onTraitRule(Token &out, Token &stmtList, Token &newStmt);
195 void onTraitPrecRule(Token &out, Token &className, Token &methodName,
196 Token &otherClasses);
197 void onTraitAliasRuleStart(Token &out, Token &className, Token &methodName);
198 void onTraitAliasRuleModify(Token &out, Token &rule, Token &accessModifiers,
199 Token &newMethodName);
200 void onMethodStart(Token &name, Token &mods, bool doPushComment = true);
201 void onMethod(Token &out, Token &modifiers, Token &ret, Token &ref,
202 Token &name, Token &params, Token &stmt, Token *attr,
203 bool reloc = true);
204 void onMemberModifier(Token &out, Token *modifiers, Token &modifier);
205 void onStatementListStart(Token &out);
206 void addStatement(Token &out, Token &stmts, Token &new_stmt);
207 void addTopStatement(Token &new_stmt);
208 void onClassStatement(Token &out, Token &stmts, Token &new_stmt) {
209 addStatement(out, stmts, new_stmt);
211 void finishStatement(Token &out, Token &stmts);
212 void onBlock(Token &out, Token &stmts);
213 void onIf(Token &out, Token &cond, Token &stmt, Token &elseifs,
214 Token &elseStmt);
215 void onElseIf(Token &out, Token &elseifs, Token &cond, Token &stmt);
216 void onWhile(Token &out, Token &cond, Token &stmt);
217 void onDo(Token &out, Token &stmt, Token &cond);
218 void onFor(Token &out, Token &expr1, Token &expr2, Token &expr3,
219 Token &stmt);
220 void onSwitch(Token &out, Token &expr, Token &cases);
221 void onCase(Token &out, Token &cases, Token *cond, Token &stmt);
222 void onBreak(Token &out, Token *expr);
223 void onContinue(Token &out, Token *expr);
224 void onReturn(Token &out, Token *expr);
225 void onYield(Token &out, Token &expr);
226 void onYieldPair(Token &out, Token &key, Token &val);
227 void onYieldBreak(Token &out);
228 void onGlobal(Token &out, Token &expr);
229 void onGlobalVar(Token &out, Token *exprs, Token &expr);
230 void onStatic(Token &out, Token &expr);
231 void onEcho(Token &out, Token &expr, bool html);
232 void onUnset(Token &out, Token &expr);
233 void onExpStatement(Token &out, Token &expr);
234 void onForEachStart();
235 void onForEach(Token &out, Token &arr, Token &name, Token &value,
236 Token &stmt);
237 void onTry(Token &out, Token &tryStmt, Token &className, Token &var,
238 Token &catchStmt, Token &catches, Token &finallyStmt);
239 void onTry(Token &out, Token &tryStmt, Token &finallyStmt);
240 void onCatch(Token &out, Token &catches, Token &className, Token &var,
241 Token &stmt);
242 void onFinally(Token &out, Token &stmt);
243 void onThrow(Token &out, Token &expr);
245 void onClosureStart(Token &name);
246 void onClosure(Token &out, Token &ret, Token &ref, Token &params,
247 Token &cparams, Token &stmts, bool is_static);
248 void onClosureParam(Token &out, Token *params, Token &param, bool ref);
249 void onLabel(Token &out, Token &label);
250 void onGoto(Token &out, Token &label, bool limited);
251 void onTypedef(Token& out, const Token& name, const Token& type);
253 void onTypeAnnotation(Token& out, const Token& name, const Token& typeArgs);
254 void onTypeList(Token& type1, const Token& type2);
255 void onTypeSpecialization(Token& type, char specialization);
257 // for namespace support
258 void onNamespaceStart(const std::string &ns, bool file_scope = false);
259 void onNamespaceEnd();
260 void onUse(const std::string &ns, const std::string &as);
261 void nns(int token = 0);
262 std::string nsDecl(const std::string &name);
263 std::string resolve(const std::string &ns, bool cls);
265 virtual void invalidateGoto(TStatementPtr stmt, GotoError error);
266 virtual void invalidateLabel(TStatementPtr stmt);
268 virtual TStatementPtr extractStatement(ScannerToken *stmt);
270 FileScopePtr getFileScope() { return m_file; }
272 private:
273 struct FunctionContext {
274 FunctionContext()
275 : isNotGenerator(false)
276 , isGenerator(false)
279 // mark this function as generator; returns true on success
280 bool setIsGenerator() {
281 if (!isNotGenerator) isGenerator = true;
282 return !isNotGenerator;
285 // mark this function as non-generator; returns true on success
286 bool setIsNotGenerator() {
287 if (!isGenerator) isNotGenerator = true;
288 return !isGenerator;
291 void checkFinalAssertions() {
292 assert(!isGenerator || !isNotGenerator);
295 bool isNotGenerator; // function determined to not be a generator
296 bool isGenerator; // function determined to be a generator
299 AnalysisResultPtr m_ar;
300 FileScopePtr m_file;
301 std::vector<std::string> m_comments; // for docComment stack
302 std::vector<BlockScopePtrVec> m_scopes;
303 std::vector<FunctionContext> m_funcContexts;
304 std::vector<std::vector<StatementPtr> > m_prependingStatements;
305 std::vector<ScalarExpressionPtr> m_compilerHaltOffsetVec;
306 std::string m_clsName; // for T_CLASS_C inside a closure
307 std::string m_funcName;
308 std::string m_containingFuncName;
309 bool m_inTrait;
311 // parser output
312 StatementListPtr m_tree;
313 std::string m_error;
315 std::vector<bool> m_hasCallToGetArgs;
316 std::vector<StringToExpressionPtrVecMap> m_staticVars;
317 bool m_lambdaMode;
318 bool m_closureGenerator;
320 void pushComment();
321 void pushComment(const std::string& s);
322 std::string popComment();
324 void newScope();
325 void completeScope(BlockScopePtr inner);
327 bool setIsGenerator();
329 ExpressionPtr getDynamicVariable(ExpressionPtr exp, bool encap);
330 ExpressionPtr createDynamicVariable(ExpressionPtr exp);
332 bool hasType(Token &type);
334 void checkAssignThis(Token &var);
336 void addStatement(StatementPtr stmt, StatementPtr new_stmt);
338 // for namespace support
339 enum NamespaceState {
340 SeenNothing,
341 SeenNonNamespaceStatement,
342 SeenNamespaceStatement,
343 InsideNamespace,
345 NamespaceState m_nsState;
346 bool m_nsFileScope;
347 std::string m_namespace; // current namespace
348 hphp_string_imap<std::string> m_aliases;
349 void registerAlias(std::string name);
352 ///////////////////////////////////////////////////////////////////////////////
355 #endif