From a0a22f8d41d7f5926378bcef00b5bb9256ba5fc2 Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Mon, 2 Aug 2021 09:24:49 +0100 Subject: [PATCH] Issue #3180351 by longwave, alexpott, daffie, catch, andypost, Charlie ChX Negyesi: doctrine/reflection is abandoned --- .../Compatibility/Php7/ReflectionClass.php | 48 ++ .../Compatibility/Php8/ReflectionClass.php | 48 ++ .../Compatibility/ReflectionClass.php | 42 ++ .../Doctrine/StaticReflectionClass.php | 424 ++++++++++++++++++ .../Doctrine/StaticReflectionParser.php | 344 ++++++++++++++ .../Discovery/AnnotatedClassDiscovery.php | 2 +- .../Annotation/Reflection/MockFileFinder.php | 9 +- .../Component/ClassFinder/ClassFinder.php | 4 +- .../ClassFinder/ClassFinderInterface.php | 21 + .../Component/ClassFinder/composer.json | 3 +- core/lib/Drupal/Core/Test/TestDiscovery.php | 2 +- ...otatedClassDiscoveryAutomatedProviders.php | 4 +- .../Discovery/StaticReflectionParser.php | 6 +- 13 files changed, 941 insertions(+), 16 deletions(-) create mode 100644 core/lib/Drupal/Component/Annotation/Doctrine/Compatibility/Php7/ReflectionClass.php create mode 100644 core/lib/Drupal/Component/Annotation/Doctrine/Compatibility/Php8/ReflectionClass.php create mode 100644 core/lib/Drupal/Component/Annotation/Doctrine/Compatibility/ReflectionClass.php create mode 100644 core/lib/Drupal/Component/Annotation/Doctrine/StaticReflectionClass.php create mode 100644 core/lib/Drupal/Component/Annotation/Doctrine/StaticReflectionParser.php create mode 100644 core/lib/Drupal/Component/ClassFinder/ClassFinderInterface.php diff --git a/core/lib/Drupal/Component/Annotation/Doctrine/Compatibility/Php7/ReflectionClass.php b/core/lib/Drupal/Component/Annotation/Doctrine/Compatibility/Php7/ReflectionClass.php new file mode 100644 index 000000000000..8ae2a6750458 --- /dev/null +++ b/core/lib/Drupal/Component/Annotation/Doctrine/Compatibility/Php7/ReflectionClass.php @@ -0,0 +1,48 @@ +<?php +// phpcs:ignoreFile + +/** + * @file + * + * This class is a near-copy of + * Doctrine\Common\Reflection\Compatibility\Php7\ReflectionClass, which is part + * of the Doctrine project: <http://www.doctrine-project.org>. It was copied + * from version 1.2.2. + * + * Original copyright: + * + * Copyright (c) 2006-2015 Doctrine Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + */ + +namespace Drupal\Component\Annotation\Doctrine\Compatibility\Php7; + +use ReflectionException; + +trait ReflectionClass +{ + /** + * {@inheritDoc} + */ + public function getConstants() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function newInstance($args) + { + throw new ReflectionException('Method not implemented'); + } +} diff --git a/core/lib/Drupal/Component/Annotation/Doctrine/Compatibility/Php8/ReflectionClass.php b/core/lib/Drupal/Component/Annotation/Doctrine/Compatibility/Php8/ReflectionClass.php new file mode 100644 index 000000000000..015939e147c9 --- /dev/null +++ b/core/lib/Drupal/Component/Annotation/Doctrine/Compatibility/Php8/ReflectionClass.php @@ -0,0 +1,48 @@ +<?php +// phpcs:ignoreFile + +/** + * @file + * + * This class is a near-copy of + * Doctrine\Common\Reflection\Compatibility\Php8\ReflectionClass, which is part + * of the Doctrine project: <http://www.doctrine-project.org>. It was copied + * from version 1.2.2. + * + * Original copyright: + * + * Copyright (c) 2006-2015 Doctrine Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + */ + +namespace Drupal\Component\Annotation\Doctrine\Compatibility\Php8; + +use ReflectionException; + +trait ReflectionClass +{ + /** + * {@inheritDoc} + */ + public function getConstants(?int $filter = null) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function newInstance(mixed ...$args) + { + throw new ReflectionException('Method not implemented'); + } +} diff --git a/core/lib/Drupal/Component/Annotation/Doctrine/Compatibility/ReflectionClass.php b/core/lib/Drupal/Component/Annotation/Doctrine/Compatibility/ReflectionClass.php new file mode 100644 index 000000000000..acb5887a72b0 --- /dev/null +++ b/core/lib/Drupal/Component/Annotation/Doctrine/Compatibility/ReflectionClass.php @@ -0,0 +1,42 @@ +<?php +// phpcs:ignoreFile + +/** + * @file + * + * This class is a near-copy of + * Doctrine\Common\Reflection\Compatibility\ReflectionClass, which is part of + * the Doctrine project: <http://www.doctrine-project.org>. It was copied from + * version 1.2.2. + * + * Original copyright: + * + * Copyright (c) 2006-2015 Doctrine Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + */ + +namespace Drupal\Component\Annotation\Doctrine\Compatibility; + +use const PHP_VERSION_ID; +use function class_alias; + +if (PHP_VERSION_ID >= 80000) { + class_alias('Drupal\Component\Annotation\Doctrine\Compatibility\Php8\ReflectionClass', 'Drupal\Component\Annotation\Doctrine\Compatibility\ReflectionClass'); +} else { + class_alias('Drupal\Component\Annotation\Doctrine\Compatibility\Php7\ReflectionClass', 'Drupal\Component\Annotation\Doctrine\Compatibility\ReflectionClass'); +} + +if (false) { + class ReflectionClass + { + } +} diff --git a/core/lib/Drupal/Component/Annotation/Doctrine/StaticReflectionClass.php b/core/lib/Drupal/Component/Annotation/Doctrine/StaticReflectionClass.php new file mode 100644 index 000000000000..0f1ff5888d76 --- /dev/null +++ b/core/lib/Drupal/Component/Annotation/Doctrine/StaticReflectionClass.php @@ -0,0 +1,424 @@ +<?php +// phpcs:ignoreFile + +/** + * @file + * + * This class is a near-copy of + * Doctrine\Common\Reflection\StaticReflectionClass, which is part of the + * Doctrine project: <http://www.doctrine-project.org>. It was copied from + * version 1.2.2. + * + * Original copyright: + * + * Copyright (c) 2006-2015 Doctrine Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + */ + +namespace Drupal\Component\Annotation\Doctrine; + +use Drupal\Component\Annotation\Doctrine\Compatibility\ReflectionClass as CompatibilityReflectionClass; +use ReflectionClass; +use ReflectionException; + +class StaticReflectionClass extends ReflectionClass +{ + use CompatibilityReflectionClass; + + /** + * The static reflection parser object. + * + * @var StaticReflectionParser + */ + private $staticReflectionParser; + + public function __construct(StaticReflectionParser $staticReflectionParser) + { + $this->staticReflectionParser = $staticReflectionParser; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return $this->staticReflectionParser->getClassName(); + } + + /** + * {@inheritDoc} + */ + public function getDocComment() + { + return $this->staticReflectionParser->getDocComment(); + } + + /** + * {@inheritDoc} + */ + public function getNamespaceName() + { + return $this->staticReflectionParser->getNamespaceName(); + } + + /** + * @return string[] + */ + public function getUseStatements() + { + return $this->staticReflectionParser->getUseStatements(); + } + + /** + * {@inheritDoc} + */ + public function getMethod($name) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getProperty($name) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public static function export($argument, $return = false) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getConstant($name) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getConstructor() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getDefaultProperties() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getEndLine() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getExtension() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getExtensionName() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getFileName() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getInterfaceNames() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getInterfaces() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getMethods($filter = null) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getModifiers() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getParentClass() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getProperties($filter = null) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getShortName() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getStartLine() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getStaticProperties() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getStaticPropertyValue($name, $default = '') + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getTraitAliases() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getTraitNames() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getTraits() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function hasConstant($name) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function hasMethod($name) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function hasProperty($name) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function implementsInterface($interface) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function inNamespace() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function isAbstract() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function isCloneable() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function isFinal() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function isInstance($object) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function isInstantiable() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function isInterface() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function isInternal() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function isIterateable() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function isSubclassOf($class) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function isTrait() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function isUserDefined() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function newInstanceArgs(array $args = []) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function newInstanceWithoutConstructor() + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function setStaticPropertyValue($name, $value) + { + throw new ReflectionException('Method not implemented'); + } + + /** + * {@inheritDoc} + */ + public function __toString() + { + throw new ReflectionException('Method not implemented'); + } +} diff --git a/core/lib/Drupal/Component/Annotation/Doctrine/StaticReflectionParser.php b/core/lib/Drupal/Component/Annotation/Doctrine/StaticReflectionParser.php new file mode 100644 index 000000000000..78fdbebe585c --- /dev/null +++ b/core/lib/Drupal/Component/Annotation/Doctrine/StaticReflectionParser.php @@ -0,0 +1,344 @@ +<?php +// phpcs:ignoreFile +// cspell:ignore paamayim nekudotayim + +/** + * @file + * + * This class is a near-copy of + * Doctrine\Common\Reflection\StaticReflectionParser, which is part of the + * Doctrine project: <http://www.doctrine-project.org>. It was copied from + * version 1.2.2. + * + * Original copyright: + * + * Copyright (c) 2006-2015 Doctrine Project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + */ + +namespace Drupal\Component\Annotation\Doctrine; + +use Doctrine\Common\Annotations\TokenParser; +use ReflectionException; +use const T_CLASS; +use const T_DOC_COMMENT; +use const T_EXTENDS; +use const T_FUNCTION; +use const T_NEW; +use const T_PAAMAYIM_NEKUDOTAYIM; +use const T_PRIVATE; +use const T_PROTECTED; +use const T_PUBLIC; +use const T_STRING; +use const T_USE; +use const T_VAR; +use const T_VARIABLE; +use function array_merge; +use function file_get_contents; +use function is_array; +use function ltrim; +use function preg_match; +use function sprintf; +use function strpos; +use function strrpos; +use function strtolower; +use function substr; + +/** + * Parses a file for namespaces/use/class declarations. + */ +class StaticReflectionParser +{ + /** + * The fully qualified class name. + * + * @var string + */ + protected $className; + + /** + * The short class name. + * + * @var string + */ + protected $shortClassName; + + /** + * Whether the caller only wants class annotations. + * + * @var bool + */ + protected $classAnnotationOptimize; + + /** + * A ClassFinder object which finds the class. + * + * @var ClassFinderInterface + */ + protected $finder; + + /** + * Whether the parser has run. + * + * @var bool + */ + protected $parsed = false; + + /** + * The namespace of the class. + * + * @var string + */ + protected $namespace = ''; + + /** + * The use statements of the class. + * + * @var string[] + */ + protected $useStatements = []; + + /** + * The docComment of the class. + * + * @var mixed[] + */ + protected $docComment = [ + 'class' => '', + 'property' => [], + 'method' => [], + ]; + + /** + * The name of the class this class extends, if any. + * + * @var string + */ + protected $parentClassName = ''; + + /** + * The parent PSR-0 Parser. + * + * @var \Doctrine\Common\Reflection\StaticReflectionParser + */ + protected $parentStaticReflectionParser; + + /** + * Parses a class residing in a PSR-0 hierarchy. + * + * @param string $className The full, namespaced class name. + * @param ClassFinderInterface $finder A ClassFinder object which finds the class. + * @param bool $classAnnotationOptimize Only retrieve the class docComment. + * Presumes there is only one statement per line. + */ + public function __construct($className, $finder, $classAnnotationOptimize = false) + { + $this->className = ltrim($className, '\\'); + $lastNsPos = strrpos($this->className, '\\'); + + if ($lastNsPos !== false) { + $this->namespace = substr($this->className, 0, $lastNsPos); + $this->shortClassName = substr($this->className, $lastNsPos + 1); + } else { + $this->shortClassName = $this->className; + } + + $this->finder = $finder; + $this->classAnnotationOptimize = $classAnnotationOptimize; + } + + /** + * @return void + */ + protected function parse() + { + $fileName = $this->finder->findFile($this->className); + + if ($this->parsed || ! $fileName) { + return; + } + $this->parsed = true; + $contents = file_get_contents($fileName); + if ($this->classAnnotationOptimize) { + $regex = sprintf('/\A.*^\s*((abstract|final)\s+)?class\s+%s\s+/sm', $this->shortClassName); + + if (preg_match($regex, $contents, $matches)) { + $contents = $matches[0]; + } + } + $tokenParser = new TokenParser($contents); + $docComment = ''; + $last_token = false; + + while ($token = $tokenParser->next(false)) { + switch ($token[0]) { + case T_USE: + $this->useStatements = array_merge($this->useStatements, $tokenParser->parseUseStatement()); + break; + case T_DOC_COMMENT: + $docComment = $token[1]; + break; + case T_CLASS: + if ($last_token !== T_PAAMAYIM_NEKUDOTAYIM && $last_token !== T_NEW) { + $this->docComment['class'] = $docComment; + $docComment = ''; + } + break; + case T_VAR: + case T_PRIVATE: + case T_PROTECTED: + case T_PUBLIC: + $token = $tokenParser->next(); + if ($token[0] === T_VARIABLE) { + $propertyName = substr($token[1], 1); + $this->docComment['property'][$propertyName] = $docComment; + continue 2; + } + if ($token[0] !== T_FUNCTION) { + // For example, it can be T_FINAL. + continue 2; + } + // No break. + case T_FUNCTION: + // The next string after function is the name, but + // there can be & before the function name so find the + // string. + while (($token = $tokenParser->next()) && $token[0] !== T_STRING) { + continue; + } + if ($token === null) { + break; + } + $methodName = $token[1]; + $this->docComment['method'][$methodName] = $docComment; + $docComment = ''; + break; + case T_EXTENDS: + $this->parentClassName = $tokenParser->parseClass(); + $nsPos = strpos($this->parentClassName, '\\'); + $fullySpecified = false; + if ($nsPos === 0) { + $fullySpecified = true; + } else { + if ($nsPos) { + $prefix = strtolower(substr($this->parentClassName, 0, $nsPos)); + $postfix = substr($this->parentClassName, $nsPos); + } else { + $prefix = strtolower($this->parentClassName); + $postfix = ''; + } + foreach ($this->useStatements as $alias => $use) { + if ($alias !== $prefix) { + continue; + } + + $this->parentClassName = '\\' . $use . $postfix; + $fullySpecified = true; + } + } + if (! $fullySpecified) { + $this->parentClassName = '\\' . $this->namespace . '\\' . $this->parentClassName; + } + break; + } + + $last_token = is_array($token) ? $token[0] : false; + } + } + + /** + * @return StaticReflectionParser + */ + protected function getParentStaticReflectionParser() + { + if (empty($this->parentStaticReflectionParser)) { + $this->parentStaticReflectionParser = new static($this->parentClassName, $this->finder); + } + + return $this->parentStaticReflectionParser; + } + + /** + * @return string + */ + public function getClassName() + { + return $this->className; + } + + /** + * @return string + */ + public function getNamespaceName() + { + return $this->namespace; + } + + /** + * Gets the ReflectionClass equivalent for this class. + * + * @return ReflectionClass + */ + public function getReflectionClass() + { + return new StaticReflectionClass($this); + } + + /** + * Gets the use statements from this file. + * + * @return string[] + */ + public function getUseStatements() + { + $this->parse(); + + return $this->useStatements; + } + + /** + * Gets the doc comment. + * + * @param string $type The type: 'class', 'property' or 'method'. + * @param string $name The name of the property or method, not needed for 'class'. + * + * @return string The doc comment, empty string if none. + */ + public function getDocComment($type = 'class', $name = '') + { + $this->parse(); + + return $name ? $this->docComment[$type][$name] : $this->docComment[$type]; + } + + /** + * Gets the PSR-0 parser for the declaring class. + * + * @param string $type The type: 'property' or 'method'. + * @param string $name The name of the property or method. + * + * @return StaticReflectionParser A static reflection parser for the declaring class. + * + * @throws ReflectionException + */ + public function getStaticReflectionParserForDeclaringClass($type, $name) + { + $this->parse(); + if (isset($this->docComment[$type][$name])) { + return $this; + } + if (! empty($this->parentClassName)) { + return $this->getParentStaticReflectionParser()->getStaticReflectionParserForDeclaringClass($type, $name); + } + throw new ReflectionException('Invalid ' . $type . ' "' . $name . '"'); + } +} diff --git a/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php b/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php index 0c3881047c47..2c5f0b4985d0 100644 --- a/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php +++ b/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php @@ -6,9 +6,9 @@ use Drupal\Component\FileCache\FileCacheFactory; use Drupal\Component\Plugin\Discovery\DiscoveryInterface; use Drupal\Component\Annotation\Doctrine\SimpleAnnotationReader; +use Drupal\Component\Annotation\Doctrine\StaticReflectionParser; use Drupal\Component\Annotation\Reflection\MockFileFinder; use Doctrine\Common\Annotations\AnnotationRegistry; -use Doctrine\Common\Reflection\StaticReflectionParser; use Drupal\Component\Plugin\Discovery\DiscoveryTrait; use Drupal\Component\Utility\Crypt; diff --git a/core/lib/Drupal/Component/Annotation/Reflection/MockFileFinder.php b/core/lib/Drupal/Component/Annotation/Reflection/MockFileFinder.php index ecfefc371e74..7aed79f14fe3 100644 --- a/core/lib/Drupal/Component/Annotation/Reflection/MockFileFinder.php +++ b/core/lib/Drupal/Component/Annotation/Reflection/MockFileFinder.php @@ -2,14 +2,15 @@ namespace Drupal\Component\Annotation\Reflection; -use Doctrine\Common\Reflection\ClassFinderInterface; +use Drupal\Component\ClassFinder\ClassFinderInterface; /** * Defines a mock file finder that only returns a single filename. * - * This can be used with Doctrine\Common\Reflection\StaticReflectionParser if - * the filename is known and inheritance is not a concern (for example, if - * only the class annotation is needed). + * This can be used with + * Drupal\Component\Annotation\Doctrine\StaticReflectionParser if the filename + * is known and inheritance is not a concern (for example, if only the class + * annotation is needed). */ class MockFileFinder implements ClassFinderInterface { diff --git a/core/lib/Drupal/Component/ClassFinder/ClassFinder.php b/core/lib/Drupal/Component/ClassFinder/ClassFinder.php index 346f7f66cd84..3d89e9b4daa2 100644 --- a/core/lib/Drupal/Component/ClassFinder/ClassFinder.php +++ b/core/lib/Drupal/Component/ClassFinder/ClassFinder.php @@ -2,8 +2,6 @@ namespace Drupal\Component\ClassFinder; -use Doctrine\Common\Reflection\ClassFinderInterface; - /** * A Utility class that uses active autoloaders to find a file for a class. */ @@ -19,7 +17,7 @@ public function findFile($class) { $file = call_user_func_array([$loader[0], 'findFile'], [$class]); // Different implementations return different empty values. For example, // \Composer\Autoload\ClassLoader::findFile() returns FALSE whilst - // \Doctrine\Common\Reflection\ClassFinderInterface::findFile() + // \Drupal\Component\ClassFinder\ClassFinderInterface::findFile() // documents that a NULL should be returned. if (!empty($file)) { return $file; diff --git a/core/lib/Drupal/Component/ClassFinder/ClassFinderInterface.php b/core/lib/Drupal/Component/ClassFinder/ClassFinderInterface.php new file mode 100644 index 000000000000..7db1d1744ba2 --- /dev/null +++ b/core/lib/Drupal/Component/ClassFinder/ClassFinderInterface.php @@ -0,0 +1,21 @@ +<?php + +namespace Drupal\Component\ClassFinder; + +/** + * Finds a class in a PSR-0 structure. + */ +interface ClassFinderInterface { + + /** + * Finds a class. + * + * @param string $class + * The name of the class. + * + * @return string|null + * The name of the class or NULL if not found. + */ + public function findFile($class); + +} diff --git a/core/lib/Drupal/Component/ClassFinder/composer.json b/core/lib/Drupal/Component/ClassFinder/composer.json index ac17b5f999b0..9efde0acdda7 100644 --- a/core/lib/Drupal/Component/ClassFinder/composer.json +++ b/core/lib/Drupal/Component/ClassFinder/composer.json @@ -5,8 +5,7 @@ "homepage": "https://www.drupal.org/project/drupal", "license": "GPL-2.0-or-later", "require": { - "php": ">=7.3.0", - "doctrine/reflection": "^1.1" + "php": ">=7.3.0" }, "autoload": { "psr-4": { diff --git a/core/lib/Drupal/Core/Test/TestDiscovery.php b/core/lib/Drupal/Core/Test/TestDiscovery.php index b9eeb0db23f0..cdcc1eeda7f8 100644 --- a/core/lib/Drupal/Core/Test/TestDiscovery.php +++ b/core/lib/Drupal/Core/Test/TestDiscovery.php @@ -2,7 +2,7 @@ namespace Drupal\Core\Test; -use Doctrine\Common\Reflection\StaticReflectionParser; +use Drupal\Component\Annotation\Doctrine\StaticReflectionParser; use Drupal\Component\Annotation\Reflection\MockFileFinder; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Extension\ExtensionDiscovery; diff --git a/core/modules/migrate/src/Plugin/Discovery/AnnotatedClassDiscoveryAutomatedProviders.php b/core/modules/migrate/src/Plugin/Discovery/AnnotatedClassDiscoveryAutomatedProviders.php index 0d6c0704532c..49c9a268ab84 100644 --- a/core/modules/migrate/src/Plugin/Discovery/AnnotatedClassDiscoveryAutomatedProviders.php +++ b/core/modules/migrate/src/Plugin/Discovery/AnnotatedClassDiscoveryAutomatedProviders.php @@ -3,8 +3,8 @@ namespace Drupal\migrate\Plugin\Discovery; use Doctrine\Common\Annotations\AnnotationRegistry; -use Doctrine\Common\Reflection\StaticReflectionParser as BaseStaticReflectionParser; use Drupal\Component\Annotation\AnnotationInterface; +use Drupal\Component\Annotation\Doctrine\StaticReflectionParser as BaseStaticReflectionParser; use Drupal\Component\Annotation\Reflection\MockFileFinder; use Drupal\Component\ClassFinder\ClassFinder; use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery; @@ -23,7 +23,7 @@ class AnnotatedClassDiscoveryAutomatedProviders extends AnnotatedClassDiscovery /** * A utility object that can use active autoloaders to find files for classes. * - * @var \Doctrine\Common\Reflection\ClassFinderInterface + * @var \Drupal\Component\ClassFinder\ClassFinderInterface */ protected $finder; diff --git a/core/modules/migrate/src/Plugin/Discovery/StaticReflectionParser.php b/core/modules/migrate/src/Plugin/Discovery/StaticReflectionParser.php index 8c574f507025..a26a2c1e422a 100644 --- a/core/modules/migrate/src/Plugin/Discovery/StaticReflectionParser.php +++ b/core/modules/migrate/src/Plugin/Discovery/StaticReflectionParser.php @@ -2,7 +2,7 @@ namespace Drupal\migrate\Plugin\Discovery; -use Doctrine\Common\Reflection\StaticReflectionParser as BaseStaticReflectionParser; +use Drupal\Component\Annotation\Doctrine\StaticReflectionParser as BaseStaticReflectionParser; /** * Allows getting the reflection parser for the parent class. @@ -17,11 +17,11 @@ class StaticReflectionParser extends BaseStaticReflectionParser { /** * If the current class extends another, get the parser for the latter. * - * @param \Doctrine\Common\Reflection\StaticReflectionParser $parser + * @param \Drupal\Component\Annotation\Doctrine\StaticReflectionParser $parser * The current static parser. * @param $finder * The class finder. Must implement - * \Doctrine\Common\Reflection\ClassFinderInterface, but can do so + * \Drupal\Component\ClassFinder\ClassFinderInterface, but can do so * implicitly (i.e., implements the interface's methods but not the actual * interface). * -- GitLab