예제 #1
0
 /**
  * @param \PhpParser\Node\Expr\MethodCall $node
  * @param \PHPStan\Analyser\Scope $scope
  * @return string[]
  */
 public function processNode(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->canCallMethods()) {
         return [sprintf('Cannot call method %s() on %s.', $node->name, $type->describe())];
     }
     $methodClass = $type->getClass();
     if ($methodClass === null) {
         return [];
     }
     $name = (string) $node->name;
     if (!$this->broker->hasClass($methodClass)) {
         return [sprintf('Call to method %s() on an unknown class %s.', $name, $methodClass)];
     }
     $methodClassReflection = $this->broker->getClass($methodClass);
     if (!$methodClassReflection->hasMethod($name)) {
         $parentClassReflection = $methodClassReflection->getParentClass();
         while ($parentClassReflection !== false) {
             if ($parentClassReflection->hasMethod($name)) {
                 return [sprintf('Call to private method %s() of parent class %s.', $parentClassReflection->getMethod($name)->getName(), $parentClassReflection->getName())];
             }
             $parentClassReflection = $parentClassReflection->getParentClass();
         }
         return [sprintf('Call to an undefined method %s::%s().', $methodClassReflection->getName(), $name)];
     }
     $methodReflection = $methodClassReflection->getMethod($name);
     $messagesMethodName = $methodReflection->getDeclaringClass()->getName() . '::' . $methodReflection->getName() . '()';
     if (!$scope->canCallMethod($methodReflection)) {
         return [sprintf('Cannot call method %s from current scope.', $messagesMethodName)];
     }
     $errors = $this->check->check($methodReflection, $node, ['Method ' . $messagesMethodName . ' invoked with %d parameter, %d required.', 'Method ' . $messagesMethodName . ' invoked with %d parameters, %d required.', 'Method ' . $messagesMethodName . ' invoked with %d parameter, at least %d required.', 'Method ' . $messagesMethodName . ' invoked with %d parameters, at least %d required.', 'Method ' . $messagesMethodName . ' invoked with %d parameter, %d-%d required.', 'Method ' . $messagesMethodName . ' invoked with %d parameters, %d-%d required.']);
     if ($methodReflection->getName() !== $name) {
         $errors[] = sprintf('Call to method %s with incorrect case: %s', $messagesMethodName, $name);
     }
     return $errors;
 }
예제 #2
0
 /**
  * @param \PhpParser\Node\Expr\PropertyFetch $node
  * @param \PHPStan\Analyser\Scope $scope
  * @return string[]
  */
 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 [];
 }