Stanislav Malyshev wrote:
>> 1) adds "unset import" syntax for declaring a namespace to have local
>> import scope (it does NOT affect variable scope or the global
>> class/function table)
>
> I don't like it. What's "unset import"? Seems to be very artificial
> concept.
>
>> be as intuitive as possible.  Having a separate scope by default for
>> import that does not inherit from the global scope is not very
>> intuitive.
>
> Yep, it isn't. But it's the only concept that we saw so far that is
> consistent and logical. 
Hi,

The purpose of all my patches is to make it possible to combine multiple
namespaces into a single file.  It looks like namespace {} syntax
introduces much more trouble than it is worth.

As such, since my only goal is to be able to combine multiple files into
a single file, the attached patch basically allows you to take these two
files:

file1.php:
<?php
namespace one;
class whatever {
}
other_php_stuff();
?>

file2.php:
<?php
include 'file1.php';
namespace two;
function thingo() {}
?>

and literally cut/paste them together to get:

<?php
namespace one;
class whatever {
}
other_php_stuff();

namespace two;
function thingo() {}
?>

The patch acts as if each namespace were a separate file with respect to
import statements as well as class/function declarations.

The only limitation is that a situation like so:

file1.php
<?php
include 'file2.php';
function thing() {}
one::thing();
?>

file2.php:
<?php
namespace one;
function thing() {echo 'hi';}
?>

combine erroneously into the "one" namespace

<?php
namespace one;
function thing() {echo 'hi';}

function thing() {}
one::thing();
?>

The solution, which is a simple one, is upon combining to insert a bogus
namespace declaration for the contents of file1.php, and is a simple one
for a build tool or a developer to accomplish.  Developers who would
combine files together would need to scan for include statements if
autoload was not used, and scanning for missing namespace declarations
is trivial in this situation:

<?php
namespace one;
function thing() {echo 'hi';}

namespace __::__main;
function thing() {}
one::thing();
?>

Can we agree on this patch?  It preserves the original simple syntax
that I like so much (no brackets), solves the import scoping problem,
and allows combining files without removing the structure in
namespacing.  It also discourages using multiple namespaces per file, as
the ease of using import across namespace declarations is gone. 
Finally, it preserves the need of the first namespace declaration being
at the top of the file, another appealing feature of the original syntax.

The attached patch is also at
http://pear.php.net/~greg/multiple_namespaces.patch.txt

Thanks for your patience,
Greg
? multiple_namespace.patch.txt
? namespace.patch.txt
? namespace_brackets_unsetimport.patch.txt
? namespace_smartimport.patch.txt
Index: Zend/zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.764
diff -u -r1.764 zend_compile.c
--- Zend/zend_compile.c 22 Aug 2007 07:39:37 -0000      1.764
+++ Zend/zend_compile.c 22 Aug 2007 23:15:02 -0000
@@ -4966,11 +4966,8 @@
        unsigned int lcname_len;
        zstr lcname;
 
-       if (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");
+       if (!CG(current_namespace) && CG(active_op_array)->last > 0) {
+               zend_error(E_COMPILE_ERROR, "First namespace declaration 
statement has to be the first statement in the script");
        }
        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) &&
@@ -4981,6 +4978,16 @@
        }
        efree(lcname.v);
 
+       if (CG(current_namespace)) {
+               zval_dtor(CG(current_namespace));
+               efree(CG(current_namespace));
+       }
+       if (CG(current_import)) {
+               zend_hash_destroy(CG(current_import));
+               efree(CG(current_import));
+       }
+       CG(current_import) = NULL;
+
        ALLOC_ZVAL(CG(current_namespace));
        *CG(current_namespace) = name->u.constant;
 }
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      22 Aug 2007 23:15:03 -0000
@@ -0,0 +1,35 @@
+--TEST--
+039: two namespace declarations
+--FILE--
+<?php
+namespace Exception;
+class test {
+static function foo() {
+  echo "Exception test::foo\n";
+}
+}
+function foo() {
+  echo "Exception foo\n";
+}
+test::foo();
+foo();
+
+namespace Second;
+import Exception as wow;
+class test {
+static function foo() {
+  echo "Second test::foo\n";
+}
+}
+function foo() {
+  echo "Second foo\n";
+}
+wow::foo();
+test::foo();
+foo();
+--EXPECTF--
+Exception test::foo
+Exception foo
+Exception foo
+Second test::foo
+Second foo
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      22 Aug 2007 23:15:03 -0000
@@ -0,0 +1,12 @@
+--TEST--
+040: namespace not first declaration
+--FILE--
+<?php
+$a = 'oops';
+namespace Exception;
+function foo() {
+  echo "ok\n";
+}
+Exception::foo();
+--EXPECTF--
+Fatal error: First namespace declaration statement has to be the 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      22 Aug 2007 23:15:03 -0000
@@ -0,0 +1,18 @@
+--TEST--
+041: class in first namespace extends class in second namespace
+--FILE--
+<?php
+namespace Exception;
+import Second as First;
+class test extends First::test {
+}
+new test;
+namespace Second;
+class test {
+function __construct()
+{
+echo 'ok';
+}
+}
+--EXPECT--
+ok
\ No newline at end of file

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to