Exemplo n.º 1
0
 /**
  * Checks if the given method is "magic". If so it adds automatically parameter-types (if not
  * already set).
  * 
  * @param string $classname the class-name
  * @param PC_Obj_Method $method the method
  * @return bool true if handled
  */
 private function handle_magic($classname, $method)
 {
     // the magic-methods:
     // public void __set ( string $name , mixed $value )
     // public mixed __get ( string $name )
     // public bool __isset ( string $name )
     // public void __unset ( string $name )
     // public mixed __call ( string $name , array $arguments )
     // public mixed __callStatic ( string $name , array $arguments )
     // * array __sleep( void )
     // * void__wakeup( void )
     // public string __toString( void )
     // public void __invoke( ... )
     // public static object __set_state( array $props )
     // * void __clone( void )
     $ismagic = true;
     $visibility = PC_Obj_Visible::V_PUBLIC;
     $static = false;
     $expected = null;
     switch (strtolower($method->get_name())) {
         case '__set':
             $expected = array(new PC_Obj_Parameter('name', PC_Obj_MultiType::create_string()), new PC_Obj_Parameter('value', new PC_Obj_MultiType()));
             break;
         case '__isset':
         case '__unset':
         case '__get':
             $expected = array(new PC_Obj_Parameter('name', PC_Obj_MultiType::create_string()));
             break;
         case '__call':
         case '__callstatic':
             $expected = array(new PC_Obj_Parameter('name', PC_Obj_MultiType::create_string()), new PC_Obj_Parameter('arguments', PC_Obj_MultiType::create_array()));
             break;
         case '__tostring':
             $expected = array();
             break;
         case '__sleep':
         case '__wakeup':
         case '__clone':
             $visibility = null;
             // may be private or protected
             $expected = array();
             break;
         case '__invoke':
             $static = true;
             break;
         case '__set_state':
             $expected = array(new PC_Obj_Parameter('props', PC_Obj_MultiType::create_array()));
             break;
         default:
             $ismagic = false;
             break;
     }
     if (!$ismagic) {
         return false;
     }
     if ($visibility !== null && $method->get_visibility() != $visibility) {
         $this->report($method, 'The magic method "#' . $classname . '#::' . $method->get_name() . '" should be public', PC_Obj_Error::E_T_MAGIC_NOT_PUBLIC);
     }
     if ($static && !$method->is_static()) {
         $this->report($method, 'The magic method "#' . $classname . '#::' . $method->get_name() . '" should be static', PC_Obj_Error::E_T_MAGIC_NOT_STATIC);
     } else {
         if (!$static && $method->is_static()) {
             $this->report($method, 'The magic method "#' . $classname . '#::' . $method->get_name() . '" should not be static', PC_Obj_Error::E_T_MAGIC_IS_STATIC);
         }
     }
     if ($expected !== null) {
         $changed = false;
         if ($this->check_params($classname, $method, $expected, $method->get_params())) {
             // set parameter-descriptions
             $i = 0;
             foreach ($method->get_params() as $param) {
                 $param->set_mtype($expected[$i++]->get_mtype());
                 $param->set_has_doc(true);
                 $changed = true;
             }
         }
         $return = new PC_Obj_MultiType();
         switch (strtolower($method->get_name())) {
             case '__set':
             case '__unset':
             case '__wakeup':
             case '__clone':
                 $return = PC_Obj_MultiType::create_void();
                 break;
             case '__set_state':
                 $return = PC_Obj_MultiType::create_object();
                 break;
             case '__isset':
                 $return = PC_Obj_MultiType::create_bool();
                 break;
             case '__sleep':
                 $return = PC_Obj_MultiType::create_array();
                 break;
             case '__tostring':
                 $return = PC_Obj_MultiType::create_string();
                 break;
         }
         if ($method->has_return_doc() && !$this->env->get_types()->is_type_conforming($method->get_return_type(), $return)) {
             // its ok to specify a more specific return-value if the expected one is "mixed"
             if (!$return->is_unknown()) {
                 $this->report($method, 'The return-type of the magic-method "#' . $classname . '#::' . $method->get_name() . '" is invalid ' . '(expected="' . $return . '", found="' . $method->get_return_type() . '")', PC_Obj_Error::E_T_MAGIC_METHOD_RET_INVALID);
             }
         }
         if ($return !== null && !$method->has_return_doc()) {
             $method->set_return_type($return);
             $method->set_has_return_doc(true);
             $changed = true;
         }
         if ($changed) {
             $this->env->get_storage()->update_function($method, $method->get_class());
         }
     }
     return true;
 }
Exemplo n.º 2
0
 /**
  * Builds the fields to insert / update in the db
  *
  * @param PC_Obj_Method $function the function/method
  * @param int $class the id of the class the function belongs to
  * @param int $pid the project-id (default = current)
  * @return array all fields
  */
 private function get_fields($function, $class, $pid = PC_Project::CURRENT_ID)
 {
     $params = serialize($function->get_params());
     return array('project_id' => PC_UTils::get_project_id($pid), 'file' => $function->get_file(), 'line' => $function->get_line(), 'class' => $class, 'name' => $function->get_name(), 'abstract' => $function->is_abstract() ? 1 : 0, 'final' => $function->is_final() ? 1 : 0, 'static' => $function->is_static() ? 1 : 0, 'anonymous' => $function->is_anonymous() ? 1 : 0, 'visibility' => $function->get_visibility(), 'return_type' => serialize(array($function->has_return_doc(), $function->get_return_type())), 'throws' => serialize($function->get_throws()), 'params' => $params, 'min_version' => serialize($function->get_version()->get_min()), 'max_version' => serialize($function->get_version()->get_max()));
 }