Re: import/use last call

From: Date: Tue, 23 Oct 2007 03:43:24 +0000
Subject: Re: import/use last call
References: 1 2 3  Groups: php.internals 
Request: Send a blank email to internals+get-32924@lists.php.net to get a copy of this message
Stanislav Malyshev wrote: >> Hold off for a bit - I may have a simple solution that solves the >> problem for class names, method names and functions, have to code the >> patch tonight first to prove it works. > > OK, please send it as soon as you have it :) Hi, The attached patch is for PHP 5.3, if it is acceptable, I will port it to PHP 6, which is not difficult, although it does involve a lot of cut/pasting. The patch does these things: 1) fixes an unrelated bug I found in implementation of LSB - "static" is not checked for in zend_do_import()/zend_do_namespace() and other places that we check for "self" and "parent" 2) fixes a rather serious error in the fix for Bug #42859 - missing parens in zend_do_import() 3) adds "import" and "namespace" as valid function/class names 4) allows any string for method names, just as we allow any string for variable names 5) fixes a bug in logic for $class->list where $class-> list (note the whitespace between -> and list) returns a T_LIST instead of T_STRING 6) It allows "import ::Classname as Blah" which is currently a parse error 7) class constants are unchanged - reserved words still error out. Note that the zend_compile.c fixes can all be committed directly as they are all bugfixes and not related to the import/namespace/reserved words fix. To implement this, I added several states to the lexer in order to return T_STRING whenever possible, which is after T_NEW, T_INTERFACE, T_CLASS, T_EXTENDS and in the T_IMPLEMENTS list. In addition, after T_FUNCTION outside of a class, it returns T_STRING for "import" and "namespace" but no other reserved words. After T_FUNCTION inside of a class (method declaration), it returns T_STRING for all possible strings. After :: or -> T_STRING is always returned. Also, rather than take the approach LSB does with T_STATIC, I have the lexer initialize the string value of T_IMPORT and T_NAMESPACE so we can preserve case for autoloading needs. The parser frees the unused char * when normal import/namespace declarations are called. In the parser, I use fully_qualified_class_name instead of namespace_name for both import syntaxes. This introduces a minor issue in that this is no longer a parse error: import static::oops as Classname; However, if "Classname" is used, this will simply result in "Fatal error: Class 'static::oops' not found in..." and shouldn't be too big of a deal. Also in the parser, I inserted T_IMPORT and T_NAMESPACE as aliases to T_STRING in global situations to allow for static method calls, class constants, and fully-qualified namespace calls. Basically this script is now possible with the patch: <?php namespace import; import ::Exception as Test; function import() {echo 'import function';} interface import {} interface fooey {} class Exception extends ::Exception implements fooey, import {} class namespace { const HI = 3; function list() {echo __METHOD__;} } import(); var_dump(namespace::HI); namespace::list(); ?> and results in this output: cellog@lot-49:~/workspace/php5$ sapi/cli/php -n testme.php import functionint(3) import::namespace::list I have not performed profiling on the patch, instead focusing on correctness for now. The patch looks complicated because of the additional states, but is really not that complicated, honest. :) Greg

« previous php.internals (#32924) next »