mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-07 20:00:50 +00:00
parent
e362a516c2
commit
ba1444959d
|
@ -191,6 +191,7 @@
|
|||
],
|
||||
"files": [
|
||||
"vendor/nette/forms/src/Forms/Controls/SubmitButton.php",
|
||||
"packages/node-type-resolver/tests/PerNodeTypeResolver/VariableTypeResolver/Fixture/this_class.php.inc",
|
||||
"rules/restoration/tests/Rector/Use_/RestoreFullyQualifiedNameRector/Source/ShortClassOnly.php",
|
||||
"rules/coding-style/tests/Rector/Namespace_/ImportFullyQualifiedNamesRector/Source/AnotherClass.php",
|
||||
"rules/coding-style/tests/Rector/Namespace_/ImportFullyQualifiedNamesRector/Source/Foo.php",
|
||||
|
|
2
ecs.php
2
ecs.php
|
@ -14,6 +14,7 @@ use Symplify\CodingStandard\Fixer\ArrayNotation\ArrayListItemNewlineFixer;
|
|||
use Symplify\CodingStandard\Fixer\ArrayNotation\ArrayOpenerAndCloserNewlineFixer;
|
||||
use Symplify\CodingStandard\Fixer\ArrayNotation\StandaloneLineInMultilineArrayFixer;
|
||||
use Symplify\CodingStandard\Fixer\Commenting\RemoveCommentedCodeFixer;
|
||||
use Symplify\CodingStandard\Fixer\LineLength\DocBlockLineLengthFixer;
|
||||
use Symplify\CodingStandard\Fixer\LineLength\LineLengthFixer;
|
||||
use Symplify\EasyCodingStandard\ValueObject\Option;
|
||||
use Symplify\EasyCodingStandard\ValueObject\Set\SetList;
|
||||
|
@ -69,6 +70,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
|
||||
// buggy - @todo fix on Symplify master
|
||||
RemoveCommentedCodeFixer::class,
|
||||
DocBlockLineLengthFixer::class,
|
||||
|
||||
// breaks on-purpose annotated variables
|
||||
ReturnAssignmentFixer::class,
|
||||
|
|
|
@ -34,6 +34,7 @@ use PHPStan\Reflection\MethodReflection;
|
|||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\ThisType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\TypeUtils;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
|
@ -49,8 +50,8 @@ use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper;
|
|||
use ReflectionMethod;
|
||||
|
||||
/**
|
||||
* This service contains all the parsed nodes. E.g. all the functions, method call, classes, static calls etc.
|
||||
* It's useful in case of context analysis, e.g. find all the usage of class method to detect, if the method is used.
|
||||
* This service contains all the parsed nodes. E.g. all the functions, method call, classes, static calls etc. It's
|
||||
* useful in case of context analysis, e.g. find all the usage of class method to detect, if the method is used.
|
||||
*/
|
||||
final class NodeRepository
|
||||
{
|
||||
|
@ -76,6 +77,7 @@ final class NodeRepository
|
|||
|
||||
/**
|
||||
* E.g. [$this, 'someLocalMethod']
|
||||
*
|
||||
* @var array<string, array<string, ArrayCallable[]>>
|
||||
*/
|
||||
private $arrayCallablesByTypeAndMethod = [];
|
||||
|
@ -150,6 +152,7 @@ final class NodeRepository
|
|||
|
||||
/**
|
||||
* To prevent circular reference
|
||||
*
|
||||
* @required
|
||||
*/
|
||||
public function autowireNodeRepository(NodeTypeResolver $nodeTypeResolver): void
|
||||
|
@ -831,7 +834,12 @@ final class NodeRepository
|
|||
private function addCallByType(Node $node, Type $classType, string $methodName): void
|
||||
{
|
||||
if ($classType instanceof TypeWithClassName) {
|
||||
if ($classType instanceof ThisType) {
|
||||
$classType = $classType->getStaticObjectType();
|
||||
}
|
||||
|
||||
$this->callsByTypeAndMethod[$classType->getClassName()][$methodName][] = $node;
|
||||
$this->addParentTypeWithClassName($classType, $node, $methodName);
|
||||
}
|
||||
|
||||
if ($classType instanceof UnionType) {
|
||||
|
@ -862,4 +870,31 @@ final class NodeRepository
|
|||
|
||||
return $classReflections;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MethodCall|StaticCall $node
|
||||
*/
|
||||
private function addParentTypeWithClassName(
|
||||
TypeWithClassName $typeWithClassName,
|
||||
Node $node,
|
||||
string $methodName
|
||||
): void {
|
||||
// include also parent types
|
||||
if (! $typeWithClassName instanceof ObjectType) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $this->reflectionProvider->hasClass($typeWithClassName->getClassName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$classReflection = $this->reflectionProvider->getClass($typeWithClassName->getClassName());
|
||||
if (! $classReflection instanceof ClassReflection) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($classReflection->getAncestors() as $ancestorClassReflection) {
|
||||
$this->callsByTypeAndMethod[$ancestorClassReflection->getName()][$methodName][] = $node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\NodeTypeCorrector;
|
||||
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\TypeUtils;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
|
||||
use Rector\NodeTypeResolver\Reflection\ClassReflectionTypesResolver;
|
||||
|
||||
final class ParentClassLikeTypeCorrector
|
||||
{
|
||||
/**
|
||||
* @var TypeFactory
|
||||
*/
|
||||
private $typeFactory;
|
||||
|
||||
/**
|
||||
* @var ReflectionProvider
|
||||
*/
|
||||
private $reflectionProvider;
|
||||
|
||||
/**
|
||||
* @var ClassReflectionTypesResolver
|
||||
*/
|
||||
private $classReflectionTypesResolver;
|
||||
|
||||
public function __construct(
|
||||
ClassReflectionTypesResolver $classReflectionTypesResolver,
|
||||
ReflectionProvider $reflectionProvider,
|
||||
TypeFactory $typeFactory
|
||||
) {
|
||||
$this->typeFactory = $typeFactory;
|
||||
$this->reflectionProvider = $reflectionProvider;
|
||||
$this->classReflectionTypesResolver = $classReflectionTypesResolver;
|
||||
}
|
||||
|
||||
public function correct(Type $type): Type
|
||||
{
|
||||
if ($type instanceof TypeWithClassName) {
|
||||
if (! $this->reflectionProvider->hasClass($type->getClassName())) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
$allTypes = $this->getClassLikeTypesByClassName($type->getClassName());
|
||||
return $this->typeFactory->createObjectTypeOrUnionType($allTypes);
|
||||
}
|
||||
|
||||
$classNames = TypeUtils::getDirectClassNames($type);
|
||||
|
||||
$allTypes = [];
|
||||
foreach ($classNames as $className) {
|
||||
if (! $this->reflectionProvider->hasClass($className)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$allTypes = array_merge($allTypes, $this->getClassLikeTypesByClassName($className));
|
||||
}
|
||||
|
||||
return $this->typeFactory->createObjectTypeOrUnionType($allTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function getClassLikeTypesByClassName(string $className): array
|
||||
{
|
||||
$classReflection = $this->reflectionProvider->getClass($className);
|
||||
$classLikeTypes = $this->classReflectionTypesResolver->resolve($classReflection);
|
||||
|
||||
return array_unique($classLikeTypes);
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ namespace Rector\NodeTypeResolver;
|
|||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
|
@ -14,12 +15,17 @@ use PhpParser\Node\Name;
|
|||
use PhpParser\Node\NullableType;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Scalar;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Type\Accessory\NonEmptyArrayType;
|
||||
use PHPStan\Type\ArrayType;
|
||||
use PHPStan\Type\BooleanType;
|
||||
use PHPStan\Type\Constant\ConstantBooleanType;
|
||||
use PHPStan\Type\FloatType;
|
||||
use PHPStan\Type\IntegerType;
|
||||
use PHPStan\Type\IntersectionType;
|
||||
|
@ -27,16 +33,17 @@ use PHPStan\Type\MixedType;
|
|||
use PHPStan\Type\NullType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\ObjectWithoutClassType;
|
||||
use PHPStan\Type\ThisType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\TypeCombinator;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\NodeAnalyzer\ClassAnalyzer;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeCorrector\GenericClassStringTypeCorrector;
|
||||
use Rector\NodeTypeResolver\NodeTypeCorrector\ParentClassLikeTypeCorrector;
|
||||
use Rector\NodeTypeResolver\TypeAnalyzer\ArrayTypeAnalyzer;
|
||||
use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper;
|
||||
use Rector\StaticTypeMapper\TypeFactory\UnionTypeFactory;
|
||||
|
@ -61,11 +68,6 @@ final class NodeTypeResolver
|
|||
*/
|
||||
private $arrayTypeAnalyzer;
|
||||
|
||||
/**
|
||||
* @var ParentClassLikeTypeCorrector
|
||||
*/
|
||||
private $parentClassLikeTypeCorrector;
|
||||
|
||||
/**
|
||||
* @var TypeUnwrapper
|
||||
*/
|
||||
|
@ -86,16 +88,27 @@ final class NodeTypeResolver
|
|||
*/
|
||||
private $unionTypeFactory;
|
||||
|
||||
/**
|
||||
* @var ReflectionProvider
|
||||
*/
|
||||
private $reflectionProvider;
|
||||
|
||||
/**
|
||||
* @var NodeNameResolver
|
||||
*/
|
||||
private $nodeNameResolver;
|
||||
|
||||
/**
|
||||
* @param NodeTypeResolverInterface[] $nodeTypeResolvers
|
||||
*/
|
||||
public function __construct(
|
||||
ObjectTypeSpecifier $objectTypeSpecifier,
|
||||
ParentClassLikeTypeCorrector $parentClassLikeTypeCorrector,
|
||||
TypeUnwrapper $typeUnwrapper,
|
||||
ClassAnalyzer $classAnalyzer,
|
||||
GenericClassStringTypeCorrector $genericClassStringTypeCorrector,
|
||||
UnionTypeFactory $unionTypeFactory,
|
||||
ReflectionProvider $reflectionProvider,
|
||||
NodeNameResolver $nodeNameResolver,
|
||||
array $nodeTypeResolvers
|
||||
) {
|
||||
foreach ($nodeTypeResolvers as $nodeTypeResolver) {
|
||||
|
@ -103,15 +116,17 @@ final class NodeTypeResolver
|
|||
}
|
||||
|
||||
$this->objectTypeSpecifier = $objectTypeSpecifier;
|
||||
$this->parentClassLikeTypeCorrector = $parentClassLikeTypeCorrector;
|
||||
$this->typeUnwrapper = $typeUnwrapper;
|
||||
$this->classAnalyzer = $classAnalyzer;
|
||||
$this->genericClassStringTypeCorrector = $genericClassStringTypeCorrector;
|
||||
$this->unionTypeFactory = $unionTypeFactory;
|
||||
$this->reflectionProvider = $reflectionProvider;
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents circular dependency
|
||||
*
|
||||
* @required
|
||||
*/
|
||||
public function autowireNodeTypeResolver(ArrayTypeAnalyzer $arrayTypeAnalyzer): void
|
||||
|
@ -135,37 +150,70 @@ final class NodeTypeResolver
|
|||
|
||||
public function isObjectType(Node $node, ObjectType $requiredObjectType): bool
|
||||
{
|
||||
if ($node instanceof ClassConstFetch) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$resolvedType = $this->resolve($node);
|
||||
|
||||
if ($resolvedType instanceof MixedType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// this should also work with ObjectType and UnionType with ObjectType
|
||||
// use PHPStan types here
|
||||
if ($resolvedType instanceof ThisType) {
|
||||
$resolvedType = $resolvedType->getStaticObjectType();
|
||||
}
|
||||
|
||||
if ($resolvedType instanceof ObjectType) {
|
||||
return $this->isObjectTypeOfObjectType($resolvedType, $requiredObjectType);
|
||||
}
|
||||
|
||||
if ($requiredObjectType->isSuperTypeOf($resolvedType)->yes()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($resolvedType->equals($requiredObjectType)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->isMatchingUnionType($requiredObjectType, $resolvedType);
|
||||
return $this->isMatchingUnionType($resolvedType, $requiredObjectType);
|
||||
}
|
||||
|
||||
public function resolve(Node $node): Type
|
||||
{
|
||||
$type = $this->resolveFirstType($node);
|
||||
|
||||
if ($type instanceof IntersectionType) {
|
||||
foreach ($type->getTypes() as $intersectionedType) {
|
||||
if ($intersectionedType instanceof TypeWithClassName) {
|
||||
return $this->parentClassLikeTypeCorrector->correct($intersectionedType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! $type instanceof TypeWithClassName) {
|
||||
$type = $this->resolveByNodeTypeResolvers($node);
|
||||
if ($type !== null) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
return $this->parentClassLikeTypeCorrector->correct($type);
|
||||
$nodeScope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
if (! $nodeScope instanceof Scope) {
|
||||
return new MixedType();
|
||||
}
|
||||
if (! $node instanceof Expr) {
|
||||
return new MixedType();
|
||||
}
|
||||
|
||||
// skip anonymous classes, ref https://github.com/rectorphp/rector/issues/1574
|
||||
if ($node instanceof New_) {
|
||||
$isAnonymousClass = $this->classAnalyzer->isAnonymousClass($node->class);
|
||||
if ($isAnonymousClass) {
|
||||
return new ObjectWithoutClassType();
|
||||
}
|
||||
}
|
||||
|
||||
$type = $nodeScope->getType($node);
|
||||
// hot fix for phpstan not resolving chain method calls
|
||||
|
||||
if (! $node instanceof MethodCall) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
if (! $type instanceof MixedType) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
return $this->resolve($node->var);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -374,6 +422,60 @@ final class NodeTypeResolver
|
|||
return $this->isObjectType($classLike, $objectType);
|
||||
}
|
||||
|
||||
public function resolveObjectTypeToCompare(Node $node): ?ObjectType
|
||||
{
|
||||
if ($node instanceof StaticCall) {
|
||||
return $this->resolveStaticCallClassNameObjectTypeToCompare($node);
|
||||
}
|
||||
|
||||
if ($node instanceof Stmt) {
|
||||
$classLike = $node->getAttribute(ClassLike::class);
|
||||
if ($classLike === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$className = $this->nodeNameResolver->getName($classLike);
|
||||
if ($className === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->reflectionProvider->hasClass($className)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classReflection = $this->reflectionProvider->getClass($className);
|
||||
if ($classReflection instanceof ClassReflection) {
|
||||
return new ObjectType($classReflection->getName(), null, $classReflection);
|
||||
}
|
||||
}
|
||||
|
||||
$callerType = $this->resolve($node);
|
||||
if ($callerType instanceof ThisType) {
|
||||
$callerType = $callerType->getStaticObjectType();
|
||||
}
|
||||
|
||||
if (! $callerType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $callerType;
|
||||
}
|
||||
|
||||
public function resolveObjectTypeFromScope(Scope $scope): ?ObjectType
|
||||
{
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if (! $classReflection instanceof ClassReflection) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$className = $classReflection->getName();
|
||||
if (! $this->reflectionProvider->hasClass($className)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ObjectType($className, null, $classReflection);
|
||||
}
|
||||
|
||||
private function addNodeTypeResolver(NodeTypeResolverInterface $nodeTypeResolver): void
|
||||
{
|
||||
foreach ($nodeTypeResolver->getNodeClasses() as $nodeClass) {
|
||||
|
@ -381,68 +483,26 @@ final class NodeTypeResolver
|
|||
}
|
||||
}
|
||||
|
||||
private function isMatchingUnionType(ObjectType $requiredObjectType, Type $resolvedType): bool
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
private function isMatchingUnionType(Type $resolvedType, ObjectType $requiredObjectType): bool
|
||||
{
|
||||
if (! $resolvedType instanceof UnionType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($resolvedType->getTypes() as $unionedType) {
|
||||
if ($unionedType instanceof TypeWithClassName && is_a(
|
||||
$unionedType->getClassName(),
|
||||
$requiredObjectType->getClassName(),
|
||||
true
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
$type = TypeCombinator::removeNull($resolvedType);
|
||||
|
||||
if (! $unionedType->equals($requiredObjectType)) {
|
||||
continue;
|
||||
}
|
||||
// for falsy nullables
|
||||
$type = TypeCombinator::remove($type, new ConstantBooleanType(false));
|
||||
|
||||
if ($unionedType->equals($requiredObjectType)) {
|
||||
return true;
|
||||
}
|
||||
if (! $type instanceof ObjectType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function resolveFirstType(Node $node): Type
|
||||
{
|
||||
$type = $this->resolveByNodeTypeResolvers($node);
|
||||
if ($type !== null) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
$nodeScope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
if (! $nodeScope instanceof Scope) {
|
||||
return new MixedType();
|
||||
}
|
||||
if (! $node instanceof Expr) {
|
||||
return new MixedType();
|
||||
}
|
||||
|
||||
// skip anonymous classes, ref https://github.com/rectorphp/rector/issues/1574
|
||||
if ($node instanceof New_) {
|
||||
$isAnonymousClass = $this->classAnalyzer->isAnonymousClass($node->class);
|
||||
if ($isAnonymousClass) {
|
||||
return new ObjectWithoutClassType();
|
||||
}
|
||||
}
|
||||
|
||||
$type = $nodeScope->getType($node);
|
||||
// hot fix for phpstan not resolving chain method calls
|
||||
|
||||
if (! $node instanceof MethodCall) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
if (! $type instanceof MixedType) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
return $this->resolveFirstType($node->var);
|
||||
return $type->isInstanceOf($requiredObjectType->getClassName())
|
||||
->yes();
|
||||
}
|
||||
|
||||
private function resolveArrayType(Expr $expr): Type
|
||||
|
@ -534,4 +594,59 @@ final class NodeTypeResolver
|
|||
|
||||
return $otherType;
|
||||
}
|
||||
|
||||
private function resolveStaticCallClassNameObjectTypeToCompare(StaticCall $staticCall): ?ObjectType
|
||||
{
|
||||
$className = $this->nodeNameResolver->getName($staticCall->class);
|
||||
|
||||
if ($className === 'parent') {
|
||||
/** @var Scope $scope */
|
||||
$scope = $staticCall->getAttribute(AttributeKey::SCOPE);
|
||||
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if (! $classReflection instanceof ClassReflection) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$className = $classReflection->getName();
|
||||
}
|
||||
|
||||
if ($className === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->reflectionProvider->hasClass($className)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classReflection = $this->reflectionProvider->getClass($className);
|
||||
return new ObjectType($classReflection->getName(), null, $classReflection);
|
||||
}
|
||||
|
||||
private function isObjectTypeOfObjectType(ObjectType $resolvedObjectType, ObjectType $requiredObjectType): bool
|
||||
{
|
||||
if ($resolvedObjectType->isInstanceOf($requiredObjectType->getClassName())->yes()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($resolvedObjectType->getClassName() === $requiredObjectType->getClassName()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (! $this->reflectionProvider->hasClass($resolvedObjectType->getClassName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$classReflection = $this->reflectionProvider->getClass($resolvedObjectType->getClassName());
|
||||
|
||||
if ($classReflection instanceof ClassReflection) {
|
||||
foreach ($classReflection->getAncestors() as $ancestorClassReflection) {
|
||||
if ($ancestorClassReflection->hasTraitUse($requiredObjectType->getClassName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $classReflection->isSubclassOf($requiredObjectType->getClassName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,30 +10,17 @@ use PhpParser\Node\Stmt\Interface_;
|
|||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
|
||||
use Rector\NodeTypeResolver\Reflection\ClassReflectionTypesResolver;
|
||||
|
||||
/**
|
||||
* @see \Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ClassAndInterfaceTypeResolver\ClassTypeResolverTest
|
||||
* @see \Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ClassAndInterfaceTypeResolver\InterfaceTypeResolverTest
|
||||
*/
|
||||
final class ClassAndInterfaceTypeResolver implements NodeTypeResolverInterface
|
||||
{
|
||||
/**
|
||||
* @var ClassReflectionTypesResolver
|
||||
*/
|
||||
private $classReflectionTypesResolver;
|
||||
|
||||
/**
|
||||
* @var TypeFactory
|
||||
*/
|
||||
private $typeFactory;
|
||||
|
||||
public function __construct(ClassReflectionTypesResolver $classReflectionTypesResolver, TypeFactory $typeFactory)
|
||||
{
|
||||
$this->classReflectionTypesResolver = $classReflectionTypesResolver;
|
||||
$this->typeFactory = $typeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
|
@ -58,8 +45,6 @@ final class ClassAndInterfaceTypeResolver implements NodeTypeResolverInterface
|
|||
return new MixedType();
|
||||
}
|
||||
|
||||
$classTypes = $this->classReflectionTypesResolver->resolve($classReflection);
|
||||
|
||||
return $this->typeFactory->createObjectTypeOrUnionType($classTypes);
|
||||
return new ObjectType($classReflection->getName(), null, $classReflection);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PHPStan\Type\Generic\GenericClassStringType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
|
||||
final class ClassConstFetchTypeResolver implements NodeTypeResolverInterface
|
||||
{
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
private $nodeTypeResolver;
|
||||
|
||||
/**
|
||||
* @var NodeNameResolver
|
||||
*/
|
||||
private $nodeNameResolver;
|
||||
|
||||
/**
|
||||
* To avoid cricular references
|
||||
* @required
|
||||
*/
|
||||
public function autowireClassConstFetchTypeResolver(
|
||||
NodeTypeResolver $nodeTypeResolver,
|
||||
NodeNameResolver $nodeNameResolver
|
||||
): void {
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeClasses(): array
|
||||
{
|
||||
return [ClassConstFetch::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassConstFetch $node
|
||||
*/
|
||||
public function resolve(Node $node): Type
|
||||
{
|
||||
if ($this->nodeNameResolver->isName($node->name, 'class')) {
|
||||
$className = $this->nodeNameResolver->getName($node->class);
|
||||
if ($className !== null) {
|
||||
return new GenericClassStringType(new ObjectType($className));
|
||||
}
|
||||
}
|
||||
|
||||
return $this->nodeTypeResolver->resolve($node->class);
|
||||
}
|
||||
}
|
|
@ -101,18 +101,17 @@ final class VariableTypeResolver implements NodeTypeResolverInterface
|
|||
|
||||
private function resolveTypesFromScope(Variable $variable, string $variableName): Type
|
||||
{
|
||||
$nodeScope = $this->resolveNodeScope($variable);
|
||||
|
||||
if (! $nodeScope instanceof Scope) {
|
||||
$scope = $this->resolveNodeScope($variable);
|
||||
if (! $scope instanceof Scope) {
|
||||
return new MixedType();
|
||||
}
|
||||
|
||||
if (! $nodeScope->hasVariableType($variableName)->yes()) {
|
||||
if (! $scope->hasVariableType($variableName)->yes()) {
|
||||
return new MixedType();
|
||||
}
|
||||
|
||||
// this → object type is easier to work with and consistent with the rest of the code
|
||||
return $nodeScope->getVariableType($variableName);
|
||||
return $scope->getVariableType($variableName);
|
||||
}
|
||||
|
||||
private function resolveNodeScope(Variable $variable): ?Scope
|
||||
|
|
|
@ -178,15 +178,17 @@ final class PHPStanNodeScopeResolver
|
|||
/**
|
||||
* @param Class_|Interface_ $classLike
|
||||
*/
|
||||
private function resolveClassOrInterfaceScope(ClassLike $classLike, Scope $scope): MutatingScope
|
||||
private function resolveClassOrInterfaceScope(ClassLike $classLike, Scope $scope): Scope
|
||||
{
|
||||
$className = $this->resolveClassName($classLike);
|
||||
|
||||
// is anonymous class? - not possible to enter it since PHPStan 0.12.33, see https://github.com/phpstan/phpstan-src/commit/e87fb0ec26f9c8552bbeef26a868b1e5d8185e91
|
||||
if ($classLike instanceof Class_ && Strings::match($className, self::ANONYMOUS_CLASS_START_REGEX)) {
|
||||
$classReflection = $this->reflectionProvider->getAnonymousClassReflection($classLike, $scope);
|
||||
} else {
|
||||
} elseif ($this->reflectionProvider->hasClass($className)) {
|
||||
$classReflection = $this->reflectionProvider->getClass($className);
|
||||
} else {
|
||||
return $scope;
|
||||
}
|
||||
|
||||
/** @var MutatingScope $scope */
|
||||
|
|
|
@ -12,12 +12,10 @@ use PHPStan\Type\Constant\ConstantStringType;
|
|||
use PHPStan\Type\FloatType;
|
||||
use PHPStan\Type\IntegerType;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\StringType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use PHPStan\Type\VerbosityLevel;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\StaticTypeMapper\TypeFactory\UnionTypeFactory;
|
||||
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
||||
use Rector\StaticTypeMapper\ValueObject\Type\ShortenedObjectType;
|
||||
|
@ -56,24 +54,6 @@ final class TypeFactory
|
|||
return $this->createUnionOrSingleType($types);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $allTypes
|
||||
* @return ObjectType|UnionType
|
||||
*/
|
||||
public function createObjectTypeOrUnionType(array $allTypes): Type
|
||||
{
|
||||
if (count($allTypes) === 1) {
|
||||
return new ObjectType($allTypes[0]);
|
||||
}
|
||||
|
||||
if (count($allTypes) > 1) {
|
||||
// keep original order, UnionType internally overrides it → impossible to get first type back, e.g. class over interface
|
||||
return $this->unionTypeFactory->createUnionObjectType($allTypes);
|
||||
}
|
||||
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Type[] $types
|
||||
* @return Type[]
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\Reflection;
|
||||
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
|
||||
final class ClassReflectionTypesResolver
|
||||
{
|
||||
/**
|
||||
* @var ReflectionProvider
|
||||
*/
|
||||
private $reflectionProvider;
|
||||
|
||||
public function __construct(ReflectionProvider $reflectionProvider)
|
||||
{
|
||||
$this->reflectionProvider = $reflectionProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning: Includes original class as well to normalize all types to strings!
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function resolve(ClassReflection $classReflection): array
|
||||
{
|
||||
// current class
|
||||
$types = [$classReflection->getName()];
|
||||
|
||||
// parent classes
|
||||
$types = array_merge($types, $classReflection->getParentClassesNames());
|
||||
|
||||
// interfaces
|
||||
foreach ($classReflection->getInterfaces() as $interfaceReflection) {
|
||||
$types[] = $interfaceReflection->getName();
|
||||
}
|
||||
|
||||
foreach ($classReflection->getInterfaces() as $interfaceReflection) {
|
||||
$types[] = $interfaceReflection->getName();
|
||||
}
|
||||
|
||||
// traits
|
||||
foreach ($classReflection->getTraits() as $traitReflection) {
|
||||
$types[] = $traitReflection->getName();
|
||||
}
|
||||
|
||||
// to cover traits of parent classes
|
||||
foreach ($classReflection->getParentClassesNames() as $parentClassName) {
|
||||
$parentClassReflection = $this->reflectionProvider->getClass($parentClassName);
|
||||
|
||||
foreach ($parentClassReflection->getTraits() as $parentClassTrait) {
|
||||
$types[] = $parentClassTrait->getName();
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique($types);
|
||||
}
|
||||
}
|
|
@ -6,16 +6,13 @@ namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ClassAndInterfaceTyp
|
|||
|
||||
use Iterator;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\AbstractNodeTypeResolverTest;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ClassAndInterfaceTypeResolver\Source\AnotherTrait;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ClassAndInterfaceTypeResolver\Source\ClassWithParentClass;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ClassAndInterfaceTypeResolver\Source\ClassWithParentInterface;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ClassAndInterfaceTypeResolver\Source\ClassWithParentTrait;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ClassAndInterfaceTypeResolver\Source\ClassWithTrait;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ClassAndInterfaceTypeResolver\Source\ParentClass;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ClassAndInterfaceTypeResolver\Source\SomeInterface;
|
||||
use Rector\StaticTypeMapper\TypeFactory\UnionTypeFactory;
|
||||
|
||||
/**
|
||||
* @see \Rector\NodeTypeResolver\NodeTypeResolver\ClassAndInterfaceTypeResolver
|
||||
|
@ -25,55 +22,35 @@ final class ClassTypeResolverTest extends AbstractNodeTypeResolverTest
|
|||
/**
|
||||
* @dataProvider dataProvider()
|
||||
*/
|
||||
public function test(string $file, int $nodePosition, Type $expectedType): void
|
||||
public function test(string $file, int $nodePosition, ObjectType $expectedObjectType): void
|
||||
{
|
||||
$variableNodes = $this->getNodesForFileOfType($file, Class_::class);
|
||||
|
||||
$resolvedType = $this->nodeTypeResolver->resolve($variableNodes[$nodePosition]);
|
||||
$this->assertEquals($expectedType, $resolvedType);
|
||||
$this->assertInstanceOf(TypeWithClassName::class, $resolvedType);
|
||||
|
||||
/** @var TypeWithClassName $resolvedType */
|
||||
$this->assertEquals($expectedObjectType->getClassName(), $resolvedType->getClassName());
|
||||
}
|
||||
|
||||
public function dataProvider(): Iterator
|
||||
{
|
||||
$unionTypeFactory = new UnionTypeFactory();
|
||||
|
||||
yield [
|
||||
__DIR__ . '/Source/ClassWithParentInterface.php',
|
||||
0,
|
||||
$unionTypeFactory->createUnionObjectType([ClassWithParentInterface::class, SomeInterface::class]),
|
||||
new ObjectType(ClassWithParentInterface::class),
|
||||
];
|
||||
|
||||
yield [
|
||||
__DIR__ . '/Source/ClassWithParentClass.php',
|
||||
0,
|
||||
$unionTypeFactory->createUnionObjectType([ClassWithParentClass::class, ParentClass::class]),
|
||||
];
|
||||
yield [__DIR__ . '/Source/ClassWithParentClass.php', 0, new ObjectType(ClassWithParentClass::class)];
|
||||
|
||||
yield [
|
||||
__DIR__ . '/Source/ClassWithTrait.php',
|
||||
0,
|
||||
$unionTypeFactory->createUnionObjectType([ClassWithTrait::class, AnotherTrait::class]),
|
||||
];
|
||||
yield [__DIR__ . '/Source/ClassWithTrait.php', 0, new ObjectType(ClassWithTrait::class)];
|
||||
|
||||
yield [
|
||||
__DIR__ . '/Source/ClassWithParentTrait.php',
|
||||
0,
|
||||
$unionTypeFactory->createUnionObjectType(
|
||||
[ClassWithParentTrait::class, ClassWithTrait::class, AnotherTrait::class]
|
||||
),
|
||||
];
|
||||
yield [__DIR__ . '/Source/ClassWithParentTrait.php', 0, new ObjectType(ClassWithParentTrait::class)];
|
||||
|
||||
yield [
|
||||
__DIR__ . '/Source/AnonymousClass.php',
|
||||
0,
|
||||
$unionTypeFactory->createUnionObjectType(
|
||||
[
|
||||
'AnonymousClassdefa360846b84894d4be1b25c2ce6da9',
|
||||
ParentClass::class,
|
||||
SomeInterface::class,
|
||||
AnotherTrait::class,
|
||||
]
|
||||
),
|
||||
new ObjectType('AnonymousClassdefa360846b84894d4be1b25c2ce6da9'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,10 @@ namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ClassAndInterfaceTyp
|
|||
|
||||
use Iterator;
|
||||
use PhpParser\Node\Stmt\Interface_;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\AbstractNodeTypeResolverTest;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ClassAndInterfaceTypeResolver\Source\SomeInterfaceWithParentInterface;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ClassAndInterfaceTypeResolver\Source\SomeParentInterface;
|
||||
use Rector\StaticTypeMapper\TypeFactory\UnionTypeFactory;
|
||||
|
||||
/**
|
||||
* @see \Rector\NodeTypeResolver\NodeTypeResolver\ClassAndInterfaceTypeResolver
|
||||
|
@ -20,22 +19,23 @@ final class InterfaceTypeResolverTest extends AbstractNodeTypeResolverTest
|
|||
/**
|
||||
* @dataProvider dataProvider()
|
||||
*/
|
||||
public function test(string $file, int $nodePosition, Type $expectedType): void
|
||||
public function test(string $file, int $nodePosition, TypeWithClassName $expectedTypeWithClassName): void
|
||||
{
|
||||
$variableNodes = $this->getNodesForFileOfType($file, Interface_::class);
|
||||
|
||||
$resolvedType = $this->nodeTypeResolver->resolve($variableNodes[$nodePosition]);
|
||||
$this->assertEquals($expectedType, $resolvedType);
|
||||
$this->assertInstanceOf(TypeWithClassName::class, $resolvedType);
|
||||
|
||||
/** @var TypeWithClassName $resolvedType */
|
||||
$this->assertEquals($expectedTypeWithClassName->getClassName(), $resolvedType->getClassName());
|
||||
}
|
||||
|
||||
public function dataProvider(): Iterator
|
||||
{
|
||||
$unionTypeFactory = new UnionTypeFactory();
|
||||
|
||||
$unionType = $unionTypeFactory->createUnionObjectType(
|
||||
[SomeInterfaceWithParentInterface::class, SomeParentInterface::class]
|
||||
);
|
||||
|
||||
yield [__DIR__ . '/Source/SomeInterfaceWithParentInterface.php', 0, $unionType];
|
||||
yield [
|
||||
__DIR__ . '/Source/SomeInterfaceWithParentInterface.php',
|
||||
0,
|
||||
new ObjectType(SomeInterfaceWithParentInterface::class),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ParamTypeResolver;
|
|||
use Iterator;
|
||||
use PhpParser\Node\Param;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\AbstractNodeTypeResolverTest;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\ParamTypeResolver\Source\Html;
|
||||
|
||||
|
@ -19,12 +19,16 @@ final class ParamTypeResolverTest extends AbstractNodeTypeResolverTest
|
|||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(string $file, int $nodePosition, Type $expectedType): void
|
||||
public function test(string $file, int $nodePosition, TypeWithClassName $expectedTypeWithClassName): void
|
||||
{
|
||||
$variableNodes = $this->getNodesForFileOfType($file, Param::class);
|
||||
|
||||
$resolvedType = $this->nodeTypeResolver->resolve($variableNodes[$nodePosition]);
|
||||
$this->assertEquals($expectedType, $resolvedType);
|
||||
|
||||
$this->assertInstanceOf(TypeWithClassName::class, $resolvedType);
|
||||
|
||||
/** @var TypeWithClassName $resolvedType */
|
||||
$this->assertSame($expectedTypeWithClassName->getClassName(), $resolvedType->getClassName());
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
|
|
|
@ -46,11 +46,7 @@ final class PropertyTypeResolverTest extends AbstractNodeTypeResolverTest
|
|||
|
||||
yield [__DIR__ . '/Source/MethodParamDocBlock.php', 0, new ObjectType(Html::class)];
|
||||
|
||||
yield [
|
||||
__DIR__ . '/Source/MethodParamDocBlock.php',
|
||||
1,
|
||||
$unionTypeFactory->createUnionObjectType([ClassThatExtendsHtml::class, Html::class]),
|
||||
];
|
||||
yield [__DIR__ . '/Source/MethodParamDocBlock.php', 1, new ObjectType(ClassThatExtendsHtml::class)];
|
||||
|
||||
// mimics failing test from DomainDrivenDesign set
|
||||
$unionType = $unionTypeFactory->createUnionObjectType([SomeChild::class, new NullType()]);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace SomeNamespace;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Fixture;
|
||||
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Source\AnotherType;
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Fixture;
|
||||
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Source\AnotherType;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Source\FirstType;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Source\SecondType;
|
||||
|
||||
final class AssignmentClass
|
||||
{
|
||||
/**
|
||||
* @var FirstType
|
||||
*/
|
||||
private $property;
|
||||
|
||||
public function getValue(): SecondType
|
||||
{
|
||||
$variable = new AnotherType();
|
||||
$assignedVariable = $variable;
|
||||
}
|
||||
}
|
||||
|
||||
$someClass = new NewClass;
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Fixture;
|
||||
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Source\AnotherType;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Source\FirstType;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Source\SecondType;
|
||||
|
||||
final class NewClass
|
||||
{
|
||||
/**
|
||||
* @var FirstType
|
||||
*/
|
||||
private $property;
|
||||
|
||||
public function getValue(): SecondType
|
||||
{
|
||||
$variable = new AnotherType();
|
||||
$variable->test();
|
||||
$assignedVariable = $variable;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Source;
|
||||
namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Fixture;
|
||||
|
||||
use Rector\NodeTypeResolver\Tests\Source\AnotherClass;
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Source;
|
||||
|
||||
final class AssignmentClass
|
||||
{
|
||||
/**
|
||||
* @var FirstType
|
||||
*/
|
||||
private $property;
|
||||
|
||||
public function getValue(): SecondType
|
||||
{
|
||||
$variable = new AnotherType;
|
||||
$assignedVariable = $variable;
|
||||
}
|
||||
}
|
||||
|
||||
$someClass = new NewClass;
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Source;
|
||||
|
||||
final class NewClass
|
||||
{
|
||||
/**
|
||||
* @var FirstType
|
||||
*/
|
||||
private $property;
|
||||
|
||||
public function getValue(): SecondType
|
||||
{
|
||||
$variable = new AnotherType;
|
||||
$variable->test();
|
||||
$assignedVariable = $variable;
|
||||
}
|
||||
}
|
|
@ -7,12 +7,12 @@ namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver
|
|||
use Iterator;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\ThisType;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\AbstractNodeTypeResolverTest;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Fixture\ThisClass;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Source\AnotherType;
|
||||
use Rector\NodeTypeResolver\Tests\PerNodeTypeResolver\VariableTypeResolver\Source\ThisClass;
|
||||
use Rector\NodeTypeResolver\Tests\Source\AnotherClass;
|
||||
use Rector\StaticTypeMapper\TypeFactory\UnionTypeFactory;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* @see \Rector\NodeTypeResolver\NodeTypeResolver\VariableTypeResolver
|
||||
|
@ -22,29 +22,25 @@ final class VariableTypeResolverTest extends AbstractNodeTypeResolverTest
|
|||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(string $file, int $nodePosition, Type $expectedType): void
|
||||
public function test(string $file, int $nodePosition, TypeWithClassName $expectedTypeWithClassName): void
|
||||
{
|
||||
$variableNodes = $this->getNodesForFileOfType($file, Variable::class);
|
||||
|
||||
$resolvedType = $this->nodeTypeResolver->resolve($variableNodes[$nodePosition]);
|
||||
$this->assertEquals($expectedType, $resolvedType);
|
||||
$this->assertInstanceOf(TypeWithClassName::class, $resolvedType);
|
||||
|
||||
/** @var TypeWithClassName $resolvedType */
|
||||
$this->assertEquals($expectedTypeWithClassName->getClassName(), $resolvedType->getClassName());
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
$unionTypeFactory = new UnionTypeFactory();
|
||||
|
||||
yield [
|
||||
__DIR__ . '/Source/ThisClass.php',
|
||||
0,
|
||||
$unionTypeFactory->createUnionObjectType([ThisClass::class, AnotherClass::class]),
|
||||
];
|
||||
yield [__DIR__ . '/Fixture/this_class.php.inc', 0, new ThisType(new ReflectionClass(ThisClass::class))];
|
||||
|
||||
$anotherTypeObjectType = new ObjectType(AnotherType::class);
|
||||
|
||||
yield [__DIR__ . '/Source/NewClass.php', 1, $anotherTypeObjectType];
|
||||
yield [__DIR__ . '/Source/NewClass.php', 3, $anotherTypeObjectType];
|
||||
yield [__DIR__ . '/Source/AssignmentClass.php', 2, $anotherTypeObjectType];
|
||||
yield [__DIR__ . '/Source/ArgumentTypehint.php', 1, $anotherTypeObjectType];
|
||||
yield [__DIR__ . '/Fixture/new_class.php.inc', 1, $anotherTypeObjectType];
|
||||
yield [__DIR__ . '/Fixture/new_class.php.inc', 3, $anotherTypeObjectType];
|
||||
yield [__DIR__ . '/Fixture/assignment_class.php.inc', 2, $anotherTypeObjectType];
|
||||
yield [__DIR__ . '/Fixture/argument_typehint.php.inc', 1, $anotherTypeObjectType];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ use PhpParser\Node\Expr;
|
|||
use PhpParser\Node\Expr\BinaryOp;
|
||||
use PhpParser\Node\FunctionLike;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
|
@ -17,22 +18,25 @@ use PHPStan\Type\Generic\GenericClassStringType;
|
|||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\Core\Contract\Rector\RectorInterface;
|
||||
use Rector\NodeTypeResolver\NodeTypeCorrector\GenericClassStringTypeCorrector;
|
||||
|
||||
final class UnionTypeCommonTypeNarrower
|
||||
{
|
||||
/**
|
||||
* Key = the winner
|
||||
* Array = the group of types matched
|
||||
* Key = the winner Array = the group of types matched
|
||||
*
|
||||
* @var array<class-string<Node|\PHPStan\PhpDocParser\Ast\Node>, array<class-string<Node|\PHPStan\PhpDocParser\Ast\Node>>>
|
||||
* @var array<string, array<class-string<Node>|class-string<\PHPStan\PhpDocParser\Ast\Node>|class-string<RectorInterface>>>
|
||||
*/
|
||||
private const PRIORITY_TYPES = [
|
||||
ClassLike::class => [ClassLike::class],
|
||||
FunctionLike::class => [FunctionLike::class],
|
||||
BinaryOp::class => [BinaryOp::class, Expr::class],
|
||||
Expr::class => [Node::class, Expr::class],
|
||||
Stmt::class => [Node::class, Stmt::class],
|
||||
PhpDocTagValueNode::class => [PhpDocTagValueNode::class, \PHPStan\PhpDocParser\Ast\Node::class],
|
||||
Node::class => [Node::class],
|
||||
RectorInterface::class => [RectorInterface::class],
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -120,10 +124,15 @@ final class UnionTypeCommonTypeNarrower
|
|||
|
||||
$typeClassReflections = $this->resolveClassParentClassesAndInterfaces($unionedType);
|
||||
$typeClassNames = [];
|
||||
|
||||
foreach ($typeClassReflections as $typeClassReflection) {
|
||||
$typeClassNames[] = $typeClassReflection->getName();
|
||||
}
|
||||
|
||||
if ($typeClassNames === []) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$availableTypes[] = $typeClassNames;
|
||||
}
|
||||
|
||||
|
@ -159,9 +168,12 @@ final class UnionTypeCommonTypeNarrower
|
|||
*/
|
||||
private function narrowAvailableTypes(array $availableTypes): array
|
||||
{
|
||||
if (count($availableTypes) < 2) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/** @var string[] $sharedTypes */
|
||||
$sharedTypes = array_intersect(...$availableTypes);
|
||||
|
||||
return array_values($sharedTypes);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ use PhpParser\Node\Name;
|
|||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\NullableType;
|
||||
use PhpParser\Node\UnionType as PhpParserUnionType;
|
||||
use PhpParser\NodeAbstract;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use PHPStan\Type\IterableType;
|
||||
use PHPStan\Type\NullType;
|
||||
|
@ -22,6 +23,7 @@ use Rector\AttributeAwarePhpDoc\Ast\Type\AttributeAwareUnionTypeNode;
|
|||
use Rector\CodeQuality\Tests\Rector\If_\ExplicitBoolCompareRector\Fixture\Nullable;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\Php\PhpVersionProvider;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface;
|
||||
use Rector\PHPStanStaticTypeMapper\DoctrineTypeAnalyzer;
|
||||
|
@ -295,7 +297,7 @@ final class UnionTypeMapper implements TypeMapperInterface
|
|||
|
||||
$sharedTypeWithClassName = $this->matchTwoObjectTypes($unionType);
|
||||
if ($sharedTypeWithClassName instanceof TypeWithClassName) {
|
||||
return $sharedTypeWithClassName;
|
||||
return $this->correctObjectType($sharedTypeWithClassName);
|
||||
}
|
||||
|
||||
// find least common denominator
|
||||
|
@ -332,4 +334,17 @@ final class UnionTypeMapper implements TypeMapperInterface
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function correctObjectType(TypeWithClassName $typeWithClassName): TypeWithClassName
|
||||
{
|
||||
if ($typeWithClassName->getClassName() === NodeAbstract::class) {
|
||||
return new ObjectType('PhpParser\Node');
|
||||
}
|
||||
|
||||
if ($typeWithClassName->getClassName() === AbstractRector::class) {
|
||||
return new ObjectType('Rector\Core\Contract\Rector\RectorInterface');
|
||||
}
|
||||
|
||||
return $typeWithClassName;
|
||||
}
|
||||
}
|
||||
|
|
10
phpstan.neon
10
phpstan.neon
|
@ -616,3 +616,13 @@ parameters:
|
|||
- src/Console/Command/ProcessCommand.php
|
||||
|
||||
- '#Content of method "getNextExpression\(\)" is duplicated with method "getNextExpression\(\)" in "Rector\\CodingStyle\\Rector\\Assign\\ManualJsonStringToJsonEncodeArrayRector" class\. Use unique content or service instead#'
|
||||
- '#Content of method "getFunctionLikePhpDocInfo\(\)" is duplicated with method "getFunctionLikePhpDocInfo\(\)" in "Rector\\NodeTypeResolver\\NodeTypeResolver\\ParamTypeResolver" class\. Use unique content or service instead#'
|
||||
|
||||
# faking phpstan reflection in tests
|
||||
- '#Parameter \#1 \$classReflection of class PHPStan\\Type\\ThisType constructor expects PHPStan\\Reflection\\ClassReflection\|string, ReflectionClass<Rector\\NodeTypeResolver\\Tests\\PerNodeTypeResolver\\VariableTypeResolver\\Fixture\\ThisClass\> given#'
|
||||
-
|
||||
message: '#Instead of "ReflectionClass" class/interface use "PHPStan\\Reflection\\ClassReflection"#'
|
||||
paths:
|
||||
- packages/node-type-resolver/tests/PerNodeTypeResolver/VariableTypeResolver/VariableTypeResolverTest.php
|
||||
|
||||
- '#Cognitive complexity for "Rector\\EarlyReturn\\Rector\\If_\\ChangeAndIfToEarlyReturnRector\:\:refactor\(\)" is 10, keep it under 9#'
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
use PHPUnit\Framework\TestCase;
|
||||
use Rector\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector;
|
||||
use Rector\CodingStyle\Rector\String_\SplitStringClassConstantToClassConstFetchRector;
|
||||
use Rector\CodingStyle\ValueObject\PreferenceSelfThis;
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\PhpVersion;
|
||||
|
@ -31,7 +32,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
$services->set(PreferThisOrSelfMethodCallRector::class)
|
||||
->call('configure', [[
|
||||
PreferThisOrSelfMethodCallRector::TYPE_TO_PREFERENCE => [
|
||||
TestCase::class => PreferThisOrSelfMethodCallRector::PREFER_THIS,
|
||||
TestCase::class => PreferenceSelfThis::PREFER_THIS,
|
||||
],
|
||||
]]);
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ use PhpParser\Node\Scalar\String_;
|
|||
use PHPStan\Reflection\Php\PhpMethodReflection;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\ThisType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
|
@ -64,6 +65,11 @@ final class CallableClassMethodMatcher
|
|||
}
|
||||
|
||||
$objectType = $this->nodeTypeResolver->resolve($objectExpr);
|
||||
|
||||
if ($objectType instanceof ThisType) {
|
||||
$objectType = $objectType->getStaticObjectType();
|
||||
}
|
||||
|
||||
$objectType = $this->popFirstObjectType($objectType);
|
||||
|
||||
if ($objectType instanceof ObjectType) {
|
||||
|
|
|
@ -97,12 +97,14 @@ CODE_SAMPLE
|
|||
}
|
||||
|
||||
$propertyFetchVarType = $this->getObjectType($issetVar->var);
|
||||
|
||||
if ($propertyFetchVarType instanceof TypeWithClassName) {
|
||||
if (! $this->reflectionProvider->hasClass($propertyFetchVarType->getClassName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$classReflection = $this->reflectionProvider->getClass($propertyFetchVarType->getClassName());
|
||||
|
||||
if (! $classReflection->hasProperty($propertyFetchName)) {
|
||||
$newNodes[] = $this->replaceToPropertyExistsWithNullCheck(
|
||||
$issetVar->var,
|
||||
|
|
|
@ -12,7 +12,6 @@ final class PropertyAfterInstantiationIfAlwaysExists
|
|||
$obj = new self();
|
||||
isset($obj->x);
|
||||
isset($obj->y);
|
||||
isset($obj->x) && isset($obj->y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +31,6 @@ final class PropertyAfterInstantiationIfAlwaysExists
|
|||
$obj = new self();
|
||||
$obj->x !== null;
|
||||
$obj->y !== null;
|
||||
$obj->x !== null && $obj->y !== null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ use PhpParser\Node;
|
|||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\CodingStyle\ValueObject\PreferenceSelfThis;
|
||||
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
|
||||
use Rector\Core\Exception\Configuration\InvalidConfigurationException;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
|
@ -26,23 +27,6 @@ final class PreferThisOrSelfMethodCallRector extends AbstractRector implements C
|
|||
*/
|
||||
public const TYPE_TO_PREFERENCE = 'type_to_preference';
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PREFER_SELF = self::SELF;
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PREFER_THIS = 'this';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private const ALLOWED_OPTIONS = [self::PREFER_THIS, self::PREFER_SELF];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
@ -79,7 +63,7 @@ CODE_SAMPLE
|
|||
,
|
||||
[
|
||||
self::TYPE_TO_PREFERENCE => [
|
||||
'PHPUnit\Framework\TestCase' => self::PREFER_SELF,
|
||||
'PHPUnit\Framework\TestCase' => PreferenceSelfThis::PREFER_SELF,
|
||||
],
|
||||
]
|
||||
),
|
||||
|
@ -104,7 +88,7 @@ CODE_SAMPLE
|
|||
continue;
|
||||
}
|
||||
|
||||
if ($preference === self::PREFER_SELF) {
|
||||
if ($preference === PreferenceSelfThis::PREFER_SELF) {
|
||||
return $this->processToSelf($node);
|
||||
}
|
||||
|
||||
|
@ -115,7 +99,7 @@ CODE_SAMPLE
|
|||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $configuration
|
||||
* @param array<string, array<class-string, string>> $configuration
|
||||
*/
|
||||
public function configure(array $configuration): void
|
||||
{
|
||||
|
@ -173,7 +157,7 @@ CODE_SAMPLE
|
|||
|
||||
private function ensurePreferenceIsValid(string $preference): void
|
||||
{
|
||||
if (in_array($preference, self::ALLOWED_OPTIONS, true)) {
|
||||
if (in_array($preference, PreferenceSelfThis::ALLOWED_VALUES, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -181,7 +165,7 @@ CODE_SAMPLE
|
|||
'Preference configuration "%s" for "%s" is not valid. Use one of "%s"',
|
||||
$preference,
|
||||
self::class,
|
||||
implode('", "', self::ALLOWED_OPTIONS)
|
||||
implode('", "', PreferenceSelfThis::ALLOWED_VALUES)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
28
rules/coding-style/src/ValueObject/PreferenceSelfThis.php
Normal file
28
rules/coding-style/src/ValueObject/PreferenceSelfThis.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\CodingStyle\ValueObject;
|
||||
|
||||
/**
|
||||
* @enum
|
||||
*/
|
||||
final class PreferenceSelfThis
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public const ALLOWED_VALUES = [self::PREFER_THIS, self::PREFER_SELF];
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PREFER_THIS = 'prefer_this';
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PREFER_SELF = 'prefer_self';
|
||||
}
|
|
@ -4,6 +4,7 @@ use PHPUnit\Framework\TestCase;
|
|||
use Rector\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector;
|
||||
use Rector\CodingStyle\Tests\Rector\MethodCall\PreferThisOrSelfMethodCallRector\Source\AbstractTestCase;
|
||||
use Rector\CodingStyle\Tests\Rector\MethodCall\PreferThisOrSelfMethodCallRector\Source\BeLocalClass;
|
||||
use Rector\CodingStyle\ValueObject\PreferenceSelfThis;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
|
@ -11,9 +12,9 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
$services->set(PreferThisOrSelfMethodCallRector::class)
|
||||
->call('configure', [[
|
||||
PreferThisOrSelfMethodCallRector::TYPE_TO_PREFERENCE => [
|
||||
AbstractTestCase::class => 'self',
|
||||
BeLocalClass::class => 'this',
|
||||
TestCase::class => 'self',
|
||||
AbstractTestCase::class => PreferenceSelfThis::PREFER_SELF,
|
||||
BeLocalClass::class => PreferenceSelfThis::PREFER_THIS,
|
||||
TestCase::class => PreferenceSelfThis::PREFER_SELF,
|
||||
],
|
||||
]]);
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace Rector\DoctrineCodeQuality\Tests\Set\DoctrineRepositoryAsServiceSet\Fi
|
|||
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Rector\DoctrineCodeQuality\Tests\Set\DoctrineRepositoryAsServiceSet\Source\User;
|
||||
|
||||
final class SomeServiceEntityRepository extends ServiceEntityRepository
|
||||
{
|
||||
|
@ -23,10 +23,6 @@ final class SomeServiceEntityRepository extends ServiceEntityRepository
|
|||
}
|
||||
}
|
||||
|
||||
class User
|
||||
{
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
@ -37,12 +33,12 @@ namespace Rector\DoctrineCodeQuality\Tests\Set\DoctrineRepositoryAsServiceSet\Fi
|
|||
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Rector\DoctrineCodeQuality\Tests\Set\DoctrineRepositoryAsServiceSet\Source\User;
|
||||
|
||||
final class SomeServiceEntityRepository
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\ORM\EntityRepository<\Rector\DoctrineCodeQuality\Tests\Set\DoctrineRepositoryAsServiceSet\Fixture\User>
|
||||
* @var \Doctrine\ORM\EntityRepository<\Rector\DoctrineCodeQuality\Tests\Set\DoctrineRepositoryAsServiceSet\Source\User>
|
||||
*/
|
||||
private \Doctrine\ORM\EntityRepository $repository;
|
||||
public function __construct(private \Doctrine\ORM\EntityManagerInterface $entityManager)
|
||||
|
@ -58,8 +54,4 @@ final class SomeServiceEntityRepository
|
|||
}
|
||||
}
|
||||
|
||||
class User
|
||||
{
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DoctrineCodeQuality\Tests\Set\DoctrineRepositoryAsServiceSet\Source;
|
||||
|
||||
final class User
|
||||
{
|
||||
|
||||
}
|
|
@ -8,6 +8,5 @@ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigura
|
|||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
$parameters->set(Option::SETS, [SetList::DOCTRINE_REPOSITORY_AS_SERVICE]);
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ use PhpParser\Node\Expr;
|
|||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
|
@ -158,8 +159,7 @@ CODE_SAMPLE
|
|||
}
|
||||
|
||||
$classReflection = $scope->getClassReflection();
|
||||
|
||||
if ($classReflection === null) {
|
||||
if (! $classReflection instanceof ClassReflection) {
|
||||
// possibly trait/interface
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -6,10 +6,8 @@ namespace Rector\Doctrine\Rector\MethodCall;
|
|||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
|
@ -81,11 +79,12 @@ CODE_SAMPLE
|
|||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($this->shouldSkip($node)) {
|
||||
$callerObjectType = $this->nodeTypeResolver->resolveObjectTypeToCompare($node->var);
|
||||
if (! $callerObjectType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isObjectType($node->var, new ObjectType('Doctrine\ORM\EntityRepository'))) {
|
||||
if (! $callerObjectType->isInstanceOf('Doctrine\ORM\EntityRepository')->yes()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -94,17 +93,6 @@ CODE_SAMPLE
|
|||
}
|
||||
|
||||
$node->var = $this->nodeFactory->createPropertyFetch('this', 'repository');
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
private function shouldSkip(MethodCall $methodCall): bool
|
||||
{
|
||||
$classLike = $methodCall->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $classLike instanceof Class_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ! $this->isObjectType($classLike, new ObjectType('Doctrine\ORM\EntityRepository'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,24 +112,27 @@ CODE_SAMPLE
|
|||
|
||||
/** @var BooleanAnd $expr */
|
||||
$expr = $node->cond;
|
||||
$conditions = $this->nodeRepository->findBooleanAndConditions($expr);
|
||||
$ifNextReturnClone = $ifNextReturn instanceof Return_
|
||||
? clone $ifNextReturn
|
||||
: new Return_();
|
||||
|
||||
$isInLoop = $this->contextAnalyzer->isInLoop($node);
|
||||
$booleanAndConditions = $this->nodeRepository->findBooleanAndConditions($expr);
|
||||
|
||||
if (! $ifNextReturn instanceof Return_) {
|
||||
$this->addNodeAfterNode($node->stmts[0], $node);
|
||||
return $this->processReplaceIfs($node, $conditions, $ifNextReturnClone);
|
||||
return $this->processReplaceIfs($node, $booleanAndConditions, new Return_());
|
||||
}
|
||||
|
||||
if ($ifNextReturn instanceof Return_ && $ifNextReturn->expr instanceof BooleanAnd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->removeNode($ifNextReturn);
|
||||
$ifNextReturn = $node->stmts[0];
|
||||
$this->addNodeAfterNode($ifNextReturn, $node);
|
||||
|
||||
if (! $isInLoop) {
|
||||
return $this->processReplaceIfs($node, $conditions, $ifNextReturnClone);
|
||||
$ifNextReturnClone = $ifNextReturn instanceof Return_
|
||||
? clone $ifNextReturn
|
||||
: new Return_();
|
||||
|
||||
if (! $this->contextAnalyzer->isInLoop($node)) {
|
||||
return $this->processReplaceIfs($node, $booleanAndConditions, $ifNextReturnClone);
|
||||
}
|
||||
|
||||
if (! $ifNextReturn instanceof Expression) {
|
||||
|
@ -140,7 +143,7 @@ CODE_SAMPLE
|
|||
$this->addNodeAfterNode(new Return_(), $node);
|
||||
}
|
||||
|
||||
return $this->processReplaceIfs($node, $conditions, $ifNextReturnClone);
|
||||
return $this->processReplaceIfs($node, $booleanAndConditions, $ifNextReturnClone);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -234,6 +237,7 @@ CODE_SAMPLE
|
|||
if (! $this->contextAnalyzer->isInLoop($if)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) $this->betterNodeFinder->findParentTypes($if, [If_::class, Else_::class, ElseIf_::class]);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\EarlyReturn\Tests\Rector\If_\ChangeAndIfToEarlyReturnRector\Fixture;
|
||||
|
||||
use PHPStan\Type\CallableType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
|
||||
final class SkipIfElseAnd
|
||||
{
|
||||
public function isClosureAndCallableType(Type $parameterStaticType, Type $argumentStaticType): bool
|
||||
{
|
||||
if ($parameterStaticType instanceof CallableType && $this->isClosureObjectType($argumentStaticType)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $argumentStaticType instanceof CallableType && $this->isClosureObjectType($parameterStaticType);
|
||||
}
|
||||
|
||||
private function isClosureObjectType(Type $type): bool
|
||||
{
|
||||
if (! $type instanceof ObjectType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $type->getClassName() === 'Closure';
|
||||
}
|
||||
}
|
|
@ -85,7 +85,12 @@ CODE_SAMPLE
|
|||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isObjectType($node, new ObjectType('Tester\TestCase'))) {
|
||||
$objectType = $this->nodeTypeResolver->resolveObjectTypeToCompare($node);
|
||||
if (! $objectType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $objectType->isInstanceOf('Tester\TestCase')->yes()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,12 @@ CODE_SAMPLE
|
|||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isObjectType($node, new ObjectType('Tester\Assert'))) {
|
||||
$objectType = $this->nodeTypeResolver->resolveObjectTypeToCompare($node);
|
||||
if (! $objectType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $objectType->isInstanceOf('Tester\Assert')->yes()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,12 +67,20 @@ CODE_SAMPLE
|
|||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isOnClassMethodCall($node, new ObjectType('PHPExcel_Style_Conditional'), 'getCondition')) {
|
||||
$callerObjectType = $this->nodeTypeResolver->resolveObjectTypeToCompare($node->var);
|
||||
if (! $callerObjectType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $callerObjectType->isInstanceOf('PHPExcel_Style_Conditional')->yes()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isName($node->name, 'getCondition')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$node->name = new Identifier('getConditions');
|
||||
|
||||
$arrayDimFetch = new ArrayDimFetch($node, new LNumber(0));
|
||||
|
||||
return new Coalesce($arrayDimFetch, new String_(''));
|
||||
|
|
|
@ -152,11 +152,11 @@ CODE_SAMPLE
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Node|Node[] $node
|
||||
* @param Node[] $node
|
||||
*/
|
||||
private function findVariableAssignName($node, string $variableName): ?Node
|
||||
private function findVariableAssignName(array $node, string $variableName): ?Node
|
||||
{
|
||||
return $this->betterNodeFinder->findFirst((array) $node, function (Node $node) use ($variableName): bool {
|
||||
return $this->betterNodeFinder->findFirst($node, function (Node $node) use ($variableName): bool {
|
||||
if (! $node instanceof Assign) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use PhpParser\Node\Expr\MethodCall;
|
|||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\PHPOffice\ValueObject\PHPExcelMethodDefaultValues;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
|
@ -22,587 +23,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
*/
|
||||
final class AddRemovedDefaultValuesRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var array<string, array<string, array<int, mixed[]>>>
|
||||
*/
|
||||
private const METHOD_NAMES_BY_TYPE_WITH_VALUE = [
|
||||
'PHPExcel' => [
|
||||
'setHasMacros' => [false],
|
||||
'setMacrosCode' => [null],
|
||||
'setMacrosCertificate' => [null],
|
||||
'setRibbonXMLData' => [null, null],
|
||||
'setRibbonBinObjects' => [null, null],
|
||||
'getRibbonBinObjects' => ['all'],
|
||||
'getSheetByCodeName' => [''],
|
||||
'createSheet' => [null],
|
||||
'removeSheetByIndex' => [0],
|
||||
'getSheet' => [0],
|
||||
'getSheetByName' => [''],
|
||||
'setActiveSheetIndex' => [0],
|
||||
'setActiveSheetIndexByName' => [''],
|
||||
'getCellXfByIndex' => [0],
|
||||
'getCellXfByHashCode' => [''],
|
||||
'cellXfExists' => [null],
|
||||
'removeCellXfByIndex' => [0],
|
||||
'getCellStyleXfByIndex' => [0],
|
||||
'getCellStyleXfByHashCode' => [''],
|
||||
'removeCellStyleXfByIndex' => [0],
|
||||
],
|
||||
'PHPExcel_CalcEngine_Logger' => [
|
||||
'setWriteDebugLog' => [false],
|
||||
'setEchoDebugLog' => [false],
|
||||
],
|
||||
'PHPExcel_Calculation' => [
|
||||
'setCalculationCacheEnabled' => [true],
|
||||
'setLocale' => ['en_us'],
|
||||
],
|
||||
'PHPExcel_Calculation_FormulaToken' => [
|
||||
'setTokenType' => ['PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN'],
|
||||
'setTokenSubType' => ['PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING'],
|
||||
],
|
||||
'PHPExcel_Cell' => [
|
||||
'setValue' => [null],
|
||||
'setValueExplicit' => [null, 'PHPExcel_Cell_DataType::TYPE_STRING'],
|
||||
'setCalculatedValue' => [null],
|
||||
'setDataType' => ['PHPExcel_Cell_DataType::TYPE_STRING'],
|
||||
'isInRange' => ['A1:A1'],
|
||||
'coordinateFromString' => ['A1'],
|
||||
'absoluteReference' => ['A1'],
|
||||
'absoluteCoordinate' => ['A1'],
|
||||
'splitRange' => ['A1:A1'],
|
||||
'rangeBoundaries' => ['A1:A1'],
|
||||
'rangeDimension' => ['A1:A1'],
|
||||
'getRangeBoundaries' => ['A1:A1'],
|
||||
'columnIndexFromString' => ['A'],
|
||||
'stringFromColumnIndex' => [0],
|
||||
'extractAllCellReferencesInRange' => ['A1'],
|
||||
'setXfIndex' => [0],
|
||||
],
|
||||
'PHPExcel_Cell_DataType' => [
|
||||
'checkString' => [null],
|
||||
'checkErrorCode' => [null],
|
||||
],
|
||||
'PHPExcel_Cell_DataValidation' => [
|
||||
'setFormula1' => [''],
|
||||
'setFormula2' => [''],
|
||||
'setType' => ['PHPExcel_Cell_DataValidation::TYPE_NONE'],
|
||||
'setErrorStyle' => ['PHPExcel_Cell_DataValidation::STYLE_STOP'],
|
||||
'setOperator' => [''],
|
||||
'setAllowBlank' => [false],
|
||||
'setShowDropDown' => [false],
|
||||
'setShowInputMessage' => [false],
|
||||
'setShowErrorMessage' => [false],
|
||||
'setErrorTitle' => [''],
|
||||
'setError' => [''],
|
||||
'setPromptTitle' => [''],
|
||||
'setPrompt' => [''],
|
||||
],
|
||||
'PHPExcel_Cell_DefaultValueBinder' => [
|
||||
'dataTypeForValue' => [null],
|
||||
],
|
||||
'PHPExcel_Cell_Hyperlink' => [
|
||||
'setUrl' => [''],
|
||||
'setTooltip' => [''],
|
||||
],
|
||||
'PHPExcel_Chart' => [
|
||||
'setPlotVisibleOnly' => [true],
|
||||
'setDisplayBlanksAs' => ['0'],
|
||||
'setTopLeftOffset' => [null, null],
|
||||
'setBottomRightOffset' => [null, null],
|
||||
],
|
||||
'PHPExcel_Chart_DataSeries' => [
|
||||
'setPlotType' => [''],
|
||||
'setPlotGrouping' => [null],
|
||||
'setPlotDirection' => [null],
|
||||
'setPlotStyle' => [null],
|
||||
'setSmoothLine' => [true],
|
||||
],
|
||||
'PHPExcel_Chart_DataSeriesValues' => [
|
||||
'setDataType' => ['PHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_NUMBER'],
|
||||
'setDataSource' => [null, true],
|
||||
'setPointMarker' => [null],
|
||||
'setFormatCode' => [null],
|
||||
'setDataValues' => [[], true],
|
||||
],
|
||||
'PHPExcel_Chart_Layout' => [
|
||||
'__construct' => [[]],
|
||||
],
|
||||
'PHPExcel_Chart_Legend' => [
|
||||
'setPosition' => ['PHPExcel_Chart_Legend::POSITION_RIGHT'],
|
||||
'setPositionXL' => ['PHPExcel_Chart_Legend::XL_LEGEND_POSITION_RIGHT'],
|
||||
'setOverlay' => [false],
|
||||
],
|
||||
'PHPExcel_Chart_PlotArea' => [
|
||||
'__construct' => [null, []],
|
||||
'setPlotSeries' => [[]],
|
||||
],
|
||||
'PHPExcel_Chart_Title' => [
|
||||
'setCaption' => [null],
|
||||
],
|
||||
'PHPExcel_Comment' => [
|
||||
'setAuthor' => [''],
|
||||
'setWidth' => ['96pt'],
|
||||
'setHeight' => ['55.5pt'],
|
||||
'setMarginLeft' => ['59.25pt'],
|
||||
'setMarginTop' => ['1.5pt'],
|
||||
'setVisible' => [false],
|
||||
'setAlignment' => ['Style\\Alignment::HORIZONTAL_GENERAL'],
|
||||
],
|
||||
'PHPExcel_DocumentProperties' => [
|
||||
'setCreator' => [''],
|
||||
'setLastModifiedBy' => [''],
|
||||
'setCreated' => [null],
|
||||
'setModified' => [null],
|
||||
'setTitle' => [''],
|
||||
'setDescription' => [''],
|
||||
'setSubject' => [''],
|
||||
'setKeywords' => [''],
|
||||
'setCategory' => [''],
|
||||
'setCompany' => [''],
|
||||
'setManager' => [''],
|
||||
],
|
||||
'PHPExcel_DocumentSecurity' => [
|
||||
'setLockRevision' => [false],
|
||||
'setLockStructure' => [false],
|
||||
'setLockWindows' => [false],
|
||||
'setRevisionsPassword' => ['', false],
|
||||
'setWorkbookPassword' => ['', false],
|
||||
],
|
||||
'PHPExcel_HashTable' => [
|
||||
'addFromSource' => [null],
|
||||
'getIndexForHashCode' => [''],
|
||||
'getByIndex' => [0],
|
||||
'getByHashCode' => [''],
|
||||
],
|
||||
'PHPExcel_IOFactory' => [
|
||||
'addSearchLocation' => ['', '', ''],
|
||||
'createReader' => [''],
|
||||
],
|
||||
'PHPExcel_NamedRange' => [
|
||||
'setName' => [null],
|
||||
'setRange' => [null],
|
||||
'setLocalOnly' => [false],
|
||||
],
|
||||
'PHPExcel_Reader_Abstract' => [
|
||||
'setReadDataOnly' => [false],
|
||||
'setReadEmptyCells' => [true],
|
||||
'setIncludeCharts' => [false],
|
||||
'setLoadSheetsOnly' => [null],
|
||||
],
|
||||
'PHPExcel_Reader_CSV' => [
|
||||
'setInputEncoding' => ['UTF-8'],
|
||||
'setDelimiter' => [','],
|
||||
'setEnclosure' => ['\\'],
|
||||
'setSheetIndex' => [0],
|
||||
'setContiguous' => [false],
|
||||
],
|
||||
'PHPExcel_Reader_Excel2003XML' => [
|
||||
'parseRichText' => [''],
|
||||
],
|
||||
'PHPExcel_Reader_Excel2007' => [
|
||||
'parseRichText' => [null],
|
||||
'boolean' => [null],
|
||||
],
|
||||
'PHPExcel_Reader_Excel2007_Chart' => [
|
||||
'parseRichText' => [null],
|
||||
],
|
||||
'PHPExcel_Reader_Excel2007_Theme' => [
|
||||
'getColourByIndex' => [0],
|
||||
],
|
||||
'PHPExcel_Reader_Excel5' => [
|
||||
'parseRichText' => [''],
|
||||
],
|
||||
'PHPExcel_Reader_Gnumeric' => [
|
||||
'parseRichText' => [''],
|
||||
],
|
||||
'PHPExcel_Reader_HTML' => [
|
||||
'setInputEncoding' => ['ANSI'],
|
||||
'setSheetIndex' => [0],
|
||||
],
|
||||
'PHPExcel_Reader_OOCalc' => [
|
||||
'parseRichText' => [''],
|
||||
],
|
||||
'PHPExcel_Reader_SYLK' => [
|
||||
'setInputEncoding' => ['ANSI'],
|
||||
'setSheetIndex' => [0],
|
||||
],
|
||||
'PHPExcel_RichText' => [
|
||||
'createText' => [''],
|
||||
'createTextRun' => [''],
|
||||
'setRichTextElements' => [null],
|
||||
],
|
||||
'PHPExcel_RichText_TextElement' => [
|
||||
'setText' => [''],
|
||||
],
|
||||
'PHPExcel_Settings' => [
|
||||
'setLocale' => ['en_us'],
|
||||
'setLibXmlLoaderOptions' => [null],
|
||||
],
|
||||
'PHPExcel_Shared_CodePage' => [
|
||||
'numberToName' => ['1252'],
|
||||
],
|
||||
'PHPExcel_Shared_Date' => [
|
||||
'excelToDateTimeObject' => [0, null],
|
||||
'excelToTimestamp' => [0, null],
|
||||
'PHPToExcel' => [0],
|
||||
'timestampToExcel' => [0],
|
||||
'isDateTimeFormatCode' => [''],
|
||||
'stringToExcel' => [''],
|
||||
],
|
||||
'PHPExcel_Shared_Drawing' => [
|
||||
'pixelsToEMU' => [0],
|
||||
'EMUToPixels' => [0],
|
||||
'pixelsToPoints' => [0],
|
||||
'pointsToPixels' => [0],
|
||||
'degreesToAngle' => [0],
|
||||
'angleToDegrees' => [0],
|
||||
],
|
||||
'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer' => [
|
||||
'setSpgr' => [false],
|
||||
'setStartCoordinates' => ['A1'],
|
||||
'setStartOffsetX' => [0],
|
||||
'setStartOffsetY' => [0],
|
||||
'setEndCoordinates' => ['A1'],
|
||||
'setEndOffsetX' => [0],
|
||||
'setEndOffsetY' => [0],
|
||||
],
|
||||
'PHPExcel_Shared_File' => [
|
||||
'setUseUploadTempDirectory' => [false],
|
||||
],
|
||||
'PHPExcel_Shared_Font' => [
|
||||
'setAutoSizeMethod' => ['PHPExcel_Shared_Font::AUTOSIZE_METHOD_APPROX'],
|
||||
'setTrueTypeFontPath' => [''],
|
||||
'fontSizeToPixels' => ['11'],
|
||||
'inchSizeToPixels' => ['1'],
|
||||
'centimeterSizeToPixels' => ['1'],
|
||||
],
|
||||
'PHPExcel_Shared_OLE' => [
|
||||
'localDateToOLE' => [null],
|
||||
],
|
||||
'PHPExcel_Shared_PasswordHasher' => [
|
||||
'hashPassword' => [''],
|
||||
],
|
||||
'PHPExcel_Shared_String' => [
|
||||
'controlCharacterOOXML2PHP' => [''],
|
||||
'controlCharacterPHP2OOXML' => [''],
|
||||
'isUTF8' => [''],
|
||||
'substring' => ['', 0, 0],
|
||||
'strToUpper' => [''],
|
||||
'strToLower' => [''],
|
||||
'strToTitle' => [''],
|
||||
'strCaseReverse' => [''],
|
||||
'setDecimalSeparator' => ['.'],
|
||||
'setThousandsSeparator' => [','],
|
||||
'setCurrencyCode' => ['$'],
|
||||
'SYLKtoUTF8' => [''],
|
||||
],
|
||||
'PHPExcel_Style' => [
|
||||
'applyFromArray' => [null, true],
|
||||
'setConditionalStyles' => [null],
|
||||
],
|
||||
'PHPExcel_Style_Alignment' => [
|
||||
'applyFromArray' => [null],
|
||||
'setHorizontal' => ['PHPExcel_Style_Alignment::HORIZONTAL_GENERAL'],
|
||||
'setVertical' => ['PHPExcel_Style_Alignment::VERTICAL_BOTTOM'],
|
||||
'setTextRotation' => [0],
|
||||
'setWrapText' => [false],
|
||||
'setShrinkToFit' => [false],
|
||||
'setIndent' => [0],
|
||||
'setReadorder' => [0],
|
||||
],
|
||||
'PHPExcel_Style_Border' => [
|
||||
'applyFromArray' => [null],
|
||||
'setBorderStyle' => ['PHPExcel_Style_Border::BORDER_NONE'],
|
||||
],
|
||||
'PHPExcel_Style_Borders' => [
|
||||
'applyFromArray' => [null],
|
||||
'setDiagonalDirection' => ['PHPExcel_Style_Borders::DIAGONAL_NONE'],
|
||||
],
|
||||
'PHPExcel_Style_Color' => [
|
||||
'applyFromArray' => [null],
|
||||
'setARGB' => ['PHPExcel_Style_Color::COLOR_BLACK'],
|
||||
'setRGB' => ['000000'],
|
||||
],
|
||||
'PHPExcel_Style_Conditional' => [
|
||||
'setConditionType' => ['PHPExcel_Style_Conditional::CONDITION_NONE'],
|
||||
'setOperatorType' => ['PHPExcel_Style_Conditional::OPERATOR_NONE'],
|
||||
'setText' => [null],
|
||||
'addCondition' => [''],
|
||||
],
|
||||
'PHPExcel_Style_Fill' => [
|
||||
'applyFromArray' => [null],
|
||||
'setFillType' => ['PHPExcel_Style_Fill::FILL_NONE'],
|
||||
'setRotation' => [0],
|
||||
],
|
||||
'PHPExcel_Style_Font' => [
|
||||
'applyFromArray' => [null],
|
||||
'setName' => ['Calibri'],
|
||||
'setSize' => ['10'],
|
||||
'setBold' => [false],
|
||||
'setItalic' => [false],
|
||||
'setSuperScript' => [false],
|
||||
'setSubScript' => [false],
|
||||
'setUnderline' => ['PHPExcel_Style_Font::UNDERLINE_NONE'],
|
||||
'setStrikethrough' => [false],
|
||||
],
|
||||
'PHPExcel_Style_NumberFormat' => [
|
||||
'applyFromArray' => [null],
|
||||
'setFormatCode' => ['PHPExcel_Style_NumberFormat::FORMAT_GENERAL'],
|
||||
'setBuiltInFormatCode' => [0],
|
||||
'toFormattedString' => ['0', 'PHPExcel_Style_NumberFormat::FORMAT_GENERAL', null],
|
||||
],
|
||||
'PHPExcel_Style_Protection' => [
|
||||
'applyFromArray' => [null],
|
||||
'setLocked' => ['PHPExcel_Style_Protection::PROTECTION_INHERIT'],
|
||||
'setHidden' => ['PHPExcel_Style_Protection::PROTECTION_INHERIT'],
|
||||
],
|
||||
'PHPExcel_Worksheet' => [
|
||||
'getChartByIndex' => [null],
|
||||
'getChartByName' => [''],
|
||||
'setTitle' => ['Worksheet', true],
|
||||
'setSheetState' => ['PHPExcel_Worksheet::SHEETSTATE_VISIBLE'],
|
||||
'setCellValue' => ['A1', null, false],
|
||||
'setCellValueByColumnAndRow' => [0, '1', null, false],
|
||||
'setCellValueExplicit' => ['A1', null, 'PHPExcel_Cell_DataType::TYPE_STRING', false],
|
||||
'setCellValueExplicitByColumnAndRow' => [0, '1', null, 'PHPExcel_Cell_DataType::TYPE_STRING', false],
|
||||
'getCell' => ['A1', true],
|
||||
'getCellByColumnAndRow' => [0, '1', true],
|
||||
'cellExists' => ['A1'],
|
||||
'cellExistsByColumnAndRow' => [0, '1'],
|
||||
'getRowDimension' => ['1', true],
|
||||
'getColumnDimension' => ['A', true],
|
||||
'getColumnDimensionByColumn' => [0],
|
||||
'getStyle' => ['A1'],
|
||||
'getConditionalStyles' => ['A1'],
|
||||
'conditionalStylesExists' => ['A1'],
|
||||
'removeConditionalStyles' => ['A1'],
|
||||
'getStyleByColumnAndRow' => [0, '1', null, null],
|
||||
'setBreak' => ['A1', 'PHPExcel_Worksheet::BREAK_NONE'],
|
||||
'setBreakByColumnAndRow' => [0, '1', 'PHPExcel_Worksheet::BREAK_NONE'],
|
||||
'mergeCells' => ['A1:A1'],
|
||||
'mergeCellsByColumnAndRow' => [0, '1', 0, '1'],
|
||||
'unmergeCells' => ['A1:A1'],
|
||||
'unmergeCellsByColumnAndRow' => [0, '1', 0, '1'],
|
||||
'setMergeCells' => [[]],
|
||||
'protectCells' => ['A1', '', false],
|
||||
'protectCellsByColumnAndRow' => [0, '1', 0, '1', '', false],
|
||||
'unprotectCells' => ['A1'],
|
||||
'unprotectCellsByColumnAndRow' => [0, '1', 0, '1', '', false],
|
||||
'setAutoFilterByColumnAndRow' => [0, '1', 0, '1'],
|
||||
'freezePane' => [''],
|
||||
'freezePaneByColumnAndRow' => [0, '1'],
|
||||
'insertNewRowBefore' => ['1', '1'],
|
||||
'insertNewColumnBefore' => ['A', '1'],
|
||||
'insertNewColumnBeforeByIndex' => [0, '1'],
|
||||
'removeRow' => ['1', '1'],
|
||||
'removeColumn' => ['A', '1'],
|
||||
'removeColumnByIndex' => [0, '1'],
|
||||
'setShowGridlines' => [false],
|
||||
'setPrintGridlines' => [false],
|
||||
'setShowRowColHeaders' => [false],
|
||||
'setShowSummaryBelow' => [true],
|
||||
'setShowSummaryRight' => [true],
|
||||
'setComments' => [[]],
|
||||
'getComment' => ['A1'],
|
||||
'getCommentByColumnAndRow' => [0, '1'],
|
||||
'setSelectedCell' => ['A1'],
|
||||
'setSelectedCells' => ['A1'],
|
||||
'setSelectedCellByColumnAndRow' => [0, '1'],
|
||||
'setRightToLeft' => [false],
|
||||
'fromArray' => [null, null, 'A1', false],
|
||||
'rangeToArray' => ['A1', null, true, true, false],
|
||||
'namedRangeToArray' => ['', null, true, true, false],
|
||||
'getHyperlink' => ['A1'],
|
||||
'setHyperlink' => ['A1', null],
|
||||
'hyperlinkExists' => ['A1'],
|
||||
'getDataValidation' => ['A1'],
|
||||
'setDataValidation' => ['A1', null],
|
||||
'dataValidationExists' => ['A1'],
|
||||
'setCodeName' => [null],
|
||||
],
|
||||
'PHPExcel_Worksheet_AutoFilter' => [
|
||||
'setRange' => [''],
|
||||
'getColumnByOffset' => [0],
|
||||
'shiftColumn' => [null, null],
|
||||
],
|
||||
'PHPExcel_Worksheet_AutoFilter_Column' => [
|
||||
'setFilterType' => ['PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER'],
|
||||
'setJoin' => ['PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR'],
|
||||
'setAttributes' => [[]],
|
||||
'addRule' => [
|
||||
1 => true,
|
||||
],
|
||||
],
|
||||
'PHPExcel_Worksheet_AutoFilter_Column_Rule' => [
|
||||
'setRuleType' => ['PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER'],
|
||||
'setValue' => [''],
|
||||
'setOperator' => ['PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL'],
|
||||
'setGrouping' => [null],
|
||||
'setRule' => ['PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL', '', null],
|
||||
],
|
||||
'PHPExcel_Worksheet_BaseDrawing' => [
|
||||
'setName' => [''],
|
||||
'setDescription' => [''],
|
||||
'setCoordinates' => ['A1'],
|
||||
'setOffsetX' => [0],
|
||||
'setOffsetY' => [0],
|
||||
'setWidth' => [0],
|
||||
'setHeight' => [0],
|
||||
'setWidthAndHeight' => [0, 0],
|
||||
'setResizeProportional' => [true],
|
||||
'setRotation' => [0],
|
||||
],
|
||||
'PHPExcel_Worksheet_CellIterator' => [
|
||||
'setIterateOnlyExistingCells' => [true],
|
||||
],
|
||||
'PHPExcel_Worksheet_ColumnDimension' => [
|
||||
'setWidth' => ['-1'],
|
||||
'setAutoSize' => [false],
|
||||
],
|
||||
'PHPExcel_Worksheet_Drawing' => [
|
||||
'setPath' => ['', true],
|
||||
],
|
||||
'PHPExcel_Worksheet_Drawing_Shadow' => [
|
||||
'setVisible' => [false],
|
||||
'setBlurRadius' => ['6'],
|
||||
'setDistance' => ['2'],
|
||||
'setDirection' => [0],
|
||||
'setAlignment' => [0],
|
||||
'setAlpha' => [0],
|
||||
],
|
||||
'PHPExcel_Worksheet_HeaderFooter' => [
|
||||
'setDifferentOddEven' => [false],
|
||||
'setDifferentFirst' => [false],
|
||||
'setScaleWithDocument' => [true],
|
||||
'setAlignWithMargins' => [true],
|
||||
],
|
||||
'PHPExcel_Worksheet_HeaderFooterDrawing' => [
|
||||
'setName' => [''],
|
||||
'setOffsetX' => [0],
|
||||
'setOffsetY' => [0],
|
||||
'setWidth' => [0],
|
||||
'setHeight' => [0],
|
||||
'setWidthAndHeight' => [0, 0],
|
||||
'setResizeProportional' => [true],
|
||||
'setPath' => ['', true],
|
||||
],
|
||||
'PHPExcel_Worksheet_MemoryDrawing' => [
|
||||
'setImageResource' => [null],
|
||||
'setRenderingFunction' => ['PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT'],
|
||||
'setMimeType' => ['PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT'],
|
||||
],
|
||||
'PHPExcel_Worksheet_PageSetup' => [
|
||||
'setPaperSize' => ['PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER'],
|
||||
'setOrientation' => ['PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT'],
|
||||
'setScale' => ['100', true],
|
||||
'setFitToPage' => [true],
|
||||
'setFitToHeight' => ['1', true],
|
||||
'setFitToWidth' => ['1', true],
|
||||
'setColumnsToRepeatAtLeft' => [null],
|
||||
'setColumnsToRepeatAtLeftByStartAndEnd' => ['A', 'A'],
|
||||
'setRowsToRepeatAtTop' => [null],
|
||||
'setRowsToRepeatAtTopByStartAndEnd' => ['1', '1'],
|
||||
'setHorizontalCentered' => [false],
|
||||
'setVerticalCentered' => [false],
|
||||
'setFirstPageNumber' => [null],
|
||||
],
|
||||
'PHPExcel_Worksheet_Protection' => [
|
||||
'setSheet' => [false],
|
||||
'setObjects' => [false],
|
||||
'setScenarios' => [false],
|
||||
'setFormatCells' => [false],
|
||||
'setFormatColumns' => [false],
|
||||
'setFormatRows' => [false],
|
||||
'setInsertColumns' => [false],
|
||||
'setInsertRows' => [false],
|
||||
'setInsertHyperlinks' => [false],
|
||||
'setDeleteColumns' => [false],
|
||||
'setDeleteRows' => [false],
|
||||
'setSelectLockedCells' => [false],
|
||||
'setSort' => [false],
|
||||
'setAutoFilter' => [false],
|
||||
'setPivotTables' => [false],
|
||||
'setSelectUnlockedCells' => [false],
|
||||
'setPassword' => ['', false],
|
||||
],
|
||||
'PHPExcel_Worksheet_RowDimension' => [
|
||||
'setRowHeight' => ['-1'],
|
||||
'setZeroHeight' => [false],
|
||||
],
|
||||
'PHPExcel_Worksheet_SheetView' => [
|
||||
'setZoomScale' => ['100'],
|
||||
'setZoomScaleNormal' => ['100'],
|
||||
'setView' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_Abstract' => [
|
||||
'setIncludeCharts' => [false],
|
||||
'setPreCalculateFormulas' => [true],
|
||||
'setUseDiskCaching' => [false, null],
|
||||
],
|
||||
'PHPExcel_Writer_CSV' => [
|
||||
'save' => [null],
|
||||
'setDelimiter' => [','],
|
||||
'setEnclosure' => ['\\'],
|
||||
'setLineEnding' => [PHP_EOL],
|
||||
'setUseBOM' => [false],
|
||||
'setIncludeSeparatorLine' => [false],
|
||||
'setExcelCompatibility' => [false],
|
||||
'setSheetIndex' => [0],
|
||||
'writeLine' => [null, null],
|
||||
],
|
||||
'PHPExcel_Writer_Excel2007' => [
|
||||
'getWriterPart' => [''],
|
||||
'save' => [null],
|
||||
'setOffice2003Compatibility' => [false],
|
||||
],
|
||||
'PHPExcel_Writer_Excel2007_ContentTypes' => [
|
||||
'getImageMimeType' => [''],
|
||||
],
|
||||
'PHPExcel_Writer_Excel2007_StringTable' => [
|
||||
'writeStringTable' => [null],
|
||||
'flipStringTable' => [[]],
|
||||
],
|
||||
'PHPExcel_Writer_Excel5' => [
|
||||
'save' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_Excel5_Workbook' => [
|
||||
'writeWorkbook' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_Excel5_Worksheet' => [
|
||||
'writeBIFF8CellRangeAddressFixed' => ['A1'],
|
||||
],
|
||||
'PHPExcel_Writer_HTML' => [
|
||||
'save' => [null],
|
||||
'setSheetIndex' => [0],
|
||||
'setGenerateSheetNavigationBlock' => [true],
|
||||
'setImagesRoot' => ['.'],
|
||||
'setEmbedImages' => [true],
|
||||
'setUseInlineCss' => [false],
|
||||
],
|
||||
'PHPExcel_Writer_OpenDocument' => [
|
||||
'getWriterPart' => [''],
|
||||
'save' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_PDF' => [
|
||||
'save' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_PDF_Core' => [
|
||||
'setPaperSize' => ['PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER'],
|
||||
'setOrientation' => ['PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT'],
|
||||
'setTempDir' => [''],
|
||||
'prepareForSave' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_PDF_DomPDF' => [
|
||||
'save' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_PDF_mPDF' => [
|
||||
'save' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_PDF_tcPDF' => [
|
||||
'save' => [null],
|
||||
],
|
||||
];
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Complete removed default values explicitly', [
|
||||
|
@ -645,8 +65,13 @@ CODE_SAMPLE
|
|||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
foreach (self::METHOD_NAMES_BY_TYPE_WITH_VALUE as $type => $defaultValuesByMethodName) {
|
||||
if (! $this->nodeTypeResolver->isMethodStaticCallOrClassMethodObjectType($node, new ObjectType($type))) {
|
||||
$objectType = $this->nodeTypeResolver->resolveObjectTypeToCompare($node);
|
||||
if (! $objectType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (PHPExcelMethodDefaultValues::METHOD_NAMES_BY_TYPE_WITH_VALUE as $type => $defaultValuesByMethodName) {
|
||||
if (! $objectType->isInstanceOf($type)->yes()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,12 @@ CODE_SAMPLE
|
|||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isObjectType($node->class, new ObjectType('PHPExcel_Cell'))) {
|
||||
$staticClassObjectType = $this->nodeTypeResolver->resolveObjectTypeToCompare($node);
|
||||
if (! $staticClassObjectType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $staticClassObjectType->isInstanceOf('PHPExcel_Cell')->yes()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
589
rules/php-office/src/ValueObject/PHPExcelMethodDefaultValues.php
Normal file
589
rules/php-office/src/ValueObject/PHPExcelMethodDefaultValues.php
Normal file
|
@ -0,0 +1,589 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PHPOffice\ValueObject;
|
||||
|
||||
final class PHPExcelMethodDefaultValues
|
||||
{
|
||||
/**
|
||||
* @var array<string, array<string, array<int, mixed>>>
|
||||
*/
|
||||
public const METHOD_NAMES_BY_TYPE_WITH_VALUE = [
|
||||
'PHPExcel' => [
|
||||
'setHasMacros' => [false],
|
||||
'setMacrosCode' => [null],
|
||||
'setMacrosCertificate' => [null],
|
||||
'setRibbonXMLData' => [null, null],
|
||||
'setRibbonBinObjects' => [null, null],
|
||||
'getRibbonBinObjects' => ['all'],
|
||||
'getSheetByCodeName' => [''],
|
||||
'createSheet' => [null],
|
||||
'removeSheetByIndex' => [0],
|
||||
'getSheet' => [0],
|
||||
'getSheetByName' => [''],
|
||||
'setActiveSheetIndex' => [0],
|
||||
'setActiveSheetIndexByName' => [''],
|
||||
'getCellXfByIndex' => [0],
|
||||
'getCellXfByHashCode' => [''],
|
||||
'cellXfExists' => [null],
|
||||
'removeCellXfByIndex' => [0],
|
||||
'getCellStyleXfByIndex' => [0],
|
||||
'getCellStyleXfByHashCode' => [''],
|
||||
'removeCellStyleXfByIndex' => [0],
|
||||
],
|
||||
'PHPExcel_CalcEngine_Logger' => [
|
||||
'setWriteDebugLog' => [false],
|
||||
'setEchoDebugLog' => [false],
|
||||
],
|
||||
'PHPExcel_Calculation' => [
|
||||
'setCalculationCacheEnabled' => [true],
|
||||
'setLocale' => ['en_us'],
|
||||
],
|
||||
'PHPExcel_Calculation_FormulaToken' => [
|
||||
'setTokenType' => ['PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN'],
|
||||
'setTokenSubType' => ['PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING'],
|
||||
],
|
||||
'PHPExcel_Cell' => [
|
||||
'setValue' => [null],
|
||||
'setValueExplicit' => [null, 'PHPExcel_Cell_DataType::TYPE_STRING'],
|
||||
'setCalculatedValue' => [null],
|
||||
'setDataType' => ['PHPExcel_Cell_DataType::TYPE_STRING'],
|
||||
'isInRange' => ['A1:A1'],
|
||||
'coordinateFromString' => ['A1'],
|
||||
'absoluteReference' => ['A1'],
|
||||
'absoluteCoordinate' => ['A1'],
|
||||
'splitRange' => ['A1:A1'],
|
||||
'rangeBoundaries' => ['A1:A1'],
|
||||
'rangeDimension' => ['A1:A1'],
|
||||
'getRangeBoundaries' => ['A1:A1'],
|
||||
'columnIndexFromString' => ['A'],
|
||||
'stringFromColumnIndex' => [0],
|
||||
'extractAllCellReferencesInRange' => ['A1'],
|
||||
'setXfIndex' => [0],
|
||||
],
|
||||
'PHPExcel_Cell_DataType' => [
|
||||
'checkString' => [null],
|
||||
'checkErrorCode' => [null],
|
||||
],
|
||||
'PHPExcel_Cell_DataValidation' => [
|
||||
'setFormula1' => [''],
|
||||
'setFormula2' => [''],
|
||||
'setType' => ['PHPExcel_Cell_DataValidation::TYPE_NONE'],
|
||||
'setErrorStyle' => ['PHPExcel_Cell_DataValidation::STYLE_STOP'],
|
||||
'setOperator' => [''],
|
||||
'setAllowBlank' => [false],
|
||||
'setShowDropDown' => [false],
|
||||
'setShowInputMessage' => [false],
|
||||
'setShowErrorMessage' => [false],
|
||||
'setErrorTitle' => [''],
|
||||
'setError' => [''],
|
||||
'setPromptTitle' => [''],
|
||||
'setPrompt' => [''],
|
||||
],
|
||||
'PHPExcel_Cell_DefaultValueBinder' => [
|
||||
'dataTypeForValue' => [null],
|
||||
],
|
||||
'PHPExcel_Cell_Hyperlink' => [
|
||||
'setUrl' => [''],
|
||||
'setTooltip' => [''],
|
||||
],
|
||||
'PHPExcel_Chart' => [
|
||||
'setPlotVisibleOnly' => [true],
|
||||
'setDisplayBlanksAs' => ['0'],
|
||||
'setTopLeftOffset' => [null, null],
|
||||
'setBottomRightOffset' => [null, null],
|
||||
],
|
||||
'PHPExcel_Chart_DataSeries' => [
|
||||
'setPlotType' => [''],
|
||||
'setPlotGrouping' => [null],
|
||||
'setPlotDirection' => [null],
|
||||
'setPlotStyle' => [null],
|
||||
'setSmoothLine' => [true],
|
||||
],
|
||||
'PHPExcel_Chart_DataSeriesValues' => [
|
||||
'setDataType' => ['PHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_NUMBER'],
|
||||
'setDataSource' => [null, true],
|
||||
'setPointMarker' => [null],
|
||||
'setFormatCode' => [null],
|
||||
'setDataValues' => [[], true],
|
||||
],
|
||||
'PHPExcel_Chart_Layout' => [
|
||||
'__construct' => [[]],
|
||||
],
|
||||
'PHPExcel_Chart_Legend' => [
|
||||
'setPosition' => ['PHPExcel_Chart_Legend::POSITION_RIGHT'],
|
||||
'setPositionXL' => ['PHPExcel_Chart_Legend::XL_LEGEND_POSITION_RIGHT'],
|
||||
'setOverlay' => [false],
|
||||
],
|
||||
'PHPExcel_Chart_PlotArea' => [
|
||||
'__construct' => [null, []],
|
||||
'setPlotSeries' => [[]],
|
||||
],
|
||||
'PHPExcel_Chart_Title' => [
|
||||
'setCaption' => [null],
|
||||
],
|
||||
'PHPExcel_Comment' => [
|
||||
'setAuthor' => [''],
|
||||
'setWidth' => ['96pt'],
|
||||
'setHeight' => ['55.5pt'],
|
||||
'setMarginLeft' => ['59.25pt'],
|
||||
'setMarginTop' => ['1.5pt'],
|
||||
'setVisible' => [false],
|
||||
'setAlignment' => ['Style\\Alignment::HORIZONTAL_GENERAL'],
|
||||
],
|
||||
'PHPExcel_DocumentProperties' => [
|
||||
'setCreator' => [''],
|
||||
'setLastModifiedBy' => [''],
|
||||
'setCreated' => [null],
|
||||
'setModified' => [null],
|
||||
'setTitle' => [''],
|
||||
'setDescription' => [''],
|
||||
'setSubject' => [''],
|
||||
'setKeywords' => [''],
|
||||
'setCategory' => [''],
|
||||
'setCompany' => [''],
|
||||
'setManager' => [''],
|
||||
],
|
||||
'PHPExcel_DocumentSecurity' => [
|
||||
'setLockRevision' => [false],
|
||||
'setLockStructure' => [false],
|
||||
'setLockWindows' => [false],
|
||||
'setRevisionsPassword' => ['', false],
|
||||
'setWorkbookPassword' => ['', false],
|
||||
],
|
||||
'PHPExcel_HashTable' => [
|
||||
'addFromSource' => [null],
|
||||
'getIndexForHashCode' => [''],
|
||||
'getByIndex' => [0],
|
||||
'getByHashCode' => [''],
|
||||
],
|
||||
'PHPExcel_IOFactory' => [
|
||||
'addSearchLocation' => ['', '', ''],
|
||||
'createReader' => [''],
|
||||
],
|
||||
'PHPExcel_NamedRange' => [
|
||||
'setName' => [null],
|
||||
'setRange' => [null],
|
||||
'setLocalOnly' => [false],
|
||||
],
|
||||
'PHPExcel_Reader_Abstract' => [
|
||||
'setReadDataOnly' => [false],
|
||||
'setReadEmptyCells' => [true],
|
||||
'setIncludeCharts' => [false],
|
||||
'setLoadSheetsOnly' => [null],
|
||||
],
|
||||
'PHPExcel_Reader_CSV' => [
|
||||
'setInputEncoding' => ['UTF-8'],
|
||||
'setDelimiter' => [','],
|
||||
'setEnclosure' => ['\\'],
|
||||
'setSheetIndex' => [0],
|
||||
'setContiguous' => [false],
|
||||
],
|
||||
'PHPExcel_Reader_Excel2003XML' => [
|
||||
'parseRichText' => [''],
|
||||
],
|
||||
'PHPExcel_Reader_Excel2007' => [
|
||||
'parseRichText' => [null],
|
||||
'boolean' => [null],
|
||||
],
|
||||
'PHPExcel_Reader_Excel2007_Chart' => [
|
||||
'parseRichText' => [null],
|
||||
],
|
||||
'PHPExcel_Reader_Excel2007_Theme' => [
|
||||
'getColourByIndex' => [0],
|
||||
],
|
||||
'PHPExcel_Reader_Excel5' => [
|
||||
'parseRichText' => [''],
|
||||
],
|
||||
'PHPExcel_Reader_Gnumeric' => [
|
||||
'parseRichText' => [''],
|
||||
],
|
||||
'PHPExcel_Reader_HTML' => [
|
||||
'setInputEncoding' => ['ANSI'],
|
||||
'setSheetIndex' => [0],
|
||||
],
|
||||
'PHPExcel_Reader_OOCalc' => [
|
||||
'parseRichText' => [''],
|
||||
],
|
||||
'PHPExcel_Reader_SYLK' => [
|
||||
'setInputEncoding' => ['ANSI'],
|
||||
'setSheetIndex' => [0],
|
||||
],
|
||||
'PHPExcel_RichText' => [
|
||||
'createText' => [''],
|
||||
'createTextRun' => [''],
|
||||
'setRichTextElements' => [null],
|
||||
],
|
||||
'PHPExcel_RichText_TextElement' => [
|
||||
'setText' => [''],
|
||||
],
|
||||
'PHPExcel_Settings' => [
|
||||
'setLocale' => ['en_us'],
|
||||
'setLibXmlLoaderOptions' => [null],
|
||||
],
|
||||
'PHPExcel_Shared_CodePage' => [
|
||||
'numberToName' => ['1252'],
|
||||
],
|
||||
'PHPExcel_Shared_Date' => [
|
||||
'excelToDateTimeObject' => [0, null],
|
||||
'excelToTimestamp' => [0, null],
|
||||
'PHPToExcel' => [0],
|
||||
'timestampToExcel' => [0],
|
||||
'isDateTimeFormatCode' => [''],
|
||||
'stringToExcel' => [''],
|
||||
],
|
||||
'PHPExcel_Shared_Drawing' => [
|
||||
'pixelsToEMU' => [0],
|
||||
'EMUToPixels' => [0],
|
||||
'pixelsToPoints' => [0],
|
||||
'pointsToPixels' => [0],
|
||||
'degreesToAngle' => [0],
|
||||
'angleToDegrees' => [0],
|
||||
],
|
||||
'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer' => [
|
||||
'setSpgr' => [false],
|
||||
'setStartCoordinates' => ['A1'],
|
||||
'setStartOffsetX' => [0],
|
||||
'setStartOffsetY' => [0],
|
||||
'setEndCoordinates' => ['A1'],
|
||||
'setEndOffsetX' => [0],
|
||||
'setEndOffsetY' => [0],
|
||||
],
|
||||
'PHPExcel_Shared_File' => [
|
||||
'setUseUploadTempDirectory' => [false],
|
||||
],
|
||||
'PHPExcel_Shared_Font' => [
|
||||
'setAutoSizeMethod' => ['PHPExcel_Shared_Font::AUTOSIZE_METHOD_APPROX'],
|
||||
'setTrueTypeFontPath' => [''],
|
||||
'fontSizeToPixels' => ['11'],
|
||||
'inchSizeToPixels' => ['1'],
|
||||
'centimeterSizeToPixels' => ['1'],
|
||||
],
|
||||
'PHPExcel_Shared_OLE' => [
|
||||
'localDateToOLE' => [null],
|
||||
],
|
||||
'PHPExcel_Shared_PasswordHasher' => [
|
||||
'hashPassword' => [''],
|
||||
],
|
||||
'PHPExcel_Shared_String' => [
|
||||
'controlCharacterOOXML2PHP' => [''],
|
||||
'controlCharacterPHP2OOXML' => [''],
|
||||
'isUTF8' => [''],
|
||||
'substring' => ['', 0, 0],
|
||||
'strToUpper' => [''],
|
||||
'strToLower' => [''],
|
||||
'strToTitle' => [''],
|
||||
'strCaseReverse' => [''],
|
||||
'setDecimalSeparator' => ['.'],
|
||||
'setThousandsSeparator' => [','],
|
||||
'setCurrencyCode' => ['$'],
|
||||
'SYLKtoUTF8' => [''],
|
||||
],
|
||||
'PHPExcel_Style' => [
|
||||
'applyFromArray' => [null, true],
|
||||
'setConditionalStyles' => [null],
|
||||
],
|
||||
'PHPExcel_Style_Alignment' => [
|
||||
'applyFromArray' => [null],
|
||||
'setHorizontal' => ['PHPExcel_Style_Alignment::HORIZONTAL_GENERAL'],
|
||||
'setVertical' => ['PHPExcel_Style_Alignment::VERTICAL_BOTTOM'],
|
||||
'setTextRotation' => [0],
|
||||
'setWrapText' => [false],
|
||||
'setShrinkToFit' => [false],
|
||||
'setIndent' => [0],
|
||||
'setReadorder' => [0],
|
||||
],
|
||||
'PHPExcel_Style_Border' => [
|
||||
'applyFromArray' => [null],
|
||||
'setBorderStyle' => ['PHPExcel_Style_Border::BORDER_NONE'],
|
||||
],
|
||||
'PHPExcel_Style_Borders' => [
|
||||
'applyFromArray' => [null],
|
||||
'setDiagonalDirection' => ['PHPExcel_Style_Borders::DIAGONAL_NONE'],
|
||||
],
|
||||
'PHPExcel_Style_Color' => [
|
||||
'applyFromArray' => [null],
|
||||
'setARGB' => ['PHPExcel_Style_Color::COLOR_BLACK'],
|
||||
'setRGB' => ['000000'],
|
||||
],
|
||||
'PHPExcel_Style_Conditional' => [
|
||||
'setConditionType' => ['PHPExcel_Style_Conditional::CONDITION_NONE'],
|
||||
'setOperatorType' => ['PHPExcel_Style_Conditional::OPERATOR_NONE'],
|
||||
'setText' => [null],
|
||||
'addCondition' => [''],
|
||||
],
|
||||
'PHPExcel_Style_Fill' => [
|
||||
'applyFromArray' => [null],
|
||||
'setFillType' => ['PHPExcel_Style_Fill::FILL_NONE'],
|
||||
'setRotation' => [0],
|
||||
],
|
||||
'PHPExcel_Style_Font' => [
|
||||
'applyFromArray' => [null],
|
||||
'setName' => ['Calibri'],
|
||||
'setSize' => ['10'],
|
||||
'setBold' => [false],
|
||||
'setItalic' => [false],
|
||||
'setSuperScript' => [false],
|
||||
'setSubScript' => [false],
|
||||
'setUnderline' => ['PHPExcel_Style_Font::UNDERLINE_NONE'],
|
||||
'setStrikethrough' => [false],
|
||||
],
|
||||
'PHPExcel_Style_NumberFormat' => [
|
||||
'applyFromArray' => [null],
|
||||
'setFormatCode' => ['PHPExcel_Style_NumberFormat::FORMAT_GENERAL'],
|
||||
'setBuiltInFormatCode' => [0],
|
||||
'toFormattedString' => ['0', 'PHPExcel_Style_NumberFormat::FORMAT_GENERAL', null],
|
||||
],
|
||||
'PHPExcel_Style_Protection' => [
|
||||
'applyFromArray' => [null],
|
||||
'setLocked' => ['PHPExcel_Style_Protection::PROTECTION_INHERIT'],
|
||||
'setHidden' => ['PHPExcel_Style_Protection::PROTECTION_INHERIT'],
|
||||
],
|
||||
'PHPExcel_Worksheet' => [
|
||||
'getChartByIndex' => [null],
|
||||
'getChartByName' => [''],
|
||||
'setTitle' => ['Worksheet', true],
|
||||
'setSheetState' => ['PHPExcel_Worksheet::SHEETSTATE_VISIBLE'],
|
||||
'setCellValue' => ['A1', null, false],
|
||||
'setCellValueByColumnAndRow' => [0, '1', null, false],
|
||||
'setCellValueExplicit' => ['A1', null, 'PHPExcel_Cell_DataType::TYPE_STRING', false],
|
||||
'setCellValueExplicitByColumnAndRow' => [0, '1', null, 'PHPExcel_Cell_DataType::TYPE_STRING', false],
|
||||
'getCell' => ['A1', true],
|
||||
'getCellByColumnAndRow' => [0, '1', true],
|
||||
'cellExists' => ['A1'],
|
||||
'cellExistsByColumnAndRow' => [0, '1'],
|
||||
'getRowDimension' => ['1', true],
|
||||
'getColumnDimension' => ['A', true],
|
||||
'getColumnDimensionByColumn' => [0],
|
||||
'getStyle' => ['A1'],
|
||||
'getConditionalStyles' => ['A1'],
|
||||
'conditionalStylesExists' => ['A1'],
|
||||
'removeConditionalStyles' => ['A1'],
|
||||
'getStyleByColumnAndRow' => [0, '1', null, null],
|
||||
'setBreak' => ['A1', 'PHPExcel_Worksheet::BREAK_NONE'],
|
||||
'setBreakByColumnAndRow' => [0, '1', 'PHPExcel_Worksheet::BREAK_NONE'],
|
||||
'mergeCells' => ['A1:A1'],
|
||||
'mergeCellsByColumnAndRow' => [0, '1', 0, '1'],
|
||||
'unmergeCells' => ['A1:A1'],
|
||||
'unmergeCellsByColumnAndRow' => [0, '1', 0, '1'],
|
||||
'setMergeCells' => [[]],
|
||||
'protectCells' => ['A1', '', false],
|
||||
'protectCellsByColumnAndRow' => [0, '1', 0, '1', '', false],
|
||||
'unprotectCells' => ['A1'],
|
||||
'unprotectCellsByColumnAndRow' => [0, '1', 0, '1', '', false],
|
||||
'setAutoFilterByColumnAndRow' => [0, '1', 0, '1'],
|
||||
'freezePane' => [''],
|
||||
'freezePaneByColumnAndRow' => [0, '1'],
|
||||
'insertNewRowBefore' => ['1', '1'],
|
||||
'insertNewColumnBefore' => ['A', '1'],
|
||||
'insertNewColumnBeforeByIndex' => [0, '1'],
|
||||
'removeRow' => ['1', '1'],
|
||||
'removeColumn' => ['A', '1'],
|
||||
'removeColumnByIndex' => [0, '1'],
|
||||
'setShowGridlines' => [false],
|
||||
'setPrintGridlines' => [false],
|
||||
'setShowRowColHeaders' => [false],
|
||||
'setShowSummaryBelow' => [true],
|
||||
'setShowSummaryRight' => [true],
|
||||
'setComments' => [[]],
|
||||
'getComment' => ['A1'],
|
||||
'getCommentByColumnAndRow' => [0, '1'],
|
||||
'setSelectedCell' => ['A1'],
|
||||
'setSelectedCells' => ['A1'],
|
||||
'setSelectedCellByColumnAndRow' => [0, '1'],
|
||||
'setRightToLeft' => [false],
|
||||
'fromArray' => [null, null, 'A1', false],
|
||||
'rangeToArray' => ['A1', null, true, true, false],
|
||||
'namedRangeToArray' => ['', null, true, true, false],
|
||||
'getHyperlink' => ['A1'],
|
||||
'setHyperlink' => ['A1', null],
|
||||
'hyperlinkExists' => ['A1'],
|
||||
'getDataValidation' => ['A1'],
|
||||
'setDataValidation' => ['A1', null],
|
||||
'dataValidationExists' => ['A1'],
|
||||
'setCodeName' => [null],
|
||||
],
|
||||
'PHPExcel_Worksheet_AutoFilter' => [
|
||||
'setRange' => [''],
|
||||
'getColumnByOffset' => [0],
|
||||
'shiftColumn' => [null, null],
|
||||
],
|
||||
'PHPExcel_Worksheet_AutoFilter_Column' => [
|
||||
'setFilterType' => ['PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER'],
|
||||
'setJoin' => ['PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR'],
|
||||
'setAttributes' => [[]],
|
||||
'addRule' => [
|
||||
1 => true,
|
||||
],
|
||||
],
|
||||
'PHPExcel_Worksheet_AutoFilter_Column_Rule' => [
|
||||
'setRuleType' => ['PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER'],
|
||||
'setValue' => [''],
|
||||
'setOperator' => ['PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL'],
|
||||
'setGrouping' => [null],
|
||||
'setRule' => ['PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL', '', null],
|
||||
],
|
||||
'PHPExcel_Worksheet_BaseDrawing' => [
|
||||
'setName' => [''],
|
||||
'setDescription' => [''],
|
||||
'setCoordinates' => ['A1'],
|
||||
'setOffsetX' => [0],
|
||||
'setOffsetY' => [0],
|
||||
'setWidth' => [0],
|
||||
'setHeight' => [0],
|
||||
'setWidthAndHeight' => [0, 0],
|
||||
'setResizeProportional' => [true],
|
||||
'setRotation' => [0],
|
||||
],
|
||||
'PHPExcel_Worksheet_CellIterator' => [
|
||||
'setIterateOnlyExistingCells' => [true],
|
||||
],
|
||||
'PHPExcel_Worksheet_ColumnDimension' => [
|
||||
'setWidth' => ['-1'],
|
||||
'setAutoSize' => [false],
|
||||
],
|
||||
'PHPExcel_Worksheet_Drawing' => [
|
||||
'setPath' => ['', true],
|
||||
],
|
||||
'PHPExcel_Worksheet_Drawing_Shadow' => [
|
||||
'setVisible' => [false],
|
||||
'setBlurRadius' => ['6'],
|
||||
'setDistance' => ['2'],
|
||||
'setDirection' => [0],
|
||||
'setAlignment' => [0],
|
||||
'setAlpha' => [0],
|
||||
],
|
||||
'PHPExcel_Worksheet_HeaderFooter' => [
|
||||
'setDifferentOddEven' => [false],
|
||||
'setDifferentFirst' => [false],
|
||||
'setScaleWithDocument' => [true],
|
||||
'setAlignWithMargins' => [true],
|
||||
],
|
||||
'PHPExcel_Worksheet_HeaderFooterDrawing' => [
|
||||
'setName' => [''],
|
||||
'setOffsetX' => [0],
|
||||
'setOffsetY' => [0],
|
||||
'setWidth' => [0],
|
||||
'setHeight' => [0],
|
||||
'setWidthAndHeight' => [0, 0],
|
||||
'setResizeProportional' => [true],
|
||||
'setPath' => ['', true],
|
||||
],
|
||||
'PHPExcel_Worksheet_MemoryDrawing' => [
|
||||
'setImageResource' => [null],
|
||||
'setRenderingFunction' => ['PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT'],
|
||||
'setMimeType' => ['PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT'],
|
||||
],
|
||||
'PHPExcel_Worksheet_PageSetup' => [
|
||||
'setPaperSize' => ['PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER'],
|
||||
'setOrientation' => ['PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT'],
|
||||
'setScale' => ['100', true],
|
||||
'setFitToPage' => [true],
|
||||
'setFitToHeight' => ['1', true],
|
||||
'setFitToWidth' => ['1', true],
|
||||
'setColumnsToRepeatAtLeft' => [null],
|
||||
'setColumnsToRepeatAtLeftByStartAndEnd' => ['A', 'A'],
|
||||
'setRowsToRepeatAtTop' => [null],
|
||||
'setRowsToRepeatAtTopByStartAndEnd' => ['1', '1'],
|
||||
'setHorizontalCentered' => [false],
|
||||
'setVerticalCentered' => [false],
|
||||
'setFirstPageNumber' => [null],
|
||||
],
|
||||
'PHPExcel_Worksheet_Protection' => [
|
||||
'setSheet' => [false],
|
||||
'setObjects' => [false],
|
||||
'setScenarios' => [false],
|
||||
'setFormatCells' => [false],
|
||||
'setFormatColumns' => [false],
|
||||
'setFormatRows' => [false],
|
||||
'setInsertColumns' => [false],
|
||||
'setInsertRows' => [false],
|
||||
'setInsertHyperlinks' => [false],
|
||||
'setDeleteColumns' => [false],
|
||||
'setDeleteRows' => [false],
|
||||
'setSelectLockedCells' => [false],
|
||||
'setSort' => [false],
|
||||
'setAutoFilter' => [false],
|
||||
'setPivotTables' => [false],
|
||||
'setSelectUnlockedCells' => [false],
|
||||
'setPassword' => ['', false],
|
||||
],
|
||||
'PHPExcel_Worksheet_RowDimension' => [
|
||||
'setRowHeight' => ['-1'],
|
||||
'setZeroHeight' => [false],
|
||||
],
|
||||
'PHPExcel_Worksheet_SheetView' => [
|
||||
'setZoomScale' => ['100'],
|
||||
'setZoomScaleNormal' => ['100'],
|
||||
'setView' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_Abstract' => [
|
||||
'setIncludeCharts' => [false],
|
||||
'setPreCalculateFormulas' => [true],
|
||||
'setUseDiskCaching' => [false, null],
|
||||
],
|
||||
'PHPExcel_Writer_CSV' => [
|
||||
'save' => [null],
|
||||
'setDelimiter' => [','],
|
||||
'setEnclosure' => ['\\'],
|
||||
'setLineEnding' => [PHP_EOL],
|
||||
'setUseBOM' => [false],
|
||||
'setIncludeSeparatorLine' => [false],
|
||||
'setExcelCompatibility' => [false],
|
||||
'setSheetIndex' => [0],
|
||||
'writeLine' => [null, null],
|
||||
],
|
||||
'PHPExcel_Writer_Excel2007' => [
|
||||
'getWriterPart' => [''],
|
||||
'save' => [null],
|
||||
'setOffice2003Compatibility' => [false],
|
||||
],
|
||||
'PHPExcel_Writer_Excel2007_ContentTypes' => [
|
||||
'getImageMimeType' => [''],
|
||||
],
|
||||
'PHPExcel_Writer_Excel2007_StringTable' => [
|
||||
'writeStringTable' => [null],
|
||||
'flipStringTable' => [[]],
|
||||
],
|
||||
'PHPExcel_Writer_Excel5' => [
|
||||
'save' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_Excel5_Workbook' => [
|
||||
'writeWorkbook' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_Excel5_Worksheet' => [
|
||||
'writeBIFF8CellRangeAddressFixed' => ['A1'],
|
||||
],
|
||||
'PHPExcel_Writer_HTML' => [
|
||||
'save' => [null],
|
||||
'setSheetIndex' => [0],
|
||||
'setGenerateSheetNavigationBlock' => [true],
|
||||
'setImagesRoot' => ['.'],
|
||||
'setEmbedImages' => [true],
|
||||
'setUseInlineCss' => [false],
|
||||
],
|
||||
'PHPExcel_Writer_OpenDocument' => [
|
||||
'getWriterPart' => [''],
|
||||
'save' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_PDF' => [
|
||||
'save' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_PDF_Core' => [
|
||||
'setPaperSize' => ['PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER'],
|
||||
'setOrientation' => ['PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT'],
|
||||
'setTempDir' => [''],
|
||||
'prepareForSave' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_PDF_DomPDF' => [
|
||||
'save' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_PDF_mPDF' => [
|
||||
'save' => [null],
|
||||
],
|
||||
'PHPExcel_Writer_PDF_tcPDF' => [
|
||||
'save' => [null],
|
||||
],
|
||||
];
|
||||
}
|
|
@ -10,6 +10,7 @@ use PhpParser\Node\Arg;
|
|||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\Error;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
|
@ -146,6 +147,10 @@ final class PhpSpecMocksToPHPUnitMocksRector extends AbstractPhpSpecToPHPUnitRec
|
|||
|
||||
$methodsWithWThisMock = $classMocks[$variable];
|
||||
|
||||
if ($param->var instanceof Error) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// single use: "$mock = $this->createMock()"
|
||||
if (! $this->phpSpecMockCollector->isVariableMockInProperty($param->var)) {
|
||||
return $this->createNewMockVariableAssign($param, $name);
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Rector\Php54\Rector\Break_;
|
|||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\Break_;
|
||||
use PhpParser\Node\Stmt\Continue_;
|
||||
use PHPStan\Type\Constant\ConstantIntegerType;
|
||||
|
@ -101,30 +102,30 @@ CODE_SAMPLE
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Break_|Continue_ $node
|
||||
* @param Break_|Continue_ $stmt
|
||||
*/
|
||||
private function processVariableNum(Node $node, Variable $numVariable): ?Node
|
||||
private function processVariableNum(Stmt $stmt, Variable $numVariable): ?Node
|
||||
{
|
||||
$staticType = $this->getStaticType($numVariable);
|
||||
|
||||
if ($staticType instanceof ConstantType) {
|
||||
if ($staticType instanceof ConstantIntegerType) {
|
||||
if ($staticType->getValue() === 0) {
|
||||
$node->num = null;
|
||||
return $node;
|
||||
$stmt->num = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
if ($staticType->getValue() > 0) {
|
||||
$node->num = new LNumber($staticType->getValue());
|
||||
return $node;
|
||||
$stmt->num = new LNumber($staticType->getValue());
|
||||
return $stmt;
|
||||
}
|
||||
}
|
||||
|
||||
return $node;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
// remove variable
|
||||
$node->num = null;
|
||||
$stmt->num = null;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace Rector\Php71\NodeFinder;
|
|||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\PropertyProperty;
|
||||
|
@ -32,14 +33,14 @@ final class EmptyStringDefaultPropertyFinder
|
|||
/**
|
||||
* @return PropertyProperty[]
|
||||
*/
|
||||
public function find(Node $node): array
|
||||
public function find(Assign $assign): array
|
||||
{
|
||||
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
|
||||
$classLike = $assign->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $classLike instanceof Class_) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$className = $node->getAttribute(AttributeKey::CLASS_NAME);
|
||||
$className = $assign->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if (! is_string($className)) {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Php71\Rector\FuncCall;
|
||||
|
||||
use function count;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
|
@ -100,16 +99,16 @@ final class RemoveExtraParametersRector extends AbstractRector
|
|||
}
|
||||
}
|
||||
|
||||
$reflection = $this->callReflectionResolver->resolveCall($node);
|
||||
if ($reflection === null) {
|
||||
$functionReflection = $this->callReflectionResolver->resolveCall($node);
|
||||
if ($functionReflection === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($reflection->getVariants() === []) {
|
||||
if ($functionReflection->getVariants() === []) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->hasVariadicParameters($reflection->getVariants());
|
||||
return $this->hasVariadicParameters($functionReflection->getVariants());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -94,6 +94,7 @@ final class ClassMethodExternalCallNodeAnalyzer
|
|||
|
||||
foreach ($methodCalls as $methodCall) {
|
||||
$callerType = $this->nodeTypeResolver->resolve($methodCall->var);
|
||||
|
||||
if (! $callerType instanceof TypeWithClassName) {
|
||||
// unable to handle reliably
|
||||
return $methodCalls;
|
||||
|
|
|
@ -9,13 +9,12 @@ use PhpParser\Node\Name\FullyQualified;
|
|||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\FamilyTree\Reflection\FamilyRelationsAnalyzer;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\Privatization\NodeAnalyzer\ClassMethodExternalCallNodeAnalyzer;
|
||||
use Rector\Privatization\VisibilityGuard\ChildClassMethodOverrideGuard;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
|
@ -30,16 +29,16 @@ final class MakeOnlyUsedByChildrenProtectedRector extends AbstractRector
|
|||
private $classMethodExternalCallNodeAnalyzer;
|
||||
|
||||
/**
|
||||
* @var FamilyRelationsAnalyzer
|
||||
* @var ChildClassMethodOverrideGuard
|
||||
*/
|
||||
private $familyRelationsAnalyzer;
|
||||
private $childClassMethodOverrideGuard;
|
||||
|
||||
public function __construct(
|
||||
ClassMethodExternalCallNodeAnalyzer $classMethodExternalCallNodeAnalyzer,
|
||||
FamilyRelationsAnalyzer $familyRelationsAnalyzer
|
||||
ChildClassMethodOverrideGuard $childClassMethodOverrideGuard
|
||||
) {
|
||||
$this->classMethodExternalCallNodeAnalyzer = $classMethodExternalCallNodeAnalyzer;
|
||||
$this->familyRelationsAnalyzer = $familyRelationsAnalyzer;
|
||||
$this->childClassMethodOverrideGuard = $childClassMethodOverrideGuard;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
|
@ -107,11 +106,6 @@ CODE_SAMPLE
|
|||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if (! $classReflection instanceof ClassReflection) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$externalCalls = $this->classMethodExternalCallNodeAnalyzer->getExternalCalls($node);
|
||||
if ($externalCalls === []) {
|
||||
return null;
|
||||
|
@ -126,13 +120,18 @@ CODE_SAMPLE
|
|||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isObjectType($class, new ObjectType($className))) {
|
||||
$classObjectType = $this->nodeTypeResolver->resolveObjectTypeToCompare($class);
|
||||
if (! $classObjectType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $classObjectType->isInstanceOf($className)->yes()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
$methodName = $this->getName($node);
|
||||
if ($this->isOverriddenInChildClass($classReflection, $methodName)) {
|
||||
if ($this->childClassMethodOverrideGuard->isOverriddenInChildClass($scope, $methodName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -166,25 +165,4 @@ CODE_SAMPLE
|
|||
|
||||
return ! $classMethod->isPublic();
|
||||
}
|
||||
|
||||
private function isOverriddenInChildClass(ClassReflection $classReflection, string $methodName): bool
|
||||
{
|
||||
$childrenClassReflection = $this->familyRelationsAnalyzer->getChildrenOfClassReflection($classReflection);
|
||||
|
||||
foreach ($childrenClassReflection as $childClassReflection) {
|
||||
$singleChildrenClassReflectionHasMethod = $childClassReflection->hasMethod($methodName);
|
||||
if (! $singleChildrenClassReflectionHasMethod) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$methodReflection = $childClassReflection->getNativeMethod($methodName);
|
||||
$methodDeclaringClass = $methodReflection->getDeclaringClass();
|
||||
|
||||
if ($methodDeclaringClass->getName() === $childClassReflection->getName()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ use PhpParser\Node;
|
|||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Privatization\NodeFactory\ClassConstantFetchValueFactory;
|
||||
|
@ -119,7 +120,7 @@ CODE_SAMPLE
|
|||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $configuration
|
||||
* @param array<string, mixed[]> $configuration
|
||||
*/
|
||||
public function configure(array $configuration): void
|
||||
{
|
||||
|
@ -130,11 +131,16 @@ CODE_SAMPLE
|
|||
MethodCall $methodCall,
|
||||
ReplaceStringWithClassConstant $replaceStringWithClassConstant
|
||||
): ?Arg {
|
||||
if (! $this->isOnClassMethodCall(
|
||||
$methodCall,
|
||||
$replaceStringWithClassConstant->getObjectType(),
|
||||
$replaceStringWithClassConstant->getMethod()
|
||||
)) {
|
||||
$callerObjectType = $this->nodeTypeResolver->resolveObjectTypeToCompare($methodCall->var);
|
||||
if (! $callerObjectType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $callerObjectType->isInstanceOf($replaceStringWithClassConstant->getClass())->yes()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isName($methodCall->name, $replaceStringWithClassConstant->getMethod())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Privatization\ValueObject;
|
||||
|
||||
use PHPStan\Type\ObjectType;
|
||||
|
||||
final class ReplaceStringWithClassConstant
|
||||
{
|
||||
/**
|
||||
|
@ -39,9 +37,9 @@ final class ReplaceStringWithClassConstant
|
|||
$this->argPosition = $argPosition;
|
||||
}
|
||||
|
||||
public function getObjectType(): ObjectType
|
||||
public function getClass(): string
|
||||
{
|
||||
return new ObjectType($this->class);
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
public function getMethod(): string
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Privatization\VisibilityGuard;
|
||||
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\FamilyTree\Reflection\FamilyRelationsAnalyzer;
|
||||
|
||||
final class ChildClassMethodOverrideGuard
|
||||
{
|
||||
/**
|
||||
* @var FamilyRelationsAnalyzer
|
||||
*/
|
||||
private $familyRelationsAnalyzer;
|
||||
|
||||
public function __construct(FamilyRelationsAnalyzer $familyRelationsAnalyzer)
|
||||
{
|
||||
$this->familyRelationsAnalyzer = $familyRelationsAnalyzer;
|
||||
}
|
||||
|
||||
public function isOverriddenInChildClass(Scope $scope, string $methodName): bool
|
||||
{
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if (! $classReflection instanceof ClassReflection) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$childrenClassReflection = $this->familyRelationsAnalyzer->getChildrenOfClassReflection($classReflection);
|
||||
|
||||
foreach ($childrenClassReflection as $childClassReflection) {
|
||||
$singleChildrenClassReflectionHasMethod = $childClassReflection->hasMethod($methodName);
|
||||
if (! $singleChildrenClassReflectionHasMethod) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$methodReflection = $childClassReflection->getNativeMethod($methodName);
|
||||
$methodDeclaringClass = $methodReflection->getDeclaringClass();
|
||||
|
||||
if ($methodDeclaringClass->getName() === $childClassReflection->getName()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -74,7 +74,7 @@ CODE_SAMPLE
|
|||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
foreach ($this->renameClassConstFetches as $renameClassConstFetch) {
|
||||
if (! $this->isObjectType($node, $renameClassConstFetch->getOldObjectType())) {
|
||||
if (! $this->isObjectType($node->class, $renameClassConstFetch->getOldObjectType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
$services->set(RenameClassConstFetchRector::class)
|
||||
->call('configure', [[
|
||||
RenameClassConstFetchRector::CLASS_CONSTANT_RENAME => ValueObjectInliner::inline([
|
||||
|
||||
new RenameClassConstFetch(LocalFormEvents::class, 'PRE_BIND', 'PRE_SUBMIT'),
|
||||
new RenameClassConstFetch(LocalFormEvents::class, 'BIND', 'SUBMIT'),
|
||||
new RenameClassConstFetch(LocalFormEvents::class, 'POST_BIND', 'POST_SUBMIT'),
|
||||
|
@ -23,7 +22,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
DifferentClass::class,
|
||||
'NEW_CONSTANT'
|
||||
),
|
||||
|
||||
]),
|
||||
]]);
|
||||
};
|
||||
|
|
|
@ -82,7 +82,12 @@ CODE_SAMPLE
|
|||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isObjectType($node, new ObjectType('Symfony\Component\Console\Command\Command'))) {
|
||||
$objectType = $this->nodeTypeResolver->resolveObjectTypeToCompare($node);
|
||||
if (! $objectType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $objectType->isInstanceOf('Symfony\Component\Console\Command\Command')->yes()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -121,7 +126,13 @@ CODE_SAMPLE
|
|||
if (! $node instanceof StaticCall) {
|
||||
return null;
|
||||
}
|
||||
if (! $this->isObjectType($node->class, new ObjectType('Symfony\Component\Console\Command\Command'))) {
|
||||
|
||||
$objectType = $this->nodeTypeResolver->resolveObjectTypeToCompare($node->class);
|
||||
if (! $objectType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $objectType->isInstanceOf('Symfony\Component\Console\Command\Command')->yes()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -144,6 +155,7 @@ CODE_SAMPLE
|
|||
if (! $node instanceof MethodCall) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isObjectType($node->var, new ObjectType('Symfony\Component\Console\Command\Command'))) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,9 @@ use PhpParser\Node;
|
|||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Type\StringType;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Naming\Naming\PropertyNaming;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
@ -27,9 +28,15 @@ final class GetParameterToConstructorInjectionRector extends AbstractRector
|
|||
*/
|
||||
private $propertyNaming;
|
||||
|
||||
public function __construct(PropertyNaming $propertyNaming)
|
||||
/**
|
||||
* @var ReflectionProvider
|
||||
*/
|
||||
private $reflectionProvider;
|
||||
|
||||
public function __construct(PropertyNaming $propertyNaming, ReflectionProvider $reflectionProvider)
|
||||
{
|
||||
$this->propertyNaming = $propertyNaming;
|
||||
$this->reflectionProvider = $reflectionProvider;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
|
@ -82,10 +89,13 @@ CODE_SAMPLE
|
|||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isObjectType(
|
||||
$node->var,
|
||||
new ObjectType('Symfony\Bundle\FrameworkBundle\Controller\Controller')
|
||||
)) {
|
||||
$varType = $this->nodeTypeResolver->resolve($node->var);
|
||||
if (! $varType instanceof TypeWithClassName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classReflection = $this->reflectionProvider->getClass($varType->getClassName());
|
||||
if (! $classReflection->isSubclassOf('Symfony\Bundle\FrameworkBundle\Controller\Controller')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -106,7 +116,7 @@ CODE_SAMPLE
|
|||
return null;
|
||||
}
|
||||
|
||||
$this->addConstructorDependencyToClass($classLike, new StringType(), $propertyName);
|
||||
$this->propertyAdder->addConstructorDependencyToClass($classLike, new StringType(), $propertyName, 0);
|
||||
|
||||
return $this->nodeFactory->createPropertyFetch('this', $propertyName);
|
||||
}
|
||||
|
|
|
@ -11,16 +11,15 @@ use PhpParser\Node\Expr\ArrayItem;
|
|||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
use Twig_SimpleFilter;
|
||||
use Twig_SimpleFunction;
|
||||
|
||||
/**
|
||||
* Covers https://twig.symfony.com/doc/1.x/deprecated.html#function
|
||||
|
@ -30,7 +29,7 @@ use Twig_SimpleFunction;
|
|||
final class SimpleFunctionAndFilterRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var array<string, class-string<Twig_SimpleFilter>|class-string<Twig_SimpleFunction>>
|
||||
* @var array<string, class-string>>
|
||||
*/
|
||||
private const OLD_TO_NEW_CLASSES = [
|
||||
'Twig_Function_Method' => 'Twig_SimpleFunction',
|
||||
|
@ -102,12 +101,13 @@ CODE_SAMPLE
|
|||
return null;
|
||||
}
|
||||
|
||||
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $classLike instanceof ClassLike) {
|
||||
return null;
|
||||
}
|
||||
/** @var Scope $scope */
|
||||
$scope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
|
||||
if (! $this->isObjectType($classLike, new ObjectType('Twig_Extension'))) {
|
||||
/** @var ClassReflection $classReflection */
|
||||
$classReflection = $scope->getClassReflection();
|
||||
|
||||
if (! $classReflection->isSubclassOf('Twig_Extension')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,8 @@ CODE_SAMPLE
|
|||
return null;
|
||||
}
|
||||
|
||||
return $this->processArrayItem($node, $this->getObjectType($node->value));
|
||||
$newObjectType = $this->nodeTypeResolver->resolve($node->value);
|
||||
return $this->processArrayItem($node, $newObjectType);
|
||||
});
|
||||
|
||||
return $node;
|
||||
|
|
|
@ -58,7 +58,7 @@ final class ConsoleExceptionToErrorEventConstantRector extends AbstractRector
|
|||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($node instanceof ClassConstFetch && (
|
||||
$this->isObjectType($node, $this->consoleEventsObjectType) &&
|
||||
$this->isObjectType($node->class, $this->consoleEventsObjectType) &&
|
||||
$this->isName($node->name, 'EXCEPTION'))
|
||||
) {
|
||||
return $this->nodeFactory->createClassConstFetch($this->consoleEventsObjectType->getClassName(), 'ERROR');
|
||||
|
|
|
@ -52,12 +52,14 @@ CODE_SAMPLE
|
|||
<<<'CODE_SAMPLE'
|
||||
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
|
||||
use Symfony\Component\Form\FormConfigBuilderInterface;
|
||||
use Symfony\Component\Form\Extension\Core\DataMapper\DataMapper;
|
||||
use Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run(FormConfigBuilderInterface $builder)
|
||||
{
|
||||
$builder->setDataMapper(new \Symfony\Component\Form\Extension\Core\DataMapper\DataMapper(new \Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor()));
|
||||
$builder->setDataMapper(new DataMapper(new PropertyPathAccessor()));
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
|
@ -78,7 +80,12 @@ CODE_SAMPLE
|
|||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isObjectType($node->var, new ObjectType('Symfony\Component\Form\FormConfigBuilderInterface'))) {
|
||||
$callerObjectType = $this->nodeTypeResolver->resolveObjectTypeToCompare($node->var);
|
||||
if (! $callerObjectType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $callerObjectType->isInstanceOf('Symfony\Component\Form\FormConfigBuilderInterface')->yes()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Rector\Symfony5\Tests\Rector\MethodCall\FormBuilderSetDataMapperRector
|
|||
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
|
||||
use Symfony\Component\Form\FormConfigBuilderInterface;
|
||||
|
||||
class Fixture
|
||||
final class Fixture
|
||||
{
|
||||
public function run(FormConfigBuilderInterface $builder)
|
||||
{
|
||||
|
@ -20,10 +20,10 @@ namespace Rector\Symfony5\Tests\Rector\MethodCall\FormBuilderSetDataMapperRector
|
|||
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
|
||||
use Symfony\Component\Form\FormConfigBuilderInterface;
|
||||
|
||||
class Fixture
|
||||
final class Fixture
|
||||
{
|
||||
public function run(FormConfigBuilderInterface $builder)
|
||||
{
|
||||
$builder->setDataMapper(new \Symfony\Component\Form\Extension\Core\DataMapper\DataMapper(new \Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@ namespace Rector\Symfony5\Tests\Rector\MethodCall\FormBuilderSetDataMapperRector
|
|||
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
|
||||
use Symfony\Component\Form\FormConfigBuilderInterface;
|
||||
|
||||
class SkipCorrectArg
|
||||
final class SkipCorrectArg
|
||||
{
|
||||
public function run(FormConfigBuilderInterface $builder)
|
||||
{
|
||||
$propertyPathAccessor = new \Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor();
|
||||
$builder->setDataMapper(new \Symfony\Component\Form\Extension\Core\DataMapper\DataMapper($propertyPathAccessor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,19 +15,10 @@ use PHPStan\Type\UnionType;
|
|||
use Rector\NodeCollector\ValueObject\ArrayCallable;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
|
||||
use Rector\TypeDeclaration\ValueObject\TypeStrictness;
|
||||
|
||||
final class CallTypesResolver
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const STRICTNESS_TYPE_DECLARATION = 'type_declaration';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const STRICTNESS_DOCBLOCK = 'docblock';
|
||||
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
|
@ -50,7 +41,7 @@ final class CallTypesResolver
|
|||
*/
|
||||
public function resolveStrictTypesFromCalls(array $calls): array
|
||||
{
|
||||
return $this->resolveTypesFromCalls($calls, self::STRICTNESS_TYPE_DECLARATION);
|
||||
return $this->resolveTypesFromCalls($calls, TypeStrictness::STRICTNESS_TYPE_DECLARATION);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,7 +50,7 @@ final class CallTypesResolver
|
|||
*/
|
||||
public function resolveWeakTypesFromCalls(array $calls): array
|
||||
{
|
||||
return $this->resolveTypesFromCalls($calls, self::STRICTNESS_DOCBLOCK);
|
||||
return $this->resolveTypesFromCalls($calls, TypeStrictness::STRICTNESS_DOCBLOCK);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,7 +78,7 @@ final class CallTypesResolver
|
|||
|
||||
private function resolveArgValueType(string $strictnessLevel, Arg $arg): Type
|
||||
{
|
||||
if ($strictnessLevel === self::STRICTNESS_TYPE_DECLARATION) {
|
||||
if ($strictnessLevel === TypeStrictness::STRICTNESS_TYPE_DECLARATION) {
|
||||
$argValueType = $this->nodeTypeResolver->getNativeType($arg->value);
|
||||
} else {
|
||||
$argValueType = $this->nodeTypeResolver->resolve($arg->value);
|
||||
|
|
|
@ -5,7 +5,9 @@ declare(strict_types=1);
|
|||
namespace Rector\TypeDeclaration\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Type\CallableType;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\StaticTypeMapper\StaticTypeMapper;
|
||||
use Rector\VendorLocker\NodeVendorLocker\ClassMethodParamVendorLockResolver;
|
||||
|
@ -82,7 +84,30 @@ final class ClassMethodParamTypeCompleter
|
|||
}
|
||||
|
||||
$parameterStaticType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($parameter->type);
|
||||
|
||||
if ($this->isClosureAndCallableType($parameterStaticType, $argumentStaticType)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// already completed → skip
|
||||
return $parameterStaticType->equals($argumentStaticType);
|
||||
}
|
||||
|
||||
private function isClosureAndCallableType(Type $parameterStaticType, Type $argumentStaticType): bool
|
||||
{
|
||||
if ($parameterStaticType instanceof CallableType && $this->isClosureObjectType($argumentStaticType)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $argumentStaticType instanceof CallableType && $this->isClosureObjectType($parameterStaticType);
|
||||
}
|
||||
|
||||
private function isClosureObjectType(Type $type): bool
|
||||
{
|
||||
if (! $type instanceof ObjectType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $type->getClassName() === 'Closure';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,6 @@ final class SomeClass
|
|||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
final class SomeClass
|
||||
|
@ -72,7 +71,6 @@ final class SomeClass
|
|||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ use PhpParser\Node;
|
|||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Type\ArrayType;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
|
@ -87,8 +88,13 @@ CODE_SAMPLE
|
|||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$objectType = $this->nodeTypeResolver->resolveObjectTypeToCompare($node);
|
||||
if (! $objectType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($this->methodReturnTypes as $methodReturnType) {
|
||||
if (! $this->isObjectType($node, $methodReturnType->getObjectType())) {
|
||||
if (! $objectType->isInstanceOf($methodReturnType->getClass())->yes()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\TypeDeclaration\ValueObject;
|
||||
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
|
||||
final class AddReturnTypeDeclaration
|
||||
|
@ -31,9 +30,9 @@ final class AddReturnTypeDeclaration
|
|||
$this->returnType = $returnType;
|
||||
}
|
||||
|
||||
public function getObjectType(): ObjectType
|
||||
public function getClass(): string
|
||||
{
|
||||
return new ObjectType($this->class);
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
public function getMethod(): string
|
||||
|
|
21
rules/type-declaration/src/ValueObject/TypeStrictness.php
Normal file
21
rules/type-declaration/src/ValueObject/TypeStrictness.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\TypeDeclaration\ValueObject;
|
||||
|
||||
/**
|
||||
* @enum
|
||||
*/
|
||||
final class TypeStrictness
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const STRICTNESS_TYPE_DECLARATION = 'type_declaration';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const STRICTNESS_DOCBLOCK = 'docblock';
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddParamTypeFromCallersRector\Fixture;
|
||||
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Trait_;
|
||||
|
||||
final class ClassTraitClassLike
|
||||
{
|
||||
/**
|
||||
* @param Class_|Trait_ $class
|
||||
*/
|
||||
public function run(\PhpParser\Node $class)
|
||||
{
|
||||
$this->process($class);
|
||||
}
|
||||
|
||||
public function process($class)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddParamTypeFromCallersRector\Fixture;
|
||||
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Trait_;
|
||||
|
||||
final class ClassTraitClassLike
|
||||
{
|
||||
/**
|
||||
* @param Class_|Trait_ $class
|
||||
*/
|
||||
public function run(\PhpParser\Node $class)
|
||||
{
|
||||
$this->process($class);
|
||||
}
|
||||
|
||||
public function process(\PhpParser\Node\Stmt\ClassLike $class)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddParamTypeFromCallersRector\Fixture;
|
||||
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\For_;
|
||||
use PhpParser\Node\Stmt\Nop;
|
||||
|
||||
final class NodeOverNodeAbstract
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$for = new For_();
|
||||
$this->provideByType($for);
|
||||
|
||||
$string = new String_('hey');
|
||||
$this->provideByType($string);
|
||||
}
|
||||
|
||||
public function provideByType($node)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddParamTypeFromCallersRector\Fixture;
|
||||
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\For_;
|
||||
use PhpParser\Node\Stmt\Nop;
|
||||
|
||||
final class NodeOverNodeAbstract
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$for = new For_();
|
||||
$this->provideByType($for);
|
||||
|
||||
$string = new String_('hey');
|
||||
$this->provideByType($string);
|
||||
}
|
||||
|
||||
public function provideByType(\PhpParser\Node $node)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddParamTypeFromCallersRector\Fixture;
|
||||
|
||||
final class SkipCallableToClosure
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$someCallback = function () {
|
||||
return 1;
|
||||
};
|
||||
|
||||
$this->setValue($someCallback);
|
||||
}
|
||||
|
||||
public function setValue(callable $someCallaback)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddParamTypeFromCallersRector\Fixture;
|
||||
|
||||
use Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddParamTypeFromCallersRector\Source\ClassWithConstant;
|
||||
|
||||
final class SkipConstantFetch
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$this->setValue(ClassWithConstant::SOME_NAME);
|
||||
}
|
||||
|
||||
public function setValue(string $value)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddParamTypeFromCallersRector\Fixture;
|
||||
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\PostRector\Rector\AbstractPostRector;
|
||||
|
||||
final class SomeRectorPass
|
||||
{
|
||||
public function run(AbstractRector $abstractRector, AbstractPostRector $postRector)
|
||||
{
|
||||
$this->setValue($abstractRector);
|
||||
$this->setValue($postRector);
|
||||
}
|
||||
|
||||
private function setValue($rector)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddParamTypeFromCallersRector\Fixture;
|
||||
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\PostRector\Rector\AbstractPostRector;
|
||||
|
||||
final class SomeRectorPass
|
||||
{
|
||||
public function run(AbstractRector $abstractRector, AbstractPostRector $postRector)
|
||||
{
|
||||
$this->setValue($abstractRector);
|
||||
$this->setValue($postRector);
|
||||
}
|
||||
|
||||
private function setValue(\Rector\Core\Contract\Rector\RectorInterface $rector)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddParamTypeFromCallersRector\Source;
|
||||
|
||||
final class ClassWithConstant
|
||||
{
|
||||
public const SOME_NAME = 'hey';
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddReturnTypeDeclarationRector\Fixture;
|
||||
|
||||
class Fixture
|
||||
{
|
||||
public function parse()
|
||||
{
|
||||
}
|
||||
|
||||
public function resolve()
|
||||
{
|
||||
}
|
||||
|
||||
public function nullable(): array
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddReturnTypeDeclarationRector\Fixture;
|
||||
|
||||
class Fixture
|
||||
{
|
||||
public function parse(): array
|
||||
{
|
||||
}
|
||||
|
||||
public function resolve(): \SomeType
|
||||
{
|
||||
}
|
||||
|
||||
public function nullable(): ?\SomeType
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddReturnTypeDeclarationRector\Fixture;
|
||||
|
||||
class RemoveReturnType
|
||||
{
|
||||
public function clear(): array
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddReturnTypeDeclarationRector\Fixture;
|
||||
|
||||
class RemoveReturnType
|
||||
{
|
||||
public function clear()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -2,11 +2,6 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
use PHPStan\Type\ArrayType;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\NullType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\UnionType;
|
||||
use PHPStan\Type\VoidType;
|
||||
use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationRector;
|
||||
use Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddReturnTypeDeclarationRector\Source\PHPUnitTestCase;
|
||||
|
@ -15,34 +10,11 @@ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigura
|
|||
use Symplify\SymfonyPhpConfig\ValueObjectInliner;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$arrayType = new ArrayType(new MixedType(), new MixedType());
|
||||
$nullableObjectUnionType = new UnionType([new ObjectType('SomeType'), new NullType()]);
|
||||
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
$services->set(AddReturnTypeDeclarationRector::class)
|
||||
->call('configure', [[
|
||||
AddReturnTypeDeclarationRector::METHOD_RETURN_TYPES => ValueObjectInliner::inline([
|
||||
new AddReturnTypeDeclaration(
|
||||
'Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddReturnTypeDeclarationRector\Fixture\Fixture',
|
||||
'parse',
|
||||
$arrayType
|
||||
),
|
||||
new AddReturnTypeDeclaration(
|
||||
'Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddReturnTypeDeclarationRector\Fixture\Fixture',
|
||||
'resolve',
|
||||
new ObjectType('SomeType')
|
||||
),
|
||||
new AddReturnTypeDeclaration(
|
||||
'Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddReturnTypeDeclarationRector\Fixture\Fixture',
|
||||
'nullable',
|
||||
$nullableObjectUnionType
|
||||
),
|
||||
new AddReturnTypeDeclaration(
|
||||
'Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddReturnTypeDeclarationRector\Fixture\RemoveReturnType',
|
||||
'clear',
|
||||
new MixedType()
|
||||
),
|
||||
new AddReturnTypeDeclaration(PHPUnitTestCase::class, 'tearDown', new VoidType()),
|
||||
]),
|
||||
]]);
|
||||
|
|
|
@ -11,12 +11,12 @@ use PhpParser\Node\Expr\New_;
|
|||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Name;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Broker\FunctionNotFoundException;
|
||||
use PHPStan\Reflection\FunctionReflection;
|
||||
use PHPStan\Reflection\MethodReflection;
|
||||
use PHPStan\Reflection\ParametersAcceptor;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\ThisType;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\Core\PHPStan\Reflection\TypeToCallReflectionResolver\TypeToCallReflectionResolverRegistry;
|
||||
|
@ -126,21 +126,23 @@ final class CallReflectionResolver
|
|||
*/
|
||||
private function resolveFunctionCall(FuncCall $funcCall)
|
||||
{
|
||||
/** @var Scope|null $scope */
|
||||
$scope = $funcCall->getAttribute(AttributeKey::SCOPE);
|
||||
|
||||
if ($funcCall->name instanceof Name) {
|
||||
try {
|
||||
if ($this->reflectionProvider->hasFunction($funcCall->name, $scope)) {
|
||||
return $this->reflectionProvider->getFunction($funcCall->name, $scope);
|
||||
} catch (FunctionNotFoundException $functionNotFoundException) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $scope instanceof Scope) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->typeToCallReflectionResolverRegistry->resolve($scope->getType($funcCall->name), $scope);
|
||||
$funcCallNameType = $scope->getType($funcCall->name);
|
||||
return $this->typeToCallReflectionResolverRegistry->resolve($funcCallNameType, $scope);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,6 +162,10 @@ final class CallReflectionResolver
|
|||
|
||||
$classType = $this->nodeTypeResolver->resolve($node instanceof MethodCall ? $node->var : $node->class);
|
||||
|
||||
if ($classType instanceof ThisType) {
|
||||
$classType = $classType->getStaticObjectType();
|
||||
}
|
||||
|
||||
if ($classType instanceof ObjectType) {
|
||||
if (! $this->reflectionProvider->hasClass($classType->getClassName())) {
|
||||
return null;
|
||||
|
|
|
@ -5,11 +5,9 @@ declare(strict_types=1);
|
|||
namespace Rector\Core\Reflection;
|
||||
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Type\IntersectionType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\ThisType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\StaticTypeMapper\ValueObject\Type\ShortenedObjectType;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use ReflectionMethod;
|
||||
|
||||
final class ClassMethodReflectionFactory
|
||||
|
@ -26,39 +24,26 @@ final class ClassMethodReflectionFactory
|
|||
|
||||
public function createFromPHPStanTypeAndMethodName(Type $type, string $methodName): ?ReflectionMethod
|
||||
{
|
||||
if ($type instanceof ShortenedObjectType) {
|
||||
return $this->createReflectionMethodIfExists($type->getFullyQualifiedName(), $methodName);
|
||||
if ($type instanceof ThisType) {
|
||||
$type = $type->getStaticObjectType();
|
||||
}
|
||||
|
||||
if ($type instanceof ObjectType) {
|
||||
return $this->createReflectionMethodIfExists($type->getClassName(), $methodName);
|
||||
}
|
||||
|
||||
if ($type instanceof UnionType || $type instanceof IntersectionType) {
|
||||
foreach ($type->getTypes() as $unionedType) {
|
||||
if (! $unionedType instanceof ObjectType) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$methodReflection = $this->createFromPHPStanTypeAndMethodName($unionedType, $methodName);
|
||||
if (! $methodReflection instanceof ReflectionMethod) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $methodReflection;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function createReflectionMethodIfExists(string $class, string $method): ?ReflectionMethod
|
||||
{
|
||||
if (! $this->reflectionProvider->hasClass($class)) {
|
||||
if (! $type instanceof TypeWithClassName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classReflection = $this->reflectionProvider->getClass($class);
|
||||
return $this->createReflectionMethodIfExists($type, $methodName);
|
||||
}
|
||||
|
||||
public function createReflectionMethodIfExists(
|
||||
TypeWithClassName $typeWithClassName,
|
||||
string $method
|
||||
): ?ReflectionMethod {
|
||||
if (! $this->reflectionProvider->hasClass($typeWithClassName->getClassName())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classReflection = $this->reflectionProvider->getClass($typeWithClassName->getClassName());
|
||||
|
||||
$reflectionClass = $classReflection->getNativeReflection();
|
||||
if (! $reflectionClass->hasMethod($method)) {
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
if (class_exists('PHPExcel_CalcEngine_Logger')) {
|
||||
return;
|
||||
}
|
||||
|
||||
final class PHPExcel_CalcEngine_Logger
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
if (class_exists('PHPExcel_Cell_DataValidation')) {
|
||||
return;
|
||||
}
|
||||
|
||||
final class PHPExcel_Cell_DataValidation
|
||||
{
|
||||
}
|
12
stubs/PHPOffice/PHPExcel/PHPExcel_Cell.php
Normal file
12
stubs/PHPOffice/PHPExcel/PHPExcel_Cell.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
if (class_exists('PHPExcel_Cell')) {
|
||||
return;
|
||||
}
|
||||
|
||||
final class PHPExcel_Cell
|
||||
{
|
||||
|
||||
}
|
11
stubs/PHPOffice/PHPExcel/Style/Conditional.php
Normal file
11
stubs/PHPOffice/PHPExcel/Style/Conditional.php
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
if (class_exists('PHPExcel_Style_Conditional')) {
|
||||
return;
|
||||
}
|
||||
|
||||
final class PHPExcel_Style_Conditional
|
||||
{
|
||||
}
|
14
stubs/Symfony/Component/Form/FormConfigBuilderInterface.php
Normal file
14
stubs/Symfony/Component/Form/FormConfigBuilderInterface.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
if (interface_exists('Symfony\Component\Form\FormConfigBuilderInterface')) {
|
||||
return;
|
||||
}
|
||||
|
||||
interface FormConfigBuilderInterface
|
||||
{
|
||||
|
||||
}
|
13
stubs/Tester/Assert.php
Normal file
13
stubs/Tester/Assert.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tester;
|
||||
|
||||
if (class_exists('Tester\Assert')) {
|
||||
return;
|
||||
}
|
||||
|
||||
class Assert
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue
Block a user