/** * Registers a parent class or interface with this constant. * * @param ClassDescriptor|InterfaceDescriptor|null $parent * * @throws \InvalidArgumentException if anything other than a class, interface or null was passed. * * @return void */ public function setParent($parent) { if (!$parent instanceof ClassDescriptor && !$parent instanceof InterfaceDescriptor && $parent !== null) { throw new \InvalidArgumentException('Constants can only have an interface or class as parent'); } $this->setFullyQualifiedStructuralElementName($parent->getFullyQualifiedStructuralElementName() . '::' . $this->getName()); $this->parent = $parent; }
/** * Checks if the passed value is valid. * * @param FileDescriptor|ClassDescriptor|InterfaceDescriptor|TraitDescriptor $value The value that should * be validated. * @param Constraint $constraint The constraint for * the validation. * * @throws ConstraintDefinitionException if this is not a constraint on a PropertyDescriptor object. */ public function validate($value, Constraint $constraint) { if (!$value instanceof FileDescriptor && !$value instanceof ClassDescriptor && !$value instanceof InterfaceDescriptor && !$value instanceof TraitDescriptor) { throw new ConstraintDefinitionException('The HasSinglePackage validator may only be used on files, classes, interfaces and traits'); } if ($value->getTags()->get('package', new Collection())->count() > 1) { $this->context->addViolationAt('package', $constraint->message); } }
/** * Checks if the passed value is valid. * * @param FileDescriptor|ClassDescriptor|InterfaceDescriptor|TraitDescriptor $value The value that should * be validated. * @param Constraint $constraint The constraint for * the validation. * * @throws ConstraintDefinitionException if this is not a constraint on a PropertyDescriptor object. */ public function validate($value, Constraint $constraint) { if (!$value instanceof FileDescriptor && !$value instanceof ClassDescriptor && !$value instanceof InterfaceDescriptor && !$value instanceof TraitDescriptor) { throw new ConstraintDefinitionException('The HasPackageWithSubpackageValidator validator may only be used on files, classes, ' . 'interfaces and traits'); } if ($value->getTags()->get('subpackage', new Collection())->count() > 0 && $value->getTags()->get('package', new Collection())->count() < 1) { $this->context->addViolationAt('package', $constraint->message, array(), null, null, $constraint->code); } }
/** * @param ClassDescriptor $class * * @return MethodDescriptor[] */ public function getPublicMethods($class) { if (!$class instanceof ClassDescriptor) { return []; } $methods = $class->getMagicMethods()->merge($class->getInheritedMethods())->merge($class->getMethods()); return array_filter($methods->getAll(), function (MethodDescriptor $method) { return $method->getVisibility() == 'public'; }); }
/** * @covers phpDocumentor\Compiler\Pass\NamespaceTreeBuilder::execute * @covers phpDocumentor\Compiler\Pass\NamespaceTreeBuilder::addElementsOfTypeToNamespace */ public function testAddClassToNamespace() { $class = new ClassDescriptor(); $class->setNamespace('My\\Space'); $class->setFullyQualifiedStructuralElementName('My\\Space\\Class1'); $this->project->getFiles()->get(0)->getClasses()->add($class); // double check if a second class in the same deep namespace ends up at the right location $class2 = new ClassDescriptor(); $class2->setNamespace('My\\Space'); $class2->setFullyQualifiedStructuralElementName('My\\Space\\Class2'); $this->project->getFiles()->get(0)->getClasses()->add($class2); $this->fixture->execute($this->project); $this->assertSame(array($class, $class2), $this->project->getNamespace()->getChildren()->get('My')->getChildren()->get('Space')->getClasses()->getAll()); }
/** * @param ClassDescriptor|TraitDescriptor $parent */ public function setParent($parent) { $this->setFullyQualifiedStructuralElementName($parent->getFullyQualifiedStructuralElementName() . '::' . $this->getName()); $this->parent = $parent; }
/** * Returns a ClassDescriptor whose namespace and name is set. * * @param string $fqnn * @param string $className * * @return ClassDescriptor */ private function givenAClassWithNamespaceAndClassName($fqnn, $className) { $classDescriptor = new ClassDescriptor(); $classDescriptor->setFullyQualifiedStructuralElementName($fqnn . '\\' . $className); $classDescriptor->setNamespace($fqnn); $classDescriptor->setName($className); return $classDescriptor; }
/** * @param string $name The name of the current property. * * @return PropertyDescriptor */ protected function whenFixtureHasPropertyInParentClassWithSameName($name) { $result = new PropertyDescriptor(); $result->setName($name); $parent = new ClassDescriptor(); $parent->getProperties()->set($name, $result); $class = new ClassDescriptor(); $class->setParent($parent); $this->fixture->setParent($class); return $result; }
/** * Exports the given reflection object to the parent XML element. * * This method creates a new child element on the given parent XML element * and takes the properties of the Reflection argument and sets the * elements and attributes on the child. * * If a child DOMElement is provided then the properties and attributes are * set on this but the child element is not appended onto the parent. This * is the responsibility of the invoker. Essentially this means that the * $parent argument is ignored in this case. * * @param \DOMElement $parent The parent element to augment. * @param ClassDescriptor $class The data source. * @param \DOMElement $child Optional: child element to use instead of creating a * new one on the $parent. * * @return void */ public function buildClass(\DOMElement $parent, ClassDescriptor $class, \DOMElement $child = null) { if (!$child) { $child = new \DOMElement('class'); $parent->appendChild($child); } $child->setAttribute('final', $class->isFinal() ? 'true' : 'false'); $child->setAttribute('abstract', $class->isAbstract() ? 'true' : 'false'); $parentFqcn = is_string($class->getParent()) ? $class->getParent() : $class->getParent()->getFullyQualifiedStructuralElementName(); $child->appendChild(new \DOMElement('extends', $parentFqcn)); /** @var InterfaceDescriptor $interface */ foreach ($class->getInterfaces() as $interface) { $interfaceFcqn = is_string($interface) ? $interface : $interface->getFullyQualifiedStructuralElementName(); $child->appendChild(new \DOMElement('implements', $interfaceFcqn)); } if ($child === null) { $child = new \DOMElement('interface'); $parent->appendChild($child); } $namespace = $class->getNamespace()->getFullyQualifiedStructuralElementName(); $child->setAttribute('namespace', ltrim($namespace, '\\')); $child->setAttribute('line', $class->getLine()); $child->appendChild(new \DOMElement('name', $class->getName())); $child->appendChild(new \DOMElement('full_name', $class->getFullyQualifiedStructuralElementName())); $this->buildDocBlock($child, $class); foreach ($class->getConstants() as $constant) { // TODO #840: Workaround; for some reason there are NULLs in the constants array. if ($constant) { $this->buildConstant($child, $constant); } } foreach ($class->getProperties() as $property) { // TODO #840: Workaround; for some reason there are NULLs in the properties array. if ($property) { $this->buildProperty($child, $property); } } foreach ($class->getMethods() as $method) { // TODO #840: Workaround; for some reason there are NULLs in the methods array. if ($method) { $this->buildMethod($child, $method); } } }
/** * Returns a class with the given parent set. * * @param string|DescriptorAbstract $parent * * @return ClassDescriptor */ protected function givenAClassWithParent($parent) { $classDescriptor1 = new ClassDescriptor(); $classDescriptor1->setParent($parent); return $classDescriptor1; }
/** * Test to cover magic method of parent abstract class * * @covers phpDocumentor\Descriptor\DescriptorAbstract::__call */ public function testCall() { $this->assertNull($this->fixture->notexisting()); $this->assertInstanceOf('phpDocumentor\\Descriptor\\Collection', $this->fixture->getNotexisting()); }
/** * Registers the used traits with the generated Class Descriptor. * * @param string[] $traits * @param ClassDescriptor $classDescriptor * * @return void */ protected function addUses(array $traits, ClassDescriptor $classDescriptor) { $classDescriptor->setUsedTraits(new Collection($traits)); }
/** * Generates a URL from the given node or returns false if unable. * * @param string|Descriptor\ClassDescriptor $node * * @return string|false */ public function __invoke($node) { $converter = new QualifiedNameToUrlConverter(); return $node instanceof Descriptor\DescriptorAbstract ? '/classes/' . $converter->fromClass($node->getFullyQualifiedStructuralElementName()) . '.html' : false; }
/** * @covers phpDocumentor\Compiler\Pass\ElementsIndexBuilder::execute * @covers phpDocumentor\Compiler\Pass\ElementsIndexBuilder::addElementsToIndexes * @covers phpDocumentor\Compiler\Pass\ElementsIndexBuilder::getIndexKey * @covers phpDocumentor\Compiler\Pass\ElementsIndexBuilder::getSubElements */ public function testAddMethodsToIndex() { $file1 = $this->project->getFiles()->get(0); $classDescriptor1 = new ClassDescriptor(); $classDescriptor1->setFullyQualifiedStructuralElementName('My\\Space\\Class1'); $file1->getClasses()->add($classDescriptor1); $classMethodDescriptor1 = new MethodDescriptor(); $classMethodDescriptor1->setFullyQualifiedStructuralElementName('My\\Space\\Class1::METHOD'); $classDescriptor1->getMethods()->add($classMethodDescriptor1); $file2 = $this->project->getFiles()->get(1); $classDescriptor2 = new ClassDescriptor(); $classDescriptor2->setFullyQualifiedStructuralElementName('My\\Space\\Class2'); $file2->getClasses()->add($classDescriptor2); $classMethodDescriptor2 = new MethodDescriptor(); $classMethodDescriptor2->setFullyQualifiedStructuralElementName('My\\Space\\Class2::METHOD'); $classDescriptor2->getMethods()->add($classMethodDescriptor2); $this->fixture->execute($this->project); $elements = $this->project->getIndexes()->get('elements')->getAll(); $this->assertCount(4, $elements); $this->assertSame(array('My\\Space\\Class1', 'My\\Space\\Class1::METHOD', 'My\\Space\\Class2', 'My\\Space\\Class2::METHOD'), array_keys($elements)); $this->assertSame(array($classDescriptor1, $classMethodDescriptor1, $classDescriptor2, $classMethodDescriptor2), array_values($elements)); // class methods are not indexed separately $this->assertNull($this->project->getIndexes()->get('methods')); }
/** * Adds a class descriptor to the project's elements and add a parent file. * * @param FileDescriptor $fileDescriptor * * @return ClassDescriptor */ protected function givenProjectHasClassDescriptorAssociatedWithFile($fileDescriptor) { $classDescriptor = new ClassDescriptor(); if ($fileDescriptor) { $classDescriptor->setFile($fileDescriptor); } $elementIndex = $this->project->getIndexes()->get('elements', new Collection()); $elementIndex->add($classDescriptor); return $classDescriptor; }
/** * Creates a Descriptor from the provided data. * * @param ClassReflector $data * * @return ClassDescriptor */ public function create($data) { $classDescriptor = new ClassDescriptor(); $classDescriptor->setFullyQualifiedStructuralElementName($data->getName()); $classDescriptor->setName($data->getShortName()); $classDescriptor->setPackage($this->extractPackageFromDocBlock($data->getDocBlock()) ?: ''); $classDescriptor->setLine($data->getLinenumber()); $classDescriptor->setParent($data->getParentClass()); $classDescriptor->setAbstract($data->isAbstract()); $classDescriptor->setFinal($data->isFinal()); // Reflection library formulates namespace as global but this is not wanted for phpDocumentor itself $classDescriptor->setNamespace('\\' . (strtolower($data->getNamespace()) == 'global' ? '' : $data->getNamespace())); foreach ($data->getInterfaces() as $interfaceClassName) { $classDescriptor->getInterfaces()->set($interfaceClassName, $interfaceClassName); } $fqcn = $classDescriptor->getFullyQualifiedStructuralElementName(); $namespace = substr($fqcn, 0, strrpos($fqcn, '\\')); $classDescriptor->setNamespace($namespace); $this->assembleDocBlock($data->getDocBlock(), $classDescriptor); $this->addConstants($data->getConstants(), $classDescriptor); $this->addProperties($data->getProperties(), $classDescriptor); $this->addMethods($data->getMethods(), $classDescriptor); return $classDescriptor; }
/** * @param string $name The name of the current method. * * @return MethodDescriptor */ protected function whenFixtureHasMethodInImplementedInterfaceWithSameName($name) { $result = new MethodDescriptor(); $result->setName($name); $parent = new InterfaceDescriptor(); $parent->getMethods()->set($name, $result); $class = new ClassDescriptor(); $class->getInterfaces()->set('Implemented', $parent); $this->fixture->setParent($class); return $result; }
/** * @return ClassDescriptor */ protected function whenFixtureHasParentClass() { $class = new ClassDescriptor(); $this->fixture->setParent($class); return $class; }