Adds more select expressions

@param string[] $expression,... A variable list of select expressions
@return self For method chaining
505672
public function addSelectExpression(string ...$expression) : self
    {
        $this->selectExpressions = array_merge($this->selectExpressions, $expression);

        return $this;
    }
736264
public function addSelectColumn($expression, $alias = null)
    {
        if (!($expression instanceof Expression)) {
            $expression = new Expr\Column($expression);
        }
        
        $expression = $this->completeExpression($expression, $alias);
        
        $this->columns->add($expression->hashCode());
        
        return $this;
    }
75122
private static function treeStruct(string $expression): array
    {
        if (\strpos($expression, '<?') === 0 || $expression[-1] === ';') {
            throw new \InvalidArgumentException('Expression syntax error');
        }

        $expression = '<?php ' . $expression . ';';

        $tokens = \token_get_all($expression);

        $temp = [];
        $level = 0;

        $n = \count($tokens);
        $i = 1; // skip T_OPEN_TAG
        for (; $i < $n; ++$i) {
            $token = $tokens[$i];

            $type = null;
            if (\is_array($token)) {
                $type = $token[0];

                if ($type === T_WHITESPACE) {
                    continue;
                }

                if (!\in_array($type, self::SUPPORT_TOKEN, true)) {
                    throw new \InvalidArgumentException('Expression contains not support token "' . \token_name($type) . '""');
                }

                if ($type === T_INC && ($tokens[$i - 1] === '+' || $tokens[$i + 1] === '+')) {
                    throw new \InvalidArgumentException('Expression contains error code: "+++');
                }

                if ($type === T_DEC && ($tokens[$i - 1] === '-' || $tokens[$i + 1] === '-')) {
                    throw new \InvalidArgumentException('Expression contains error code: "---');
                }
            }

            switch ($token) {
                case '?':
                    $part = $temp[$level];

                    if ($level === 0) {
                        $temp[$level++] = [$part, new Token($token)];
                    } else {
                        $parentLevel = $level - 1;
                        $temp[$parentLevel][] = $part;
                        $temp[$parentLevel][] = new Token($token);
                    }

                    $temp[$level] = [];
                    break;

                case ':':
                    if ($level === 0) {
                        throw new \InvalidArgumentException('Expression ternary syntax error');
                    }

                    $part = $temp[$level];

                    $parentLevel = $level - 1;
                    $temp[$parentLevel][] = $part;
                    $temp[$parentLevel][] = new Token($token);

                    $temp[$level] = [];
                    break;

                case ';':
                    if ($level > 0) {
                        $part = $temp[$level];
                        unset($temp[$level]);

                        $temp[--$level][] = $part;
                    }
                    ++$i;
                    break 2;
                case ')':
                case ']':
                    $temp[$level][] = new Token($token);
                    $part = $temp[$level];
                    unset($temp[$level]);

                    $temp[--$level][] = $part;
                    break;

                case '(':
                case '[':
                    $temp[++$level] = [new Token($token)];
                    break;

                default:
                    $temp[$level][] = new Token($token);
            }
        }

        if ($i !== $n) {
            throw new \InvalidArgumentException('The code has multi-line expression');
        }

        if (\count($temp) > 1) {
            throw new \InvalidArgumentException('Expression syntax error');
        }

        return $temp[0];
    }
1078613
public function addExpression($name, $expression)
    {
        if (!is_array($expression)) {
            $expression = ['expr' => $expression];
        } elseif (isset($expression[0])) {
            $expression['expr'] = $expression[0];
            unset($expression[0]);
        }

        $c = $this->_default_seed_addExpression;

        return $this->add($this->factory($c, $expression), $name);
    }
684976
public function andWhere(Expression $expression) : self
    {
        if ($this->expression === null) {
            return $this->where($expression);
        }

        $this->expression = new CompositeExpression(
            CompositeExpression::TYPE_AND,
            [$this->expression, $expression]
        );

        return $this;
    }
592493
public function select($expression = '*')
    {
        if (!is_array($expression)) {
            $expression = explode(',', $expression);
        }

        $this->type        = self::TYPE_SELECT;
        $this->expressions = array_merge($this->expressions, array_map(function ($expression, $alias) {
            return is_string($alias) ? "$expression AS $alias" : $expression;
        }, $expression, array_keys($expression)));

        return $this;
    }
1220119
public function fromRaw($expression, $bindings = [])
    {
        $this->from = new Expression($expression);

        $this->addBinding($bindings, 'from');

        return $this;
    }
498601
public function addSelect($_)
    {
        RecursiveArgs::each(func_get_args(), function ($arg) {
           $this->selectClauses[] = $arg;
        });

        return $this;
    }
1056895
private function operator(string $operator, $expression) : self
    {
        if ($this->currentField) {
            $this->expr[$this->currentField][$operator] = $this->ensureArray($expression);
        } else {
            $this->expr[$operator] = $this->ensureArray($expression);
        }

        return $this;
    }
546551
public function selectElemMatch(string $fieldName, $expression) : self
    {
        if ($expression instanceof Expr) {
            $expression = $expression->getQuery();
        }
        $this->query['select'][$fieldName] = ['$elemMatch' => $expression];
        return $this;
    }
991936
public function selectRaw(string $expression, array $bindings = []): BaseQueryRelateContract
    {
        $this->query->selectRaw($expression, $bindings);

        return $this;
    }
215709
public function then($expression) : self
    {
        if (! is_array($this->switchBranch)) {
            throw new BadMethodCallException(static::class . '::then requires a valid case statement (call case() first).');
        }

        $this->switchBranch['then'] = $expression;

        if ($this->currentField) {
            $this->expr[$this->currentField]['$switch']['branches'][] = $this->ensureArray($this->switchBranch);
        } else {
            $this->expr['$switch']['branches'][] = $this->ensureArray($this->switchBranch);
        }

        $this->switchBranch = null;

        return $this;
    }
105907
public function passNew(array $expression)
    {
        if (isset($expression['parameters'])) {
            foreach ($expression['parameters'] as $parameter) {
                $usePass = self::DETECT_PARAM_PASS == ($this->detectionFlags & self::DETECT_PARAM_PASS);
                if ($usePass && 'variable' == $parameter['parameter']['type']) {
                    $this->increaseMutations($parameter['parameter']['value']);
                } else {
                    $this->passExpression($parameter['parameter']);
                }
            }
        }
    }
1186514
private function query(string $expression): \DOMNodeList
    {
        return $this->xpath->query(
            $this->expressionTranslator->convertToXpath($expression)
        );
    }
649876
public function cron(string $expression): self
    {
        /** @var array $parts */
        $parts = \preg_split(
            '/\s/',
            $expression,
            -1,
            PREG_SPLIT_NO_EMPTY
        );

        if (\count($parts) > 5) {
            throw new TaskException("Expression '{$expression}' has more than five parts and this is not allowed.");
        }

        $this->expression = $expression;

        return $this;
    }
687748
public static function buildExpressions(array $expressions)
    {
        foreach ($expressions as $k => $expr) {
            if ($expr instanceof self) {
                $if = $expr->ifPart;
                $then = $expr->thenPart;
                $expressions[$k] = function ($v) use ($if, $then) {
                    return $if($v) ? $then($v) : $v;
                };
            }
        }

        return $expressions;
    }
297210
private function operator($operator, $expression)
    {
        if ($this->currentField) {
            $this->expr[$this->currentField][$operator] = $this->ensureArray($expression);
        } else {
            $this->expr[$operator] = $this->ensureArray($expression);
        }

        return $this;
    }