Пример #1
0
 /**
  * @param \Runkit\RunkitMethod $method
  *
  * @return boolean
  */
 public function addMethod(\Runkit\RunkitMethod $method)
 {
     if (!function_exists('runkit_method_add')) {
         return false;
     }
     return runkit_method_add($method->getClass(), $method->getName(), (string) $method->getArguments(), $method->getCode()->get(), $method->getAccess());
 }
Пример #2
0
 /**
  *	Reimplements the given function.
  */
 public static function reimplementMethod($class, $method, $arguments, $code)
 {
     $originalMethod = "__original_{$method}";
     if (!method_exists($class, $originalMethod)) {
         runkit_method_rename($class, $method, $originalMethod);
     }
     runkit_method_add($class, $method, $arguments, $code);
 }
Пример #3
0
 public static function replaceMethod($className, $methodName, $args, $code, $flags)
 {
     yTest_debugCC("replaceMethod {$className}::{$methodName}({$args}) with code (flags = " . self::flagsToString($flags) . "):\n" . $code);
     $res = runkit_method_rename($className, $methodName, strtolower(self::getOriginalMethodName($methodName)));
     yTest_assert($res);
     $res = runkit_method_add($className, strtolower($methodName), $args, $code, $flags);
     yTest_assert($res);
     //var_dump(get_class_methods($className));
 }
Пример #4
0
 /**
  * Apply a mutation to the relevant file
  *
  * @param array $mutation
  */
 public function applyMutation(array $mutation)
 {
     require_once $mutation['mutation']->getFilename();
     $newBlock = $mutation['mutation']->mutate($mutation['tokens'], $mutation['index']);
     $this->_methodPreserveCode = md5($mutation['method']);
     if (runkit_method_rename($mutation['class'], $mutation['method'], $mutation['method'] . $this->_methodPreserveCode) == false) {
         throw new \Exception('runkit_method_rename() failed from ' . $mutation['class'] . '::' . $mutation['method'] . ' to ' . $mutation['class'] . '::' . $mutation['method'] . $this->_methodPreserveCode . ' (mutation application)');
     }
     if (runkit_method_add($mutation['class'], $mutation['method'], $mutation['args'], $newBlock, $this->getMethodFlags($mutation)) == false) {
         throw new \Exception('runkit_method_add() failed when replacing original ' . $mutation['class'] . '::' . $mutation['method'] . '(' . var_export($mutation['args']) . ') with a mutation of' . ' type ' . get_class($mutation['mutation']) . ' using the' . ' following (mutated) source code from ' . $mutation['mutation']->getFilename() . ':' . PHP_EOL . $newBlock);
     }
 }
Пример #5
0
 /**
  * Mock
  *
  * @return \MockFunction
  */
 public function mock()
 {
     if ($this->_mock) {
         return $this;
     }
     $this->_mock = true;
     foreach ($this->_methods as $method) {
         runkit_method_rename($this->_class_name, $method, "_origin_" . $method);
         runkit_method_add($this->_class_name, $method, '', $this->getMockCode($method));
     }
     return $this;
 }
Пример #6
0
 protected function _redirectCallToMethod()
 {
     $newOrigFuncName = $this->_functionName . $this->_origFuncSuffix;
     $spyFuncName = $this->_functionName . $this->_spyFuncSuffix;
     $isStatic = (new \ReflectionMethod($this->_context, $this->_functionName))->isStatic();
     $isInherited = !method_exists($this->_context, $this->_functionName) && method_exists(get_parent_class($this->_context), $this->_functionName);
     runkit_method_add($this->_context, $spyFuncName, '', $this->_getSpyFunctionBody(), RUNKIT_ACC_PRIVATE | ($isStatic ? RUNKIT_ACC_STATIC : 0));
     if (!method_exists($this->_context, $newOrigFuncName)) {
         runkit_method_copy($this->_context, $newOrigFuncName, $this->_context, $this->_functionName);
     }
     //keep memory address of function to prevent seg fault
     $runkit_method_modifier = $isInherited ? 'runkit_method_add' : 'runkit_method_redefine';
     $runkit_method_modifier($this->_context, $this->_functionName, '', $this->_getReplaceFunctionBody(), RUNKIT_ACC_PUBLIC | ($isStatic ? RUNKIT_ACC_STATIC : 0));
 }
Пример #7
0
 public function apply()
 {
     $runkitFlags = RUNKIT_ACC_PUBLIC;
     if (yTest_Reflection::isStaticProperty($this->className, $this->propertyName)) {
         $setter = 'self::$' . $this->propertyName . ' = $value;';
         $getter = 'return self::$' . $this->propertyName . ';';
         $runkitFlags |= RUNKIT_ACC_STATIC;
     } else {
         $setter = '$this->' . $this->propertyName . ' = $value;';
         $getter = 'return $this->' . $this->propertyName . ';';
     }
     runkit_method_add($this->className, $this->setterName, '$value', $setter, $runkitFlags);
     runkit_method_add($this->className, $this->getterName, '', $getter, $runkitFlags);
 }
Пример #8
0
 public function apply()
 {
     if (method_exists($this->className, yTest_Reflection::getOriginalMethodName($this->methodName))) {
         throw new yTest_Exception('trying to create public delegate (letMeCall) on the already rewired method ' . $this->className . '::' . $this->methodName);
     }
     $params = yTest_Signature::getParamsDecl($this->methodName, $this->className);
     $runkitFlags = RUNKIT_ACC_PUBLIC;
     if (yTest_Reflection::isStaticMethod($this->className, $this->methodName)) {
         $code = 'return self::' . $this->methodName . '(' . yTest_Signature::getArgsForSimpleCall($this->methodName, $this->className) . ');';
         $runkitFlags |= RUNKIT_ACC_STATIC;
     } else {
         $code = 'return $this->' . $this->methodName . '(' . yTest_Signature::getArgsForSimpleCall($this->methodName, $this->className) . ');';
     }
     yTest_debugCC("PARAMS: {$params}", "CODE: {$code}");
     runkit_method_add($this->className, $this->delegateName, $params, $code, $runkitFlags);
 }
Пример #9
0
 /**
  * Apply a mutation to the relevant file
  *
  * @param MutantInterface $mutant
  *
  * @throws \Exception
  */
 public function applyMutation(MutantInterface $mutant)
 {
     $class = $mutant->getClassName();
     $method = $mutant->getMethodName();
     $args = $mutant->getArguments();
     $filename = $mutant->getFileName();
     require_once $filename;
     $newBlock = $mutant->mutate();
     $this->_methodPreserveCode = md5($method);
     if (runkit_method_rename($class, $method, $method . $this->_methodPreserveCode) == false) {
         throw new \Exception('runkit_method_rename() failed from ' . $class . '::' . $method . ' to ' . $class . '::' . $method . $this->_methodPreserveCode . ' (mutation application)');
     }
     if (runkit_method_add($class, $method, $args, $newBlock, $this->getMethodFlags($mutant)) == false) {
         throw new \Exception('runkit_method_add() failed when replacing original ' . $class . '::' . $method . '(' . var_export($args) . ') with a mutation of' . ' type ' . get_class($mutant->getMutation()) . ' using the' . ' following (mutated) source code from ' . $filename . ':' . PHP_EOL . $newBlock);
     }
 }
Пример #10
0
 function setup()
 {
     global $conf;
     // set purge to avoid trying to retrieve from cache
     $this->purge = isset($_REQUEST['purge']) ? $_REQUEST['purge'] : null;
     $_REQUEST['purge'] = 1;
     if (!isset($conf['cachedir'])) {
         $conf['cachedir'] = '';
         $this->cachedir = false;
     } else {
         $this->cachedir = true;
     }
     if (function_exists('io_makefiledir')) {
         runkit_function_rename('io_makefiledir', 'io_makefiledir_real');
     }
     runkit_function_rename('xhtml_htmlphp_test_io_makefiledir', 'io_makefiledir');
     if (function_exists('io_savefile')) {
         runkit_function_rename('io_savefile', 'io_savefile_real');
     }
     runkit_function_rename('xhtml_htmlphp_test_io_savefile', 'io_savefile');
     runkit_method_rename('GeSHi', 'parse_code', 'parse_code_real');
     runkit_method_add('GeSHi', 'parse_code', '', '{ return hsc($this->source); }');
     parent::setup();
 }
Пример #11
0
 protected function updateState($type, $id, $state)
 {
     $parts = explode('|', $id);
     switch ($type) {
         case self::STATIC_METHOD:
         case self::DYNAMIC_METHOD:
             $className = $parts[1];
             $methodName = $parts[2];
             $savedName = self::SAVED_PREFIX . $methodName;
             if ($state) {
                 // enable
                 is_callable("{$className}::{$methodName}");
                 $flags = RUNKIT_ACC_PUBLIC | ($type == self::STATIC_METHOD ? RUNKIT_ACC_STATIC : 0);
                 runkit_method_rename($className, $methodName, $savedName);
                 // save the original method
                 runkit_method_add($className, $methodName, '', $this->getExecuteCallCode($type, $id, $type === self::DYNAMIC_METHOD), $flags);
             } else {
                 // diable
                 runkit_method_remove($className, $methodName);
                 // remove the redefined instance
                 runkit_method_rename($className, $savedName, $methodName);
                 // restore the original
             }
             break;
         case self::GLOBAL_FUNCTION:
             $functionName = $parts[1];
             list($namespace, $baseName) = self::parseGlobalFunctionName($functionName);
             $functionName = $namespace . $baseName;
             $savedName = $namespace . self::SAVED_PREFIX . $baseName;
             if ($state) {
                 // enable
                 $tempName = "WikiaMockProxyTempFuncName";
                 // workaround for namespaces functions
                 runkit_function_rename($functionName, $savedName);
                 runkit_function_add($tempName, '', $this->getExecuteCallCode($type, $id));
                 runkit_function_rename($tempName, $functionName);
             } else {
                 // disable
                 runkit_function_remove($functionName);
                 // remove the redefined instance
                 runkit_function_rename($savedName, $functionName);
                 // restore the original
             }
             break;
     }
 }
 /**
  * Added the information of the pseudo implementation
  *
  * @param string $method_name
  * @param callable $func anonymous function
  * @return $this
  * @throws MethodNotFoundException
  */
 public function addMethod($method_name, \Closure $func)
 {
     if (!method_exists($this->class_name, $method_name)) {
         throw new MethodNotFoundException("{$this->class_name} doesn't have such a method ({$method_name})");
     }
     $this->methods[$method_name] = $func;
     /**
      * Stash the original implementation temporarily as a method of different name.
      * Need to check the existence of stashed method not to write psuedo implementation
      * twice and forget the original implementation
      */
     if (!$this->stashedMethodExists($method_name)) {
         runkit_method_rename($this->class_name, $method_name, $this->getStashedMethodName($method_name));
     } else {
         runkit_method_remove($this->class_name, $method_name);
     }
     $code = $this->getFakeCode($this->class_name, $method_name);
     runkit_method_add($this->class_name, $method_name, '', $code, RUNKIT_ACC_STATIC);
     return $this;
 }
Пример #13
0
 /**
  * Redefine constructor of the class.
  * Note: loading (including) any of classes, extending this one will fail
  * with fatal error, so pre-loading is needed.
  *
  * @param string $class - name of the class to redefine constructor in
  * @param string $args - comma-seperated list of arguments
  * @param string $body -  body of method
  * @param int $access - any of RUNKIT_ACC_* constants
  */
 public function redefineConstructor($class, $args, $code, $access = RUNKIT_ACC_PUBLIC)
 {
     $this->loadClass($class);
     $backupMethod = $this->getBackupName(self::CONSTRUCTOR);
     try {
         $this->checkMethodNotDefined($class, $backupMethod);
     } catch (PStub_RunkitAdapter_Exception $e) {
         throw new PStub_RunkitAdapter_Exception('Constructor of the class ' . $class . ' can not be redefined more than once');
     }
     $tempMethod = $this->getTempName(self::CONSTRUCTOR);
     // this is a workaround for runkit bugs, just redefing won't work
     runkit_method_rename($class, self::CONSTRUCTOR, $backupMethod);
     runkit_method_add($class, $tempMethod, $args, $code, $access);
     runkit_method_rename($class, $tempMethod, self::CONSTRUCTOR);
 }