Stanislav Malyshev wrote: >> file1.php: >> <?php >> namespace foo; >> class bar {} >> ?> >> >> file2.php: >> <?php >> namespace gronk; >> import foo::bar; >> class bar {} >> ?> > > The problem is not this code. The problem is this code: > > file1.php > <?php > namespace foo; > import otherfoo::bar; > ?> > > file2.php: > <?php > namespace gronk; > > class bar {} > ?> > > Would start failing too once you merge them in one file, even though > they worked just fine before.
Right, that's why I was saying expansion of imports would be necessary, meaning that all references to "bar" would need to be translated to "otherfoo::bar" If this is a huge problem, it could be solved by having a separate import scope within namespace brackets. This is accomplished easily by storing the existing CG(current_import) in a temp variable, CG(saved_import), resetting CG(current_import) to NULL to start over at the namespace declaration, and then restoring the old import list via CG(current_import) = CG(saved_import) and freeing CG(saved_import). This would of course mean that top-level import is not the same as import within a namespace, would that make sense? I've attached an updated patch to reflect this (it adds 9 lines and a new test for the approach, ns_046.phpt). Please note that I am not so sure I like this approach, and I have not deleted the original patch (at http://pear.php.net/~greg/namespaces.patch.txt). The new patch is also at http://pear.php.net/~greg/namespaces_smartimport.patch.txt Greg
? halt_compiler_php6.patch.txt ? namespace.patch.txt ? namespace_smartimport.patch.txt Index: Zend/zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.762 diff -u -r1.762 zend_compile.c --- Zend/zend_compile.c 20 Aug 2007 09:48:41 -0000 1.762 +++ Zend/zend_compile.c 21 Aug 2007 23:08:35 -0000 @@ -4966,16 +4966,16 @@ } /* }}} */ -void zend_do_namespace(znode *name TSRMLS_DC) /* {{{ */ +void zend_do_namespace(znode *name, int brackets TSRMLS_DC) /* {{{ */ { unsigned int lcname_len; zstr lcname; - if (CG(active_op_array)->last > 0) { + if (!brackets && CG(active_op_array)->last > 0) { zend_error(E_COMPILE_ERROR, "Namespace declaration statement has to be the very first statement in the script"); } if (CG(current_namespace)) { - zend_error(E_COMPILE_ERROR, "Namespace cannot be declared twice"); + zend_error(E_COMPILE_ERROR, "Namespace cannot be declared twice (without brackets) or nested within brackets"); } lcname = zend_u_str_case_fold(Z_TYPE(name->u.constant), Z_UNIVAL(name->u.constant), Z_UNILEN(name->u.constant), 0, &lcname_len); if (((lcname_len == sizeof("self")-1) && @@ -4988,6 +4988,25 @@ ALLOC_ZVAL(CG(current_namespace)); *CG(current_namespace) = name->u.constant; + CG(saved_import) = CG(current_import); + CG(current_import) = NULL; +} +/* }}} */ + +void zend_do_end_namespace(TSRMLS_D) /* {{{ */ +{ + if (CG(current_namespace)) { + zval_dtor(CG(current_namespace)); + efree(CG(current_namespace)); + CG(current_namespace) = NULL; + } + if (CG(current_import)) { + zend_hash_destroy(CG(current_import)); + efree(CG(current_import)); + CG(current_import) = NULL; + } + CG(current_import) = CG(saved_import); + CG(saved_import) = NULL; } /* }}} */ @@ -5068,6 +5087,11 @@ efree(CG(current_import)); CG(current_import) = NULL; } + if (CG(saved_import)) { + zend_hash_destroy(CG(saved_import)); + efree(CG(saved_import)); + CG(saved_import) = NULL; + } } /* }}} */ Index: Zend/zend_compile.h =================================================================== RCS file: /repository/ZendEngine2/zend_compile.h,v retrieving revision 1.363 diff -u -r1.363 zend_compile.h --- Zend/zend_compile.h 20 Aug 2007 09:48:41 -0000 1.363 +++ Zend/zend_compile.h 21 Aug 2007 23:08:36 -0000 @@ -520,7 +520,8 @@ void zend_do_abstract_method(znode *function_name, znode *modifiers, znode *body TSRMLS_DC); void zend_do_build_namespace_name(znode *result, znode *prefix, znode *name TSRMLS_DC); -void zend_do_namespace(znode *name TSRMLS_DC); +void zend_do_namespace(znode *name, int brackets TSRMLS_DC); +void zend_do_end_namespace(TSRMLS_D); void zend_do_import(znode *name, znode *new_name TSRMLS_DC); void zend_do_end_compilation(TSRMLS_D); Index: Zend/zend_globals.h =================================================================== RCS file: /repository/ZendEngine2/zend_globals.h,v retrieving revision 1.168 diff -u -r1.168 zend_globals.h --- Zend/zend_globals.h 12 Jul 2007 09:23:48 -0000 1.168 +++ Zend/zend_globals.h 21 Aug 2007 23:08:36 -0000 @@ -140,6 +140,7 @@ zval *current_namespace; HashTable *current_import; + HashTable *saved_import; #ifdef ZTS HashTable **static_members; Index: Zend/zend_language_parser.y =================================================================== RCS file: /repository/ZendEngine2/zend_language_parser.y,v retrieving revision 1.188 diff -u -r1.188 zend_language_parser.y --- Zend/zend_language_parser.y 20 Aug 2007 09:48:41 -0000 1.188 +++ Zend/zend_language_parser.y 21 Aug 2007 23:08:37 -0000 @@ -171,12 +171,12 @@ | function_declaration_statement { zend_do_early_binding(TSRMLS_C); } | class_declaration_statement { zend_do_early_binding(TSRMLS_C); } | T_HALT_COMPILER '(' ')' ';' { zend_do_halt_compiler_register(TSRMLS_C); YYACCEPT; } - | T_NAMESPACE namespace_name ';' { zend_do_namespace(&$2 TSRMLS_CC); } + | T_NAMESPACE namespace_name ';' { zend_do_namespace(&$2, 0 TSRMLS_CC); } + | T_NAMESPACE namespace_name '{' { zend_do_namespace(&$2, 1 TSRMLS_CC); } top_statement_list '}' { zend_do_end_namespace(TSRMLS_C); } | T_IMPORT namespace_name ';' { zend_do_import(&$2, NULL TSRMLS_CC); } | T_IMPORT namespace_name T_AS T_STRING ';' { zend_do_import(&$2, &$4 TSRMLS_CC); } ; - inner_statement_list: inner_statement_list { zend_do_extended_info(TSRMLS_C); } inner_statement { HANDLE_INTERACTIVE(); } | /* empty */ Index: Zend/tests/ns_039.phpt =================================================================== RCS file: Zend/tests/ns_039.phpt diff -N Zend/tests/ns_039.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_039.phpt 21 Aug 2007 23:08:37 -0000 @@ -0,0 +1,14 @@ +--TEST-- +039: double namespace declaration +--FILE-- +<?php +namespace Exception; +namespace Oops; +function foo() { + echo "ok\n"; +} +Exception::foo(); +Exception::bar(); +--EXPECTF-- +Fatal error: Namespace cannot be declared twice (without brackets) or nested within brackets in %sns_039.php on line 3 + Index: Zend/tests/ns_040.phpt =================================================================== RCS file: Zend/tests/ns_040.phpt diff -N Zend/tests/ns_040.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_040.phpt 21 Aug 2007 23:08:37 -0000 @@ -0,0 +1,14 @@ +--TEST-- +040: namespace not first declaration +--FILE-- +<?php +$a = oops; +namespace Exception; +function foo() { + echo "ok\n"; +} +Exception::foo(); +Exception::bar(); +--EXPECTF-- +Fatal error: Namespace declaration statement has to be the very first statement in the script in %sns_040.php on line 3 + Index: Zend/tests/ns_041.phpt =================================================================== RCS file: Zend/tests/ns_041.phpt diff -N Zend/tests/ns_041.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_041.phpt 21 Aug 2007 23:08:37 -0000 @@ -0,0 +1,13 @@ +--TEST-- +041: namespace with brackets, function declaration +--FILE-- +<?php +namespace Exception { +function foo() { + echo "ok\n"; +} +} +Exception::foo(); +--EXPECTF-- +ok + Index: Zend/tests/ns_042.phpt =================================================================== RCS file: Zend/tests/ns_042.phpt diff -N Zend/tests/ns_042.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_042.phpt 21 Aug 2007 23:08:37 -0000 @@ -0,0 +1,15 @@ +--TEST-- +042: namespace with brackets, class declaration +--FILE-- +<?php +namespace Exception { +class test { +static function foo() { + echo "ok\n"; +} +} +} +Exception::test::foo(); +--EXPECTF-- +ok + Index: Zend/tests/ns_043.phpt =================================================================== RCS file: Zend/tests/ns_043.phpt diff -N Zend/tests/ns_043.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_043.phpt 21 Aug 2007 23:08:37 -0000 @@ -0,0 +1,20 @@ +--TEST-- +043: namespace with brackets, class declaration + function declaration +--FILE-- +<?php +namespace Exception { +class test { +static function foo() { + echo "ok\n"; +} +} +function foo() { + echo "ok\n"; +} +} +Exception::test::foo(); +Exception::foo(); +--EXPECTF-- +ok +ok + Index: Zend/tests/ns_044.phpt =================================================================== RCS file: Zend/tests/ns_044.phpt diff -N Zend/tests/ns_044.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_044.phpt 21 Aug 2007 23:08:37 -0000 @@ -0,0 +1,34 @@ +--TEST-- +044: namespace with brackets, two namespace declarations +--FILE-- +<?php +namespace Exception { +class test { +static function foo() { + echo "ok\n"; +} +} +function foo() { + echo "ok\n"; +} +} +Exception::test::foo(); +Exception::foo(); +namespace Second { +class test { +static function foo() { + echo "ok\n"; +} +} +function foo() { + echo "ok\n"; +} +} +Second::test::foo(); +Second::foo(); +--EXPECTF-- +ok +ok +ok +ok + Index: Zend/tests/ns_045.phpt =================================================================== RCS file: Zend/tests/ns_045.phpt diff -N Zend/tests/ns_045.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_045.phpt 21 Aug 2007 23:08:37 -0000 @@ -0,0 +1,30 @@ +--TEST-- +045: illegal nested namespace with brackets +--FILE-- +<?php +namespace Exception { +class test { +static function foo() { + echo "ok\n"; +} +} +function foo() { + echo "ok\n"; +} +test::foo(); +foo(); +namespace Second { +class test { +static function foo() { + echo "ok\n"; +} +} +function foo() { + echo "ok\n"; +} +} +} +Second::test::foo(); +Second::foo(); +--EXPECTF-- +Fatal error: Namespace cannot be declared twice (without brackets) or nested within brackets in %sns_045.php on line 13 \ No newline at end of file Index: Zend/tests/ns_046.phpt =================================================================== RCS file: Zend/tests/ns_046.phpt diff -N Zend/tests/ns_046.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_046.phpt 21 Aug 2007 23:08:37 -0000 @@ -0,0 +1,31 @@ +--TEST-- +046: smart import +--FILE-- +<?php +namespace foo { + class bar { + function __construct() + { + echo "foo::bar\n"; + } + } + new bar; +} +import foo::bar; +namespace gronk { + import foo::bar as gronk; + class bar { + function __construct() + { + echo "gronk::bar\n"; + } + } + new bar; + new gronk; +} +new bar(); +--EXPECT-- +foo::bar +gronk::bar +foo::bar +foo::bar \ No newline at end of file
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php