Accessors Parsing
| From: | Clint M Priest | Date: | Tue, 08 Nov 2011 14:26:44 +0000 |
| Subject: | Accessors Parsing | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-56164@lists.php.net to get a copy of this message | ||
Working to implement Getter/Setter Accessor syntax as per https://wiki.php.net/rfc/propertygetsetsyntax
but brand new to php internals development.
I was planning on having the parser define methods on the class for the getter/setter such as
__getHours() and __setHours() and then have those functions called in leiu of __get() if they are
defined, does that seem like a reasonable strategy for this?
More specific problems on the parser side of things, here is what I have now:
getter_setter_declarations:
getter_declaration
setter_declaration
| setter_declaration
getter_declaration
| setter_declaration
| getter_declaration
| /* empty */
;
getter_declaration:
method_modifiers T_GET
{ zend_do_begin_function_declaration(&$2, &$$, 1, ZEND_RETURN_VAL, &$1 TSRMLS_CC); }
'{' inner_statement_list '}'
{ /******** $$ != Hours Here!! ***************/
zend_do_abstract_method(&$$, &$1, &$4 TSRMLS_CC);
zend_do_end_function_declaration(&$2 TSRMLS_CC); }
setter_declaration:
T_SET '{' inner_statement_list '}'
class_variable_declaration:
T_VARIABLE { $$ = $1; /**** Capture variable name ****/ } '{' getter_setter_declarations
'}'
| class_variable_declaration ',' T_VARIABLE { zend_do_declare_property(&$3, NULL,
CG(access_type) TSRMLS_CC); }
| class_variable_declaration ',' T_VARIABLE '=' static_scalar {
zend_do_declare_property(&$3, &$5, CG(access_type) TSRMLS_CC); }
| T_VARIABLE { zend_do_declare_property(&$1, NULL, CG(access_type) TSRMLS_CC); }
| T_VARIABLE '=' static_scalar { zend_do_declare_property(&$1, &$3,
CG(access_type) TSRMLS_CC); }
;
I'm just working on the getter now.
1) I am able to get the T_VARIABLE name passed through to the zend_do_begin_function() using $$
however $$ is no longer correctly set by zend_do_abstract_method(). What would be a more
appropriate way to store the variable znode? I see there are a number of stacks in the
compiler_globals, would using one of those or creating a new one be appropriate?
1.1) Alternatively to #1, is there a way to access the T_VARIABLE znode from the
zend_do_begin_function_declaration() line? (Reach re patterns from previous/prior matches/lines)
2) I am having trouble with building the function name (2nd param to zend_do_begin_function) since
that function needs to have a znode as the input. I could stuff code in here to concat the strings
together and build a znode but since there is sparsely any real code in this file I hesitate to do
so. Any recommendations here?
3) An interesting situation with the above code is that the function is declared and is seen through
a ReflectionClass() but calling it indicates that the function does not exist, I think that is
because $$ was cleared/changed by the time zend_do_abstract() is called, is this something I should
add a check for? (Calling zend_do_abstract() with a function name that was not previously seen via
zend_do_begin_function_declaration())
For reference, here is the PHP test class I am using:
#!/opt/trunk/sapi/cli/php
<?php
class TimePeriod {
public $Seconds;
public function __construct($Seconds) {
$this->Seconds = $Seconds;
}
public $Hours {
get {
return $this->Seconds / 3600;
}
/* set { $this->Seconds = $value * 3600; } // The variable $value holds the incoming value to be
"set"*/
};
}
$o = new TimePeriod(3600);
echo $o->Seconds."\r\n";
echo $o->Hours()."\r\n";
?>