public function testParentClass() { $testsRoot = substr(__DIR__, 0, -strlen(__NAMESPACE__) - 1); $paths = array('Doctrine\\Tests' => array($testsRoot)); $noParentClassName = 'Doctrine\\Tests\\Common\\Reflection\\NoParent'; $staticReflectionParser = new StaticReflectionParser($noParentClassName, new Psr0FindFile($paths)); $declaringClassName = $staticReflectionParser->getStaticReflectionParserForDeclaringClass('property', 'test')->getClassName(); $this->assertEquals($noParentClassName, $declaringClassName); $className = 'Doctrine\\Tests\\Common\\Reflection\\FullyClassifiedParent'; $staticReflectionParser = new StaticReflectionParser($className, new Psr0FindFile($paths)); $declaringClassName = $staticReflectionParser->getStaticReflectionParserForDeclaringClass('property', 'test')->getClassName(); $this->assertEquals($noParentClassName, $declaringClassName); $className = 'Doctrine\\Tests\\Common\\Reflection\\SameNamespaceParent'; $staticReflectionParser = new StaticReflectionParser($className, new Psr0FindFile($paths)); $declaringClassName = $staticReflectionParser->getStaticReflectionParserForDeclaringClass('property', 'test')->getClassName(); $this->assertEquals($noParentClassName, $declaringClassName); $dummyParentClassName = 'Doctrine\\Tests\\Common\\Reflection\\Dummies\\NoParent'; $className = 'Doctrine\\Tests\\Common\\Reflection\\DeeperNamespaceParent'; $staticReflectionParser = new StaticReflectionParser($className, new Psr0FindFile($paths)); $declaringClassName = $staticReflectionParser->getStaticReflectionParserForDeclaringClass('property', 'test')->getClassName(); $this->assertEquals($dummyParentClassName, $declaringClassName); $className = 'Doctrine\\Tests\\Common\\Reflection\\UseParent'; $staticReflectionParser = new StaticReflectionParser($className, new Psr0FindFile($paths)); $declaringClassName = $staticReflectionParser->getStaticReflectionParserForDeclaringClass('property', 'test')->getClassName(); $this->assertEquals($dummyParentClassName, $declaringClassName); }
public function getReflectionClass() { $className = 'Doctrine\\Tests\\Common\\Annotations\\DummyClass'; $testsRoot = substr(__DIR__, 0, -strlen(__NAMESPACE__) - 1); $paths = array('Doctrine\\Tests' => array($testsRoot)); $staticReflectionParser = new StaticReflectionParser($className, new Psr0FindFile($paths)); return array('native' => array(new ReflectionClass($className)), 'static' => array($staticReflectionParser->getReflectionClass())); }
/** * If the current class extends another, get the parser for the latter. * * @param \Doctrine\Common\Reflection\StaticReflectionParser $parser * The current static parser. * @param $finder * The class finder. Must implement * \Doctrine\Common\Reflection\ClassFinderInterface, but can do so * implicitly (i.e., implements the interface's methods but not the actual * interface). * * @return static|null * The static parser for the parent if there's a parent class or NULL. */ public static function getParentParser(BaseStaticReflectionParser $parser, $finder) { // Ensure the class has been parsed before accessing the parentClassName // property. $parser->parse(); if ($parser->parentClassName) { return new static($parser->parentClassName, $finder, $parser->classAnnotationOptimize); } }
public static function getQueryDataFormInstance($controllerClassName) { $finder = new Psr4FindFile(['app' => [Yii::getAlias('@app')]]); $staticReflectionParser = new StaticReflectionParser($controllerClassName, $finder); $useStatements = $staticReflectionParser->getUseStatements(); if (isset($useStatements['querydataform']) && class_exists($useStatements['querydataform'])) { return new $useStatements['querydataform'](); } return null; }
/** * @dataProvider classAnnotationOptimize */ public function testClassAnnotationOptimizedParsing($classAnnotationOptimize) { $testsRoot = substr(__DIR__, 0, -strlen(__NAMESPACE__) - 1); $paths = array('Doctrine\\Tests' => array($testsRoot)); $staticReflectionParser = new StaticReflectionParser('Doctrine\\Tests\\Common\\Reflection\\ExampleAnnotationClass', new Psr0FindFile($paths), $classAnnotationOptimize); $expectedDocComment = '/** * @Annotation( * key = "value" * ) */'; $this->assertEquals($expectedDocComment, $staticReflectionParser->getDocComment('class')); }
public function testGetterSetter() { $Transformer = new CaseTransformer(new SnakeCase(), new StudlyCaps()); $data = $this->getMockData(); /** @var AbstractModel $Model */ $Model = new $this->modelClass(); $Model->exchangeArray(json_decode($data)); $ModelReflection = new \ReflectionClass($this->modelClass); $ClassFinder = new ClassFinder('DockerCloud'); $StaticReflectionParser = new StaticReflectionParser($this->modelClass, $ClassFinder); $useStatements = $StaticReflectionParser->getUseStatements(); foreach ($ModelReflection->getProperties(\ReflectionProperty::IS_PROTECTED) as $ReflectionProperty) { // Parse @var tag $DockBlock = DocBlockFactory::createInstance()->create($ReflectionProperty->getDocComment()); $this->assertTrue($DockBlock->hasTag('var')); /** * @var Var_ $VarTag */ $VarTag = $DockBlock->getTagsByName('var')[0]; $varTypes = explode('|', $VarTag->getType()->__toString()); //echo $VarTag . PHP_EOL; $foundMatchVarTypeCount = 0; foreach ($varTypes as $varType) { // Get value by using getter method $getterMethodName = $Transformer->transform($ReflectionProperty->getName()); if ('bool' == $varType || 'boolean' == $varType) { $getterMethodName = 'is' . $getterMethodName; } else { $getterMethodName = 'get' . $getterMethodName; } if (!method_exists($Model, $getterMethodName)) { continue; } $value = $Model->{$getterMethodName}(); if (strpos($varType, '[]') && is_array($value)) { $value = array_pop($value); } // If there's no actual value we cannot really validate it... $varType = str_replace('[]', '', $varType); if (strpos($varType, '\\') === 0) { $varType = substr($varType, 1); } $foundMatchVarType = $this->validateInternalType($varType, $value); if (is_null($foundMatchVarType)) { $foundMatchVarType = $this->validateImportedType($varType, $value, $useStatements); } if ($foundMatchVarType) { $foundMatchVarTypeCount++; } } self::assertTrue($foundMatchVarTypeCount > 0, sprintf("[%s] haven't getter method.", $ReflectionProperty->getName())); } }
public function resolveRelativeName($shortClassName) { if ($this->useStatements === null) { $p = new StaticReflectionParser($this->className, new ReflectionClassFinder()); $this->useStatements = $p->getUseStatements(); $this->namespace = $p->getNamespaceName(); } $matches = array(); preg_match("/^[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*/", $shortClassName, $matches); $firstName = strtolower($matches[0]); if (isset($this->useStatements[$firstName])) { return $this->useStatements[$firstName] . substr($shortClassName, strlen($firstName)); } else { return $this->namespace . "\\" . $shortClassName; } }
public function getPropertyObjectClass($propertyName) { if (!in_array($this->getPropertyType($propertyName), [Swagger::DATA_TYPE_OBJECT, Swagger::DATA_TYPE_OBJECT_ARRAY])) { throw new Exception('The property type is not object'); } $type = str_replace('[]', '', $this->_getPropertyType($propertyName)); $finder = new Psr4FindFile(['app' => [Yii::getAlias('@app')]]); $staticReflectionParser = new StaticReflectionParser($this->className, $finder); $useStatements = $staticReflectionParser->getUseStatements(); if (isset($useStatements[strtolower($type)])) { return $useStatements[strtolower($type)]; } if (class_exists($className = $this->reflection->getNamespaceName() . '\\' . $type)) { return $className; } return null; }
/** * {@see addTagsAsAnnotations} for a class' methods. * @param StaticReflectionParser $reflectionParser * @todo Since StaticReflectionProperty does not support docblocks for static * members, tags are not added for those atm. */ protected function addMethodTagsAsAnnotations(StaticReflectionParser $reflectionParser) { $className = $reflectionParser->getClassName(); $methods =& $this->classReflectionData[$className][static::DATA_CLASS_METHODS]; if (!is_array($methods)) { return; } foreach ($methods as $methodName => &$method) { if ($methodName == 'jsonSerialize') { // FIXME Prevent jsonSerialize bug. continue; } $reflector = $reflectionParser->getReflectionMethod($methodName); $isStatic = $this->digArray($method, static::DATA_METHOD_STATIC); if (!$isStatic) { $this->addTagsAsAnnotations($reflector, $method); } } }
/** * @return StaticReflectionParser */ protected function getStaticReflectionParser() { return $this->staticReflectionParser->getStaticReflectionParserForDeclaringClass('property', $this->propertyName); }
/** * Discovers all available tests in all extensions. * * @param string $extension * (optional) The name of an extension to limit discovery to; e.g., 'node'. * * @return array * An array of tests keyed by the first @group specified in each test's * PHPDoc comment block, and then keyed by class names. For example: * @code * $groups['block'] => array( * 'Drupal\block\Tests\BlockTest' => array( * 'name' => 'Drupal\block\Tests\BlockTest', * 'description' => 'Tests block UI CRUD functionality.', * 'group' => 'block', * ), * ); * @endcode * * @throws \ReflectionException * If a discovered test class does not match the expected class name. * * @todo Remove singular grouping; retain list of groups in 'group' key. * @see https://www.drupal.org/node/2296615 * @todo Add base class groups 'Kernel' + 'Web', complementing 'PHPUnit'. */ public function getTestClasses($extension = NULL) { $reader = new SimpleAnnotationReader(); $reader->addNamespace('Drupal\\simpletest\\Annotation'); if (!isset($extension)) { if ($this->cacheBackend && ($cache = $this->cacheBackend->get('simpletest:discovery:classes'))) { return $cache->data; } } $list = array(); $classmap = $this->findAllClassFiles($extension); // Prevent expensive class loader lookups for each reflected test class by // registering the complete classmap of test classes to the class loader. // This also ensures that test classes are loaded from the discovered // pathnames; a namespace/classname mismatch will throw an exception. $this->classLoader->addClassMap($classmap); foreach ($classmap as $classname => $pathname) { $finder = MockFileFinder::create($pathname); $parser = new StaticReflectionParser($classname, $finder, TRUE); try { $info = static::getTestInfo($classname, $parser->getDocComment()); } catch (MissingGroupException $e) { // If the class name ends in Test and is not a migrate table dump. if (preg_match('/Test$/', $classname) && strpos($classname, 'migrate_drupal\\Tests\\Table') === FALSE) { throw $e; } // If the class is @group annotation just skip it. Most likely it is an // abstract class, trait or test fixture. continue; } // Skip this test class if it requires unavailable modules. // @todo PHPUnit skips tests with unmet requirements when executing a test // (instead of excluding them upfront). Refactor test runner to follow // that approach. // @see https://www.drupal.org/node/1273478 if (!empty($info['requires']['module'])) { if (array_diff($info['requires']['module'], $this->availableExtensions['module'])) { continue; } } $list[$info['group']][$classname] = $info; } // Sort the groups and tests within the groups by name. uksort($list, 'strnatcasecmp'); foreach ($list as &$tests) { uksort($tests, 'strnatcasecmp'); } // Allow modules extending core tests to disable originals. \Drupal::moduleHandler()->alter('simpletest', $list); if (!isset($extension)) { if ($this->cacheBackend) { $this->cacheBackend->set('simpletest:discovery:classes', $list); } } return $list; }
/** * {@inheritDoc} */ public function getProperty($name) { return $this->staticReflectionParser->getReflectionProperty($name); }
/** * {@inheritdoc} */ public function getDefinitions() { $definitions = array(); $reader = $this->getAnnotationReader(); // Clear the annotation loaders of any previous annotation classes. AnnotationRegistry::reset(); // Register the namespaces of classes that can be used for annotations. AnnotationRegistry::registerLoader('class_exists'); // Search for classes within all PSR-0 namespace locations. foreach ($this->getPluginNamespaces() as $namespace => $dirs) { foreach ($dirs as $dir) { if (file_exists($dir)) { $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS)); foreach ($iterator as $fileinfo) { if ($fileinfo->getExtension() == 'php') { $sub_path = $iterator->getSubIterator()->getSubPath(); $sub_path = $sub_path ? str_replace('/', '\\', $sub_path) . '\\' : ''; $class = $namespace . '\\' . str_replace('/', '\\', $this->pluginManagerDefinition['directory']) . '\\' . $sub_path . $fileinfo->getBasename('.php'); // The filename is already known, so there is no need to find the // file. However, StaticReflectionParser needs a finder, so use a // mock version. $finder = MockFileFinder::create($fileinfo->getPathName()); $parser = new StaticReflectionParser($class, $finder, TRUE); if ($annotation = $reader->getClassAnnotation($parser->getReflectionClass(), $this->pluginDefinitionAnnotationName)) { $this->prepareAnnotationDefinition($annotation, $class); $definitions[$annotation->getId()] = $annotation->get(); } } } } } } // Don't let annotation loaders pile up. AnnotationRegistry::reset(); return $definitions; }
/** * @return StaticReflectionParser */ protected function getStaticReflectionParser() { return $this->staticReflectionParser->getStaticReflectionParserForDeclaringClass('method', $this->methodName); }
/** * {@inheritdoc} */ public function getDefinitions() { $definitions = array(); $reader = $this->getAnnotationReader(); // Clear the annotation loaders of any previous annotation classes. AnnotationRegistry::reset(); // Register the namespaces of classes that can be used for annotations. AnnotationRegistry::registerLoader('class_exists'); // Search for classes within all PSR-0 namespace locations. foreach ($this->getPluginNamespaces() as $namespace => $dirs) { foreach ($dirs as $dir) { if (file_exists($dir)) { $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS)); foreach ($iterator as $fileinfo) { if ($fileinfo->getExtension() == 'php') { if ($cached = $this->fileCache->get($fileinfo->getPathName())) { if (isset($cached['id'])) { // Explicitly unserialize this to create a new object instance. $definitions[$cached['id']] = unserialize($cached['content']); } continue; } $sub_path = $iterator->getSubIterator()->getSubPath(); $sub_path = $sub_path ? str_replace(DIRECTORY_SEPARATOR, '\\', $sub_path) . '\\' : ''; $class = $namespace . '\\' . $sub_path . $fileinfo->getBasename('.php'); // The filename is already known, so there is no need to find the // file. However, StaticReflectionParser needs a finder, so use a // mock version. $finder = MockFileFinder::create($fileinfo->getPathName()); $parser = new BaseStaticReflectionParser($class, $finder, FALSE); /** @var $annotation \Drupal\Component\Annotation\AnnotationInterface */ if ($annotation = $reader->getClassAnnotation($parser->getReflectionClass(), $this->pluginDefinitionAnnotationName)) { $this->prepareAnnotationDefinition($annotation, $class, $parser); $id = $annotation->getId(); $content = $annotation->get(); $definitions[$id] = $content; // Explicitly serialize this to create a new object instance. $this->fileCache->set($fileinfo->getPathName(), ['id' => $id, 'content' => serialize($content)]); } else { // Store a NULL object, so the file is not reparsed again. $this->fileCache->set($fileinfo->getPathName(), [NULL]); } } } } } } // Don't let annotation loaders pile up. AnnotationRegistry::reset(); return $definitions; }