/** * Adds the member from <var>$class</var> to <var>$data</var>. That means, inheritance is * performed. * * @param PC_Obj_Class $data the class to which the members should be added * @param string $class the class-name * @param boolean $overwrite just internal: whether the members should be overwritten */ private function add_members($data, $class, $overwrite = true) { $cobj = $this->env->get_types()->get_class($class); if ($cobj !== null) { if (strcasecmp($class, $data->get_name()) != 0) { // methods foreach ($cobj->get_methods() as $function) { if ($function->get_visibility() != PC_Obj_Visible::V_PRIVATE) { // if we don't want to overwrite the methods and the method is already there // we add just the types that are not known yet if (!$overwrite && ($f = $data->get_method($function->get_name())) !== null) { $changed = false; /* @var $f PC_Obj_Method */ if (!$f->has_return_doc()) { $f->set_return_type($function->get_return_type()); $f->set_has_return_doc($function->has_return_doc()); $changed = true; } // add missing throws foreach (array_keys($function->get_throws()) as $tclass) { if (!$f->contains_throw($tclass)) { $f->add_throw($tclass, PC_Obj_Method::THROW_PARENT); $changed = true; } } foreach ($function->get_params() as $param) { $fparam = $f->get_param($param->get_name()); // just replace the parameter if it exists and the type is unknown yet if ($fparam !== null && $fparam->get_mtype()->is_unknown()) { $f->put_param($param); $changed = true; } } if ($changed) { $this->env->get_storage()->update_function($f, $data->get_id()); } } else { $clone = clone $function; // change constructor-name, if it is an old-style-one if (strcasecmp($function->get_name(), $cobj->get_name()) == 0) { $clone->set_name($data->get_name()); } $clone->set_id($this->env->get_storage()->create_function($clone, $data->get_id())); $data->add_method($clone); } } } // fields foreach ($cobj->get_fields() as $field) { if ($field->get_visibility() != PC_Obj_Visible::V_PRIVATE) { $clone = clone $field; $data->add_field($clone); $this->env->get_storage()->create_field($clone, $data->get_id()); } } // constants foreach ($cobj->get_constants() as $const) { $clone = clone $const; $data->add_constant($clone); $this->env->get_storage()->create_constant($clone, $data->get_id()); } } // protect ourself from recursion here. in fact, Iterator implements itself, so that this is // actually necessary. if (strcasecmp($class, $cobj->get_super_class()) != 0) { $this->add_members($data, $cobj->get_super_class(), false); } foreach ($cobj->get_interfaces() as $interface) { if (strcasecmp($class, $interface) != 0) { $this->add_members($data, $interface, false); } } } }