Skip to content

Commit

Permalink
Merge branch '31600-deprecated-reflection-method' of github.com:Proko…
Browse files Browse the repository at this point in the history
…povVitaliy/magento2 into php8-develop
  • Loading branch information
sivaschenko committed Mar 5, 2021
2 parents ca16be7 + 79e89c8 commit a76bcb6
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@

namespace Magento\CodeMessDetector\Rule\Design;

use Magento\Framework\Session\SessionManagerInterface;
use Magento\Framework\Stdlib\Cookie\CookieReaderInterface;
use PDepend\Source\AST\ASTClass;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Node\ClassNode;
use PHPMD\Rule\ClassAware;
use ReflectionClass;
use ReflectionException;
use ReflectionParameter;

/**
* Session and Cookies must be used only in HTML Presentation layer.
Expand Down Expand Up @@ -105,7 +110,7 @@ private function isControllerPlugin(\ReflectionClass $class): bool
foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
if (preg_match('/^(after|around|before).+/i', $method->getName())) {
try {
$argument = $method->getParameters()[0]->getClass();
$argument = $this->getParameterClass($method->getParameters()[0]);
} catch (\Throwable $exception) {
//Non-existing class (autogenerated perhaps) or doesn't have an argument.
continue;
Expand Down Expand Up @@ -134,7 +139,7 @@ private function isBlockPlugin(\ReflectionClass $class): bool
foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
if (preg_match('/^(after|around|before).+/i', $method->getName())) {
try {
$argument = $method->getParameters()[0]->getClass();
$argument = $this->getParameterClass($method->getParameters()[0]);
} catch (\Throwable $exception) {
//Non-existing class (autogenerated perhaps) or doesn't have an argument.
continue;
Expand Down Expand Up @@ -164,14 +169,16 @@ private function doesUseRestrictedClasses(\ReflectionClass $class): bool
if ($constructor) {
foreach ($constructor->getParameters() as $argument) {
try {
if ($class = $argument->getClass()) {
if ($class->isSubclassOf(\Magento\Framework\Session\SessionManagerInterface::class)
|| $class->getName() === \Magento\Framework\Session\SessionManagerInterface::class
|| $class->isSubclassOf(\Magento\Framework\Stdlib\Cookie\CookieReaderInterface::class)
|| $class->getName() === \Magento\Framework\Stdlib\Cookie\CookieReaderInterface::class
) {
return true;
}
$class = $this->getParameterClass($argument);
if ($class === null) {
continue;
}
if ($class->isSubclassOf(SessionManagerInterface::class)
|| $class->getName() === SessionManagerInterface::class
|| $class->isSubclassOf(CookieReaderInterface::class)
|| $class->getName() === CookieReaderInterface::class
) {
return true;
}
} catch (\ReflectionException $exception) {
//Failed to load the argument's class information
Expand All @@ -183,6 +190,22 @@ private function doesUseRestrictedClasses(\ReflectionClass $class): bool
return false;
}

/**
* Get class by reflection parameter
*
* @param ReflectionParameter $reflectionParameter
* @return ReflectionClass|null
* @throws ReflectionException
*/
private function getParameterClass(ReflectionParameter $reflectionParameter): ?ReflectionClass
{
$parameterType = $reflectionParameter->getType();

return $parameterType && !$parameterType->isBuiltin()
? new ReflectionClass($parameterType->getName())
: null;
}

/**
* @inheritdoc
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
use Laminas\Code\Reflection\ClassReflection;
use Laminas\Code\Reflection\FileReflection;
use Laminas\Code\Reflection\ParameterReflection;
use ReflectionClass;
use ReflectionException;
use ReflectionParameter;

/**
* Provide dependencies for the file
Expand Down Expand Up @@ -39,7 +42,7 @@ public function getDependencies(FileReflection $fileReflection)
foreach ($method->getParameters() as $parameter) {
try {
/** @var ParameterReflection $parameter */
$dependency = $parameter->getClass();
$dependency = $this->getParameterClass($parameter);
if ($dependency instanceof ClassReflection) {
$this->dependencies[] = $dependency->getName();
}
Expand All @@ -56,4 +59,20 @@ public function getDependencies(FileReflection $fileReflection)
return $this->dependencies;
}
/**
* Get class by reflection parameter
*
* @param ReflectionParameter $reflectionParameter
* @return ReflectionClass|null
* @throws ReflectionException
*/
private function getParameterClass(ReflectionParameter $reflectionParameter): ?ReflectionClass
{
$parameterType = $reflectionParameter->getType();
return $parameterType && !$parameterType->isBuiltin()
? new ReflectionClass($parameterType->getName())
: null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
namespace Magento\Test\Integrity;

use Magento\Framework\App\Utility\Files;
use ReflectionClass;
use ReflectionException;
use ReflectionParameter;

/**
* Tests @api annotated code integrity
Expand Down Expand Up @@ -277,7 +280,7 @@ private function checkParameters($class, \ReflectionMethod $method, array $nonPu
&& !$parameter->getType()->isBuiltin()
&& !$this->isGenerated($parameter->getType()->getName())
) {
$parameterClass = $parameter->getClass();
$parameterClass = $this->getParameterClass($parameter);
/*
* We don't want to check integrity of @api coverage of classes
* that belong to different vendors, because it is too complicated.
Expand All @@ -286,7 +289,7 @@ private function checkParameters($class, \ReflectionMethod $method, array $nonPu
* we don't want to fail test, because Zend is considered public by default,
* and we don't care if Zend classes are @api-annotated
*/
if (!$parameterClass->isInternal()
if ($parameterClass && !$parameterClass->isInternal()
&& $this->areClassesFromSameVendor($parameterClass->getName(), $class)
&& !$this->isPublished($parameterClass)
) {
Expand All @@ -296,4 +299,20 @@ private function checkParameters($class, \ReflectionMethod $method, array $nonPu
}
return $nonPublishedClasses;
}

/**
* Get class by reflection parameter
*
* @param ReflectionParameter $reflectionParameter
* @return ReflectionClass|null
* @throws ReflectionException
*/
private function getParameterClass(ReflectionParameter $reflectionParameter): ?ReflectionClass
{
$parameterType = $reflectionParameter->getType();

return $parameterType && !$parameterType->isBuiltin()
? new ReflectionClass($parameterType->getName())
: null;
}
}
50 changes: 35 additions & 15 deletions lib/internal/Magento/Framework/Code/Generator/EntityAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
namespace Magento\Framework\Code\Generator;

use Laminas\Code\Generator\ValueGenerator;
use ReflectionClass;
use ReflectionException;
use ReflectionParameter;

/**
* Abstract entity
Expand Down Expand Up @@ -323,29 +326,46 @@ protected function _getNullDefaultValue()
private function extractParameterType(
\ReflectionParameter $parameter
): ?string {
if (!$parameter->hasType()) {
return null;
}

/** @var string|null $typeName */
$typeName = null;
if ($parameter->hasType()) {
if ($parameter->isArray()) {
$typeName = 'array';
} elseif ($parameter->getClass()) {
$typeName = $this->_getFullyQualifiedClassName(
$parameter->getClass()->getName()
);
} elseif ($parameter->isCallable()) {
$typeName = 'callable';
} else {
$typeName = $parameter->getType()->getName();
}

if ($parameter->allowsNull()) {
$typeName = '?' .$typeName;
}
if ($parameter->isArray()) {
$typeName = 'array';
} elseif ($parameterClass = $this->getParameterClass($parameter)) {
$typeName = $this->_getFullyQualifiedClassName($parameterClass->getName());
} elseif ($parameter->isCallable()) {
$typeName = 'callable';
} else {
$typeName = $parameter->getType()->getName();
}

if ($parameter->allowsNull()) {
$typeName = '?' . $typeName;
}

return $typeName;
}

/**
* Get class by reflection parameter
*
* @param ReflectionParameter $reflectionParameter
* @return ReflectionClass|null
* @throws ReflectionException
*/
private function getParameterClass(ReflectionParameter $reflectionParameter): ?ReflectionClass
{
$parameterType = $reflectionParameter->getType();

return $parameterType && !$parameterType->isBuiltin()
? new ReflectionClass($parameterType->getName())
: null;
}

/**
* Extract parameter default value
*
Expand Down
28 changes: 25 additions & 3 deletions lib/internal/Magento/Framework/Code/Reader/ArgumentsReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
*/
namespace Magento\Framework\Code\Reader;

use ReflectionClass;
use ReflectionException;
use ReflectionParameter;

/**
* The class arguments reader
*/
Expand Down Expand Up @@ -98,11 +102,13 @@ public function getConstructorArguments(\ReflectionClass $class, $groupByPositio
*/
private function processType(\ReflectionClass $class, \Laminas\Code\Reflection\ParameterReflection $parameter)
{
if ($parameter->getClass()) {
return NamespaceResolver::NS_SEPARATOR . $parameter->getClass()->getName();
$parameterClass = $this->getParameterClass($parameter);

if ($parameterClass) {
return NamespaceResolver::NS_SEPARATOR . $parameterClass->getName();
}

$type = $parameter->detectType();
$type = $parameter->detectType();

if ($type === 'null') {
return null;
Expand All @@ -121,6 +127,22 @@ private function processType(\ReflectionClass $class, \Laminas\Code\Reflection\P
return $type;
}

/**
* Get class by reflection parameter
*
* @param ReflectionParameter $reflectionParameter
* @return ReflectionClass|null
* @throws ReflectionException
*/
private function getParameterClass(ReflectionParameter $reflectionParameter): ?ReflectionClass
{
$parameterType = $reflectionParameter->getType();

return $parameterType && !$parameterType->isBuiltin()
? new ReflectionClass($parameterType->getName())
: null;
}

/**
* Get arguments of parent __construct call
*
Expand Down
38 changes: 30 additions & 8 deletions lib/internal/Magento/Framework/Code/Reader/ClassReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
*/
namespace Magento\Framework\Code\Reader;

use ReflectionClass;
use ReflectionException;
use ReflectionParameter;

/**
* Class ClassReader
*/
Expand All @@ -17,46 +21,64 @@ class ClassReader implements ClassReaderInterface
*
* @param string $className
* @return array|null
* @throws \ReflectionException
* @throws ReflectionException
*/
public function getConstructor($className)
{
$class = new \ReflectionClass($className);
$class = new ReflectionClass($className);
$result = null;
$constructor = $class->getConstructor();
if ($constructor) {
$result = [];
/** @var $parameter \ReflectionParameter */
/** @var $parameter ReflectionParameter */
foreach ($constructor->getParameters() as $parameter) {
try {
$parameterClass = $this->getParameterClass($parameter);

$result[] = [
$parameter->getName(),
$parameter->getClass() !== null ? $parameter->getClass()->getName() : null,
$parameterClass ? $parameterClass->getName() : null,
!$parameter->isOptional() && !$parameter->isDefaultValueAvailable(),
$this->getReflectionParameterDefaultValue($parameter),
$parameter->isVariadic(),
];
} catch (\ReflectionException $e) {
} catch (ReflectionException $e) {
$message = sprintf(
'Impossible to process constructor argument %s of %s class',
$parameter->__toString(),
$className
);
throw new \ReflectionException($message, 0, $e);
throw new ReflectionException($message, 0, $e);
}
}
}

return $result;
}

/**
* Get class by reflection parameter
*
* @param ReflectionParameter $reflectionParameter
* @return ReflectionClass|null
* @throws ReflectionException
*/
private function getParameterClass(ReflectionParameter $reflectionParameter): ?ReflectionClass
{
$parameterType = $reflectionParameter->getType();

return $parameterType && !$parameterType->isBuiltin()
? new ReflectionClass($parameterType->getName())
: null;
}

/**
* Get reflection parameter default value
*
* @param \ReflectionParameter $parameter
* @param ReflectionParameter $parameter
* @return array|mixed|null
*/
private function getReflectionParameterDefaultValue(\ReflectionParameter $parameter)
private function getReflectionParameterDefaultValue(ReflectionParameter $parameter)
{
if ($parameter->isVariadic()) {
return [];
Expand Down
Loading

0 comments on commit a76bcb6

Please sign in to comment.