protected function recurseWithNewContext(FunctionContext $newContext, array $nodes) { $oldContext = $this->context->getFunctionContext(); $this->context->setFunctionContext($newContext); $this->recurse($nodes); $this->context->setFunctionContext($oldContext); }
public function check($path) { if (!defined('PHINT_DEBUG')) { define('PHINT_DEBUG', false); } if (!defined('PHINT_STRICT')) { define('PHINT_STRICT', false); } $this->errors->clear(); $code = file_get_contents($path); $nodes = $this->parser->parse($code); $this->context->setFileName($path); $this->traverser->traverse($nodes); }
private function checkMethodCall(MethodCall $node) { $this->recurse(array_map(function ($arg) { return $arg->value; }, $node->args)); $reflClasses = $this->getCurrentReflectionClass(); if (!$reflClasses && $this->getCurrentType() !== 'mixed' && $this->getCurrentType() !== 'object') { $this->addMethodOnNonObjectError($node); return false; } if (!is_array($reflClasses)) { $reflClasses = [$reflClasses]; } $types = []; foreach ($reflClasses as $reflClass) { if (!$reflClass->hasMethod($node->name)) { if (!$reflClass->hasMethod('__call')) { $class = $reflClass->getName(); $this->addUndefinedMethodError($node, $class, $node->name); } return false; } $reflMethod = $reflClass->getMethod($node->name); $params = $reflMethod->getParameters(); // verify number of arguments if (count($node->args) > count($params)) { // cannot error on this as php functions can use func_get_args() } $requiredParams = 0; foreach ($params as $param) { if ($param->isOptional() || $param->isDefaultValueAvailable()) { break; } $requiredParams++; } if (count($node->args) < $requiredParams) { $this->addNotEnoughParamsError($node, $reflClass, $requiredParams); } // look for function parameters passed by reference foreach ($params as $param) { if ($param->isPassedByReference()) { $pos = $param->getPosition(); if (isset($node->args[$pos])) { $var = $node->args[$pos]->value; if ($var instanceof Variable) { $this->context->setVariable($var->name, $var); } } } } $type = $this->getReflectionType($reflMethod); if (!$type) { if (!$this->isLastLink) { $this->addUndeterminableTypeError($node, $reflClass->getName()); } return false; } $types = array_merge($types, (array) $type); } return $this->updateType($types); }