Pastakhov has uploaded a new change for review. https://gerrit.wikimedia.org/r/148610
Change subject: add possibility to set property value (v 2.7.0) ...................................................................... add possibility to set property value (v 2.7.0) * add PHPTAGS_STACK_HOOK_TYPE * add function Compiler::stepFunction() * add function Compiler::stepFunctionFromVariable() * refactoring function Hooks::callHook() Change-Id: I5ef1406b51e137b96359a3403b06f512578a5e82 --- M PhpTags.php M includes/Compiler.php M includes/Hooks.php M includes/PhpTagsException.php M includes/Runtime.php 5 files changed, 260 insertions(+), 84 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/PhpTags refs/changes/10/148610/1 diff --git a/PhpTags.php b/PhpTags.php index 658bd21..007896f 100644 --- a/PhpTags.php +++ b/PhpTags.php @@ -16,8 +16,8 @@ } define( 'PHPTAGS_MAJOR_VERSION', 2 ); -define( 'PHPTAGS_MINOR_VERSION', 6 ); -define( 'PHPTAGS_RELEASE_VERSION', 2 ); +define( 'PHPTAGS_MINOR_VERSION', 7 ); +define( 'PHPTAGS_RELEASE_VERSION', 0 ); define( 'PHPTAGS_VERSION', PHPTAGS_MAJOR_VERSION . '.' . PHPTAGS_MINOR_VERSION . '.' . PHPTAGS_RELEASE_VERSION ); define( 'PHPTAGS_HOOK_RELEASE', 4 ); diff --git a/includes/Compiler.php b/includes/Compiler.php index b44a0eb..70734ae 100644 --- a/includes/Compiler.php +++ b/includes/Compiler.php @@ -345,16 +345,19 @@ } else { $ref = false; } - $this->stack[] = array( + $hookCheckParam = array( PHPTAGS_STACK_COMMAND => PHPTAGS_T_HOOK_CHECK_PARAM, PHPTAGS_STACK_PARAM_3 => &$ref, - PHPTAGS_STACK_PARAM => $functionName, + PHPTAGS_STACK_PARAM => false, // $functionName PHPTAGS_STACK_PARAM_2 => $value[PHPTAGS_STACK_COMMAND] == PHPTAGS_T_VARIABLE, PHPTAGS_STACK_AIM => $i, PHPTAGS_STACK_RESULT => &$result, PHPTAGS_STACK_TOKEN_LINE => $this->tokenLine, ); - unset( $ref ); + $func = $functionName; // clone the function name for use in the next loop + $this->addValueIntoStack( $func, $hookCheckParam, PHPTAGS_STACK_PARAM ); + $this->stack[] =& $hookCheckParam; + unset( $ref, $hookCheckParam, $func ); if ( current($this->tokens) != ',' ) { break; @@ -494,8 +497,9 @@ $this->stepUP(); - $result = array( // define hook as the constant + $result = array( // define blank hook as the constant PHPTAGS_STACK_COMMAND => PHPTAGS_T_HOOK, + PHPTAGS_STACK_HOOK_TYPE => PHPTAGS_HOOK_GET_CONSTANT, PHPTAGS_STACK_PARAM => $text, // function or method PHPTAGS_STACK_PARAM_2 => false, // &$functionParameters PHPTAGS_STACK_PARAM_3 => false, // false or &object @@ -505,29 +509,15 @@ ); if ( $this->id == '(' ) { // it is function - $this->stepUP(); - - if ( $owner !== false ) { // it is object - $this->addValueIntoStack( $owner[0], $result, PHPTAGS_STACK_PARAM_3 ); - $functionParameters =& $this->getFunctionParameters( $text, array( &$result ) ); - } else { // it is function - $functionParameters =& $this->getFunctionParameters( $text ); - } - - $result[PHPTAGS_STACK_PARAM_2] =& $functionParameters; // now, hook is function - - if ( $this->id != ')' ) { - // PHP Parse error: syntax error, unexpected $tmp_id, expecting ')' - throw new PhpTagsException( PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id, "')'" ), $this->tokenLine, $this->place ); - } - $this->stepUP(); + $this->stepFunction( $result, array(PHPTAGS_STACK_COMMAND=>false, PHPTAGS_STACK_RESULT=>$text), $owner ); } elseif ( $owner !== false ) { // it is an objects property. Example: it's 'bar' for FOO::bar + $result[PHPTAGS_STACK_HOOK_TYPE] = $owner[1] === true ? PHPTAGS_HOOK_GET_STATIC_PROPERTY : PHPTAGS_HOOK_GET_OBJECT_PROPERTY; $this->addValueIntoStack( $owner[0], $result, PHPTAGS_STACK_PARAM_3 ); } elseif ( $this->id == T_DOUBLE_COLON ) { // it is static constant or method of an object. Examples: FOO::property or FOO::method() $result[PHPTAGS_STACK_COMMAND] = false; $result[PHPTAGS_STACK_RESULT] = $text; - $result = & $this->stepMethodChaining( $result ); + $result = & $this->stepMethodChaining( $result, true ); } return $result; @@ -560,9 +550,12 @@ $cannotRead = false; $variable = array( PHPTAGS_STACK_COMMAND=>PHPTAGS_T_VARIABLE, PHPTAGS_STACK_PARAM=>substr($text, 1), PHPTAGS_STACK_PARAM_2=>null, PHPTAGS_STACK_RESULT=>null, PHPTAGS_STACK_TOKEN_LINE=>$this->tokenLine, PHPTAGS_STACK_DEBUG=>$text ); - $this->stepUP(); - if ( $this->id == '[' ) { // There is array index + +checkOperators: + if ( $this->id == '(' ) { // it is function + $variable =& $this->stepFunctionFromVariable( $variable, $text, $owner ); + } elseif ( $this->id == '[' ) { // There is array index $variable[PHPTAGS_STACK_ARRAY_INDEX] = array(); $i = 0; do { // Example: $foo[ @@ -593,41 +586,101 @@ // PHP Parse error: syntax error, unexpected $id throw new PhpTagsException( PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id ), $this->tokenLine, $this->place ); } - $return = array( - PHPTAGS_STACK_COMMAND => self::$runtimeOperators[$id], - PHPTAGS_STACK_PARAM => $variable, - PHPTAGS_STACK_PARAM_2 => null, - PHPTAGS_STACK_RESULT => null, - PHPTAGS_STACK_TOKEN_LINE => $this->tokenLine, - PHPTAGS_STACK_DEBUG => $text, - ); - $this->addValueIntoStack( $val, $return, PHPTAGS_STACK_PARAM_2 ); - return $return; // *********** EXIT *********** + if ( $owner === false && $variable[PHPTAGS_STACK_COMMAND] == PHPTAGS_T_VARIABLE ) { + $return = array( + PHPTAGS_STACK_COMMAND => self::$runtimeOperators[$id], + PHPTAGS_STACK_PARAM => $variable, + PHPTAGS_STACK_PARAM_2 => null, + PHPTAGS_STACK_RESULT => null, + PHPTAGS_STACK_TOKEN_LINE => $this->tokenLine, + PHPTAGS_STACK_DEBUG => $text, + ); + $this->addValueIntoStack( $val, $return, PHPTAGS_STACK_PARAM_2 ); + return $return; // *********** EXIT *********** + } elseif ( $owner === false ) { + // $variable[PHPTAGS_STACK_COMMAND] == PHPTAGS_T_HOOK + switch ( $variable[PHPTAGS_STACK_HOOK_TYPE] ) { + case PHPTAGS_HOOK_GET_OBJECT_PROPERTY: // Example: $foo = new FOO(); $foo->bar = + $variable[PHPTAGS_STACK_HOOK_TYPE] = PHPTAGS_HOOK_SET_OBJECT_PROPERTY; + break; + case PHPTAGS_HOOK_GET_STATIC_PROPERTY: // Example: $foo = new FOO(); $foo::bar = + $variable[PHPTAGS_STACK_HOOK_TYPE] = PHPTAGS_HOOK_SET_STATIC_PROPERTY; + break; + default : // Example: FOO->$bar() = + // PHP Parse error: syntax error, unexpected $id + throw new PhpTagsException( PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id ), $this->tokenLine, $this->place ); + } + $this->addValueIntoStack( $val, $variable, PHPTAGS_STACK_PARAM_2 ); + return $variable; // *********** EXIT *********** + } else { // Property name as variable. Example: $foo = new FOO(); $bar='anyproperty'; $foo->$bar = + $return = array( // define hook + PHPTAGS_STACK_COMMAND => PHPTAGS_T_HOOK, + PHPTAGS_STACK_HOOK_TYPE => $owner[1] === true ? PHPTAGS_HOOK_SET_STATIC_PROPERTY : PHPTAGS_HOOK_SET_OBJECT_PROPERTY, + PHPTAGS_STACK_PARAM => false, // function or method + PHPTAGS_STACK_PARAM_2 => false, // &$functionParameters + PHPTAGS_STACK_PARAM_3 => false, // false or &object + PHPTAGS_STACK_RESULT => null, + PHPTAGS_STACK_TOKEN_LINE => $this->tokenLine, + PHPTAGS_STACK_DEBUG => $text, + ); + $this->addValueIntoStack( $variable, $return, PHPTAGS_STACK_PARAM ); // property name + $this->addValueIntoStack( $val, $return, PHPTAGS_STACK_PARAM_2 ); // value + $this->addValueIntoStack( $owner[0], $return, PHPTAGS_STACK_PARAM_3 ); // object + return $return; + } } elseif ( $id == T_INC || $id == T_DEC ) { - $variable = array( - PHPTAGS_STACK_COMMAND => self::$runtimeOperators[$id], - PHPTAGS_STACK_PARAM => $variable, - PHPTAGS_STACK_PARAM_2 => true, // Example: $foo++ - PHPTAGS_STACK_RESULT => null, - PHPTAGS_STACK_TOKEN_LINE => $this->tokenLine, - PHPTAGS_STACK_DEBUG => $text, - ); - $this->stepUP(); - } elseif ( $cannotRead ) { + if ( $variable[PHPTAGS_STACK_COMMAND] == PHPTAGS_T_VARIABLE ) { + $variable = array( + PHPTAGS_STACK_COMMAND => self::$runtimeOperators[$id], + PHPTAGS_STACK_PARAM => $variable, + PHPTAGS_STACK_PARAM_2 => true, // Example: $foo++ + PHPTAGS_STACK_RESULT => null, + PHPTAGS_STACK_TOKEN_LINE => $this->tokenLine, + PHPTAGS_STACK_DEBUG => $text, + ); + $this->stepUP(); + } else { // $variable[PHPTAGS_STACK_COMMAND] == PHPTAGS_T_HOOK Example: FOO->$bar()++ + // PHP Parse error: syntax error, unexpected $id + throw new PhpTagsException( PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id ), $this->tokenLine, $this->place ); + } + } elseif ( $cannotRead ) { // Example: echo $foo[]; // PHP Fatal error: Cannot use [] for reading throw new PhpTagsException( PhpTagsException::FATAL_CANNOT_USE_FOR_READING, null, $this->tokenLine, $this->place ); - } elseif ( $owner === false && ($id == T_OBJECT_OPERATOR || $id == T_DOUBLE_COLON) ) { // Example: $foo-> + } elseif ( $owner !== false ) { + if ( $variable[PHPTAGS_STACK_COMMAND] == PHPTAGS_T_HOOK ) { // Example: $bar = 'anymethod'; echo $foo->$bar(); + return $variable; + } // Example: $bar = 'anyproperty'; echo $foo->$bar + $return = array( // define hook + PHPTAGS_STACK_COMMAND => PHPTAGS_T_HOOK, + PHPTAGS_STACK_HOOK_TYPE => $owner[1] === true ? PHPTAGS_HOOK_GET_STATIC_PROPERTY : PHPTAGS_HOOK_GET_OBJECT_PROPERTY, + PHPTAGS_STACK_PARAM => false, // function or method + PHPTAGS_STACK_PARAM_2 => false, // &$functionParameters + PHPTAGS_STACK_PARAM_3 => false, // false or &object + PHPTAGS_STACK_RESULT => null, + PHPTAGS_STACK_TOKEN_LINE => $this->tokenLine, + PHPTAGS_STACK_DEBUG => $text, + ); + $this->addValueIntoStack( $variable, $return, PHPTAGS_STACK_PARAM ); // property name + $this->addValueIntoStack( $owner[0], $return, PHPTAGS_STACK_PARAM_3 ); // object + + $id = $this->id; + if ( $id == T_OBJECT_OPERATOR || $id == T_DOUBLE_COLON ) { + $return =& $this->stepMethodChaining( $return, $id == T_DOUBLE_COLON ); + } + return $return; + } elseif ( $id == T_OBJECT_OPERATOR || $id == T_DOUBLE_COLON ) { // Example: $foo-> $this->stepUP(); - $val =& $this->stepValue( array(&$variable) ); - if ( $val == false || $val[PHPTAGS_STACK_COMMAND] != PHPTAGS_T_HOOK ) { // Example: $foo->; + $variable =& $this->stepValue( array(&$variable, $id == T_DOUBLE_COLON) ); + if ( $variable == false || $variable[PHPTAGS_STACK_COMMAND] != PHPTAGS_T_HOOK ) { // Example: $foo->; // PHP Parse error: syntax error, unexpected $id throw new PhpTagsException( PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id ), $this->tokenLine, $this->place ); } - if ( $this->id == T_OBJECT_OPERATOR || $this->id == T_DOUBLE_COLON ) { - $val = & $this->stepMethodChaining( $val ); + $id = $this->id; + if ( $id == T_OBJECT_OPERATOR || $id == T_DOUBLE_COLON ) { + $variable =& $this->stepMethodChaining( $variable, $id == T_DOUBLE_COLON ); } - return $val; + goto checkOperators; } return $variable; // *********** EXIT *********** case T_INC: @@ -826,7 +879,10 @@ } if ( $this->id == '(' ) { // it has parameters $this->stepUP(); - $objectParameters =& $this->getFunctionParameters( PHPTAGS_METHOD_CONSTRUCTOR, array( &$result ) ); + $objectParameters =& $this->getFunctionParameters( + array( PHPTAGS_STACK_COMMAND => false, PHPTAGS_STACK_RESULT => PHPTAGS_METHOD_CONSTRUCTOR), + array( &$result ) + ); if ( $this->id != ')' ) { // PHP Parse error: syntax error, unexpected $tmp_id, expecting ')' throw new PhpTagsException( PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id, "')'" ), $this->tokenLine, $this->place ); @@ -1388,16 +1444,16 @@ return true; } - private function & stepMethodChaining( &$result ) { + private function & stepMethodChaining( &$result, $isStatic ) { do { $this->stepUP(); - $val =& $this->stepValue( array(&$result) ); + $val =& $this->stepValue( array(&$result, $isStatic) ); if ( $val == false ) { // Example: FOO::bar-> ; // PHP Parse error: syntax error, unexpected $id throw new PhpTagsException( PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id ), $this->tokenLine, $this->place ); } switch ( $val[PHPTAGS_STACK_COMMAND] ) { - case PHPTAGS_T_HOOK: // Example: FOO::bar->too + case PHPTAGS_T_HOOK: // Examples: FOO::bar->too $result =& $val; break; case PHPTAGS_T_VARIABLE: // Example: FOO::bar->$variable @@ -1422,34 +1478,99 @@ return $result; } - private function addValueIntoStack( &$value, &$result, $aim, $doit = false ) { + /** + * This function adds $value to the $aim in $command + * If $value has a variable then it will be added to stack + * If the values of the command are scalar then command can be processed + * and if $doit is TRUE then the command will be processed + * and in this case the function returns TRUE otherwise FALSE. + * @param array $value Array with PHPTAGS_STACK_COMMAND + * @param array $command Array with $aim + * @param string $aim The aim in $command + * @param boolean $doit Process the command if possible + * @return boolean Returns TRUE, if the command was processed + */ + private function addValueIntoStack( &$value, &$command, $aim, $doit = false ) { if ( $value[PHPTAGS_STACK_COMMAND] == PHPTAGS_T_VARIABLE ) { - $value[PHPTAGS_STACK_PARAM_2] =& $result; + $value[PHPTAGS_STACK_PARAM_2] =& $command; $value[PHPTAGS_STACK_AIM] = $aim; } else { - $result[$aim] =& $value[PHPTAGS_STACK_RESULT]; + $command[$aim] =& $value[PHPTAGS_STACK_RESULT]; } - if ( $value[PHPTAGS_STACK_COMMAND] ) { - $this->stack[] =& $value; - } elseif( $value[PHPTAGS_STACK_COMMAND] === null ) { - // The values of the operator have no command + if ( $value[PHPTAGS_STACK_COMMAND] === null ) { + // The values of the command are scalar if ( $doit ) { - $tmp = array( PHPTAGS_STACK_COMMAND => PHPTAGS_T_RETURN, PHPTAGS_STACK_PARAM => &$result[PHPTAGS_STACK_RESULT] ); - $runtimeReturn = Runtime::run( array($result, $tmp), array('PhpTags\\Compiler') ); + $tmp = array( PHPTAGS_STACK_COMMAND => PHPTAGS_T_RETURN, PHPTAGS_STACK_PARAM => &$command[PHPTAGS_STACK_RESULT] ); + $runtimeReturn = Runtime::run( array($command, $tmp), array('PhpTags\\Compiler') ); if ( $runtimeReturn instanceof PhpTagsException ) { return false; } - $result = array( + $command = array( PHPTAGS_STACK_COMMAND => null, // Mark the operator as the already processed. PHPTAGS_STACK_RESULT => $runtimeReturn, ); } return true; + } elseif ( $value[PHPTAGS_STACK_COMMAND] !== false ) { + $this->stack[] =& $value; } return false; } + /** + * Returns Hook as function() or $object->method() + * @param array $hook The blank hook + * @param array $funcName The function name + * @param mixed $owner Object as array or FALSE for function + * @return array Hook + * @throws PhpTagsException + */ + private function & stepFunction( &$hook, $funcName, $owner ) { + $this->stepUP(); + + if ( $owner !== false ) { // $owner is object + $hook[PHPTAGS_STACK_HOOK_TYPE] = $owner[1] === true ? PHPTAGS_HOOK_STATIC_METHOD : PHPTAGS_HOOK_OBJECT_METHOD; + $this->addValueIntoStack( $owner[0], $hook, PHPTAGS_STACK_PARAM_3 ); + $hook[PHPTAGS_STACK_PARAM_2] =& $this->getFunctionParameters( $funcName, array( &$hook ) ); + } else { // it is function + $hook[PHPTAGS_STACK_HOOK_TYPE] = PHPTAGS_HOOK_FUNCTION; + $hook[PHPTAGS_STACK_PARAM_2] =& $this->getFunctionParameters( $funcName ); + } + + if ( $this->id != ')' ) { + // PHP Parse error: syntax error, unexpected $tmp_id, expecting ')' + throw new PhpTagsException( PhpTagsException::PARSE_SYNTAX_ERROR_UNEXPECTED, array( $this->id, "')'" ), $this->tokenLine, $this->place ); + } + $this->stepUP(); + return $hook; + } + + /** + * Returns Hook as $function() or objects->$method() where name will be received from variable + * @param array $variable The variable as function or method name + * @param string $text Text of variable for debug + * @param mixed $owner Object as array or FALSE for function + * @return array Hook + * @throws PhpTagsException + */ + public function & stepFunctionFromVariable( $variable, $text, $owner ) { + $hook = array( // define the blank hook + PHPTAGS_STACK_COMMAND => PHPTAGS_T_HOOK, + PHPTAGS_STACK_HOOK_TYPE => false, + PHPTAGS_STACK_PARAM => false, // function or method name from $variable + PHPTAGS_STACK_PARAM_2 => false, // &$functionParameters + PHPTAGS_STACK_PARAM_3 => false, // false or &object + PHPTAGS_STACK_RESULT => null, + PHPTAGS_STACK_TOKEN_LINE => $this->tokenLine, + PHPTAGS_STACK_DEBUG => $text, + ); + + $return =& $this->stepFunction( $hook, $variable, $owner ); + $this->addValueIntoStack( $variable, $return, PHPTAGS_STACK_PARAM ); // Add function or method name to hook + return $return; + } + } diff --git a/includes/Hooks.php b/includes/Hooks.php index 837b4b4..20aaf77 100644 --- a/includes/Hooks.php +++ b/includes/Hooks.php @@ -140,28 +140,33 @@ } /** - * Call a hook like as constant or function or object's method of PhpTags + * Call a hook of PhpTags + * @param int $type Hook type * @param mixed $arguments Array or boolean false for the constants * @param mixed $name Name of constant or function or method * @param mixed $object boolean false for the functions or the object or object's name * @return mixed * @throws PhpTagsException */ - public static function callHook( $arguments, $name, $object ) { - // it is a constant or a function or a method of an object - if ( $arguments === false ) { // it is a constant or a property of an object - if ( $object === false ) { // it is a constant - return self::callConstant( $name ); - } else { // it is a property of an object - return self::callObjectsProperty( $name, $object ); - } + public static function callHook( $type, $arguments, $name, $object ) { + switch ( $type ) { + case PHPTAGS_HOOK_GET_CONSTANT: // Hook is a constant. Example: echo M_PI; + return self::callGetConstant( $name ); + case PHPTAGS_HOOK_FUNCTION: // Hook is a function. Example: echo foo(); + return self::callFunction( $arguments, $name ); + case PHPTAGS_HOOK_GET_STATIC_PROPERTY: // Hook is a static property of a method. Example: echo FOO::bar; + return self::callGetStaticProperty( $name, $object ); + case PHPTAGS_HOOK_GET_OBJECT_PROPERTY: // Hook is a property of a method. Example: $foo = new Foo(); echo $foo->bar; + return self::callGetObjectsProperty( $name, $object ); + case PHPTAGS_HOOK_SET_STATIC_PROPERTY: // Example FOO::bar = true; + return self::callSetStaticProperty( $name, $object, $arguments ); + case PHPTAGS_HOOK_SET_OBJECT_PROPERTY: // Example: $foo = new Foo(); $foo->bar = true; + return self::callSetObjectsProperty( $name, $object, $arguments ); + case PHPTAGS_HOOK_STATIC_METHOD: // Example: FOO::bar() + return self::callStaticMethod( $arguments, $name, $object ); + case PHPTAGS_HOOK_OBJECT_METHOD: // Example: $foo = new Foo(); $foo->bar(); + return self::callObjectsMethod( $arguments, $name, $object ); } - // it is a function or a method of an object - if ( $object === false ) { // it is a function - return self::callFunction( $arguments, $name ); - } - // it is a method of an object - return self::callObjectsMethod( $arguments, $name, $object ); } /** @@ -169,7 +174,7 @@ * @param string $name Name of the constant * @return mixed */ - private static function callConstant( $name ) { + private static function callGetConstant( $name ) { static $constants = array(); // cache of called constants if ( isset ( self::$constants[$name] ) ) { @@ -221,7 +226,13 @@ return; } } - // it is calling of static method + Runtime::$transit[PHPTAGS_TRANSIT_EXCEPTION][] = new PhpTagsException( PhpTagsException::FATAL_CALL_FUNCTION_ON_NON_OBJECT, $name ); + } + + private static function callStaticMethod( $arguments, $name, $object ) { + if ( $object instanceof GenericObject ) { + $object = $object->getName(); + } $className = self::getClassNameByObjectName( $object ); if ( true === $className::checkArguments( $object, $name, $arguments ) ) { $arguments[] = $object; @@ -236,15 +247,36 @@ * @return mixed * @throws PhpTagsException */ - public static function callObjectsProperty( $name, $object ) { + public static function callGetObjectsProperty( $name, $object ) { if ( $object instanceof GenericObject ) { return call_user_func( array($object, "p_$name") ); } - // it is calling of static property + Runtime::$transit[PHPTAGS_TRANSIT_EXCEPTION][] = new PhpTagsException( PhpTagsException::NOTICE_GET_PROPERTY_OF_NON_OBJECT, null ); + } + + public static function callGetStaticProperty( $name, $object ) { + if ( $object instanceof GenericObject ) { + $object = $object->getName(); + } $className = self::getClassNameByObjectName( $object ); return call_user_func( array($className, "c_$name"), $object ); } + public static function callSetObjectsProperty( $name, $object, $value ) { + if ( $object instanceof GenericObject ) { + return call_user_func( array($object, "b_$name"), $value ); + } + Runtime::$transit[PHPTAGS_TRANSIT_EXCEPTION][] = new PhpTagsException( PhpTagsException::WARNING_ATTEMPT_TO_ASSIGN_PROPERTY, null ); + } + + public static function callSetStaticProperty( $name, $object, $value ) { + if ( $object instanceof GenericObject ) { + $object = $object->getName(); + } + $className = self::getClassNameByObjectName( $object ); + return call_user_func( array($className, "k_$name"), $object, $value ); + } + public static function createObject( $arguments, $name, $showException = true ) { $className = self::getClassNameByObjectName( $name ); $object = new $className( $name ); diff --git a/includes/PhpTagsException.php b/includes/PhpTagsException.php index aa714cf..6ee01ec 100644 --- a/includes/PhpTagsException.php +++ b/includes/PhpTagsException.php @@ -150,6 +150,15 @@ case self::FATAL_CALLED_MANY_EXPENSIVE_FUNCTION: $message = "Too many expensive function calls, last is $arguments"; break; + case self::NOTICE_GET_PROPERTY_OF_NON_OBJECT: + $message = 'Trying to get property of non-object'; + break; + case self::WARNING_ATTEMPT_TO_ASSIGN_PROPERTY: + $message = 'Attempt to assign property of non-object'; + break; + case self::FATAL_CALL_FUNCTION_ON_NON_OBJECT; + $message = "Call to a member function $arguments() on a non-object"; + break; default: $message = "Undefined error, code {$this->code}"; $this->code = self::EXCEPTION_FATAL * 1000; @@ -191,6 +200,7 @@ const NOTICE_UNDEFINED_PROPERTY = 2006; // PHP Notice: Undefined property: DateInterval::$rsss const NOTICE_UNDEFINED_CLASS_CONSTANT = 2007; // PHP Fatal error: Undefined class constant 'EXCLUDE_START_DATEqqqq' const NOTICE_OBJECT_CONVERTED = 2008; // PHP Notice: Object of class Exception could not be converted to int + const NOTICE_GET_PROPERTY_OF_NON_OBJECT = 2009; // PHP Notice: Trying to get property of non-object const EXCEPTION_WARNING = 3; const WARNING_DIVISION_BY_ZERO = 3001; // PHP Warning: Division by zero @@ -203,6 +213,7 @@ const WARNING_EXPECTS_EXACTLY_PARAMETER = 3009; // PHP Warning: date_format() expects exactly 1 parameter, 3 given const WARNING_EXPECTS_AT_LEAST_PARAMETERS = 3010; const WARNING_EXPECTS_AT_LEAST_PARAMETER = 3011; // PHP Warning: sprintf() expects at least 1 parameter, 0 given + const WARNING_ATTEMPT_TO_ASSIGN_PROPERTY = 3012; // PHP Warning: Attempt to assign property of non-object const WARNING_CALLFUNCTION_INVALID_HOOK = 3900; const WARNING_CALLCONSTANT_INVALID_HOOK = 3901; @@ -226,6 +237,7 @@ const FATAL_INVALID_CONSTANT_CLASS = 4016; const FATAL_CANNOT_UNSET_STRING_OFFSETS = 4017; // PHP Fatal error: Cannot unset string offsets const FATAL_CALLED_MANY_EXPENSIVE_FUNCTION = 4018; + const FATAL_CALL_FUNCTION_ON_NON_OBJECT = 4019; // PHP Fatal error: Call to a member function doo() on a non-object const EXCEPTION_CATCHABLE_FATAL = 5; const FATAL_OBJECT_COULD_NOT_BE_CONVERTED = 5001; //PHP Catchable fatal error: Object of class stdClass could not be converted to string diff --git a/includes/Runtime.php b/includes/Runtime.php index cdc4644..7b8b2d3 100644 --- a/includes/Runtime.php +++ b/includes/Runtime.php @@ -13,6 +13,16 @@ define( 'PHPTAGS_STACK_ARRAY_INDEX', 'a' ); define( 'PHPTAGS_STACK_DEBUG', '#' ); define( 'PHPTAGS_STACK_AIM', '*' ); +define( 'PHPTAGS_STACK_HOOK_TYPE', 'h' ); + +define( 'PHPTAGS_HOOK_GET_CONSTANT', '_' ); +define( 'PHPTAGS_HOOK_FUNCTION', 'f' ); +define( 'PHPTAGS_HOOK_GET_STATIC_PROPERTY', 'c' ); +define( 'PHPTAGS_HOOK_GET_OBJECT_PROPERTY', 'p' ); +define( 'PHPTAGS_HOOK_SET_STATIC_PROPERTY', 'k' ); +define( 'PHPTAGS_HOOK_SET_OBJECT_PROPERTY', 'b' ); +define( 'PHPTAGS_HOOK_STATIC_METHOD', 's' ); +define( 'PHPTAGS_HOOK_OBJECT_METHOD', 'm' ); define( 'PHPTAGS_OBJECT_DEFINITION', 0 ); define( 'PHPTAGS_METHOD_CONSTRUCTOR', 1 ); @@ -438,6 +448,7 @@ break; case PHPTAGS_T_HOOK: $result = Hooks::callHook( + $value[PHPTAGS_STACK_HOOK_TYPE], $value[PHPTAGS_STACK_PARAM_2], // arguments $value[PHPTAGS_STACK_PARAM], // name of function or method $value[PHPTAGS_STACK_PARAM_3] // $object or false -- To view, visit https://gerrit.wikimedia.org/r/148610 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5ef1406b51e137b96359a3403b06f512578a5e82 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/PhpTags Gerrit-Branch: master Gerrit-Owner: Pastakhov <pastak...@yandex.ru> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits