*/ protected $allowedClasses = []; /** @psalm-var list */ protected $parts = []; /** * @param mixed $args */ public function __construct($args = []) { $this->addMultiple($args); } /** * @param string[]|object[]|string|object $args * @psalm-param list|string|object $args * * @return $this */ public function addMultiple($args = []) { foreach ((array) $args as $arg) { $this->add($arg); } return $this; } /** * @param mixed $arg * * @return $this * * @throws InvalidArgumentException */ public function add($arg) { if ($arg !== null && (! $arg instanceof self || $arg->count() > 0)) { // If we decide to keep Expr\Base instances, we can use this check if (! is_string($arg) && ! in_array(get_class($arg), $this->allowedClasses, true)) { throw new InvalidArgumentException(sprintf( "Expression of type '%s' not allowed in this context.", get_debug_type($arg) )); } $this->parts[] = $arg; } return $this; } /** * @return int * @psalm-return 0|positive-int */ public function count() { return count($this->parts); } /** * @return string */ public function __toString() { if ($this->count() === 1) { return (string) $this->parts[0]; } return $this->preSeparator . implode($this->separator, $this->parts) . $this->postSeparator; } }