/** * Exports the PHP code * * @return string */ public function exportCode() { $code_lines = array(); $code_lines[] = '<?php'; // Export the namespace if ($this->_reflection_class->getNamespaceName()) { $code_lines[] = ''; $code_lines[] = 'namespace ' . $this->_reflection_class->getNamespaceName() . ';'; $code_lines[] = ''; } // Export the class' signature $code_lines[] = sprintf('%s%s%s %s%s%s', $this->_reflection_class->isAbstract() ? 'abstract ' : '', $this->_reflection_class->isFinal() ? 'final ' : '', $this->_reflection_class->isInterface() ? 'interface' : ($this->_reflection_class->isTrait() ? 'trait' : 'class'), $this->getClassName(), $this->_getParentClassName() ? " extends {$this->_getParentClassName()}" : '', $this->_getInterfaceNames() ? " implements " . join(', ', $this->_getInterfaceNames()) : ''); $code_lines[] = '{'; $code_lines[] = ''; // Export constants foreach ($this->_reflection_class->getConstants() as $name => $value) { $reflection_constant = new ReflectionConstant($name, $value); $code_lines[] = "\t" . $reflection_constant->exportCode(); $code_lines[] = ''; } // Export properties foreach ($this->_reflection_class->getProperties() as $property) { $reflection_property = new ReflectionProperty($property); $code_lines[] = "\t" . $reflection_property->exportCode(); $code_lines[] = ''; } // Export methods foreach ($this->_reflection_class->getMethods() as $method) { $reflection_method = new ReflectionMethod($method); $code_lines[] = "\t" . $reflection_method->exportCode(); $code_lines[] = ''; } $code_lines[] = '}'; return join("\n", $code_lines); }
/** * Get current object type * @return string - class/trait/interface */ public function getType() { if ($this->reflectionClass->isInterface()) { return 'interface'; } if (method_exists($this->reflectionClass, 'isTrait') && $this->reflectionClass->isTrait()) { return 'trait'; } return 'class'; }
/** * @param \Donquixote\HastyReflectionCommon\Canvas\ClassIndex\ClassIndexInterface $classIndex * @param string $class * * @dataProvider provideClassIndexArgs() */ function testClassIndex(ClassIndexInterface $classIndex, $class) { $classReflection = $classIndex->classGetReflection($class); $reflectionClass = new \ReflectionClass($class); // Test identity. $this->assertTrue($classReflection === $classIndex->classGetReflection($class)); // Test class type/info. $expectedIsClass = !$reflectionClass->isInterface() && !$reflectionClass->isTrait(); $this->assertEquals($reflectionClass->getName(), $classReflection->getName()); $this->assertEquals($reflectionClass->getShortName(), $classReflection->getShortName()); $this->assertEquals($reflectionClass->getDocComment(), $classReflection->getDocComment()); $this->assertEquals($reflectionClass->isInterface(), $classReflection->isInterface()); $this->assertEquals($reflectionClass->isTrait(), $classReflection->isTrait()); $this->assertEquals($expectedIsClass, $classReflection->isClass()); $this->assertEquals($reflectionClass->isAbstract() && $expectedIsClass, $classReflection->isAbstractClass()); // Test context. $this->assertEquals($reflectionClass->getNamespaceName(), $classReflection->getNamespaceUseContext()->getNamespaceName()); // Test interfaces foreach ($classReflection->getOwnInterfaces() as $interfaceName => $interfaceReflection) { $this->assertTrue($reflectionClass->implementsInterface($interfaceName)); } foreach ($reflectionClass->getInterfaceNames() as $interfaceName) { $this->assertTrue($classReflection->extendsOrImplementsInterface($interfaceName, FALSE)); } $expectedAllInterfaceNames = $expectedAllAndSelfInterfaceNames = $reflectionClass->getInterfaceNames(); if ($reflectionClass->isInterface()) { array_unshift($expectedAllAndSelfInterfaceNames, $class); } $this->assertEqualSorted($expectedAllAndSelfInterfaceNames, array_keys($classReflection->getAllInterfaces(TRUE))); $this->assertEqualSorted($expectedAllInterfaceNames, array_keys($classReflection->getAllInterfaces(FALSE))); $expectedMethodNames = array(); $expectedOwnMethodNames = array(); foreach ($reflectionClass->getMethods() as $method) { $expectedMethodNames[] = $method->getName(); if ($method->getDeclaringClass()->getName() === $reflectionClass->getName()) { $expectedOwnMethodNames[] = $method->getName(); } } $this->assertEquals($expectedOwnMethodNames, array_keys($classReflection->getOwnMethods())); $this->assertEqualSorted($expectedMethodNames, array_keys($classReflection->getMethods())); $methodReflections = $classReflection->getMethods(); foreach ($reflectionClass->getMethods() as $reflectionMethod) { $methodReflection = $methodReflections[$reflectionMethod->getShortName()]; $this->assertEqualMethods($reflectionMethod, $methodReflection); } // isAbstract() is a beast, so we test it least. $this->assertEquals($reflectionClass->isAbstract(), $classReflection->isAbstract()); }
/** * Check if all classes given by the cli are instantiable. */ public function run() { $classNames = array_keys($this->_args); //No classes given if (!$classNames) { exit(1); } //Perform single checks for the classes foreach ($classNames as $className) { $reflectionClass = new ReflectionClass($className); //Is an interface? if ($reflectionClass->isInterface()) { echo "Interface"; exit(1); } //Is an abstract class? if ($reflectionClass->isAbstract()) { echo "Abstract"; exit(1); } //Is a trait? if ($reflectionClass->isTrait()) { echo "Trait"; exit(1); } //Can create the class with new? if (!$reflectionClass->isInstantiable()) { echo "Not instantiable"; exit(1); } } echo 'Done'; }
/** * @testdox Uses the ListenerAggregateTrait from the Zend Framework */ public function testUsesZfListenerAggregateTrait() { $reflection = new \ReflectionClass('\\Core\\EventManager\\ListenerAggregateTrait'); $traits = $reflection->getTraitNames(); $this->assertTrue($reflection->isTrait()); $this->assertEquals(['Zend\\EventManager\\ListenerAggregateTrait'], $traits); }
public function __construct(\ReflectionClass $interface) { if (!$interface->isInterface() || $interface->isTrait()) { throw new \InvalidArgumentException('Only interfaces supported'); } parent::__construct($interface); }
/** * @param \ReflectionClass|string * @return self */ public static function from($from) { $from = new \ReflectionClass($from instanceof \ReflectionClass ? $from->getName() : $from); if (PHP_VERSION_ID >= 70000 && $from->isAnonymous()) { $class = new static('anonymous'); } else { $class = new static($from->getShortName(), new PhpNamespace($from->getNamespaceName())); } $class->type = $from->isInterface() ? 'interface' : (PHP_VERSION_ID >= 50400 && $from->isTrait() ? 'trait' : 'class'); $class->final = $from->isFinal() && $class->type === 'class'; $class->abstract = $from->isAbstract() && $class->type === 'class'; $class->implements = $from->getInterfaceNames(); $class->documents = $from->getDocComment() ? array(preg_replace('#^\\s*\\* ?#m', '', trim($from->getDocComment(), "/* \r\n\t"))) : array(); if ($from->getParentClass()) { $class->extends = $from->getParentClass()->getName(); $class->implements = array_diff($class->implements, $from->getParentClass()->getInterfaceNames()); } foreach ($from->getProperties() as $prop) { if ($prop->getDeclaringClass()->getName() === $from->getName()) { $class->properties[$prop->getName()] = Property::from($prop); } } foreach ($from->getMethods() as $method) { if ($method->getDeclaringClass()->getName() === $from->getName()) { $class->methods[$method->getName()] = Method::from($method)->setNamespace($class->namespace); } } return $class; }
protected function addTrait($fqcn) { $added = new \ReflectionClass($fqcn); if (!$added->isTrait()) { throw new \LogicException("{$fqcn} is not a trait"); } $this->traitList[] = $added; }
/** * Check if given class targeted by locator. * * @param \ReflectionClass $class * @param \ReflectionClass|null $target * @return bool */ protected function isTargeted(\ReflectionClass $class, \ReflectionClass $target = null) { if (empty($target)) { return true; } if (!$target->isTrait()) { //Target is interface or class return $class->isSubclassOf($target) || $class->getName() == $target->getName(); } //Checking using traits return in_array($target->getName(), $this->getTraits($class->getName())); }
public static function createFromReflectionClass(\ReflectionClass $class) { if ($class->isInterface()) { return new ReflectedInterface($class); } else { if ($class->isTrait()) { throw new \InvalidArgumentException('Traits are not supported'); } else { return new ReflectedClass($class); } } }
/** Given the name of a method and a ReflectionClass, either returns a ReflectionMethod if the method was defined in that specific class, or returns false. */ protected function getImmediateMethod($methodName, \ReflectionClass $class, \ReflectionClass &$instanceClass = null) { if ($this->includeTraits) { if ($class->isTrait()) { $methodName = $this->getTraitMethodPrefix($class) . $methodName; } else { $instanceClass = $class; } } $useClass = $instanceClass ?: $class; $method = $useClass->hasMethod($methodName) ? $useClass->getMethod($methodName) : false; return $method && $useClass->name === $method->getDeclaringClass()->name ? $method : false; }
public function getPHPUnitMockObjectFor($className, array $methods) { $rc = new \ReflectionClass($className); $mockObject = null; if ($rc->isInterface()) { $mockObject = $this->testCase->getMockBuilder($className)->getMock(); } elseif ($rc->isAbstract()) { $mockObject = $this->testCase->getMockBuilder($className)->disableOriginalConstructor()->setMethods($methods)->getMockForAbstractClass(); } elseif ($rc->isTrait()) { $mockObject = $this->testCase->getMockBuilder($className)->disableOriginalConstructor()->setMethods($methods)->getMockForTrait(); } else { $mockObject = $this->testCase->getMockBuilder($className)->disableOriginalConstructor()->disableOriginalClone()->disableArgumentCloning()->disallowMockingUnknownTypes()->getMock(); } return $mockObject; }
/** * Get all DBAL types inside the $folder using the $namespace * * @param string $path The real path to the DBAL types directory * * @return array */ protected function getDBALTypes($path) { //find for .php files and load automatically $finder = new Finder(); $finder->files()->name('*.php')->in($path); $types = []; /** @var SplFileInfo $file */ foreach ($finder as $file) { $class = ClassUtils::getFileClassName($file->getRealPath()); $reflectionClass = new \ReflectionClass($class); if ($reflectionClass->isSubclassOf('Doctrine\\DBAL\\Types\\Type') && !$reflectionClass->isAbstract() && !$reflectionClass->isTrait()) { $name = $reflectionClass->newInstanceWithoutConstructor()->getName(); $types[$name] = $reflectionClass->getName(); } } return $types; }
public function actionExport($args) { printf("Exporting ORM structures...\n\n"); $orm_dirs = \Gini\Core::pharFilePaths(CLASS_DIR, 'Gini/ORM'); foreach ($orm_dirs as $orm_dir) { if (!is_dir($orm_dir)) { continue; } \Gini\File::eachFilesIn($orm_dir, function ($file) use($orm_dir) { $oname = strtolower(preg_replace('|.php$|', '', $file)); if ($oname == 'object') { return; } $class_name = '\\Gini\\ORM\\' . str_replace('/', '\\', $oname); // Check if it is abstract class $rc = new \ReflectionClass($class_name); if ($rc->isAbstract() || $rc->isTrait() || $rc->isInterface()) { return; } printf(" %s\n", $oname); $o = \Gini\IoC::construct($class_name); $structure = $o->structure(); // unset system fields unset($structure['id']); unset($structure['_extra']); $i = 1; $max = count($structure); foreach ($structure as $k => $v) { if ($i == $max) { break; } printf(" ├─ %s (%s)\n", $k, implode(',', array_map(function ($k, $v) { return $v ? "{$k}:{$v}" : $k; }, array_keys($v), $v))); ++$i; } printf(" └─ %s (%s)\n\n", $k, implode(',', array_map(function ($k, $v) { return $v ? "{$k}:{$v}" : $k; }, array_keys($v), $v))); }); } }
/** * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function getExistingClasses(array $paths) : array { $namespaceList = []; $classList = []; $list = []; foreach ($paths as $path) { if (false === $path->isSourceCode()) { continue; } $iter = new ClassIterator($this->getPhpFiles($path->getPathBase())); foreach (array_keys($iter->getClassMap()) as $classname) { if (in_array(substr($classname, -4), ['Test', 'Spec'])) { continue; } $reflection = new \ReflectionClass($classname); if ($reflection->isAbstract() || $reflection->isTrait() || $reflection->isInterface()) { continue; } if ($reflection->inNamespace()) { $namespaces = explode('\\', $reflection->getNamespaceName()); $namespace = ''; foreach ($namespaces as $key => $namespacePart) { if ($namespace !== '') { $namespace .= '/'; } $namespace .= $namespacePart; if (!array_key_exists($key, $namespaceList)) { $namespaceList[$key] = []; } $namespaceList[$key][$namespace] = $namespace; } } $escapedName = str_replace('\\', '/', $classname); $classList[$escapedName] = $escapedName; } } foreach ($namespaceList as $namespaceDepthList) { $list = array_merge($list, $namespaceDepthList); } $list = array_merge($list, $classList); return $list; }
public function run($args) { if (!isset($args['dir']) || !is_dir($args['dir'])) { throw new \InvalidArgumentException('need dir'); } $root = getcwd(); $dotScruitPath = "{$root}/.scruit"; $handle = opendir($args['dir']); $commands = null; if (is_file($dotScruitPath)) { $commands = (require $dotScruitPath); } else { $commands = array(); } while ($fn = readdir($handle)) { if ($fn === '.' || $fn === '..' || substr($fn, -4) !== '.php') { continue; } $path = "{$args['dir']}/{$fn}"; require_once $path; $info = pathinfo($path); $className = null; if (preg_match('#namespace +(\\S+);#', file_get_contents($path), $tmp)) { $className = $tmp[1] . '\\' . $info['filename']; } else { $className = $info['filename']; } $clazz = new \ReflectionClass($className); if ($clazz->implementsInterface('Scruit\\Runnable') && !$clazz->isAbstract() && !$clazz->isInterface() && !$clazz->isTrait()) { $obj = $clazz->newInstance(); $commands[$obj->getName()] = $clazz->getName(); } } file_put_contents($dotScruitPath, "<?php\n" . 'return ' . var_export($commands, true) . ';'); print "generated:{$dotScruitPath}\n"; }
/** * @param CodeBase $code_base * A reference to the entire code base in which this * context exists * * @param ReflectionClass $class * A reflection class representing a builtin class. * * @return Clazz * A Class structural element representing the given named * builtin. */ public static function fromReflectionClass(CodeBase $code_base, \ReflectionClass $class) : Clazz { // Build a set of flags based on the constitution // of the built-in class $flags = 0; if ($class->isFinal()) { $flags = \ast\flags\CLASS_FINAL; } else { if ($class->isInterface()) { $flags = \ast\flags\CLASS_INTERFACE; } else { if ($class->isTrait()) { $flags = \ast\flags\CLASS_TRAIT; } } } if ($class->isAbstract()) { $flags |= \ast\flags\CLASS_ABSTRACT; } $context = new Context(); // Build a base class element $clazz = new Clazz($context, $class->getName(), UnionType::fromStringInContext($class->getName(), $context), $flags); // If this class has a parent class, add it to the // class info if ($parent_class = $class->getParentClass()) { $parent_class_fqsen = FullyQualifiedClassName::fromFullyQualifiedString('\\' . $parent_class->getName()); $clazz->setParentClassFQSEN($parent_class_fqsen); } foreach ($class->getDefaultProperties() as $name => $value) { // TODO: whats going on here? $reflection_property = new \ReflectionProperty($class->getName(), $name); $property = new Property($context->withClassFQSEN($clazz->getFQSEN()), $name, Type::fromObject($value)->asUnionType(), 0); $clazz->addProperty($code_base, $property); } foreach ($class->getInterfaceNames() as $name) { $clazz->addInterfaceClassFQSEN(FullyQualifiedClassName::fromFullyQualifiedString('\\' . $name)); } foreach ($class->getTraitNames() as $name) { $clazz->addTraitFQSEN(FullyQualifiedClassName::fromFullyQualifiedString('\\' . $name)); } foreach ($class->getConstants() as $name => $value) { $clazz->addConstant($code_base, new Constant($context, $name, Type::fromObject($value)->asUnionType(), 0)); } foreach ($class->getMethods() as $reflection_method) { $method_list = Method::methodListFromReflectionClassAndMethod($context->withClassFQSEN($clazz->getFQSEN()), $code_base, $class, $reflection_method); foreach ($method_list as $method) { $clazz->addMethod($code_base, $method); } } return $clazz; }
public function getTraitNames() { $ret = array(); foreach ($this->fetch('traits') as $name => $_) { $cls = new ReflectionClass($name); if ($cls->isTrait()) { $ret[] = $cls->getName(); } } return $ret; }
/** * @return bool */ public function isTrait() { return $this->reflectionClass->isTrait(); }
<?php class this_is_a_class { function class_func() { } } trait this_is_a_trait { function trait_func() { } } interface this_is_an_interface { function interface_func(); } $rclass = new ReflectionClass('this_is_a_class'); var_dump($rclass->isTrait()); $rtrait = new ReflectionClass('this_is_a_trait'); var_dump($rtrait->isTrait()); $rinterface = new ReflectionClass('this_is_an_interface'); var_dump($rinterface->isTrait());
/** * Returns if the class is a trait. * * @return boolean */ public function isTrait() { return NATIVE_TRAITS && parent::isTrait(); }
public function scan() { require_once $this->path; $ns = ""; $_ns = ""; $ns_bracket = false; $aliases = []; $tokens = new Tokenizer(FS::get($this->path)); while ($tokens->valid()) { if ($tokens->is(T_NAMESPACE)) { $ns = ""; $_ns = ""; $tokens->next(); if ($tokens->is(T_STRING)) { $ns = $this->_parseName($tokens); if ($tokens->is('{')) { $tokens->skip(); $ns_bracket = true; } else { $tokens->skipIf(';'); } $_ns = $ns . '\\'; } elseif ($tokens->is('{')) { $ns_bracket = true; $tokens->next(); } } elseif ($tokens->is(T_USE)) { do { $tokens->next(); $name = $this->_parseName($tokens); if ($tokens->is(T_AS)) { $aliases[$tokens->next()->get(T_STRING)] = $name; $tokens->next(); } else { if (strpos($name, '\\') === false) { $aliases[$name] = $name; } else { $aliases[ltrim('\\', strrchr($name, '\\'))] = $name; } } } while ($tokens->is(',')); $tokens->need(';')->next(); } elseif ($tokens->is(T_CONST)) { $name = $tokens->next()->get(T_STRING); $constant = new EntityConstant($_ns . $name); $constant->setValue(constant($_ns . $name)); $constant->setLine($this->line($tokens->getLine())); $this->constants[$_ns . $name] = $constant; $tokens->forwardTo(';')->next(); } elseif ($tokens->is(T_FUNCTION)) { $name = $tokens->next()->get(T_STRING); $function = new EntityFunction($_ns . $name); $function->setLine($this->line($tokens->getLine())); $function->setAliases($aliases); $this->parseCallable($function, new \ReflectionFunction($function->name)); $function->setBody($tokens->forwardTo('{')->getScope()); $tokens->next(); $this->functions[$function->name] = $function; } elseif ($tokens->is(T_FINAL, T_ABSTRACT, T_INTERFACE, T_TRAIT, T_CLASS)) { $tokens->forwardTo(T_STRING); $name = $tokens->current(); $class = new EntityClass($_ns . $name); $ref = new \ReflectionClass($class->name); $doc = $ref->getDocComment(); // if($name == "NamesInterface") { // drop($ref); // } if ($ref->isInterface()) { $class->addFlag(Flags::IS_INTERFACE); } elseif ($ref->isTrait()) { $class->addFlag(Flags::IS_TRAIT); } else { $class->addFlag(Flags::IS_CLASS); } if ($ref->isAbstract()) { $class->addFlag(Flags::IS_ABSTRACT); } elseif ($ref->isFinal()) { $class->addFlag(Flags::IS_FINAL); } if ($doc) { $info = ToolKit::parseDoc($doc); $class->setDescription($info['desc']); $class->addOptions($info['options']); } $class->setAliases($aliases); $class->setLine($this->line($tokens->getLine())); $tokens->next(); if ($tokens->is(T_EXTENDS)) { // process 'extends' keyword do { $tokens->next(); $root = $tokens->is(T_NS_SEPARATOR); $parent = $this->_parseName($tokens); if ($root) { // extends from root namespace $class->setParent($parent, $class->isInterface()); } elseif (isset($aliases[$parent])) { $class->setParent($aliases[$parent], $class->isInterface()); } else { $class->setParent($_ns . $parent, $class->isInterface()); } } while ($tokens->is(',')); } if ($tokens->is(T_IMPLEMENTS)) { // process 'implements' keyword do { $tokens->next(); $root = $tokens->is(T_NS_SEPARATOR); $parent = $this->_parseName($tokens); if ($root) { // extends from root namespace $class->addInterface($parent); } elseif (isset($aliases[$parent])) { $class->addInterface($aliases[$parent]); } else { $class->addInterface($_ns . $parent); } } while ($tokens->is(',')); } $tokens->forwardTo('{')->next(); while ($tokens->forwardTo(T_CONST, T_FUNCTION, '{', '}', T_VARIABLE) && $tokens->valid()) { switch ($tokens->key()) { case T_CONST: $constant = new EntityConstant($class->name . '::' . $tokens->next()->get(T_STRING)); $constant->setValue(constant($constant->name)); $constant->setLine(new Line($this, $tokens->getLine())); $class->addConstant($constant); break; case T_VARIABLE: $property = new EntityProperty(ltrim($tokens->getAndNext(), '$')); $ref = new \ReflectionProperty($class->name, $property->name); $doc = $ref->getDocComment(); if ($doc) { $property->setDescription(ToolKit::parseDoc($doc)['desc']); } if ($ref->isPrivate()) { $property->addFlag(Flags::IS_PRIVATE); } elseif ($ref->isProtected()) { $property->addFlag(Flags::IS_PROTECTED); } else { $property->addFlag(Flags::IS_PUBLIC); } if ($ref->isStatic()) { $property->addFlag(Flags::IS_STATIC); } if ($ref->isDefault()) { $property->setValue($ref->getDeclaringClass()->getDefaultProperties()[$property->name]); } $class->addProperty($property); break; case T_FUNCTION: $method = new EntityMethod($name . '::' . $tokens->next()->get(T_STRING)); $method->setLine($this->line($tokens->getLine())); $this->parseCallable($method, $ref = new \ReflectionMethod($class->name, $method->short)); if ($ref->isPrivate()) { $method->addFlag(Flags::IS_PRIVATE); } elseif ($ref->isProtected()) { $method->addFlag(Flags::IS_PROTECTED); } else { $method->addFlag(Flags::IS_PUBLIC); } if ($ref->isStatic()) { $method->addFlag(Flags::IS_STATIC); } if ($ref->isAbstract()) { $method->addFlag(Flags::IS_ABSTRACT); $method->addFlag(Flags::IS_ABSTRACT_IMPLICIT); } elseif ($ref->isFinal()) { $method->addFlag(Flags::IS_FINAL); } if (isset($method->options['deprecated'])) { $method->addFlag(Flags::IS_DEPRECATED); } $tokens->forwardTo(')')->next(); if ($tokens->is('{')) { $method_body = $tokens->getScope(); $method->setBody($method_body); } $tokens->next(); $class->addMethod($method); break; case '{': // use traits scope $tokens->forwardTo('}')->next(); break; case '}': // end of class $tokens->next(); $this->classes[$class->name] = $class; break 2; } } } elseif ($tokens->is('}') && $ns_bracket) { $tokens->next(); $ns_bracket = false; } else { drop($tokens->curr); if ($tokens->valid()) { throw new UnexpectedTokenException($tokens); } break; } } }
/** * @param ReflectionClass $rc * @return XRef_Class */ private function getClassByReflection(ReflectionClass $rc) { $class_name = $rc->getName(); if (!isset(self::$hasTraits)) { $rrc = new ReflectionClass("ReflectionClass"); self::$hasTraits = $rrc->hasMethod("isTrait"); } $c = new XRef_Class(); $c->index = -1; $c->nameIndex = -1; $c->bodyStarts = -1; $c->bodyEnds = -1; if ($rc->isInterface()) { $c->kind = T_INTERFACE; } elseif (self::$hasTraits && $rc->isTrait()) { $c->kind = T_TRAIT; } else { $c->kind = T_CLASS; } $c->name = $class_name; $parent_class = $rc->getParentClass(); $c->extends = $parent_class ? array($parent_class->getName()) : array(); $c->implements = $rc->getInterfaceNames(); $c->uses = self::$hasTraits ? $rc->getTraitNames() : array(); foreach ($rc->getMethods() as $rm) { $method_name = $rm->getName(); if (isset(self::$overrideInternalClasses[$class_name]) && isset(self::$overrideInternalClasses[$class_name][$method_name])) { $m = $this->getFunctionFromString(self::$overrideInternalClasses[$class_name][$method_name]); } else { $m = $this->getMethodByReflection($rm); } $m->className = $class_name; $c->methods[] = $m; } foreach ($rc->getConstants() as $name => $value) { $const = $this->getConstantByReflection($name); $const->className = $class_name; $c->constants[] = $const; } foreach ($rc->getProperties() as $rp) { $p = $this->getPropertyByReflection($rp); $p->className = $class_name; $c->properties[] = $p; } return $c; }
/** * @return ReflectionClass|NULL */ public function getDeclaringTrait() { return $this->declaringClass->isTrait() ? $this->declaringClass : NULL; }
/** * @param CodeBase $code_base * A reference to the entire code base in which this * context exists * * @param ReflectionClass $class * A reflection class representing a builtin class. * * @return Clazz * A Class structural element representing the given named * builtin. */ public static function fromReflectionClass(CodeBase $code_base, \ReflectionClass $class) : Clazz { // Build a set of flags based on the constitution // of the built-in class $flags = 0; if ($class->isFinal()) { $flags = \ast\flags\CLASS_FINAL; } elseif ($class->isInterface()) { $flags = \ast\flags\CLASS_INTERFACE; } elseif ($class->isTrait()) { $flags = \ast\flags\CLASS_TRAIT; } if ($class->isAbstract()) { $flags |= \ast\flags\CLASS_ABSTRACT; } $context = new Context(); $class_fqsen = FullyQualifiedClassName::fromStringInContext($class->getName(), $context); // Build a base class element $clazz = new Clazz($context, $class->getName(), UnionType::fromStringInContext($class->getName(), $context), $flags, $class_fqsen); // If this class has a parent class, add it to the // class info if ($parent_class = $class->getParentClass()) { $parent_class_fqsen = FullyQualifiedClassName::fromFullyQualifiedString('\\' . $parent_class->getName()); $parent_type = $parent_class_fqsen->asType(); $clazz->setParentType($parent_type); } // n.b.: public properties on internal classes don't get // listed via reflection until they're set unless // they have a default value. Therefore, we don't // bother iterating over `$class->getProperties()` // `$class->getStaticProperties()`. foreach ($class->getDefaultProperties() as $name => $value) { $property_context = $context->withScope(new ClassScope(new GlobalScope(), $clazz->getFQSEN())); $property_fqsen = FullyQualifiedPropertyName::make($clazz->getFQSEN(), $name); $property = new Property($property_context, $name, Type::fromObject($value)->asUnionType(), 0, $property_fqsen); $clazz->addProperty($code_base, $property, new None()); } foreach (UnionType::internalPropertyMapForClassName($clazz->getName()) as $property_name => $property_type_string) { $property_context = $context->withScope(new ClassScope(new GlobalScope(), $clazz->getFQSEN())); $property_type = UnionType::fromStringInContext($property_type_string, new Context()); $property_fqsen = FullyQualifiedPropertyName::make($clazz->getFQSEN(), $property_name); $property = new Property($property_context, $property_name, $property_type, 0, $property_fqsen); $clazz->addProperty($code_base, $property, new None()); } foreach ($class->getInterfaceNames() as $name) { $clazz->addInterfaceClassFQSEN(FullyQualifiedClassName::fromFullyQualifiedString('\\' . $name)); } foreach ($class->getTraitNames() as $name) { $clazz->addTraitFQSEN(FullyQualifiedClassName::fromFullyQualifiedString('\\' . $name)); } foreach ($class->getConstants() as $name => $value) { $constant_fqsen = FullyQualifiedClassConstantName::make($clazz->getFQSEN(), $name); $constant = new ClassConstant($context, $name, Type::fromObject($value)->asUnionType(), 0, $constant_fqsen); $clazz->addConstant($code_base, $constant); } foreach ($class->getMethods() as $reflection_method) { $method_context = $context->withScope(new ClassScope(new GlobalScope(), $clazz->getFQSEN())); $method_list = FunctionFactory::methodListFromReflectionClassAndMethod($method_context, $code_base, $class, $reflection_method); foreach ($method_list as $method) { $clazz->addMethod($code_base, $method, new None()); } } return $clazz; }
<?php trait Foo { public function someMethod() { } } class Bar { use Foo; public function someOtherMethod() { } } $rFoo = new ReflectionClass('Foo'); $rBar = new ReflectionClass('Bar'); var_dump($rFoo->isTrait()); var_dump($rBar->isTrait()); echo $rFoo; echo $rBar;
public function isTrait() : bool { return $this->reflection->isTrait(); }
/** * Returns class type. * * @param \ReflectionClass $class Class. * * @return integer */ protected function getClassType(\ReflectionClass $class) { if ($class->isInterface()) { return self::CLASS_TYPE_INTERFACE; } if ($class->isTrait()) { return self::CLASS_TYPE_TRAIT; } return self::CLASS_TYPE_CLASS; }
function add_class($class_name) { global $classes, $internal_arginfo; $lc = strtolower($class_name); $class = new \ReflectionClass($class_name); $flags = 0; if ($class->isFinal()) { $flags = \ast\flags\CLASS_FINAL; } else { if ($class->isInterface()) { $flags = \ast\flags\CLASS_INTERFACE; } else { if ($class->isTrait()) { $flags = \ast\flags\CLASS_TRAIT; } } } if ($class->isAbstract()) { $flags |= \ast\flags\CLASS_ABSTRACT; } $classes[$lc] = ['file' => 'internal', 'namespace' => $class->getNamespaceName(), 'conditional' => false, 'flags' => $flags, 'lineno' => 0, 'endLineno' => 0, 'name' => $class_name, 'docComment' => '', 'type' => '', 'traits' => []]; foreach ($class->getDefaultProperties() as $name => $value) { $prop = new \ReflectionProperty($class_name, $name); $classes[$lc]['properties'][strtolower($name)] = ['flags' => $prop->getModifiers(), 'name' => $name, 'lineno' => 0, 'value' => $value]; } $classes[$lc]['interfaces'] = $class->getInterfaceNames(); $classes[$lc]['traits'] = $class->getTraitNames(); $parents = []; $parent = $class->getParentClass(); if ($parent) { $temp = $class; while ($parent = $temp->getParentClass()) { $parents[] = $parent->getName(); $parents = array_merge($parents, $parent->getInterfaceNames()); $temp = $parent; } } $types = [$class_name]; $types = array_merge($types, $classes[$lc]['interfaces']); $types = array_merge($types, $parents); $classes[$lc]['type'] = implode('|', array_unique($types)); foreach ($class->getConstants() as $name => $value) { $classes[$lc]['constants'][strtolower($name)] = ['name' => $name, 'lineno' => 0, 'value' => $value]; } foreach ($class->getMethods() as $method) { $meth = new \ReflectionMethod($class_name, $method->name); $required = $meth->getNumberOfRequiredParameters(); $optional = $meth->getNumberOfParameters() - $required; $lmname = strtolower($method->name); $classes[$lc]['methods'][$lmname] = ['file' => 'internal', 'namespace' => $class->getNamespaceName(), 'conditional' => false, 'flags' => $meth->getModifiers(), 'lineno' => 0, 'endLineno' => 0, 'name' => $method->name, 'docComment' => '', 'required' => $required, 'optional' => $optional, 'ret' => null]; $arginfo = null; if (!empty($internal_arginfo["{$class_name}::{$method->name}"])) { $arginfo = $internal_arginfo["{$class_name}::{$method->name}"]; $classes[$lc]['methods'][$lmname]['ret'] = $arginfo[0]; } foreach ($method->getParameters() as $param) { $flags = 0; if ($param->isPassedByReference()) { $flags |= \ast\flags\PARAM_REF; } if ($param->isVariadic()) { $flags |= \ast\flags\PARAM_VARIADIC; } $classes[$lc]['methods'][strtolower($method->name)]['params'][] = ['file' => 'internal', 'flags' => $flags, 'lineno' => 0, 'name' => $param->name, 'type' => empty($arginfo) ? null : next($arginfo), 'def' => null]; } } }
/** * Calls the class constructor * * If the class $class has the method public static $constructor, it * will be called. * * @param String $class A class which might have a class constructor * @param String $constructorName the method name of the class constructor * * @return bool true if the class constructor was called */ public static function _callClassConstructor($class, $constructorName) { $reflectionClass = new \ReflectionClass($class); if (!$reflectionClass->hasMethod($constructorName)) { return false; } $constructor = $reflectionClass->getMethod($constructorName); if (!$constructor->isStatic()) { return false; } if (\version_compare(PHP_VERSION, "5.4", '>=') && $reflectionClass->isTrait()) { return false; } if ($constructor->getDeclaringClass()->getName() != $reflectionClass->getName()) { return false; } $constructor->invoke(null); return true; }