Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:31819 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 80342 invoked by uid 1010); 21 Aug 2007 23:12:51 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 80327 invoked from network); 21 Aug 2007 23:12:51 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 21 Aug 2007 23:12:51 -0000 Authentication-Results: pb1.pair.com smtp.mail=greg@chiaraquartet.net; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=greg@chiaraquartet.net; sender-id=unknown Received-SPF: error (pb1.pair.com: domain chiaraquartet.net from 38.99.98.18 cause and error) X-PHP-List-Original-Sender: greg@chiaraquartet.net X-Host-Fingerprint: 38.99.98.18 beast.bluga.net Linux 2.6 Received: from [38.99.98.18] ([38.99.98.18:50965] helo=mail.bluga.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 67/B0-10378-0717BC64 for ; Tue, 21 Aug 2007 19:12:50 -0400 Received: from mail.bluga.net (localhost.localdomain [127.0.0.1]) by mail.bluga.net (Postfix) with ESMTP id 2FED094E010; Tue, 21 Aug 2007 16:12:46 -0700 (MST) Received: from [192.168.0.106] (CPE-76-84-1-170.neb.res.rr.com [76.84.1.170]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.bluga.net (Postfix) with ESMTP id 5F5AB94E00E; Tue, 21 Aug 2007 16:12:45 -0700 (MST) Message-ID: <46CB71FD.9070407@chiaraquartet.net> Date: Tue, 21 Aug 2007 18:15:09 -0500 User-Agent: Thunderbird 1.5.0.12 (X11/20070604) MIME-Version: 1.0 To: Stanislav Malyshev CC: Dmitry Stogov , 'internals Mailing List' References: <46C9F217.8040804@chiaraquartet.net> <000001c7e3cb$9a80b160$6e02a8c0@thinkpad> <46CB3DF1.5090203@chiaraquartet.net> <46CB55A0.3050904@zend.com> <46CB59C0.1020306@chiaraquartet.net> <46CB5C06.6050006@zend.com> In-Reply-To: <46CB5C06.6050006@zend.com> Content-Type: multipart/mixed; boundary="------------000408070703050601090708" X-Virus-Scanned: ClamAV using ClamSMTP Subject: Re: [PHP-DEV] [PATCH] allowing multiple namespaces per file plus namespaces with brackets From: greg@chiaraquartet.net (Gregory Beaver) --------------000408070703050601090708 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Stanislav Malyshev wrote: >> file1.php: >> > namespace foo; >> class bar {} >> ?> >> >> file2.php: >> > namespace gronk; >> import foo::bar; >> class bar {} >> ?> > > The problem is not this code. The problem is this code: > > file1.php > namespace foo; > import otherfoo::bar; > ?> > > file2.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 --------------000408070703050601090708 Content-Type: text/plain; name="namespace_smartimport.patch.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="namespace_smartimport.patch.txt" ? 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-- +