Chris@16: atLeastPhp71 = \version_compare(PHP_VERSION, '7.1', '>='); Chris@16: } Chris@16: Chris@16: /** Chris@16: * Validate use of list assignment. Chris@16: * Chris@16: * @throws ParseErrorException if the user used empty with anything but a variable Chris@16: * Chris@16: * @param Node $node Chris@16: */ Chris@16: public function enterNode(Node $node) Chris@16: { Chris@16: if (!$node instanceof Assign) { Chris@16: return; Chris@16: } Chris@16: Chris@16: if (!$node->var instanceof Array_ && !$node->var instanceof List_) { Chris@16: return; Chris@16: } Chris@16: Chris@16: if (!$this->atLeastPhp71 && $node->var instanceof Array_) { Chris@16: $msg = "syntax error, unexpected '='"; Chris@16: throw new ParseErrorException($msg, $node->expr->getLine()); Chris@16: } Chris@16: Chris@16: // Polyfill for PHP-Parser 2.x Chris@16: $items = isset($node->var->items) ? $node->var->items : $node->var->vars; Chris@16: Chris@16: if ($items === [] || $items === [null]) { Chris@16: throw new ParseErrorException('Cannot use empty list', $node->var->getLine()); Chris@16: } Chris@16: Chris@16: $itemFound = false; Chris@16: foreach ($items as $item) { Chris@16: if ($item === null) { Chris@16: continue; Chris@16: } Chris@16: Chris@16: $itemFound = true; Chris@16: Chris@16: // List_->$vars in PHP-Parser 2.x is Variable instead of ArrayItem. Chris@16: if (!$this->atLeastPhp71 && $item instanceof ArrayItem && $item->key !== null) { Chris@16: $msg = 'Syntax error, unexpected T_CONSTANT_ENCAPSED_STRING, expecting \',\' or \')\''; Chris@16: throw new ParseErrorException($msg, $item->key->getLine()); Chris@16: } Chris@16: Chris@17: if (!self::isValidArrayItem($item)) { Chris@16: $msg = 'Assignments can only happen to writable values'; Chris@16: throw new ParseErrorException($msg, $item->getLine()); Chris@16: } Chris@16: } Chris@16: Chris@16: if (!$itemFound) { Chris@16: throw new ParseErrorException('Cannot use empty list'); Chris@16: } Chris@16: } Chris@17: Chris@17: /** Chris@17: * Validate whether a given item in an array is valid for short assignment. Chris@17: * Chris@17: * @param Expr $item Chris@17: * Chris@17: * @return bool Chris@17: */ Chris@17: private static function isValidArrayItem(Expr $item) Chris@17: { Chris@17: $value = ($item instanceof ArrayItem) ? $item->value : $item; Chris@17: Chris@17: while ($value instanceof ArrayDimFetch || $value instanceof PropertyFetch) { Chris@17: $value = $value->var; Chris@17: } Chris@17: Chris@17: // We just kind of give up if it's a method call. We can't tell if it's Chris@17: // valid via static analysis. Chris@17: return $value instanceof Variable || $value instanceof MethodCall || $value instanceof FuncCall; Chris@17: } Chris@16: }