Skip to content
Browse files

Add support for PHP 5.3 namespaces

Summary:
http://github.com/facebook/xhp/issues/issue/6

Currently if you use `namespace` anywhere in your client code you can no longer use XHP. This is because of the new semantics introduced to PHP 5.3. Unfortunately XHP has its own namespace structure which conflicts with PHP's. So if we detect PHP 5.3 we will embrace namespaces by sticking all our classes in the global namespace.

Reviewed By: dweatherford

Test Plan:
Build and run tests. No new tests since we don't run PHP 5.3.
  • Loading branch information...
1 parent d238075 commit 8595cf7d043f7604141550047ff2931515e572fe @laverdet laverdet committed
Showing with 18 additions and 8 deletions.
  1. +5 −0 ext.cpp
  2. +8 −8 xhp/parser.y
  3. +2 −0 xhp/xhp.hpp
  4. +2 −0 xhp/xhp_preprocess.cpp
  5. +1 −0 xhp/xhp_preprocess.hpp
View
5 ext.cpp
@@ -151,6 +151,11 @@ static zend_op_array* xhp_compile_file(zend_file_handle* f, int type TSRMLS_DC)
flags.short_tags = CG(short_tags);
flags.idx_expr = XHPG(idx_expr);
flags.include_debug = XHPG(include_debug);
+#if PHP_VERSION_ID >= 50300
+ flags.emit_namespaces = true;
+#else
+ flags.emit_namespaces = false;
+#endif
result = xhp_preprocess(original_code, rewrit, error_str, error_lineno, flags);
if (result == XHPErred) {
View
16 xhp/parser.y
@@ -1481,9 +1481,9 @@ xhp_singleton:
if (yyextra->include_debug) {
char line[16];
sprintf(line, "%lu", (unsigned long)$1.lineno());
- $$ = "new xhp_" + $1 + "(array(" + $2 + "), array(), __FILE__, " + line + ")";
+ $$ = (yyextra->emit_namespaces ? "new \\xhp_" : "new xhp_") + $1 + "(array(" + $2 + "), array(), __FILE__, " + line + ")";
} else {
- $$ = "new xhp_" + $1 + "(array(" + $2 + "), array())";
+ $$ = (yyextra->emit_namespaces ? "new \\xhp_" : "new xhp_") + $1 + "(array(" + $2 + "), array())";
}
}
;
@@ -1493,7 +1493,7 @@ xhp_tag_open:
pop_state(); // XHP_ATTRS
push_state(XHP_CHILD_START);
yyextra->pushTag($1.c_str());
- $$ = "new xhp_" + $1 + "(array(" + $2 + "), array(";
+ $$ = (yyextra->emit_namespaces ? "new \\xhp_" : "new xhp_") + $1 + "(array(" + $2 + "), array(";
}
;
@@ -1723,7 +1723,7 @@ xhp_attribute_decl:
| T_XHP_COLON xhp_label_immediate {
$2.strip_lines();
yyextra->attribute_inherit = yyextra->attribute_inherit +
- "xhp_" + $2 + "::__xhpAttributeDeclaration(),";
+ (yyextra->emit_namespaces ? "\\xhp_" : "xhp_") + $2 + "::__xhpAttributeDeclaration(),";
}
;
@@ -1873,7 +1873,7 @@ xhp_children_decl_tag:
$$ = "2, null";
}
| T_XHP_COLON xhp_label {
- $$ = "3, \'xhp_" + $2 + "\'";
+ $$ = (yyextra->emit_namespaces ? "3, \'\\\\xhp_" + $2 + "\'" : "3, \'xhp_" + $2 + "\'");
}
| '%' xhp_label {
$$ = "4, \'" + $2 + "\'";
@@ -1886,7 +1886,7 @@ class_name:
pop_state();
push_state(PHP);
yyextra->used = true;
- $$ = "xhp_" + $2;
+ $$ = (yyextra->emit_namespaces ? "\\xhp_" : "xhp_") + $2;
}
;
@@ -1895,7 +1895,7 @@ fully_qualified_class_name:
pop_state();
push_state(PHP);
yyextra->used = true;
- $$ = "xhp_" + $2;
+ $$ = (yyextra->emit_namespaces ? "\\xhp_" : "xhp_") + $2;
}
;
@@ -1908,7 +1908,7 @@ expr_without_variable:
expr '[' dim_offset ']' {
if (yyextra->idx_expr) {
yyextra->used = true;
- $$ = "__xhp_idx(" + $1 + ", " + $3 + ")";
+ $$ = (yyextra->emit_namespaces ? "\\__xhp_idx(" : "__xhp_idx(") + $1 + ", " + $3 + ")";
} else {
$$ = $1 + $2 + $3 + $4;
}
View
2 xhp/xhp.hpp
@@ -33,6 +33,7 @@ class yy_extra_type {
idx_expr = false;
include_debug = false;
has_doc_block = false;
+ emit_namespaces = false;
expecting_xhp_class_statements = false;
pushStack();
}
@@ -41,6 +42,7 @@ class yy_extra_type {
bool asp_tags; // `asp_tags` in php.ini
bool idx_expr; // allow code like `foo()['bar']`
bool include_debug; // include line numbers and file names in XHP object creation
+ bool emit_namespaces; // put everything in the global namespace (php 5.3+)
size_t first_lineno; // line number before scanning the current token
size_t lineno; // current line number being scanned.
std::string error; // description of error (if terminated true)
View
2 xhp/xhp_preprocess.cpp
@@ -38,6 +38,7 @@ XHPResult xhp_preprocess(string &in, string &out, bool isEval, string &errDescri
flags.short_tags = true;
flags.idx_expr = true;
flags.include_debug = true;
+ flags.emit_namespaces = false;
return xhp_preprocess(in, out, errDescription, errLineno, flags);
}
@@ -63,6 +64,7 @@ XHPResult xhp_preprocess(std::string &in, std::string &out, std::string &errDesc
extra.insert_token = flags.eval ? T_OPEN_TAG_FAKE : 0;
extra.short_tags = flags.short_tags;
extra.asp_tags = flags.asp_tags;
+ extra.emit_namespaces = flags.emit_namespaces;
xhplex_init(&scanner);
xhpset_extra(&extra, scanner);
View
1 xhp/xhp_preprocess.hpp
@@ -31,6 +31,7 @@ struct xhp_flags_t {
bool idx_expr;
bool include_debug;
bool eval;
+ bool emit_namespaces;
};
XHPResult xhp_preprocess(std::istream &in, std::string &out, bool isEval,

0 comments on commit 8595cf7

Please sign in to comment.
Something went wrong with that request. Please try again.