/** * Returns all fields of the given class * * @param array $cids the class ids * @param int $pid the project-id (default = current) * @return array an array of PC_Obj_Field objects */ public function get_all($cids, $pid = PC_Project::CURRENT_ID) { $db = FWS_Props::get()->db(); if (!FWS_Array_Utils::is_integer($cids)) { FWS_Helper::def_error('intarray', 'cids', $cids); } if (count($cids) == 0) { return array(); } $stmt = $db->get_prepared_statement('SELECT * FROM ' . PC_TB_CLASS_FIELDS . ' WHERE project_id = :pid AND class IN (:cids)'); $stmt->bind(':pid', PC_Utils::get_project_id($pid)); $stmt->bind(':cids', $cids); $fields = array(); $rows = $db->get_rows($stmt->get_statement()); foreach ($rows as $row) { $field = new PC_Obj_Field($row['file'], $row['line'], $row['name'], unserialize($row['type']), $row['visibility'], $row['class']); $field->set_static($row['static']); $fields[] = $field; } return $fields; }
public function test_oop() { list(, $classes, $vars, $calls, $errors) = $this->analyze(self::$code); self::assert_equals(0, count($errors)); $a = $classes['a']; /* @var $a PC_Obj_Class */ self::assert_equals(false, $a->is_abstract()); self::assert_equals(false, $a->is_interface()); self::assert_equals(false, $a->is_final()); self::assert_equals(null, $a->get_super_class()); self::assert_equals(array(), $a->get_interfaces()); self::assert_equals((string) PC_Obj_MultiType::create_int(0), (string) $a->get_constant('c')->get_type()); self::assert_equals((string) PC_Obj_MultiType::create_int(4), (string) $a->get_constant('ME')->get_type()); self::assert_equals((string) PC_Obj_MultiType::create_string('str'), (string) $a->get_constant('YOU')->get_type()); self::assert_equals((string) new PC_Obj_Field('', 0, 'f', PC_Obj_MultiType::create_string('abc'), PC_Obj_Field::V_PRIVATE), (string) $a->get_field('f')); self::assert_equals((string) new PC_Obj_Field('', 0, 'foo', PC_Obj_MultiType::get_type_by_name('int|string'), PC_Obj_Field::V_PRIVATE), (string) $a->get_field('foo')); self::assert_equals((string) new PC_Obj_Field('', 0, 'bar', PC_Obj_MultiType::get_type_by_name('int|string'), PC_Obj_Field::V_PRIVATE), (string) $a->get_field('bar')); self::assert_equals((string) new PC_Obj_Field('', 0, 'a', PC_Obj_MultiType::create_string(), PC_Obj_Field::V_PRIVATE), (string) $a->get_field('a')); self::assert_equals((string) new PC_Obj_Field('', 0, 'b', PC_Obj_MultiType::create_string('a'), PC_Obj_Field::V_PRIVATE), (string) $a->get_field('b')); $array = PC_Obj_MultiType::create_array(array()); $array->get_first()->set_array_type(0, PC_Obj_MultiType::create_int(1)); $array->get_first()->set_array_type(1, PC_Obj_MultiType::create_int(2)); $array->get_first()->set_array_type(2, PC_Obj_MultiType::create_int(3)); self::assert_equals((string) new PC_Obj_Field('', 0, 'p', $array, PC_Obj_Field::V_PROTECTED), (string) $a->get_field('p')); self::assert_equals('public function __construct()', (string) $a->get_method('__construct')); self::assert_equals('protected function test(): void', (string) $a->get_method('test')); self::assert_equals('public function test2(a): a', (string) $a->get_method('test2')); $b = $classes['b']; /* @var $b PC_Obj_Class */ self::assert_equals(true, $b->is_abstract()); self::assert_equals(false, $b->is_interface()); self::assert_equals(false, $b->is_final()); self::assert_equals('a', $b->get_super_class()); self::assert_equals(array('i', 'j'), $b->get_interfaces()); self::assert_equals((string) PC_Obj_MultiType::create_int(0), (string) $b->get_constant('c')->get_type()); self::assert_equals(null, $b->get_field('f')); self::assert_equals((string) new PC_Obj_Field('', 0, 'p', $array, PC_Obj_Field::V_PROTECTED), (string) $b->get_field('p')); $i = $classes['i']; /* @var $i PC_Obj_Class */ self::assert_equals(true, $i->is_abstract()); self::assert_equals(true, $i->is_interface()); self::assert_equals(false, $i->is_final()); self::assert_equals(array('i1', 'i2'), $i->get_interfaces()); self::assert_equals('public abstract function doSomething(): string', (string) $i->get_method('doSomething')); $x = $classes['x']; /* @var $x PC_Obj_Class */ self::assert_equals(false, $x->is_abstract()); self::assert_equals(false, $x->is_interface()); self::assert_equals(true, $x->is_final()); self::assert_equals('b', $x->get_super_class()); self::assert_equals(array('i'), $x->get_interfaces()); self::assert_equals('public function doSomething(): string', (string) $x->get_method('doSomething')); self::assert_equals('public function test2(b): b', (string) $x->get_method('test2')); self::assert_equals('public static function mystatic(): void', (string) $x->get_method('mystatic')); $field = new PC_Obj_Field('', 0, 'var', PC_Obj_MultiType::create_int(4), PC_Obj_Field::V_PRIVATE); $field->set_static(true); self::assert_equals((string) $field, (string) $x->get_field('var')); $global = $vars[PC_Obj_Variable::SCOPE_GLOBAL]; self::assert_equals((string) PC_Obj_MultiType::create_int(0), (string) $global['a']->get_type()); self::assert_equals('a', (string) $global['b']->get_type()); self::assert_equals('a', (string) $global['c']->get_type()); self::assert_equals('x', (string) $global['d']->get_type()); self::assert_equals('b', (string) $global['e']->get_type()); self::assert_equals((string) PC_Obj_MultiType::create_int(4), (string) $global['f']->get_type()); self::assert_equals((string) PC_Obj_MultiType::create_int(1), (string) $global['g']->get_type()); self::assert_equals((string) PC_Obj_MultiType::create_int(4), (string) $global['h']->get_type()); self::assert_equals((string) PC_Obj_MultiType::create_object('b'), (string) $global['i']->get_type()); self::assert_equals((string) PC_Obj_MultiType::create_int(), (string) $global['j']->get_type()); self::assert_equals((string) PC_Obj_MultiType::create_string(), (string) $global['n']->get_type()); self::assert_equals((string) PC_Obj_MultiType::create_int(95), (string) $global['o']->get_type()); self::assert_equals((string) PC_Obj_MultiType::create_object('a'), (string) $global['q']->get_type()); self::assert_equals((string) PC_Obj_MultiType::create_object('b'), (string) $global['r']->get_type()); // check calls $i = 0; self::assert_equals((string) $calls[$i++], 'strstr(integer=4, string=str)'); self::assert_call($calls[$i++], 'b', 'get42', true); self::assert_call($calls[$i++], 'a', 'test', false); self::assert_equals((string) $calls[$i++], 'dummy(integer=2)'); self::assert_equals((string) $calls[$i++], 'dummy(integer=3)'); self::assert_equals((string) $calls[$i++], 'dummy(integer=6)'); self::assert_equals((string) $calls[$i++], 'dummy(unknown)'); self::assert_equals((string) $calls[$i++], 'dummy(unknown)'); self::assert_call($calls[$i++], 'a', '__construct', false); self::assert_call($calls[$i++], 'a', 'test2', false); self::assert_call($calls[$i++], 'x', '__construct', false); self::assert_call($calls[$i++], 'x', 'test2', false); self::assert_call($calls[$i++], 'x', 'test2', false); self::assert_call($calls[$i++], 'b', 'test2', false); self::assert_call($calls[$i++], 'b', 'sdf', true); self::assert_call($calls[$i++], 'x', 'partest', false); self::assert_call($calls[$i++], 'a', '__construct', false); self::assert_call($calls[$i++], 'x', '__construct', false); self::assert_call($calls[$i++], 'a', 'test2', false); self::assert_call($calls[$i++], 'x', 'test2', false); }
/** * Parses the type of a class-field from the given phpdoc * * @param PC_Obj_Field $field the field */ public function parse_field_doc($field) { if (isset($this->fieldComments[$field->get_name()])) { // if we already know the value, we don't have to use the phpdoc // TODO we could issue a warning here if the type differs if ($field->get_type()->is_unknown()) { $type = $this->parse_var_from($this->fieldComments[$field->get_name()]); if ($type !== null) { $field->set_type($type); } } unset($this->fieldComments[$field->get_name()]); } }
/** * Parses the given field-description * * @param string $desc the description * @return PC_Obj_Field|PC_Obj_Constant the field or constant * @throws PC_PHPRef_Exception if it fails */ public static function parse_field_desc($desc) { // prepare description $desc = trim(strip_tags($desc)); $desc = FWS_StringHelper::htmlspecialchars_back($desc); // filter out modifier, return-type, name and params $match = array(); $res = preg_match('/^(?:(const|readonly|static|public|protected|private)\\s*)?' . '(?:(const|readonly|static|public|protected|private)\\s*)?' . '(?:(const|readonly|static|public|protected|private)\\s*)?' . '(?:(\\S+)\\s+)?' . '\\$?([a-zA-Z0-9_:]+)\\s*(?:=\\s*([^' . "\n" . ';]+)\\s*)?;$/s', $desc, $match); if (!$res) { throw new PC_PHPRef_Exception('Unable to parse "' . $desc . '"'); } list(, $modifier1, $modifier2, $modifier3, $type, $name) = $match; if ($modifier1 == 'const' || $modifier2 == 'const' || $modifier3 == 'const') { $field = new PC_Obj_Constant('', 0, $name); } else { $field = new PC_Obj_Field('', 0, $name); if ($modifier1 == 'static' || $modifier2 == 'static' || $modifier3 == 'static') { $field->set_static(true); } if (in_array($modifier1, array('private', 'protected'))) { $field->set_visibility($modifier1); } else { if (in_array($modifier2, array('private', 'protected'))) { $field->set_visibility($modifier2); } else { if (in_array($modifier3, array('private', 'protected'))) { $field->set_visibility($modifier3); } } } } if ($type) { $field->set_type(PC_Obj_MultiType::get_type_by_name($type)); } if (isset($match[6]) && $match[6] !== '' && !$field->get_type()->is_multiple()) { if ($type) { $field->get_type()->get_first()->set_value($match[6]); } else { $field->set_type(new PC_Obj_MultiType(PC_Obj_Type::get_type_by_value($match[6]))); } } return $field; }