/opt/cpanel/ea-wappspector/vendor/rector/rector/src/NodeManipulator
Edit: /opt/cpanel/ea-wappspector/vendor/rector/rector/src/NodeManipulator/PropertyManipulator.php (8862B)
[]
*/
private const DOCTRINE_PROPERTY_ANNOTATIONS = ['Doctrine\\ORM\\Mapping\\Entity', 'Doctrine\\ORM\\Mapping\\Table', 'Doctrine\\ORM\\Mapping\\MappedSuperclass', 'Doctrine\\ORM\\Mapping\\Embeddable'];
public function __construct(\Rector\NodeManipulator\AssignManipulator $assignManipulator, BetterNodeFinder $betterNodeFinder, PhpDocInfoFactory $phpDocInfoFactory, PropertyFetchFinder $propertyFetchFinder, NodeNameResolver $nodeNameResolver, PhpAttributeAnalyzer $phpAttributeAnalyzer, NodeTypeResolver $nodeTypeResolver, PromotedPropertyResolver $promotedPropertyResolver, ConstructorAssignDetector $constructorAssignDetector, AstResolver $astResolver, PropertyFetchAnalyzer $propertyFetchAnalyzer)
{
$this->assignManipulator = $assignManipulator;
$this->betterNodeFinder = $betterNodeFinder;
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->propertyFetchFinder = $propertyFetchFinder;
$this->nodeNameResolver = $nodeNameResolver;
$this->phpAttributeAnalyzer = $phpAttributeAnalyzer;
$this->nodeTypeResolver = $nodeTypeResolver;
$this->promotedPropertyResolver = $promotedPropertyResolver;
$this->constructorAssignDetector = $constructorAssignDetector;
$this->astResolver = $astResolver;
$this->propertyFetchAnalyzer = $propertyFetchAnalyzer;
}
/**
* @param \PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $propertyOrParam
*/
public function isPropertyChangeableExceptConstructor(Class_ $class, $propertyOrParam, Scope $scope) : bool
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($class);
if ($this->hasAllowedNotReadonlyAnnotationOrAttribute($phpDocInfo, $class)) {
return \true;
}
$propertyFetches = $this->propertyFetchFinder->findPrivatePropertyFetches($class, $propertyOrParam, $scope);
$classMethod = $class->getMethod(MethodName::CONSTRUCT);
foreach ($propertyFetches as $propertyFetch) {
if ($this->isChangeableContext($propertyFetch)) {
return \true;
}
// skip for constructor? it is allowed to set value in constructor method
$propertyName = (string) $this->nodeNameResolver->getName($propertyFetch);
if ($this->isPropertyAssignedOnlyInConstructor($class, $propertyName, $propertyFetch, $classMethod)) {
continue;
}
if ($this->assignManipulator->isLeftPartOfAssign($propertyFetch)) {
return \true;
}
if ($propertyFetch->getAttribute(AttributeKey::IS_UNSET_VAR) === \true) {
return \true;
}
}
return \false;
}
/**
* @api Used in rector-symfony
*/
public function resolveExistingClassPropertyNameByType(Class_ $class, ObjectType $objectType) : ?string
{
foreach ($class->getProperties() as $property) {
$propertyType = $this->nodeTypeResolver->getType($property);
if (!$propertyType->equals($objectType)) {
continue;
}
return $this->nodeNameResolver->getName($property);
}
$promotedPropertyParams = $this->promotedPropertyResolver->resolveFromClass($class);
foreach ($promotedPropertyParams as $promotedPropertyParam) {
$paramType = $this->nodeTypeResolver->getType($promotedPropertyParam);
if (!$paramType->equals($objectType)) {
continue;
}
return $this->nodeNameResolver->getName($promotedPropertyParam);
}
return null;
}
public function isUsedByTrait(ClassReflection $classReflection, string $propertyName) : bool
{
foreach ($classReflection->getTraits() as $traitUse) {
$trait = $this->astResolver->resolveClassFromClassReflection($traitUse);
if (!$trait instanceof Trait_) {
continue;
}
if ($this->propertyFetchAnalyzer->containsLocalPropertyFetchName($trait, $propertyName)) {
return \true;
}
}
return \false;
}
/**
* @param \PhpParser\Node\Expr\StaticPropertyFetch|\PhpParser\Node\Expr\PropertyFetch $propertyFetch
*/
private function isPropertyAssignedOnlyInConstructor(Class_ $class, string $propertyName, $propertyFetch, ?ClassMethod $classMethod) : bool
{
if (!$classMethod instanceof ClassMethod) {
return \false;
}
$node = $this->betterNodeFinder->findFirst((array) $classMethod->stmts, static function (Node $subNode) use($propertyFetch) : bool {
return ($subNode instanceof PropertyFetch || $subNode instanceof StaticPropertyFetch) && $subNode === $propertyFetch;
});
// there is property unset in Test class, so only check on __construct
if (!$node instanceof Node) {
return \false;
}
return $this->constructorAssignDetector->isPropertyAssigned($class, $propertyName);
}
/**
* @param \PhpParser\Node\Expr\PropertyFetch|\PhpParser\Node\Expr\StaticPropertyFetch $propertyFetch
*/
private function isChangeableContext($propertyFetch) : bool
{
if ($propertyFetch->getAttribute(AttributeKey::IS_UNSET_VAR, \false)) {
return \true;
}
if ($propertyFetch->getAttribute(AttributeKey::INSIDE_ARRAY_DIM_FETCH, \false)) {
return \true;
}
if ($propertyFetch->getAttribute(AttributeKey::IS_USED_AS_ARG_BY_REF_VALUE, \false) === \true) {
return \true;
}
return $propertyFetch->getAttribute(AttributeKey::IS_INCREMENT_OR_DECREMENT, \false) === \true;
}
private function hasAllowedNotReadonlyAnnotationOrAttribute(PhpDocInfo $phpDocInfo, Class_ $class) : bool
{
if ($phpDocInfo->hasByAnnotationClasses(self::DOCTRINE_PROPERTY_ANNOTATIONS)) {
return \true;
}
return $this->phpAttributeAnalyzer->hasPhpAttributes($class, self::DOCTRINE_PROPERTY_ANNOTATIONS);
}
}