/** * Returns class' code inside namespace * * @param ClassReflection $class */ private function dumpClass(ClassReflection $class) { if (array_search($class->getName(), $this->cachedClasses) !== false) { return; } if ($class->isInternal()) { return; } if ($class->getParentClass()) { $this->dumpClass($class->getParentClass()); } foreach ($class->getInterfaces() as $interface) { $this->dumpClass($interface); } if ($class->getTraits()) { foreach ($class->getTraits() as $trait) { $this->dumpClass($trait); } } $classContents = $class->getContents(false); $classFileDir = dirname($class->getFileName()); $classContents = trim(str_replace('__DIR__', sprintf("'%s'", $classFileDir), $classContents)); $uses = implode("\n", $this->codeGenerator->getUseLines($class)); $this->cache[] = "namespace " . $class->getNamespaceName() . " {\n" . ($uses ? $uses . "\n" : '') . $this->codeGenerator->getDeclarationLine($class) . "\n" . $classContents . "\n}\n"; $this->cachedClasses[] = $class->getName(); }
public function testParentReturn() { $reflectionClass = new ClassReflection('ZendTest\\Code\\Reflection\\TestAsset\\TestSampleClass'); $parent = $reflectionClass->getParentClass(); $this->assertEquals('Zend\\Code\\Reflection\\ClassReflection', get_class($parent)); $this->assertEquals('ArrayObject', $parent->getName()); }
public function findPropertiesDefinedInClass(ClassReflection $class) { $parent = $class->getParentClass(); if (false === $parent) { return $this->findProperties($class); } return array_diff($this->findProperties($class), $this->findProperties($parent)); }
/** * Generate code to cache from class reflection. * This is a total mess, I know. Just wanted to flesh out the logic. * * @todo Refactor into a class, clean up logic, DRY it up, maybe move * some of this into Zend\Code * @param ClassReflection $r * @return string */ protected static function getCacheCode(ClassReflection $r) { $useString = ''; $usesNames = array(); if (count($uses = $r->getDeclaringFile()->getUses())) { foreach ($uses as $use) { $usesNames[$use['use']] = $use['as']; $useString .= "use {$use['use']}"; if ($use['as']) { $useString .= " as {$use['as']}"; } $useString .= ";\n"; } } $declaration = ''; if ($r->isAbstract() && !$r->isInterface()) { $declaration .= 'abstract '; } if ($r->isFinal()) { $declaration .= 'final '; } if ($r->isInterface()) { $declaration .= 'interface '; } if (!$r->isInterface()) { $declaration .= 'class '; } $declaration .= $r->getShortName(); $parentName = false; if (($parent = $r->getParentClass()) && $r->getNamespaceName()) { $parentName = array_key_exists($parent->getName(), $usesNames) ? $usesNames[$parent->getName()] ?: $parent->getShortName() : (0 === strpos($parent->getName(), $r->getNamespaceName()) ? substr($parent->getName(), strlen($r->getNamespaceName()) + 1) : '\\' . $parent->getName()); } else { if ($parent && !$r->getNamespaceName()) { $parentName = '\\' . $parent->getName(); } } if ($parentName) { $declaration .= " extends {$parentName}"; } $interfaces = array_diff($r->getInterfaceNames(), $parent ? $parent->getInterfaceNames() : array()); if (count($interfaces)) { foreach ($interfaces as $interface) { $iReflection = new ClassReflection($interface); $interfaces = array_diff($interfaces, $iReflection->getInterfaceNames()); } $declaration .= $r->isInterface() ? ' extends ' : ' implements '; $declaration .= implode(', ', array_map(function ($interface) use($usesNames, $r) { $iReflection = new ClassReflection($interface); return array_key_exists($iReflection->getName(), $usesNames) ? $usesNames[$iReflection->getName()] ?: $iReflection->getShortName() : (0 === strpos($iReflection->getName(), $r->getNamespaceName()) ? substr($iReflection->getName(), strlen($r->getNamespaceName()) + 1) : '\\' . $iReflection->getName()); }, $interfaces)); } $classContents = $r->getContents(false); $classFileDir = dirname($r->getFileName()); $classContents = trim(str_replace('__DIR__', sprintf("'%s'", $classFileDir), $classContents)); $return = "\nnamespace " . $r->getNamespaceName() . " {\n" . $useString . $declaration . "\n" . $classContents . "\n}\n"; return $return; }
private function getParentName(ClassReflection $classReflection) { $parentName = false; if (($parent = $classReflection->getParentClass()) && $classReflection->getNamespaceName()) { $parentName = $this->classUseNameService->getClassUseName($classReflection, $parent); } else { if ($parent && !$classReflection->getNamespaceName()) { $parentName = '\\' . $parent->getName(); } } return $parentName; }
/** * Build a Code Generation Php Object from a Class Reflection * * @param ClassReflection $classReflection * @return ClassGenerator */ public static function fromReflection(ClassReflection $classReflection) { $cg = new static($classReflection->getName()); $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $cg->setDocBlock(DocBlockGenerator::fromReflection($classReflection->getDocBlock())); } $cg->setAbstract($classReflection->isAbstract()); // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } /* @var \Zend\Code\Reflection\ClassReflection $parentClass */ $parentClass = $classReflection->getParentClass(); $interfaces = $classReflection->getInterfaces(); if ($parentClass) { $cg->setExtendedClass($parentClass->getName()); $interfaces = array_diff($interfaces, $parentClass->getInterfaces()); } $interfaceNames = array(); foreach ($interfaces as $interface) { /* @var \Zend\Code\Reflection\ClassReflection $interface */ $interfaceNames[] = $interface->getName(); } $cg->setImplementedInterfaces($interfaceNames); $properties = array(); foreach ($classReflection->getProperties() as $reflectionProperty) { if ($reflectionProperty->getDeclaringClass()->getName() == $classReflection->getName()) { $properties[] = PropertyGenerator::fromReflection($reflectionProperty); } } $cg->addProperties($properties); $constants = array(); foreach ($classReflection->getConstants() as $name => $value) { $constants[] = array('name' => $name, 'value' => $value); } $cg->addConstants($constants); $methods = array(); foreach ($classReflection->getMethods() as $reflectionMethod) { $className = $cg->getNamespaceName() ? $cg->getNamespaceName() . "\\" . $cg->getName() : $cg->getName(); if ($reflectionMethod->getDeclaringClass()->getName() == $className) { $methods[] = MethodGenerator::fromReflection($reflectionMethod); } } $cg->addMethods($methods); return $cg; }
/** * Retrieve a class's `implements` statement * * @param ClassReflection $reflection * @return string */ public function getInterfaceStatement(ClassReflection $reflection) { $interfaceStatement = ''; $parent = $reflection->getParentClass(); $interfaces = array_diff($reflection->getInterfaceNames(), $parent ? $parent->getInterfaceNames() : array()); if (!count($interfaces)) { return $interfaceStatement; } foreach ($interfaces as $interface) { $iReflection = new ClassReflection($interface); $interfaces = array_diff($interfaces, $iReflection->getInterfaceNames()); } $interfaceStatement .= $reflection->isInterface() ? ' extends ' : ' implements '; $classUseNameService = $this->classUseNameService; $interfaceStatement .= implode(', ', array_map(function ($interface) use($classUseNameService, $reflection) { $interfaceReflection = new ClassReflection($interface); return $classUseNameService->getClassUseName($reflection, $interfaceReflection); }, $interfaces)); return $interfaceStatement; }
/** * Build the interface part * * @param array $uses * @param Reflection\ClassReflection $class * @return string */ protected function buildInterface(&$uses, Reflection\ClassReflection $class) { $code = ''; $interfaces = $class->getInterfaces(); $parentClass = $class->getParentClass(); // Normalize interfaces array to string foreach ($interfaces as &$interface) { $interfaceReflections[$interface->getName()] = $interface; $interface = $interface->getName(); } // Remove interface from parent class if ($parentClass !== false) { $parentInterfaces = $parentClass->getInterfaces(); foreach ($parentInterfaces as &$parentInterface) { $interfaceReflections[$parentInterface->getName()] = $parentInterface; $parentInterface = $parentInterface->getName(); } $interfaces = array_diff($interfaces, $parentInterfaces); } // No interfaces found? Return '' if (count($interfaces) === 0) { return $code; } // Create extend/implement keyword $code .= $class->isInterface() ? ' extends ' : ' implements '; $classNamespace = $class->getNamespaceName(); // Retrieve interfaces from the interfaces foreach ($interfaces as &$interface) { $parentInterfaces = $interfaceReflections[$interface]->getInterfaces(); foreach ($parentInterfaces as &$parentInterface) { $interfaceReflections[$parentInterface->getName()] = $parentInterface; $parentInterface = $parentInterface->getName(); } // Remove already implemented interfaces $interfaces = array_diff($interfaces, $parentInterfaces); } // define interface names foreach ($interfaces as &$interface) { // Make sure the class has already been cached $this->processClassIntoCacheFile($interfaceReflections[$interface]); // Check if the interface has been defined in the uses if (array_key_exists($interface, $uses)) { // Set the use alias or the shortname when no alias has been set $interface = empty($uses[$interface]) ? $interfaceReflections[$interface]->getShortName() : $uses[$interface]; } else { // Check if we're implementing from a subnamespace $inNamespace = strpos($interface, $classNamespace) === 0; if ($inNamespace) { $interface = substr($interface, strlen($classNamespace) + 1); } else { $interface = "\\{$interface}"; } } } $code .= implode(', ', $interfaces); return $code; }
/** * fromReflection() - build a Code Generation Php Object from a Class Reflection * * @param ReflectionClass $classReflection * @return ClassGenerator */ public static function fromReflection(ClassReflection $classReflection) { // class generator $cg = new static($classReflection->getName()); $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $cg->setDocblock(DocblockGenerator::fromReflection($classReflection->getDocblock())); } $cg->setAbstract($classReflection->isAbstract()); // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } /* @var $parentClass \Zend\Code\Reflection\ReflectionClass */ if ($parentClass = $classReflection->getParentClass()) { $cg->setExtendedClass($parentClass->getName()); $interfaces = array_diff($classReflection->getInterfaces(), $parentClass->getInterfaces()); } else { $interfaces = $classReflection->getInterfaces(); } $interfaceNames = array(); foreach ($interfaces as $interface) { /* @var $interface \Zend\Code\Reflection\ReflectionClass */ $interfaceNames[] = $interface->getName(); } $cg->setImplementedInterfaces($interfaceNames); $properties = array(); foreach ($classReflection->getProperties() as $reflectionProperty) { /* @var $reflectionProperty \PropertyReflection\Code\Reflection\ReflectionProperty */ if ($reflectionProperty->getDeclaringClass()->getName() == $cg->getName()) { $properties[] = PropertyGenerator::fromReflection($reflectionProperty); } } $cg->setProperties($properties); $methods = array(); foreach ($classReflection->getMethods() as $reflectionMethod) { /* @var $reflectionMethod \MethodReflection\Code\Reflection\ReflectionMethod */ if ($reflectionMethod->getDeclaringClass()->getName() == $cg->getName()) { $methods[] = MethodGenerator::fromReflection($reflectionMethod); } } $cg->setMethods($methods); return $cg; }
/** * Copied from ClassGenerator::fromReflection and tweaked slightly * @param ClassReflection $classReflection * * @return ClassGenerator */ public function getGeneratorFromReflection(ClassReflection $classReflection) { // class generator $cg = new ClassGenerator($classReflection->getName()); $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $docblock = DocBlockGenerator::fromReflection($classReflection->getDocBlock()); $docblock->setIndentation(Generator::$indentation); $cg->setDocBlock($docblock); } $cg->setAbstract($classReflection->isAbstract()); // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } /* @var \Zend\Code\Reflection\ClassReflection $parentClass */ $parentClass = $classReflection->getParentClass(); if ($parentClass) { $cg->setExtendedClass('\\' . ltrim($parentClass->getName(), '\\')); $interfaces = array_diff($classReflection->getInterfaces(), $parentClass->getInterfaces()); } else { $interfaces = $classReflection->getInterfaces(); } $interfaceNames = array(); foreach ($interfaces as $interface) { /* @var \Zend\Code\Reflection\ClassReflection $interface */ $interfaceNames[] = $interface->getName(); } $cg->setImplementedInterfaces($interfaceNames); $properties = array(); foreach ($classReflection->getProperties() as $reflectionProperty) { if ($reflectionProperty->getDeclaringClass()->getName() == $classReflection->getName()) { $property = PropertyGenerator::fromReflection($reflectionProperty); $property->setIndentation(Generator::$indentation); $properties[] = $property; } } $cg->addProperties($properties); $methods = array(); foreach ($classReflection->getMethods() as $reflectionMethod) { $className = $cg->getNamespaceName() ? $cg->getNamespaceName() . "\\" . $cg->getName() : $cg->getName(); if ($reflectionMethod->getDeclaringClass()->getName() == $className) { $method = MethodGenerator::fromReflection($reflectionMethod); $method->setBody(preg_replace("/^\\s+/m", '', $method->getBody())); $method->setIndentation(Generator::$indentation); $methods[] = $method; } } $cg->addMethods($methods); return $cg; }