public function processNode(Node $node, Scope $scope) : array
{
if (!$node->name instanceof \PhpParser\Node\Name) {
return [];
}
$functionsArgumentPositions = ['printf' => 0, 'sprintf' => 0, 'sscanf' => 1, 'fscanf' => 1];
$minimumNumberOfArguments = ['printf' => 1, 'sprintf' => 1, 'sscanf' => 3, 'fscanf' => 3];
$name = (string) $node->name;
if (!isset($functionsArgumentPositions[$name])) {
return [];
}
$formatArgumentPosition = $functionsArgumentPositions[$name];
$args = $node->args;
$argsCount = count($args);
if ($argsCount < $minimumNumberOfArguments[$name]) {
return [];
// caught by CallToFunctionParametersRule
}
$formatArg = $args[$formatArgumentPosition]->value;
if (!$formatArg instanceof String_) {
return [];
// inspect only literal string format
}
$format = $formatArg->value;
$placeHoldersCount = $this->getPlaceholdersCount($format);
$argsCount -= $formatArgumentPosition;
if ($argsCount !== $placeHoldersCount + 1) {
return [sprintf(sprintf('%s, %s.', $placeHoldersCount === 1 ? 'Call to %s contains %d placeholder' : 'Call to %s contains %d placeholders', $argsCount - 1 === 1 ? '%d value given' : '%d values given'), $name, $placeHoldersCount, $argsCount - 1)];
}
return [];
}