Electronics & Programming

develissimo

Open Source electronics development and programming

  • You are not logged in.
  • Root
  • » PHP
  • » [PHP-DEV] Re: PDM Meeting Notes [RSS Feed]

#1 Nov. 22, 2005 18:21:19

Jessie H.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Re: PDM Meeting Notes


Hello all,I saw the notes regarding namespaces, and it really suprised me that thenamespace patch was not looked at in detail, discarded, and then theapproach that was agreed on was _THE EXACT SAME ONE_ that my patch uses.To add insult to injury, it's mentioned that Marcus was going to providea patch (my problem is not with Marcus, in fact, he was very supportiveand helpful when I was writing the patch and the __autoload mechanismI'm using is thanks to his input. My problem is that my patch wascompletely ignored and someone else was assigned to write a patch, whenthe one I already wrote can be used).My patch meets all the requirements, except for the following items:1) "The suggested separator is "\" as this is the only free choice." - Icurrently use the ':' separator, but this can be easily changed.2) "Functions in name spaces are allowed." - I added this once andposted the patch to the list, but many (including Andi himself) agreedthat we should just stick to classes inside namespaces. The only thing Iaccomplished was having the function be used asnamespace_name:my_function. If a namespace import for functions were towork, then an __autoload for functions would need to be supported in theengine. This has been suggested before, as having a global __callfunction. With a global __call function, namespace imports can alsoimport functions.3) "Constants in name spaces are allowed unless we find problems withthe implementation." - I have not tried this, but if all agree, I cancheck to see how easy it would be to add this to my patch.The attached patch is identical to what I had since August 9th, but wasupdated to apply cleanly to the latest PHP 5.1 CVS version (it must beapplied before running buildconf).I do not mean to offend anyone or point fingers, and I am sorry if mytone is a bit harsh, but please understand that I have reason to havefelt ignored in this whole manner. If you need more information aboutthe "inner workings of my patch", then please email me or post yourquestions to the list, and I'll be more than happy to explain.Regards,

Jessie Hernandez


Derick Rethans wrote:Hello folks!On 11 and 12 November a bunch of us had a developers meeting in Paris,discussing the things we want to do for PHP 6. Partly because of theUnicode support, but we also discussed the items on "Rasmus' wishlist"and a lot of other items. I made a report of the discussions we had andplaced the notes here:http://php.net/~derick/meeting-notes.htmlregards,
Derick? tests/classes/namespace
Index: ext/spl/php_spl.c
===================================================================
RCS file: /repository/php-src/ext/spl/php_spl.c,v
retrieving revision 1.52.2.15
diff -u -r1.52.2.15 php_spl.c
--- ext/spl/php_spl.c 7 Nov 2005 13:08:24 -0000 1.52.2.15
+++ ext/spl/php_spl.c 22 Nov 2005 03:50:42 -0000
@@ -209,7 +209,21 @@
zend_op_array *new_op_array;
zval *result = NULL;

- class_file_len = spprintf(&class_file, 0, "%s%s", lc_name, file_extension);
+ /* if the class name contains one or more colons, then replace these with
+ the directory separators */
+ if (strchr(lc_name, ':') != NULL) {
+ char *lc_name_cpy = estrndup(lc_name, class_name_len);
+ char *lc_name_bak = lc_name_cpy;
+
+ while((lc_name_bak = strchr(lc_name_bak, ':')) != NULL) {
+ *lc_name_bak++ = DEFAULT_SLASH;
+ }
+
+ class_file_len = spprintf(&class_file, 0, "%s%s", lc_name_cpy, file_extension);
+ efree(lc_name_cpy);
+ } else {
+ class_file_len = spprintf(&class_file, 0, "%s%s", lc_name, file_extension);
+ }

if (zend_stream_open(class_file, &file_handle TSRMLS_CC) == SUCCESS) {
if (!file_handle.opened_path) {
Index: tests/classes/namespace_001.phpt
===================================================================
RCS file: tests/classes/namespace_001.phpt
diff -N tests/classes/namespace_001.phpt
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/classes/namespace_001.phpt 22 Nov 2005 03:50:42 -0000
@@ -0,0 +1,25 @@
+--TEST--
+Namespace: Simple Compile-Time Import
+--FILE--
+<?php
+require_once( dirname( __FILE__ ) . '/namespace_autoload.php' );
+
+import ns:class1;
+import ns:class2 as ns_class2;
+
+$full = new ns:class1();
+var_dump( $full->mem1 );
+
+$alias = new class1();
+var_dump( $alias->mem1 );
+
+$alias2 = new ns_class2();
+var_dump( $alias2->mem2 );
+
+var_dump( ns_class2::$my_static );
+?>
+--EXPECT--
+int(1)
+int(1)
+int(2)
+string(14) "this is static"
Index: tests/classes/namespace_002.phpt
===================================================================
RCS file: tests/classes/namespace_002.phpt
diff -N tests/classes/namespace_002.phpt
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/classes/namespace_002.phpt 22 Nov 2005 03:50:42 -0000
@@ -0,0 +1,17 @@
+--TEST--
+Namespace: Runtime-Resolved Import
+--FILE--
+<?php
+require_once( dirname( __FILE__ ) . '/namespace_autoload.php' );
+
+import ns:class1;
+
+$class1_str = 'class1';
+$c1 = new $class1_str();
+var_dump( $c1 );
+?>
+--EXPECT--
+object(ns:class1)#1 (1) {
+ =>
+ int(1)
+}
Index: tests/classes/namespace_003.phpt
===================================================================
RCS file: tests/classes/namespace_003.phpt
diff -N tests/classes/namespace_003.phpt
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/classes/namespace_003.phpt 22 Nov 2005 03:50:42 -0000
@@ -0,0 +1,14 @@
+--TEST--
+Namespace: Private Classes
+--FILE--
+<?php
+require_once( dirname( __FILE__ ) . '/namespace_autoload.php' );
+
+import ns:class3;
+
+$class3_str = 'class3';
+$c3 = new $class3_str();
+var_dump( $c3 );
+?>
+--EXPECTREGEX--
+Fatal error: Cannot use class 'ns:class3' outside of its namespace, as it is private.*
Index: tests/classes/namespace_004.phpt
===================================================================
RCS file: tests/classes/namespace_004.phpt
diff -N tests/classes/namespace_004.phpt
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/classes/namespace_004.phpt 22 Nov 2005 03:50:42 -0000
@@ -0,0 +1,16 @@
+--TEST--
+Namespace: Public Derived/Private Base
+--FILE--
+<?php
+require_once( dirname( __FILE__ ) . '/namespace_autoload.php' );
+
+import ns:class3_child;
+
+$c3 = new class3_child();
+$c3->printValue();
+$c3->callStatic();
+?>
+--EXPECT--
+3
+static called
+
Index: tests/classes/namespace_005.phpt
===================================================================
RCS file: tests/classes/namespace_005.phpt
diff -N tests/classes/namespace_005.phpt
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/classes/namespace_005.phpt 22 Nov 2005 03:50:42 -0000
@@ -0,0 +1,16 @@
+--TEST--
+Namespace: Namespace Import
+--FILE--
+<?php
+require_once( dirname( __FILE__ ) . '/namespace_autoload.php' );
+
+import namespace ns;
+
+$c1 = new class1();
+var_dump( $c1 );
+?>
+--EXPECT--
+object(ns:class1)#1 (1) {
+ =>
+ int(1)
+}
Index: tests/classes/namespace_006.phpt
===================================================================
RCS file: tests/classes/namespace_006.phpt
diff -N tests/classes/namespace_006.phpt
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/classes/namespace_006.phpt 22 Nov 2005 03:50:42 -0000
@@ -0,0 +1,12 @@
+--TEST--
+Namespace: Anonymous Namespace
+--FILE--
+<?php
+require_once( dirname( __FILE__ ) . '/namespace_anonymous.php' );
+
+$c = new anon_class();
+var_dump( $c );
+?>
+--EXPECTREGEX--
+inside anonymous namespace
+.*Fatal error: Class \'anon_class\' not found.*
Index: tests/classes/namespace_anonymous.php
===================================================================
RCS file: tests/classes/namespace_anonymous.php
diff -N tests/classes/namespace_anonymous.php
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/classes/namespace_anonymous.php 22 Nov 2005 03:50:42 -0000
@@ -0,0 +1,12 @@
+<?php
+namespace
+{
+ class anon_class
+ {
+ public $member = 'inside anonymous namespace';
+ }
+}
+
+$a = new anon_class();
+echo $a->member;
+?>
Index: tests/classes/namespace_autoload.php
===================================================================
RCS file: tests/classes/namespace_autoload.php
diff -N tests/classes/namespace_autoload.php
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/classes/namespace_autoload.php 22 Nov 2005 03:50:42 -0000
@@ -0,0 +1,25 @@
+<?php
+function __autoload($className)
+{
+ $directoryPrefix = dirname( __FILE__ ) . '/namespace/';
+
+ if( strpos( $className, ':' ) !== false )
+ {
+ require_once( $directoryPrefix . str_replace( ':', '/', $className ) . '.php' );
+ }
+ else
+ {
+ foreach( get_imported_namespaces( $className ) as $importNS )
+ {
+ $tryPath = $directoryPrefix . str_replace( ':', '/', $importNS ) . "/${className}.php";
+
+ if( file_exists( $tryPath ) )
+ {
+ require_once( $tryPath );
+ autoload_import_class( $className, $importNS );
+ break;
+ }
+ }
+ }
+}
+?>
Index: ZendEngine2/zend.c
===================================================================
RCS file: /repository/ZendEngine2/zend.c,v
retrieving revision 1.308.2.4
diff -u -r1.308.2.4 zend.c
--- ZendEngine2/zend.c 15 Nov 2005 13:29:28 -0000 1.308.2.4
+++ ZendEngine2/zend.c 22 Nov 2005 03:50:43 -0000
@@ -34,11 +34,15 @@
# define GLOBAL_CLASS_TABLE global_class_table
# define GLOBAL_CONSTANTS_TABLE global_constants_table
# define GLOBAL_AUTO_GLOBALS_TABLE global_auto_globals_table
+# define GLOBAL_IMPORT_CLASS_TABLE global_import_class_table
+# define GLOBAL_IMPORT_NAMESPACE_TABLE global_import_namespace_table
#else
# define GLOBAL_FUNCTION_TABLE CG(function_table)
# define GLOBAL_CLASS_TABLE CG(class_table)
# define GLOBAL_AUTO_GLOBALS_TABLE CG(auto_globals)
# define GLOBAL_CONSTANTS_TABLE EG(zend_constants)
+# define GLOBAL_IMPORT_CLASS_TABLE CG(import_class_table)
+# define GLOBAL_IMPORT_NAMESPACE_TABLE CG(import_namespace_table)
#endif

#if defined(ZEND_WIN32) && ZEND_DEBUG
@@ -92,6 +96,8 @@
HashTable *global_class_table;
HashTable *global_constants_table;
HashTable *global_auto_globals_table;
+HashTable *global_import_class_table;
+HashTable *global_import_namespace_table;
static HashTable *global_persistent_list = NULL;
#endif

@@ -435,6 +441,7 @@
{
zend_function tmp_func;
zend_class_entry *tmp_class;
+ HashTable tmp_hash;

compiler_globals->compiled_filename = NULL;

@@ -448,6 +455,25 @@

zend_set_default_compile_time_values(TSRMLS_C);

+ /* initialize namespace variables */
+ compiler_globals->in_anonymous_namespace = 0;
+ compiler_globals->namespace_prefix = NULL;
+ compiler_globals->namespace_prefix_lc = NULL;
+ compiler_globals->namespace_prefix_len = 0;
+ INIT_ZVAL(compiler_globals->extending_child);
+
+ /* initialize the import class table */
+ compiler_globals->import_class_table = (HashTable *) malloc(sizeof(HashTable));
+ compiler_globals->current_import_class_table = NULL;
+ zend_hash_init_ex(compiler_globals->import_class_table, 10, NULL, (dtor_func_t) zend_hash_destroy, , 0);
+ zend_hash_copy(compiler_globals->import_class_table, global_import_class_table, NULL, &tmp_hash, sizeof(tmp_hash));
+
+ /* initialize the import namespace table */
+ compiler_globals->import_namespace_table = (HashTable *) malloc(sizeof(HashTable));
+ compiler_globals->current_import_namespace_table = NULL;
+ zend_hash_init_ex(compiler_globals->import_namespace_table, 10, NULL, (dtor_func_t) zend_hash_destroy, 1, 0);
+ zend_hash_copy(compiler_globals->import_namespace_table, global_import_namespace_table, NULL, &tmp_hash, sizeof(tmp_hash));
+
CG(interactive) = 0;

compiler_globals->auto_globals = (HashTable *) malloc(sizeof(HashTable));
@@ -470,6 +496,14 @@
zend_hash_destroy(compiler_globals->auto_globals);
free(compiler_globals->auto_globals);
}
+ if (compiler_globals->import_class_table != GLOBAL_IMPORT_CLASS_TABLE) {
+ zend_hash_destroy(compiler_globals->import_class_table);
+ free(compiler_globals->import_class_table);
+ }
+ if (compiler_globals->import_namespace_table != GLOBAL_IMPORT_NAMESPACE_TABLE) {
+ zend_hash_destroy(compiler_globals->import_namespace_table);
+ free(compiler_globals->import_namespace_table);
+ }
}


@@ -600,11 +634,15 @@
GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));
GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));
+ GLOBAL_IMPORT_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
+ GLOBAL_IMPORT_NAMESPACE_TABLE = (HashTable *) malloc(sizeof(HashTable));
#ifdef ZTS
GLOBAL_CONSTANTS_TABLE = (HashTable *) malloc(sizeof(HashTable));
#endif
zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
zend_hash_init_ex(GLOBAL_CLASS_TABLE, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
+ zend_hash_init_ex(GLOBAL_IMPORT_CLASS_TABLE, 10, NULL, (dtor_func_t) zend_hash_destroy, 1, 0);
+ zend_hash_init_ex(GLOBAL_IMPORT_NAMESPACE_TABLE, 10, NULL, (dtor_func_t) zend_hash_destroy, 1, 0);

zend_hash_init_ex(&module_registry, 50, NULL, ZEND_MODULE_DTOR, 1, 0);
zend_init_rsrc_list_dtors();
@@ -630,10 +668,18 @@
compiler_globals->in_compilation = 0;
compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
+ compiler_globals->import_class_table = (HashTable *) malloc(sizeof(HashTable));
+ compiler_globals->import_namespace_table = (HashTable *) malloc(sizeof(HashTable));
+ compiler_globals->in_anonymous_namespace = 0;
+ compiler_globals->current_import_class_table = NULL;
+ compiler_globals->current_import_namespace_table = NULL;
+ INIT_ZVAL(compiler_globals->extending_child);

*compiler_globals->function_table = *GLOBAL_FUNCTION_TABLE;
*compiler_globals->class_table = *GLOBAL_CLASS_TABLE;
compiler_globals->auto_globals = GLOBAL_AUTO_GLOBALS_TABLE;
+ *compiler_globals->import_class_table = *GLOBAL_IMPORT_CLASS_TABLE;
+ *compiler_globals->import_namespace_table = *GLOBAL_IMPORT_NAMESPACE_TABLE;

zend_hash_destroy(executor_globals->zend_constants);
*executor_globals->zend_constants = *GLOBAL_CONSTANTS_TABLE;
@@ -688,9 +734,13 @@
*GLOBAL_FUNCTION_TABLE = *compiler_globals->function_table;
*GLOBAL_CLASS_TABLE = *compiler_globals->class_table;
*GLOBAL_CONSTANTS_TABLE = *executor_globals->zend_constants;
+ *GLOBAL_IMPORT_CLASS_TABLE = *compiler_globals->import_class_table;
+ *GLOBAL_IMPORT_NAMESPACE_TABLE = *compiler_globals->import_namespace_table;
zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
free(compiler_globals->function_table);
free(compiler_globals->class_table);
+ free(compiler_globals->import_class_table);
+ free(compiler_globals->import_namespace_table);
compiler_globals_ctor(compiler_globals, tsrm_ls);
free(EG(zend_constants));
executor_globals_ctor(executor_globals, tsrm_ls);
@@ -710,6 +760,8 @@

zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
zend_hash_destroy(GLOBAL_CLASS_TABLE);
+ zend_hash_destroy(GLOBAL_IMPORT_CLASS_TABLE);
+ zend_hash_destroy(GLOBAL_IMPORT_NAMESPACE_TABLE);

zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
free(GLOBAL_AUTO_GLOBALS_TABLE);
@@ -719,6 +771,8 @@

free(GLOBAL_FUNCTION_TABLE);
free(GLOBAL_CLASS_TABLE);
+ free(GLOBAL_IMPORT_CLASS_TABLE);
+ free(GLOBAL_IMPORT_NAMESPACE_TABLE);

zend_hash_destroy(GLOBAL_CONSTANTS_TABLE);
free(GLOBAL_CONSTANTS_TABLE);
@@ -727,6 +781,8 @@
GLOBAL_FUNCTION_TABLE = NULL;
GLOBAL_CLASS_TABLE = NULL;
GLOBAL_AUTO_GLOBALS_TABLE = NULL;
++ GLOBAL_IMPORT_CLASS_TABLE = NULL;
++ GLOBAL_IMPORT_NAMESPACE_TABLE = NULL;
GLOBAL_CONSTANTS_TABLE = NULL;
#endif
zend_destroy_rsrc_list_dtors();
Index: ZendEngine2/zend_builtin_functions.c
===================================================================
RCS file: /repository/ZendEngine2/zend_builtin_functions.c,v
retrieving revision 1.277.2.5
diff -u -r1.277.2.5 zend_builtin_functions.c
--- ZendEngine2/zend_builtin_functions.c 16 Sep 2005 17:05:06 -0000 1.277.2.5
+++ ZendEngine2/zend_builtin_functions.c 22 Nov 2005 03:50:43 -0000
@@ -76,6 +76,8 @@
static ZEND_FUNCTION(get_defined_constants);
static ZEND_FUNCTION(debug_backtrace);
static ZEND_FUNCTION(debug_print_backtrace);
+static ZEND_FUNCTION(get_imported_namespaces);
+static ZEND_FUNCTION(autoload_import_class);
#if ZEND_DEBUG
static ZEND_FUNCTION(zend_test_func);
#ifdef ZTS
@@ -138,6 +140,8 @@
ZEND_FE(get_defined_constants, NULL)
ZEND_FE(debug_backtrace, NULL)
ZEND_FE(debug_print_backtrace, NULL)
+ ZEND_FE(get_imported_namespaces, NULL)
+ ZEND_FE(autoload_import_class, NULL)
#if ZEND_DEBUG
ZEND_FE(zend_test_func, NULL)
#ifdef ZTS
@@ -1998,6 +2002,113 @@
}
/* }}} */

+static int copy_namespace_name(zval *name, void *return_array)
+{
+ add_next_index_stringl((zval *) return_array, Z_STRVAL_P(name), Z_STRLEN_P(name), 1);
+ return ZEND_HASH_APPLY_KEEP;
+}
+
+/* {{{ proto array get_imported_namespaces()
+ Returns an array of all imported namespaces. */
+ZEND_FUNCTION(get_imported_namespaces)
+{
+ char *class_name = NULL;
+ char *class_name_lc = NULL;
+ int class_name_len = 0;
+ HashTable *import_table = NULL;
+ zval *referencing_file = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &class_name, &class_name_len) == FAILURE) {
+ return;
+ }
+
+ if (class_name != NULL) {
+ /* lowercase the class name */
+ class_name_lc = zend_str_tolower_dup(class_name, class_name_len);
+
+ if (zend_hash_find(&EG(autoload_class_file_map), class_name_lc, class_name_len + 1, (void **) &referencing_file) == SUCCESS) {
+ zend_hash_find(EG(import_namespace_table), Z_STRVAL_P(referencing_file), Z_STRLEN_P(referencing_file) + 1, (void **) &import_table);
+ }
+
+ efree(class_name_lc);
+ } else {
+ zend_hash_find(EG(import_namespace_table), zend_get_executed_filename(TSRMLS_C), strlen(zend_get_executed_filename(TSRMLS_C)) + 1, (void **) &import_table);
+ }
+
+ array_init(return_value);
+
+ if (import_table != NULL) {
+ zend_hash_apply_with_argument(import_table, (apply_func_arg_t) copy_namespace_name, return_value TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/* {{{ proto boolean autoload_import_class($className, $namespaceName)
+ Registers a class with its namespace that has been fully imported (can only be used while in an __autoload operation). */
+ZEND_FUNCTION(autoload_import_class)
+{
+ char *class_name = NULL;
+ int class_name_len = 0;
+ char *class_name_lc = NULL;
+ HashTable *current_import_table = NULL;
+ char *full_name = NULL;
+ int full_name_len = 0;
+ zval import_val;
+ char *namespace_name = NULL;
+ int namespace_name_len = 0;
+ zval *referencing_file = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &class_name, &class_name_len, &namespace_name, &namespace_name_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ /* get lowercased class name */
+ class_name_lc = zend_str_tolower_dup(class_name, class_name_len);
+
+ if (zend_hash_exists(EG(in_autoload), class_name_lc, class_name_len + 1)) {
+ /* get the referencing file name */
+ zend_hash_find(&EG(autoload_class_file_map), class_name_lc, class_name_len + 1, (void **) &referencing_file);
+
+ if (zend_hash_find(EG(import_class_table), Z_STRVAL_P(referencing_file), Z_STRLEN_P(referencing_file) + 1, (void **)&current_import_table) == SUCCESS) {
+ /* make sure this import alias has not been used before */
+ if (zend_hash_exists(current_import_table, class_name_lc, class_name_len + 1)) {
+ zend_error(E_ERROR, "An import was already done with the %s alias", class_name);
+ efree(class_name_lc);
+ RETURN_FALSE;
+ }
+
+ /* get the full class name */
+ full_name_len = namespace_name_len + class_name_len + 1;
+ full_name = malloc(full_name_len + 1);
+ strncpy(full_name, namespace_name, namespace_name_len + 1);
+ strcat(full_name, ":");
+ strcat(full_name, class_name);
+
+ /* initialize the full class name zval */
+ INIT_ZVAL(import_val);
+ Z_STRVAL(import_val) = full_name;
+ Z_STRLEN(import_val) = full_name_len;
+
+ /* add the import alias */
+ if (zend_hash_add(current_import_table, class_name_lc, class_name_len + 1, &import_val, sizeof(import_val), NULL) == FAILURE) {
+ zend_error(E_ERROR, "Could not import %s", class_name);
+ efree(class_name_lc);
+ RETURN_FALSE;
+ }
+
+ efree(class_name_lc);
+ RETURN_TRUE;
+ }
+ } else {
+ zend_error(E_ERROR, "Class %s is not being autoloaded", class_name);
+ RETURN_FALSE;
+ }
+
+ efree(class_name_lc);
+ RETURN_FALSE;
+}
+/* }}} */
+
/* {{{ proto bool extension_loaded(string extension_name)
Returns true if the named extension is loaded */
ZEND_FUNCTION(extension_loaded)
Index: ZendEngine2/zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.647.2.14
diff -u -r1.647.2.14 zend_compile.c
--- ZendEngine2/zend_compile.c 16 Nov 2005 15:10:56 -0000 1.647.2.14
+++ ZendEngine2/zend_compile.c 22 Nov 2005 03:50:44 -0000
@@ -182,11 +182,34 @@
}


+void import_zval_dtor(zval *zv)
+{
+ free(Z_STRVAL_P(zv));
+}
+
ZEND_API char *zend_set_compiled_filename(char *new_compiled_filename TSRMLS_DC)
{
char **pp, *p;
+ HashTable file_class_imports;
+ HashTable file_namespace_imports;
int length = strlen(new_compiled_filename);

+ /* make sure the import class hashtable for this file exists */
+ if (!zend_hash_exists(CG(import_class_table), new_compiled_filename, length+1)) {
+ zend_hash_init(&file_class_imports, 10, NULL, (dtor_func_t) import_zval_dtor, 1);
+ zend_hash_add(CG(import_class_table), new_compiled_filename, length + 1, &file_class_imports, sizeof(file_class_imports), NULL);
+ }
+
+ /* make sure the import namespace hashtable for this file exists */
+ if (!zend_hash_exists(CG(import_namespace_table), new_compiled_filename, length+1)) {
+ zend_hash_init(&file_namespace_imports, 10, NULL, (dtor_func_t) import_zval_dtor, 1);
+ zend_hash_add(CG(import_namespace_table), new_compiled_filename, length + 1, &file_namespace_imports, sizeof(file_namespace_imports), NULL);
+ }
+
+ /* get the import hashtables for this file */
+ zend_hash_find(CG(import_class_table), new_compiled_filename, length + 1, (void **)&CG(current_import_class_table));
+ zend_hash_find(CG(import_namespace_table), new_compiled_filename, length + 1, (void **)&CG(current_import_namespace_table));
+
if (zend_hash_find(&CG(filenames_table), new_compiled_filename, length+1, (void **) &pp) == SUCCESS) {
CG(compiled_filename) = *pp;
return *pp;
@@ -1411,7 +1434,18 @@
opline = get_next_op(CG(active_op_array) TSRMLS_CC);

opline->opcode = ZEND_FETCH_CLASS;
- SET_UNUSED(opline->op1);
+
+ if (CG(extending_child).type == IS_NULL) {
+ SET_UNUSED(opline->op1);
+ } else {
+ /* copy the child name */
+ INIT_ZVAL(opline->op1.u.constant);
+ opline->op1.op_type = IS_CONST;
+ opline->op1.u.constant.type = IS_STRING;
+ opline->op1.u.constant.value.str.val = estrndup(CG(extending_child).value.str.val, CG(extending_child).value.str.len);
+ opline->op1.u.constant.value.str.len = CG(extending_child).value.str.len;
+ }
+
opline->extended_value = ZEND_FETCH_CLASS_GLOBAL;
CG(catch_begin) = fetch_class_op_number;
if (class_name->op_type == IS_CONST) {
@@ -2689,6 +2723,11 @@
zend_error(E_COMPILE_ERROR, "Cannot use '%s' as class name as it is reserved", class_name->u.constant.value.str.val);
}

+ /* fully prefix the class name */
+ efree(lcname);
+ zend_prefix_class_name_node(class_name TSRMLS_CC);
+ lcname = zend_str_tolower_dup(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len);
+
new_class_entry->type = ZEND_USER_CLASS;
new_class_entry->name = class_name->u.constant.value.str.val;
new_class_entry->name_length = class_name->u.constant.value.str.len;
@@ -2737,6 +2776,11 @@
opline->result.op_type = IS_CONST;
CG(implementing_class) = opline->result;

+ /* if we are in an anonymous namespace, then immediately import this class */
+ if (CG(in_anonymous_namespace)) {
+ zend_do_import(NULL, class_name, NULL, 0 TSRMLS_CC);
+ }
+
if (CG(doc_comment)) {
CG(active_class_entry)->doc_comment = CG(doc_comment);
CG(active_class_entry)->doc_comment_len = CG(doc_comment_len);
@@ -2745,6 +2789,191 @@
}
}

+/*****************************
+ * BEGIN NAMESPACE FUNCTIONS *
+ *****************************/
+
+void zend_do_begin_extending(znode *child_name TSRMLS_DC)
+{
+ int name_len = Z_STRLEN(child_name->u.constant);
+
+ /* add the namespace prefix length, if applicable */
+ if (CG(namespace_prefix) != NULL) {
+ name_len += CG(namespace_prefix_len);
+ }
+
+ INIT_ZVAL(CG(extending_child));
+ CG(extending_child).type = IS_STRING;
+ Z_STRVAL(CG(extending_child)) = emalloc(name_len + 1);
+ Z_STRLEN(CG(extending_child)) = name_len;
+
+ if (CG(namespace_prefix) != NULL) {
+ /* copy the namespace prefix, then the child name */
+ strncpy(Z_STRVAL(CG(extending_child)), CG(namespace_prefix), CG(namespace_prefix_len) + 1);
+ strcat(Z_STRVAL(CG(extending_child)), Z_STRVAL(child_name->u.constant));
+ } else {
+ /* copy just the class name */
+ strncpy(Z_STRVAL(CG(extending_child)), Z_STRVAL(child_name->u.constant), Z_STRLEN(child_name->u.constant) + 1);
+ }
+}
+
+void zend_do_begin_namespace(znode *ns_token, znode *ns_name TSRMLS_DC)
+{
+ char *namespace_name = NULL;
+ int namespace_name_len = 0;
+
+ if (ns_name != NULL) {
+ namespace_name = Z_STRVAL(ns_name->u.constant);
+ namespace_name_len = Z_STRLEN(ns_name->u.constant);
+ } else {
+ /* this is an anonymous namespace */
+ CG(in_anonymous_namespace) = 1;
+ namespace_name = zend_get_compiled_filename(TSRMLS_C);
+ namespace_name_len = strlen(namespace_name);
+ }
+
+ /* allocate space for the namespace prefix */
+ CG(namespace_prefix) = emalloc(namespace_name_len + 2);
+
+ /* get the namespace prefix */
+ strncpy(CG(namespace_prefix), namespace_name, namespace_name_len + 1);
+ strcat(CG(namespace_prefix), ":");
+
+ /* get the lowercased namespace prefix */
+ CG(namespace_prefix_lc) = zend_str_tolower_dup(CG(namespace_prefix), namespace_name_len + 1);
+
+ /* save the prefix length */
+ CG(namespace_prefix_len) = namespace_name_len + 1;
+
+ /* we don't need the namespace name anymore, so free it */
+ if (ns_name != NULL) {
+ zval_dtor(&ns_name->u.constant);
+ }
+}
+
+void zend_do_end_extending(TSRMLS_D)
+{
+ efree(Z_STRVAL(CG(extending_child)));
+ CG(extending_child).type = IS_NULL;
+ Z_STRLEN(CG(extending_child)) = 0;
+ Z_STRVAL(CG(extending_child)) = NULL;
+}
+
+void zend_do_end_namespace(znode *ns_token TSRMLS_DC)
+{
+ /* free the string memory */
+ efree(CG(namespace_prefix));
+ efree(CG(namespace_prefix_lc));
+ CG(namespace_prefix_len) = 0;
+
+ /* set the prefixes to null */
+ CG(namespace_prefix) = NULL;
+ CG(namespace_prefix_lc) = NULL;
+
+ CG(in_anonymous_namespace) = 0;
+}
+
+void zend_do_verify_private_class(TSRMLS_D)
+{
+ if (CG(namespace_prefix) == NULL) {
+ zend_error(E_COMPILE_ERROR, "Cannot declare a private class in the global namespace");
+ }
+}
+
+void zend_do_import(znode *result, znode *class_name, znode *alias_name, zend_bool free_class_name TSRMLS_DC)
+{
+ char *alias_name_lc = NULL;
+ zend_uint alias_name_len = 0;
+ zval alias_val;
+ /* 'colon_pos' is the position of the last colon in the full class name */
+ char *colon_pos = strrchr(Z_STRVAL(class_name->u.constant), ':');
+ /* 'last_pos' is the position of the null terminator in the full class name */
+ char *last_pos = Z_STRVAL(class_name->u.constant) + Z_STRLEN(class_name->u.constant);
+
+ if (colon_pos == NULL) {
+ zend_error(E_COMPILE_ERROR, "Cannot import non-namespace class: %s!", Z_STRVAL(class_name->u.constant));
+ return;
+ }
+
+ if (alias_name == NULL) {
+ /* advance to the first character of the class name */
+ ++colon_pos;
+
+ /* get the lowercased class name as the alias */
+ alias_name_len = last_pos - colon_pos;
+ alias_name_lc = zend_str_tolower_dup(colon_pos, alias_name_len);
+ } else /* alias_name != NULL */ {
+ alias_name_lc = zend_str_tolower_dup(Z_STRVAL(alias_name->u.constant), Z_STRLEN(alias_name->u.constant));
+ alias_name_len = Z_STRLEN(alias_name->u.constant);
+ zval_dtor(&alias_name->u.constant);
+ }
+
+ /* make sure this import alias has not been used before */
+ if (zend_hash_exists(CG(current_import_class_table), alias_name_lc, alias_name_len + 1)) {
+ zend_error(E_COMPILE_ERROR, "An import was already done with the %s alias", alias_name_lc);
+ return;
+ }
+
+ /* create the alias value */
+ INIT_ZVAL(alias_val);
+ Z_STRVAL(alias_val) = zend_strndup(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant));
+ Z_STRLEN(alias_val) = Z_STRLEN(class_name->u.constant);
+
+ /* add the alias */
+ if (zend_hash_add(CG(current_import_class_table), alias_name_lc, alias_name_len + 1, &alias_val, sizeof(zval), NULL) == FAILURE) {
+ zend_error(E_COMPILE_ERROR, "Could not import %s as %s!", Z_STRVAL(class_name->u.constant), alias_name_lc);
+ }
+
+ if (free_class_name) {
+ zval_dtor(&class_name->u.constant);
+ }
+
+ efree(alias_name_lc);
+}
+
+void zend_do_namespace_import(znode *ns_name TSRMLS_DC)
+{
+ zval name_val;
+
+ INIT_ZVAL(name_val);
+ name_val.type = IS_STRING;
+ Z_STRVAL(name_val) = zend_strndup(Z_STRVAL(ns_name->u.constant), Z_STRLEN(ns_name->u.constant));
+ Z_STRLEN(name_val) = Z_STRLEN(ns_name->u.constant);
+
+ /* we don't need the namespace name anymore, so free it */
+ zval_dtor(&ns_name->u.constant);
+
+ if (zend_hash_next_index_insert(CG(current_import_namespace_table), &name_val, sizeof(name_val), NULL) == FAILURE) {
+ zend_error(E_COMPILE_ERROR, "Could not import namespace %s!", Z_STRVAL(ns_name->u.constant));
+ return;
+ }
+}
+
+void zend_prefix_class_name_node(znode *class_name TSRMLS_DC)
+{
+ zend_uint new_length = 0;
+ char *org_class_name = NULL;
+
+ if (CG(namespace_prefix) != NULL) {
+ new_length = CG(namespace_prefix_len) + Z_STRLEN(class_name->u.constant);
+ org_class_name = estrdup(Z_STRVAL(class_name->u.constant));
+
+ STR_REALLOC(Z_STRVAL(class_name->u.constant), new_length + 1);
+
+ /* get the full class name */
+ strncpy(Z_STRVAL(class_name->u.constant), CG(namespace_prefix), CG(namespace_prefix_len) + 1);
+ strcat(Z_STRVAL(class_name->u.constant), org_class_name);
+
+ /* get the new string length */
+ Z_STRLEN(class_name->u.constant) = new_length;
+
+ efree(org_class_name);
+ }
+}
+
+/***************************
+ * END NAMESPACE FUNCTIONS *
+ ***************************/

static void do_verify_abstract_class(TSRMLS_D)
{
Index: ZendEngine2/zend_compile.h
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.h,v
retrieving revision 1.316.2.5
diff -u -r1.316.2.5 zend_compile.h
--- ZendEngine2/zend_compile.h 20 Oct 2005 07:30:42 -0000 1.316.2.5
+++ ZendEngine2/zend_compile.h 22 Nov 2005 03:50:45 -0000
@@ -387,6 +387,7 @@
void zend_do_add_variable(znode *result, znode *op1, znode *op2 TSRMLS_DC);

int zend_do_verify_access_types(znode *current_access_type, znode *new_modifier);
+void zend_do_verify_private_class(TSRMLS_D);
void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC);
void zend_do_end_function_declaration(znode *function_token TSRMLS_DC);
void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initialization, znode *class_type, znode *varname, zend_bool pass_by_reference TSRMLS_DC);
@@ -438,6 +439,15 @@
void zend_do_declare_implicit_property(TSRMLS_D);
void zend_do_declare_class_constant(znode *var_name, znode *value TSRMLS_DC);

+void zend_do_begin_extending(znode *child_name TSRMLS_DC);
+void zend_do_begin_namespace(znode *ns_token, znode *ns_name TSRMLS_DC);
+void zend_do_end_extending(TSRMLS_D);
+void zend_do_end_namespace(znode *ns_token TSRMLS_DC);
+void zend_do_import(znode *result, znode *class_name, znode *alias_name, zend_bool free_class_name TSRMLS_DC);
+void zend_do_namespace_import(znode *ns_name TSRMLS_DC);
+void zend_do_unimport_all(TSRMLS_D);
+void zend_prefix_class_name_node(znode *class_name TSRMLS_DC);
+
void zend_do_fetch_property(znode *result, znode *object, znode *property TSRMLS_DC);


Index: ZendEngine2/zend_execute_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_execute_API.c,v
retrieving revision 1.331.2.4
diff -u -r1.331.2.4 zend_execute_API.c
--- ZendEngine2/zend_execute_API.c 27 Oct 2005 19:25:48 -0000 1.331.2.4
+++ ZendEngine2/zend_execute_API.c 22 Nov 2005 03:50:45 -0000
@@ -135,6 +135,8 @@

EG(function_table) = CG(function_table);
EG(class_table) = CG(class_table);
+ EG(import_class_table) = CG(import_class_table);
+ EG(import_namespace_table) = CG(import_namespace_table);

EG(in_execution) = 0;
EG(in_autoload) = NULL;
@@ -156,6 +158,8 @@
}
EG(active_symbol_table) = &EG(symbol_table);

+ zend_hash_init(&EG(autoload_class_file_map), 1, NULL, ZVAL_PTR_DTOR, 0);
+
zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC);
EG(opline_ptr) = NULL;

@@ -292,6 +296,8 @@
zend_hash_destroy(EG(in_autoload));
FREE_HASHTABLE(EG(in_autoload));
}
+
+ zend_hash_destroy(&EG(autoload_class_file_map));
} zend_end_try();
}

@@ -915,6 +921,112 @@
}


+char* zend_get_class_namespace(const char *class_name)
+{
+ int namespace_length = 0;
+ char *result = NULL;
+ char *tmp = strrchr(class_name, ':');
+
+ if (tmp != NULL) {
+ namespace_length = tmp - class_name;
+
+ /* get the namespace name, which is everything before the last colon */
+ result = estrndup(class_name, namespace_length);
+ zend_str_tolower(result, namespace_length);
+ }
+
+ return result;
+}
+
+
+zval *zend_resolve_class_name_string(char *name, int name_len TSRMLS_DC)
+{
+ HashTable *current_import_table = NULL;
+ char *executed_filename = zend_get_executed_filename(TSRMLS_C);
+ int executed_filename_len = strlen(executed_filename);
+ char *lc_name = NULL;
+ zval* mapped_class_name = NULL;
+
+ if (zend_hash_find(EG(import_class_table), executed_filename, executed_filename_len + 1, (void **)&current_import_table) == SUCCESS) {
+ /* get the lowercased class name */
+ lc_name = zend_str_tolower_dup(name, name_len);
+
+ /* check to see if this class name is actually an import alias */
+ zend_hash_find(current_import_table, lc_name, name_len + 1, (void **)&mapped_class_name);
+
+ /* free the class name string */
+ efree(lc_name);
+ }
+
+ return mapped_class_name;
+}
+
+
+int zend_verify_can_use_class(zend_class_entry *ce TSRMLS_DC)
+{
+ int result = SUCCESS;
+
+ /* exit immediately if this is not a private class */
+ if ((ce->ce_flags & ZEND_ACC_PRIVATE) == 0) {
+ return SUCCESS;
+ }
+
+ /* check if we are in compilation mode */
+ if (zend_is_compiling(TSRMLS_C)) {
+ char *class_namespace = zend_get_class_namespace(ce->name);
+ char *current_namespace = NULL;
+
+ if (CG(namespace_prefix) != NULL) {
+ /* copy the namespace prefix minus the last character, which is a colon */
+ current_namespace = estrndup(CG(namespace_prefix), CG(namespace_prefix_len) - 1);
+ }
+
+ /* check if the namespaces match */
+ if (class_namespace != NULL
+ && (current_namespace == NULL
+ || strcmp(class_namespace, current_namespace) != 0)) {
+ /* the namespaces don't match, so don't allow use of this class */
+ result = FAILURE;
+ }
+
+ efree(class_namespace);
+ efree(current_namespace);
+ } else /* zend_is_executing */ {
+ char *class_namespace = zend_get_class_namespace(ce->name);
+ char *current_namespace = NULL;
+
+ if (active_opline->opcode == ZEND_FETCH_CLASS && active_opline->op1.op_type == IS_CONST) {
+ current_namespace = zend_get_class_namespace(active_opline->op1.u.constant.value.str.val);
+ } else if (EG(scope) != NULL) {
+ current_namespace = zend_get_class_namespace(EG(scope)->name);
+ }
+
+ /* check if the namespaces match */
+ if (class_namespace != NULL
+ && (current_namespace == NULL
+ || strcmp(class_namespace, current_namespace) != 0)) {
+ /* the namespaces don't match, so don't allow use of this class */
+ result = FAILURE;
+ }
+
+ if (class_namespace != NULL) {
+ efree(class_namespace);
+ }
+
+ if (current_namespace != NULL) {
+ efree(current_namespace);
+ }
+ }
+
+ /* generate the error message, if needed */
+ if (result == FAILURE) {
+ zend_error(E_ERROR, "Cannot use class '%s' outside of its namespace, as it is private", ce->name);
+ }
+
+ return result;
+}
+
+
ZEND_API int zend_lookup_class_ex(char *name, int name_length, int use_autoload, zend_class_entry ***ce TSRMLS_DC)
{
zval **args;
@@ -927,6 +1039,8 @@
char dummy = 1;
zend_fcall_info fcall_info;
zend_fcall_info_cache fcall_cache;
+ zval executed_filename_val;
+ zval *resolved_name = NULL;

if (name == NULL) {
return FAILURE;
@@ -937,7 +1051,26 @@

if (zend_hash_find(EG(class_table), lc_name, name_length+1, (void **) ce) == SUCCESS) {
free_alloca(lc_name);
- return SUCCESS;
+ return zend_verify_can_use_class(**ce TSRMLS_CC);
+ }
+
+ /* try to resolve the class name and try again */
+ if ((resolved_name = zend_resolve_class_name_string(name, name_length TSRMLS_CC)) != NULL) {
+ /* get the new name */
+ name = estrndup(Z_STRVAL_P(resolved_name), Z_STRLEN_P(resolved_name));
+ name_length = Z_STRLEN_P(resolved_name);
+
+ /* get the lowercased version of the resolved name */
+ free_alloca(lc_name);
+ lc_name = do_alloca(name_length + 1);
+ zend_str_tolower_copy(lc_name, name, name_length);
+
+ /* try the search with the resolved name */
+ if (zend_hash_find(EG(class_table), lc_name, name_length+1, (void **) ce) == SUCCESS) {
+ free_alloca(lc_name);
+ efree(name);
+ return zend_verify_can_use_class(**ce TSRMLS_CC);
+ }
}

/* The compiler is not-reentrant. Make sure we __autoload() only during run-time
@@ -945,6 +1078,11 @@
*/
if (!use_autoload || zend_is_compiling(TSRMLS_C)) {
free_alloca(lc_name);
+
+ if (resolved_name != NULL) {
+ efree(name);
+ }
+
return FAILURE;
}

@@ -955,9 +1093,19 @@

if (zend_hash_add(EG(in_autoload), lc_name, name_length+1, (void**)&dummy, sizeof(char), NULL) == FAILURE) {
free_alloca(lc_name);
+
+ if (resolved_name != NULL) {
+ efree(name);
+ }
+
return FAILURE;
}

+ /* insert the autoload class -> file mapping */
+ INIT_ZVAL(executed_filename_val);
+ ZVAL_STRINGL(&executed_filename_val, zend_get_executed_filename(TSRMLS_C), strlen(zend_get_executed_filename(TSRMLS_C)), 1);
+ zend_hash_add(&EG(autoload_class_file_map), lc_name, name_length + 1, &executed_filename_val, sizeof(executed_filename_val), NULL);
+
ZVAL_STRINGL(&autoload_function, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME)-1, 0);

ALLOC_ZVAL(class_name_ptr);
@@ -988,16 +1136,30 @@

zval_ptr_dtor(&class_name_ptr);

+ /* remove the autoload class -> file mapping */
+ zend_hash_del(&EG(autoload_class_file_map), name, name_length + 1);
+ zval_dtor(&executed_filename_val);
+
zend_hash_del(EG(in_autoload), lc_name, name_length+1);

if (retval == FAILURE) {
EG(exception) = exception;
free_alloca(lc_name);
+
+ if (resolved_name != NULL) {
+ efree(name);
+ }
+
return FAILURE;
}

if (EG(exception) && exception) {
free_alloca(lc_name);
+
+ if (resolved_name != NULL) {
+ efree(name);
+ }
+
zend_error(E_ERROR, "Function %s(%s) threw an exception of type '%s'", ZEND_AUTOLOAD_FUNC_NAME, name, Z_OBJCE_P(EG(exception))->name);
return FAILURE;
}
@@ -1007,7 +1169,32 @@
}

retval = zend_hash_find(EG(class_table), lc_name, name_length + 1, (void **) ce);
+
+ /* try to resolve the class name after the autoload and try again */
+ if (retval == FAILURE && (resolved_name = zend_resolve_class_name_string(name, name_length TSRMLS_CC)) != NULL) {
+ /* get the new name */
+ name = estrndup(Z_STRVAL_P(resolved_name), Z_STRLEN_P(resolved_name));
+ name_length = Z_STRLEN_P(resolved_name);
+
+ /* get the lowercased version of the resolved name */
+ free_alloca(lc_name);
+ lc_name = do_alloca(name_length + 1);
+ zend_str_tolower_copy(lc_name, name, name_length);
+
+ /* try the search with the resolved name */
+ retval = zend_hash_find(EG(class_table), lc_name, name_length+1, (void **) ce);
+ }
+
free_alloca(lc_name);
+
+ if (resolved_name != NULL) {
+ efree(name);
+ }
+
+ if (retval == SUCCESS) {
+ retval = zend_verify_can_use_class(**ce TSRMLS_CC);
+ }
+
return retval;
}

Index: ZendEngine2/zend_globals.h
===================================================================
RCS file: /repository/ZendEngine2/zend_globals.h,v
retrieving revision 1.141.2.1
diff -u -r1.141.2.1 zend_globals.h
--- ZendEngine2/zend_globals.h 15 Nov 2005 13:29:28 -0000 1.141.2.1
+++ ZendEngine2/zend_globals.h 22 Nov 2005 03:50:45 -0000
@@ -144,6 +144,17 @@
zend_encoding_converter encoding_converter;
zend_encoding_oddlen encoding_oddlen;
#endif /* ZEND_MULTIBYTE */
+
+ /* namespace-related variables */
+ zend_bool in_anonymous_namespace;
+ char *namespace_prefix;
+ char *namespace_prefix_lc;
+ zend_uint namespace_prefix_len;
+ HashTable *import_class_table;
+ HashTable *import_namespace_table;
+ HashTable *current_import_class_table;
+ HashTable *current_import_namespace_table;
+ zval extending_child;
};


@@ -233,6 +244,10 @@

zend_property_info std_property_info;

+ HashTable autoload_class_file_map;
+ HashTable *import_class_table;
+ HashTable *import_namespace_table;
+
void *reserved;
};

Index: ZendEngine2/zend_language_parser.y
===================================================================
RCS file: /repository/ZendEngine2/zend_language_parser.y,v
retrieving revision 1.160.2.2
diff -u -r1.160.2.2 zend_language_parser.y
--- ZendEngine2/zend_language_parser.y 17 Oct 2005 07:57:00 -0000 1.160.2.2
+++ ZendEngine2/zend_language_parser.y 22 Nov 2005 03:50:46 -0000
@@ -145,6 +145,10 @@
%token T_DOLLAR_OPEN_CURLY_BRACES
%token T_CURLY_OPEN
%token T_PAAMAYIM_NEKUDOTAYIM
+%token T_IMPORT
+%token T_NAMESPACE_NAME
+%token T_NAMESPACE
+%token T_NAMESPACE_C

%% /* Rules */

@@ -162,6 +166,7 @@
statement
| function_declaration_statement { zend_do_early_binding(TSRMLS_C); }
| class_declaration_statement { zend_do_early_binding(TSRMLS_C); }
+ | namespace_declaration_statement
| T_HALT_COMPILER '(' ')' ';' { REGISTER_MAIN_LONG_CONSTANT("__COMPILER_HALT_OFFSET__", zend_get_scanned_file_offset(TSRMLS_C), CONST_CS); YYACCEPT; }
;

@@ -231,6 +236,8 @@
'{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
additional_catches { zend_do_mark_last_catch(&$7, &$18 TSRMLS_CC); }
| T_THROW expr ';' { zend_do_throw(&$2 TSRMLS_CC); }
+ | T_IMPORT T_NAMESPACE_NAME ';' { zend_do_import(&$$, &$2, NULL, 1 TSRMLS_CC); }
+ | T_IMPORT T_NAMESPACE_NAME T_AS T_STRING ';' { zend_do_import(&$$, &$2, &$4, 1 TSRMLS_CC); }
;


@@ -286,8 +293,8 @@
;

unticked_class_declaration_statement:
- class_entry_type T_STRING extends_from
- { zend_do_begin_class_declaration(&$1, &$2, &$3 TSRMLS_CC); }
+ class_entry_type T_STRING { zend_do_begin_extending(&$2 TSRMLS_CC); } extends_from { zend_do_end_extending(TSRMLS_C); }
+ { zend_do_begin_class_declaration(&$1, &$2, &$4 TSRMLS_CC); }
implements_list
'{'
class_statement_list
@@ -305,6 +312,23 @@
T_CLASS { $$.u.opline_num = CG(zend_lineno); $$.u.EA.type = 0; }
| T_ABSTRACT T_CLASS { $$.u.opline_num = CG(zend_lineno); $$.u.EA.type = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; }
| T_FINAL T_CLASS { $$.u.opline_num = CG(zend_lineno); $$.u.EA.type = ZEND_ACC_FINAL_CLASS; }
+ | T_PRIVATE T_CLASS { $$.u.opline_num = CG(zend_lineno); zend_do_verify_private_class(TSRMLS_C); $$.u.EA.type = ZEND_ACC_PRIVATE; }
+ | T_PRIVATE T_ABSTRACT T_CLASS { $$.u.opline_num = CG(zend_lineno); zend_do_verify_private_class(TSRMLS_C); $$.u.EA.type = ZEND_ACC_PRIVATE | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; }
+ | T_PRIVATE T_FINAL T_CLASS { $$.u.opline_num = CG(zend_lineno); zend_do_verify_private_class(TSRMLS_C); $$.u.EA.type = ZEND_ACC_PRIVATE | ZEND_ACC_FINAL_CLASS; }
+;
+
+namespace_declaration_statement:
+ T_NAMESPACE '{' { zend_do_begin_namespace(&$1, NULL TSRMLS_CC); } namespace_statement_list '}' { zend_do_end_namespace(&$1 TSRMLS_CC); }
+ | T_NAMESPACE namespace_name '{' { zend_do_begin_namespace(&$1, &$2 TSRMLS_CC); } namespace_statement_list '}' { zend_do_end_namespace(&$1 TSRMLS_CC); }
+;
+
+namespace_statement_list:
+ namespace_statement_list namespace_statement
+ | /* empty */
+;
+
+namespace_statement:
+ class_declaration_statement { zend_do_early_binding(TSRMLS_C); }
;

extends_from:
@@ -439,6 +463,7 @@
optional_class_type:
/* empty */ { $$.op_type = IS_UNUSED; }
| T_STRING { $$ = $1; }
+ | T_NAMESPACE_NAME { $$ = $1; }
| T_ARRAY { $$.op_type = IS_CONST; $$.u.constant.type=IS_NULL;}
;

@@ -639,10 +664,12 @@

fully_qualified_class_name:
T_STRING { zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
+ | T_NAMESPACE_NAME { zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
;

class_name_reference:
T_STRING { zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
+ | T_NAMESPACE_NAME { zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
| dynamic_class_name_reference { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
;

@@ -654,6 +681,10 @@
| base_variable { $$ = $1; }
;

+namespace_name:
+ T_NAMESPACE_NAME { $$ = $1; }
+ | T_STRING { $$ = $1; }
+;

dynamic_class_name_variable_properties:
dynamic_class_name_variable_properties dynamic_class_name_variable_property
@@ -687,6 +718,7 @@
| T_CLASS_C { $$ = $1; }
| T_METHOD_C { $$ = $1; }
| T_FUNC_C { $$ = $1; }
+ | T_NAMESPACE_C { $$ = $1; }
;


@@ -910,6 +942,8 @@
| T_EVAL '(' expr ')' { zend_do_include_or_eval(ZEND_EVAL, &$$, &$3 TSRMLS_CC); }
| T_REQUIRE expr { zend_do_include_or_eval(ZEND_REQUIRE, &$$, &$2 TSRMLS_CC); }
| T_REQUIRE_ONCE expr { zend_do_include_or_eval(ZEND_REQUIRE_ONCE, &$$, &$2 TSRMLS_CC); }
+ | T_IMPORT T_NAMESPACE T_NAMESPACE_NAME { zend_do_namespace_import(&$3 TSRMLS_CC); }
+ | T_IMPORT T_NAMESPACE T_STRING { zend_do_namespace_import(&$3 TSRMLS_CC); }
;

isset_variables:
Index: ZendEngine2/zend_language_scanner.l
===================================================================
RCS file: /repository/ZendEngine2/zend_language_scanner.l,v
retrieving revision 1.131.2.3
diff -u -r1.131.2.3 zend_language_scanner.l
--- ZendEngine2/zend_language_scanner.l 15 Nov 2005 13:29:28 -0000 1.131.2.3
+++ ZendEngine2/zend_language_scanner.l 22 Nov 2005 03:50:46 -0000
@@ -793,6 +793,7 @@
ESCAPED_AND_WHITESPACE
ANY_CHAR (.|)
NEWLINE ("\r"|"\n"|"\r\n")
+NAMESPACE_NAME ({LABEL}":")*{LABEL}

%option noyylineno
%option noyywrap
@@ -926,6 +927,14 @@
return T_CLASS;
}

+<ST_IN_SCRIPTING>"namespace" {
+ return T_NAMESPACE;
+}
+
+<ST_IN_SCRIPTING>"import" {
+ return T_IMPORT;
+}
+
<ST_IN_SCRIPTING>"interface" {
return T_INTERFACE;
}
@@ -1304,6 +1313,25 @@
return T_FUNC_C;
}

+<ST_IN_SCRIPTING>"__NAMESPACE__" {
+ char *namespace_name = NULL;
+ int namespace_name_len = 0;
+
+ if (CG(namespace_prefix)) {
+ namespace_name = CG(namespace_prefix);
+ namespace_name_len = CG(namespace_prefix_len);
+ }
+
+ if (!namespace_name) {
+ namespace_name = ":";
+ namespace_name_len = 1;
+ }
+ zendlval->value.str.len = namespace_name_len - 1;
+ zendlval->value.str.val = estrndup(namespace_name, zendlval->value.str.len);
+ zendlval->type = IS_STRING;
+ return T_NAMESPACE_C;
+}
+
<ST_IN_SCRIPTING>"__METHOD__" {
char *class_name = CG(active_class_entry) ? CG(active_class_entry)->name : NULL;
char *func_name = CG(active_op_array)? CG(active_op_array)->function_name : NULL;
@@ -1436,6 +1464,13 @@
return T_STRING;
}

+<ST_IN_SCRIPTING>{NAMESPACE_NAME} {
+ zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ return T_NAMESPACE_NAME;
+}
+
<ST_DOUBLE_QUOTES,ST_BACKQUOTE,ST_HEREDOC>{LABEL} {
zend_copy_value(zendlval, yytext, yyleng);
zendlval->type = IS_STRING;tests.tar.gzDescription:GNU Zip compressed data--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit:http://www.php.net/unsub.php

Attachments:
attachment tests.tar.gz (543 bytes)

Offline

#2 Nov. 22, 2005 18:27:37

Derick R.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Re: PDM Meeting Notes


On Tue, 22 Nov 2005, Jessie Hernandez wrote:

> I saw the notes regarding namespaces, and it really suprised me that the
> namespace patch was not looked at in detail, discarded, and then the approach
> that was agreed on was _THE EXACT SAME ONE_ that my patch uses. To add insult
> to injury, it's mentioned that Marcus was going to provide a patch (my problem
> is not with Marcus, in fact, he was very supportive and helpful when I was
> writing the patch and the __autoload mechanism I'm using is thanks to his
> input. My problem is that my patch was completely ignored and someone else was
> assigned to write a patch, when the one I already wrote can be used).

Hang on a bit, if it's assigned to Marcus, doesn't mean he can not work
with you on that.

regards,
Derick

--
Derick Rethanshttp://derickrethans.nl|http://ez.no|http://xdebug.org--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit:http://www.php.net/unsub.php

Offline

#3 Nov. 22, 2005 18:33:25

Rasmus L.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Re: PDM Meeting Notes


Jessie Hernandez wrote:I saw the notes regarding namespaces, and it really suprised me that thenamespace patch was not looked at in detail, discarded, and then theapproach that was agreed on was _THE EXACT SAME ONE_ that my patch uses.To add insult to injury, it's mentioned that Marcus was going to providea patch (my problem is not with Marcus, in fact, he was very supportiveand helpful when I was writing the patch and the __autoload mechanismI'm using is thanks to his input. My problem is that my patch wascompletely ignored and someone else was assigned to write a patch, whenthe one I already wrote can be used).How in the world do you know your patch was ignored? It wasn't. But italso isn't going to work as-is, especially in the new Unicode world, soit is going to take more than one person to play with it and see whatcan be done. Marcus simply volunteered to do that.-Rasmus

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

Offline

#4 Nov. 22, 2005 18:44:25

Jessie H.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Re: PDM Meeting Notes


Hi Rasmus,The way the sentence was worded athttp://www.php.net/~derick/meeting-notes.html#name-spacesled me tobelieve this:"First we briefly discussed the current name space patch, but as we werenot all familiar with its workings we did not go into deep detail forthis. Then we saw an alternative implementation of name spaces with"Modules"".Anyways, from what you said, is namespace support only going to be addedin PHP 6? I have been basing my patch on 5.1, hoping that it would makeit before 6, as the patch is small and has absolutely no BC problems.Obviously, I don't agree on having to wait that long, but if that is thecase, I'll check what changes I need to do in order to apply it to PHP6. Thanks for the clarification.Regards,

Jessie Hernandez


Rasmus Lerdorf wrote:Jessie Hernandez wrote:I saw the notes regarding namespaces, and it really suprised me thatthe namespace patch was not looked at in detail, discarded, and thenthe approach that was agreed on was _THE EXACT SAME ONE_ that my patchuses. To add insult to injury, it's mentioned that Marcus was going toprovide a patch (my problem is not with Marcus, in fact, he was verysupportive and helpful when I was writing the patch and the __autoloadmechanism I'm using is thanks to his input. My problem is that mypatch was completely ignored and someone else was assigned to write apatch, when the one I already wrote can be used).How in the world do you know your patch was ignored? It wasn't. But italso isn't going to work as-is, especially in the new Unicode world, soit is going to take more than one person to play with it and see whatcan be done. Marcus simply volunteered to do that.-Rasmus--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit:http://www.php.net/unsub.php

Offline

#5 Nov. 22, 2005 18:54:35

Rasmus L.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Re: PDM Meeting Notes


Jessie Hernandez wrote:The way the sentence was worded athttp://www.php.net/~derick/meeting-notes.html#name-spacesled me tobelieve this:"First we briefly discussed the current name space patch, but as we werenot all familiar with its workings we did not go into deep detail forthis. Then we saw an alternative implementation of name spaces with"Modules"".Yes, Dmitry has a module-based namespace patch as well. Yours isn'tactually the only working patch on the table right now and as the notessay, we looked at it.Anyways, from what you said, is namespace support only going to be addedin PHP 6? I have been basing my patch on 5.1, hoping that it would makeit before 6, as the patch is small and has absolutely no BC problems.The entire meeting was exclusively about PHP 6. We are too far along inthe 5.1 process to make any large changes at this point.-Rasmus

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

Offline

#6 Nov. 22, 2005 19:00:07

Jessie H.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Re: PDM Meeting Notes


Rasmus Lerdorf wrote:The entire meeting was exclusively about PHP 6. We are too far along inthe 5.1 process to make any large changes at this point.Actually, I did not mean to include it in the current 5.1 version (asthat's about to be released), but I was hoping for it to make it in a5.2 release, for example. Or will there be no more minor releases until 6?Regards,

Jessie Hernandez

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

Offline

#7 Nov. 22, 2005 19:30:46

Marcus B.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Re: PDM Meeting Notes


Hello Jessie,

Tuesday, November 22, 2005, 7:57:47 PM, you wrote:

> Rasmus Lerdorf wrote:
>>
>> The entire meeting was exclusively about PHP 6. We are too far along in
>> the 5.1 process to make any large changes at this point.
>>

> Actually, I did not mean to include it in the current 5.1 version (as
> that's about to be released), but I was hoping for it to make it in a
> 5.2 release, for example. Or will there be no more minor releases until 6?

There was no decison on that yet. Actually there was no real discussion on
that issue anyway. PHP is developed in a way that those decisions are done
when they are at hand. That said we are all working on getting 5.1 out of
the doors. Ass soon as we have done that there will be a bunch of MFHing
from head to 5.1.1-dev. Then there will be 5.1.1 and then..well i cannot
look deeper in my glass ball. It doesn't show anything more.

marcus

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

Offline

#8 Nov. 22, 2005 19:43:31

Marcus B.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Re: PDM Meeting Notes


Hello Derick,

Tuesday, November 22, 2005, 7:26:56 PM, you wrote:

> On Tue, 22 Nov 2005, Jessie Hernandez wrote:

>> I saw the notes regarding namespaces, and it really suprised me that the
>> namespace patch was not looked at in detail, discarded, and then the approach
>> that was agreed on was _THE EXACT SAME ONE_ that my patch uses. To add insult
>> to injury, it's mentioned that Marcus was going to provide a patch (my
>> problem
>> is not with Marcus, in fact, he was very supportive and helpful when I was
>> writing the patch and the __autoload mechanism I'm using is thanks to his
>> input. My problem is that my patch was completely ignored and someone else
>> was
>> assigned to write a patch, when the one I already wrote can be used).

> Hang on a bit, if it's assigned to Marcus, doesn't mean he can not work
> with you on that.

Despite the written sentence i had namespaces on my radar for a long time
now. That i didn't do anything just reflects the current state of PHP. We
are not going to have namespaces for a list of good reasons. Your patch
and the amount of people asking for that feature started discussions all
over again. So while beeing in paris we were able to look at the following
things the stuff we knew your patch was supposed to do and the stuff we
wanted your patch to do as well as the module patch and the stuff we thought
that patch should do. After a long discussion we came to the intermediate
conclusion that it is worth to restart working on namespaces again since a
few issues we had with the first approach have been solved as of now.
However the notes show that PHP will undergo a big amount of changes
especially engine api wise. Thus i guess we won't start working on that
beforehand. If you feel to do more work on your stuff then go ahead we
might go with exactly your patch or ignore it completley when the changes
are done. That's how PHP is done and has nothing to do whetehr i plan to do
some work on my own. Indeed i could come up with a patch that would be
outrules by yours or somebody elses as well. That's open source. Things
might be ignored or removed or rewritten at any time by others. The
advantage is that we can all work together if we feel like and that by doing
so we cannot only learn from each other but reach a very good final result
(if there is such a thing as final result in software).

To cut this short. As soon as i feel like i will start to do some work. And
as soon as there is something to show i will post it. Since i always showed
my stuff were early here. Should you do something earlier i think i will try
to catch up with you and either say nothing to do for me left or send you my
thoughts by mail or try to come up with my brand own ideas.

We'll see, nothing has been made a law by those notes.

marcus

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

Offline

#9 Nov. 22, 2005 20:55:22

Jessie H.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Re: PDM Meeting Notes


Marcus,I agree that we should work together on this, so that we can achieve thebest result possible and to avoid duplicate work. To a certain degree,we have already worked together on this, when you suggested using the__autoload mechanism to resolve namespace imports and this is what Iended up doing.I will try to add functions and constants soon to the patch, and willlook at the PHP 6 source to see what I need to do to make it work withthat version.Regards,

Jessie



Marcus Boerger wrote:Despite the written sentence i had namespaces on my radar for a long time
now. That i didn't do anything just reflects the current state of PHP. We
are not going to have namespaces for a list of good reasons. Your patch
and the amount of people asking for that feature started discussions all
over again. So while beeing in paris we were able to look at the following
things the stuff we knew your patch was supposed to do and the stuff we
wanted your patch to do as well as the module patch and the stuff we thought
that patch should do. After a long discussion we came to the intermediate
conclusion that it is worth to restart working on namespaces again since a
few issues we had with the first approach have been solved as of now.
However the notes show that PHP will undergo a big amount of changes
especially engine api wise. Thus i guess we won't start working on that
beforehand. If you feel to do more work on your stuff then go ahead we
might go with exactly your patch or ignore it completley when the changes
are done. That's how PHP is done and has nothing to do whetehr i plan to do
some work on my own. Indeed i could come up with a patch that would be
outrules by yours or somebody elses as well. That's open source. Things
might be ignored or removed or rewritten at any time by others. The
advantage is that we can all work together if we feel like and that by doing
so we cannot only learn from each other but reach a very good final result
(if there is such a thing as final result in software).

To cut this short. As soon as i feel like i will start to do some work. And
as soon as there is something to show i will post it. Since i always showed
my stuff were early here. Should you do something earlier i think i will try
to catch up with you and either say nothing to do for me left or send you my
thoughts by mail or try to come up with my brand own ideas.

We'll see, nothing has been made a law by those notes.

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

Offline

#10 Nov. 23, 2005 16:41:01

Christian S.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[PHP-DEV] Re: PDM Meeting Notes


Derick Rethans wrote:discussing the things we want to do for PHP 6. Partly because of theThe whole list of decisions is very reasonable, congratulations!My only gripe is about the removal of curly braces for string offsets: Ivery much like the way you undeprecated var ('As there is no real reasonwhy we should remove it, we agreed on simply making "var" an alias to"public" and removing the warning"') and I think curly braces for stringoffsets should be treated the same way.As far as named parameters go: I can live with the decision as we useour own patch for that anyway ;-)- Chris

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

Offline

  • Root
  • » PHP
  • » [PHP-DEV] Re: PDM Meeting Notes [RSS Feed]

Board footer

Moderator control

Enjoy the 22nd of January
PoweredBy

The Forums are managed by develissimo stuff members, if you find any issues or misplaced content please help us to fix it. Thank you! Tell us via Contact Options
Leave a Message
Welcome to Develissimo Live Support