public function processNode(\PhpParser\Node $node, Scope $scope) : array
{
if (!is_string($node->name)) {
return [];
}
if ($this->checkThisOnly && !$this->ruleLevelHelper->isThis($node->var)) {
return [];
}
$type = $scope->getType($node->var);
if (!$type->canAccessProperties()) {
return [sprintf('Cannot access property $%s on %s.', $node->name, $type->describe())];
}
$propertyClass = $type->getClass();
if ($propertyClass === null) {
return [];
}
$name = (string) $node->name;
if (!$this->broker->hasClass($propertyClass)) {
return [sprintf('Access to property $%s on an unknown class %s.', $name, $propertyClass)];
}
$propertyClassReflection = $this->broker->getClass($propertyClass);
if (!$propertyClassReflection->hasProperty($name)) {
if ($scope->isSpecified($node)) {
return [];
}
$parentClassReflection = $propertyClassReflection->getParentClass();
while ($parentClassReflection !== false) {
if ($parentClassReflection->hasProperty($name)) {
return [sprintf('Access to private property $%s of parent class %s.', $name, $parentClassReflection->getName())];
}
$parentClassReflection = $parentClassReflection->getParentClass();
}
return [sprintf('Access to an undefined property %s::$%s.', $propertyClass, $name)];
}
$propertyReflection = $propertyClassReflection->getProperty($name, $scope);
if (!$scope->canAccessProperty($propertyReflection)) {
return [sprintf('Cannot access property %s::$%s from current scope.', $propertyReflection->getDeclaringClass()->getName(), $name)];
}
return [];
}