Hello Marcus,
Tuesday, August 12, 2008, 3:36:36 PM, you wrote:
> Hello Etienne,
> Tuesday, August 12, 2008, 3:04:48 AM, you wrote:
>> Hello,
>> On Tue, Aug 12, 2008 at 2:39 AM, Stanislav Malyshev <[EMAIL PROTECTED]>
>> wrote:
>>> Hi!
>>>
>>>> but if the {} syntax is introduced, it will be made to affect only the
>>>> code inside it, right? If so, I fail to see your point, since the new
>>>> syntax will solve that problem.
>>>
>>> While introducing a whole collection of new problems - such as that we will
>>> have now split scope, that you can get in and out many times in the same
>>> file. As we discussed on the list many times, it's not exactly what we want
>>> and definitely not the use case it was designed for. I don't see any use for
>>> it besides promoting bad coding practices.
>> To me
>> namespace A {
>> code
>> }
>> namespace B {
>> code
>> }
>> code
>> seems equivalent to
>> namespace A;
>> code
>> namespace B;
>> code
>> namespace <none>;
>> code
>> Only nicer. And I can hardly how it's going to cause more problems?
>> But if that's so, fine.
>> My point is that if we are going to allow multiple namespaces per file
>> solely on the perspective of permitting packaging, we should also
>> allow mixing namespaced and non-namespaced code for that same
>> perspective, and the current syntax is not going to allow that.
>> I'd really like the {} syntax if multiple namespaces per file is
>> allowed. If it's not, then it's not much more than syntactic sugar and
>> I couldn't care less.
> Exact same reasoning here. Now, I want to follow up with two things:
> I) personal recent encounters
> II) collection of argumenmts
> III) personal preference
> IV) what to do next
> I) personal recent encounters
> Technically it is pretty easy to come up with parser/lexer changes that
> allow anything you want. Starting from real parser support for only one
> namespace as the first statement per file down to muliple nested
> namespaces after some initial code outside any namespace as in global,
> patch for that attached. It does not include zend_language_scanner.c
> and is not fully functionally. it just allows getting a feeling for
> namespaces with curlies and and a potential limitationt to have non
> namespaces code only prior to the first namespace keyword. Also it
> could be done much easier but I wanted the extended info stuff the way
> it is.
> At the end of the day my biggest issues her are:
> 1) Namespaces without curly braces and concatenation of files lead to
> difference code behavior.
> I am not saying that curly braces would solve this fully per se, as you
> could still use include/require statements. My point is rather that we
> do not addredss this issue at all right now.
> And btw, with curly braces we could at least disallow include/require
> inside namespaces. Just as we don't allow include/require in classes
> outside methods.
> 2) When we allow multiple namespaces per file for concatenation, then
> why do we not allow code outside of namespaces. Because sooner or
> later we want that too. We would want that for the exact reason we
> want to have multiple namespaces today - concatenation of files.
> However without curly braces we can never concatenate files with code
> outside namespaces.
> 3) We are moving in the wrong direction here. Instead of keeping the
> language easy we make it more complex to understand and deal with. And
> the biggest reasons brought up so far are, circled around
> - concatenation for speed
> - whitespace
> - which other language we relate to
> I am really sorry for having to keep this running, but we are running
> into somethign extremely bad. And it doesn't even work out in the long
> run.
> Another example. Remember when we first introduced cli? We thought of
> adding a new file type that wouldn't need PIs (<?php...?>). We luckily
> decided against that idea to keep the language easy. Without curlies we
> will sooner or later be in a situation where there are two kinds of php
> files. Those with namespaces and those without and they wouldn't be
> able to cooperate.
> II) collection of argumenmts
> Let me try to summarize up to this point. The following options have been
> outlined and discussed in more detail:
> 1) Kepp all as is: multiple 'namespace' declarations per file, no {}
> + For some people this means no additional whitespace (other people do
> not have this issue, yet counted as +)
> 0 No direct nesting support (some like it, some don't)
> 0 Looks and feels more or less like Java packages
> 0 Original namespaces in pre 5.0beta had curlies
> 0 Is different from C++'s namespaces so it should look different,
> more in: http://news.php.net/php.internals/39838
> - Indirect nesting (only): php -r 'namespace foo; namespace foo::bar;'
> - Like Java but allows multiple per file and has different keyword
> - Multiple namespaces per file as a hack that is not meant to be used
> - Two types of scripts, those with and those without namespaces, which
> also prevents concatenation as a general solution if one file has
> global code
> - A file included in a namespaced method is not in that same namespace,
> if we fix this we end up in different behavior of include/require for
> namespe/non namespace files. If we disallow that, we make it harder
> to understand when it is allowed and when not.
> - A file included from a namespaced function/method body ends up in
> that function method but not in its namespace:
> http://lxr.php.net/source/ZendEngine2/tests/ns_069.phpt
> http://lxr.php.net/source/ZendEngine2/tests/ns_069.inc
> 2) Change keyword 'namespace' to 'package'
> 0 Besides the file concatenation this would be exactly what Java does
> - Namespace has been a reserved keyword, added 15th August 2007:
>
> http://cvs.php.net/viewvc.cgi/phpdoc/en/appendices/reserved.xml?r1=1.66&r2=1.67
> - 'Package' is not a reserved keyword at all
> [The arguments of 1) aply]
> 2b) Like 2) but no multiple namespaces per file (no file concatenation)
> 0 Phar can be used to put several file in one anyway
> 3) Add curly braces to 'namespace'
> + Real nesting (some people don't like it but we support it anyway)
> + Allows for global, non namespaced code, and thus full concatenation of
> files
> 0 Looks and feels exactly like C++ (besides we need to discuss whether to
> allow code outside namespace).
> 0 Makes it a block structure like class which uses {}
> - For some people this means additional whitespace (other people do not
> have this issue, yet counted as -)
> Why reuse keyword 'namespace' to identify root namespace (namespace::)?
> - Why not use ':::' instead (re2c allows that easily) ?
> Why no non namespced code?
> - Issues with compiler caches
> Do we need to support concatenation of files at all costs?
> - We actually ship phar which allows to pack as many namespaced files
> in a single php file, no matter what namespace support we end up
> allowing.
> III) personal preference
> My preference is 3) and the next one would be 2) without file
> concatenation support, as in one namespace per file only.
> IV) what to do next
> Someone should collect more arguments from the various threads (I am
> sure there are more) and put them on a wiki. This pretty much looks
> like a job for Lukas :-)
In a pretty long IRC discussion we discussed besides other stuff the
following:
a) Prevent include/require inside namespaced functions.
Patch: php-no-include-in-namespaced-functions-6.0-20080812.diff.txt
Should pretty much work.
b) Allow both 'namspace foo;' as well as 'namespace foo {}'.
Patch: php-namespaces-with-curlies-6.0-20080812.diff.txt
Note that this patch does not come with test updates and necessary error
message adjustage.
Best regards,
Marcus
Index: Zend/zend.c
===================================================================
RCS file: /repository/ZendEngine2/zend.c,v
retrieving revision 1.421
diff -u -p -d -r1.421 zend.c
--- Zend/zend.c 12 Aug 2008 17:15:58 -0000 1.421
+++ Zend/zend.c 12 Aug 2008 20:11:22 -0000
@@ -874,6 +874,7 @@ static void compiler_globals_ctor(zend_c
CG(interactive) = 0;
CG(literal_type) = ZEND_STR_TYPE;
+ CG(function_nest_level) = 0;
compiler_globals->auto_globals = (HashTable *)
malloc(sizeof(HashTable));
zend_u_hash_init_ex(compiler_globals->auto_globals,
global_auto_globals_table->nNumOfElements, NULL, NULL, 1, UG(unicode), 0);
Index: Zend/zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.837
diff -u -p -d -r1.837 zend_compile.c
--- Zend/zend_compile.c 12 Aug 2008 17:15:59 -0000 1.837
+++ Zend/zend_compile.c 12 Aug 2008 20:11:23 -0000
@@ -1216,6 +1216,7 @@ void zend_do_begin_function_declaration(
zstr lcname;
zend_bool orig_interactive;
+ CG(function_nest_level)++;
if (is_method) {
if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
if ((Z_LVAL(fn_flags_znode->u.constant) &
~(ZEND_ACC_STATIC|ZEND_ACC_PUBLIC))) {
@@ -1498,6 +1499,7 @@ void zend_do_end_function_declaration(co
zend_do_extended_info(TSRMLS_C);
zend_do_return(NULL, 0 TSRMLS_CC);
+ CG(function_nest_level)--;
pass_two(CG(active_op_array) TSRMLS_CC);
@@ -4487,6 +4489,16 @@ void zend_do_include_or_eval(int type, z
{
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+ if (type != ZEND_EVAL && CG(function_nest_level)
+ && CG(current_namespace) &&
Z_STRLEN_P(CG(current_namespace)))
+ {
+ zend_error(E_COMPILE_WARNING,
+ "Include or require statement inside function
%v%s%v inside namespace %R",
+ CG(active_class_entry) ?
CG(active_class_entry)->name : EMPTY_ZSTR,
+ CG(active_class_entry) ? "::" : "",
+ CG(active_op_array)->function_name.v,
+ Z_TYPE_P(CG(current_namespace)),
Z_UNIVAL_P(CG(current_namespace)));
+ }
opline->opcode = ZEND_INCLUDE_OR_EVAL;
opline->result.op_type = IS_VAR;
opline->result.u.var =
get_temporary_variable(CG(active_op_array));
Index: Zend/zend_globals.h
===================================================================
RCS file: /repository/ZendEngine2/zend_globals.h,v
retrieving revision 1.180
diff -u -p -d -r1.180 zend_globals.h
--- Zend/zend_globals.h 11 Aug 2008 17:19:01 -0000 1.180
+++ Zend/zend_globals.h 12 Aug 2008 20:11:23 -0000
@@ -88,6 +88,7 @@ struct _zend_compiler_globals {
char *heredoc;
int heredoc_len;
+ int function_nest_level;
zend_op_array *active_op_array;
Index: Zend/tests/ns_069.phpt
===================================================================
RCS file: /repository/ZendEngine2/tests/ns_069.phpt,v
retrieving revision 1.1
diff -u -p -d -r1.1 ns_069.phpt
--- Zend/tests/ns_069.phpt 12 Aug 2008 11:51:34 -0000 1.1
+++ Zend/tests/ns_069.phpt 12 Aug 2008 20:11:24 -0000
@@ -3,22 +3,36 @@
--FILE--
<?php
-namespace foo;
+namespace foo::bar;
+
+function funcA() {
+ var_dump((binary)__NAMESPACE__);
+ include __DIR__ . '/ns_069.inc';
+ var_dump((binary)__NAMESPACE__);
+}
class Test {
- static function f() {
+ static function funcB() {
var_dump((binary)__NAMESPACE__);
include __DIR__ . '/ns_069.inc';
var_dump((binary)__NAMESPACE__);
}
}
-Test::f();
+funcA();
+Test::funcB();
?>
===DONE===
---EXPECT--
-string(3) "foo"
+--EXPECTF--
+
+Warning: Include or require statement inside function foo::bar::funcA inside
namespace foo::bar in %sns_069.php on line %d
+
+Warning: Include or require statement inside function foo::bar::Test::funcB
inside namespace foo::bar in %sns_069.php on line %d
+string(8) "foo::bar"
string(0) ""
-string(3) "foo"
+string(8) "foo::bar"
+string(8) "foo::bar"
+string(0) ""
+string(8) "foo::bar"
===DONE===
Index: Zend/zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.837
diff -u -p -d -r1.837 zend_compile.c
--- Zend/zend_compile.c 12 Aug 2008 17:15:59 -0000 1.837
+++ Zend/zend_compile.c 12 Aug 2008 20:47:30 -0000
@@ -5382,7 +5382,21 @@ void zend_do_build_namespace_name(znode
}
/* }}} */
-void zend_do_namespace(const znode *name TSRMLS_DC) /* {{{ */
+void zend_do_end_namespace(TSRMLS_D) /* {{{ */
+{
+ if (CG(current_namespace)) {
+ zval_dtor(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;
+ }
+}
+/* }}} */
+
+void zend_do_begin_namespace(const znode *name TSRMLS_DC) /* {{{ */
{
unsigned int lcname_len;
zstr lcname;
@@ -5408,16 +5446,8 @@ void zend_do_namespace(const znode *name
}
efree(lcname.v);
- if (CG(current_namespace)) {
- zval_dtor(CG(current_namespace));
- } else {
- ALLOC_ZVAL(CG(current_namespace));
- }
- if (CG(current_import)) {
- zend_hash_destroy(CG(current_import));
- efree(CG(current_import));
- CG(current_import) = NULL;
- }
+ zend_do_end_namespace(TSRMLS_C);
+ ALLOC_ZVAL(CG(current_namespace));
*CG(current_namespace) = name->u.constant;
}
Index: Zend/zend_compile.h
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.h,v
retrieving revision 1.388
diff -u -p -d -r1.388 zend_compile.h
--- Zend/zend_compile.h 12 Aug 2008 17:15:59 -0000 1.388
+++ Zend/zend_compile.h 12 Aug 2008 20:47:30 -0000
@@ -543,7 +543,8 @@ void zend_do_abstract_method(const znode
void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC);
void zend_do_build_namespace_name(znode *result, znode *prefix, znode *name
TSRMLS_DC);
-void zend_do_namespace(const znode *name TSRMLS_DC);
+void zend_do_begin_namespace(const znode *name TSRMLS_DC);
+void zend_do_end_namespace(TSRMLS_D);
void zend_do_use(znode *name, znode *new_name, int is_global TSRMLS_DC);
void zend_do_end_compilation(TSRMLS_D);
Index: Zend/zend_language_parser.y
===================================================================
RCS file: /repository/ZendEngine2/zend_language_parser.y,v
retrieving revision 1.210
diff -u -p -d -r1.210 zend_language_parser.y
--- Zend/zend_language_parser.y 12 Aug 2008 10:22:57 -0000 1.210
+++ Zend/zend_language_parser.y 12 Aug 2008 20:47:30 -0000
@@ -153,17 +153,23 @@
%% /* Rules */
start:
- top_statement_list { zend_do_end_compilation(TSRMLS_C); }
+ top_statement_or_namespace_list { zend_do_end_compilation(TSRMLS_C); }
;
-top_statement_list:
- top_statement_list { zend_do_extended_info(TSRMLS_C); }
top_statement { HANDLE_INTERACTIVE(); }
+top_statement_or_namespace_list:
+ top_statement_or_namespace_list {
zend_do_extended_info(TSRMLS_C); } top_statement_or_namespace {
HANDLE_INTERACTIVE(); }
| /* empty */
;
-namespace_name:
- T_STRING { $$ = $1; }
- | namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING {
zend_do_build_namespace_name(&$$, &$1, &$3 TSRMLS_CC); }
+top_statement_or_namespace:
+ top_statement
+ | T_NAMESPACE namespace_name ';' { zend_do_begin_namespace(&$2
TSRMLS_CC); }
+ | T_NAMESPACE namespace_name '{' { zend_do_begin_namespace(&$2
TSRMLS_CC); } top_statement_list '}' { zend_do_end_namespace(TSRMLS_C); }
+;
+
+top_statement_list:
+ top_statement_list { zend_do_extended_info(TSRMLS_C); }
top_statement { HANDLE_INTERACTIVE(); }
+ | /* empty */
;
top_statement:
@@ -171,11 +177,15 @@ top_statement:
| 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_USE use_declarations ';'
| constant_declaration ';'
;
+namespace_name:
+ T_STRING { $$ = $1; }
+ | namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING {
zend_do_build_namespace_name(&$$, &$1, &$3 TSRMLS_CC); }
+;
+
use_declarations:
use_declarations ',' use_declaration
| use_declaration
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php