Some crazy stuff to work around a private constructor

@param ExecutionContext $exeContext
@return Executor
498171
protected static function construct(ExecutionContext $exeContext = null): Executor
    {
        $executorReflection = new \ReflectionClass(Executor::class);
        /** @var Executor $executor */
        $executor = $executorReflection->newInstanceWithoutConstructor();

        if ($exeContext !== null) {
            $constructor = $executorReflection->getConstructor();
            $constructor->setAccessible(true);
            $constructor->invoke($executor, $exeContext);
        }

        return $executor;
    }
823811
public function compile(CompilationContext $compilationContext)
    {
        $readDetector = new ReadDetector();

        $statement = $this->statement;
        foreach ($statement['assignments'] as $assignment) {
            $variable = $assignment['variable'];

            /*
             * Get the symbol from the symbol table if necessary
             */
            switch ($assignment['assign-type']) {
                case 'static-property':
                case 'static-property-append':
                case 'static-property-array-index':
                case 'static-property-array-index-append':
                case 'dynamic-variable-string':
                    $symbolVariable = null;
                    break;

                case 'array-index':
                case 'variable-append':
                case 'object-property':
                case 'array-index-append':
                case 'string-dynamic-object-property':
                case 'variable-dynamic-object-property':
                    $symbolVariable = $compilationContext->symbolTable->getVariableForUpdate($variable, $compilationContext, $assignment);
                    break;

                default:
                    $symbolVariable = $compilationContext->symbolTable->getVariableForWrite($variable, $compilationContext, $assignment);
                    break;
            }

            /*
             * Incr/Decr assignments don't require an expression
             */
            if (isset($assignment['expr'])) {
                $expr = new Expression($assignment['expr']);

                switch ($assignment['assign-type']) {
                    case 'variable':
                        if (!$readDetector->detect($variable, $assignment['expr'])) {
                            if (isset($assignment['operator'])) {
                                if ('assign' == $assignment['operator']) {
                                    $expr->setExpectReturn(true, $symbolVariable);
                                }
                            } else {
                                $expr->setExpectReturn(true, $symbolVariable);
                            }
                        } else {
                            if (isset($assignment['operator'])) {
                                if ('assign' == $assignment['operator']) {
                                    $expr->setExpectReturn(true);
                                }
                            } else {
                                $expr->setExpectReturn(true);
                            }
                        }
                        break;
                }

                switch ($assignment['expr']['type']) {
                    case 'property-access':
                    case 'array-access':
                    case 'type-hint':
                        $expr->setReadOnly(true);
                        break;
                }

                $resolvedExpr = $expr->compile($compilationContext);

                /*
                 * Bad implemented operators could return values different than objects
                 */
                if (!\is_object($resolvedExpr)) {
                    throw new CompilerException('Resolved expression is not valid', $assignment['expr']);
                }
            }

            if ($symbolVariable) {
                $variable = $symbolVariable->getName();
            }

            /*
             * There are four types of assignments
             */
            switch ($assignment['assign-type']) {
                case 'variable':
                    $let = new LetVariable();
                    $let->assign($variable, $symbolVariable, $resolvedExpr, $readDetector, $compilationContext, $assignment);
                    break;

                case 'variable-append':
                    $let = new LetVariableAppend();
                    $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'object-property':
                    $let = new LetObjectProperty();
                    $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'variable-dynamic-object-property':
                    $let = new LetObjectDynamicProperty();
                    $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'string-dynamic-object-property':
                    $let = new LetObjectDynamicStringProperty();
                    $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'static-property':
                    $let = new LetStaticProperty();
                    $let->assignStatic($variable, $assignment['property'], $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'static-property-append':
                    $let = new LetStaticPropertyAppend();
                    $let->assignStatic($variable, $assignment['property'], $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'static-property-array-index':
                    $let = new LetStaticPropertyArrayIndex();
                    $let->assignStatic($variable, $assignment['property'], $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'static-property-array-index-append':
                    $let = new LetStaticPropertyArrayIndexAppend();
                    $let->assignStatic($variable, $assignment['property'], $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'array-index':
                    $let = new LetArrayIndex();
                    $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'array-index-append':
                    $let = new LetArrayIndexAppend();
                    $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'object-property-append':
                    $let = new LetObjectPropertyAppend();
                    $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'object-property-array-index':
                    $let = new LetObjectPropertyArrayIndex();
                    $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'object-property-array-index-append':
                    $let = new LetObjectPropertyArrayIndexAppend();
                    $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'incr':
                    $let = new LetIncr();
                    $let->assign($variable, $symbolVariable, $compilationContext, $assignment);
                    break;

                case 'decr':
                    $let = new LetDecr();
                    $let->assign($variable, $symbolVariable, $compilationContext, $assignment);
                    break;

                case 'object-property-incr':
                    $let = new LetObjectPropertyIncr();
                    $let->assign($variable, $assignment['property'], $symbolVariable, $compilationContext, $assignment);
                    break;

                case 'object-property-decr':
                    $let = new LetObjectPropertyDecr();
                    $let->assign($variable, $assignment['property'], $symbolVariable, $compilationContext, $assignment);
                    break;

                case 'dynamic-variable':
                    $let = new LetExportSymbol();
                    $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                    break;

                case 'dynamic-variable-string':
                    $let = new LetExportSymbolString();
                    $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                    break;

                default:
                    throw new CompilerException('Unknown assignment: '.$assignment['assign-type'], $assignment);
            }
        }
    }
1021898
protected function getStepContext() {
        if (!$this->_stepContext) {
            $this->_stepContext = new ExecutionStepContextList(
                $this->version,
                $this->solution['flowSid'],
                $this->solution['executionSid'],
                $this->solution['sid']
            );
        }

        return $this->_stepContext;
    }
824054
public function setExecute(ExecuteInterface $execute)
    {
        return new self(
            $this->undefined,
            $this->enabled,
            $execute,
            $this->messages
        );
    }
541679
public function compileIterator(array $exprRaw, CompilationContext $compilationContext)
    {
        $iteratorVariable = $compilationContext->symbolTable->getTempVariableForWrite('zend_object_iterator', $compilationContext);

        $compilationContext->headersManager->add('kernel/iterator');

        $codePrinter = $compilationContext->codePrinter;

        /**
         * Resolve first parameter of iterator(p).
         */
        $expr = new Expression($exprRaw['parameters'][0]['parameter']);
        $expr->setReadOnly(false);
        $expression = $expr->compile($compilationContext);

        if ('variable' != $expression->getType()) {
            throw new CompilerException('Unknown type: '.$expression->getType(), $exprRaw);
        }

        $exprVariable = $compilationContext->symbolTable->getVariableForRead($expression->getCode(), $compilationContext, $this->statement['expr']);
        switch ($exprVariable->getType()) {
            case 'variable':
                break;
        }

        /*
         * Initialize 'key' variable
         */
        if (isset($this->statement['key'])) {
            if ('_' != $this->statement['key']) {
                $keyVariable = $compilationContext->symbolTable->getVariableForWrite($this->statement['key'], $compilationContext, $this->statement['expr']);
                if ('variable' != $keyVariable->getType()) {
                    throw new CompilerException('Cannot use variable: '.$this->statement['key'].' type: '.$keyVariable->getType().' as key in hash traversal', $this->statement['expr']);
                }
            } else {
                /**
                 * Anonymous key variable.
                 */
                $keyVariable = $compilationContext->symbolTable->getTempVariableForWrite('variable', $compilationContext);
                $keyVariable->increaseUses();
            }

            $keyVariable->setMustInitNull(true);
            $keyVariable->setIsInitialized(true, $compilationContext);
            $keyVariable->setDynamicTypes('undefined');
        }

        /*
         * Initialize 'value' variable
         */
        if (isset($this->statement['value'])) {
            if ('_' != $this->statement['value']) {
                $variable = $compilationContext->symbolTable->getVariableForWrite($this->statement['value'], $compilationContext, $this->statement['expr']);
                if ('variable' != $variable->getType()) {
                    throw new CompilerException('Cannot use variable: '.$this->statement['value'].' type: '.$variable->getType().' as value in hash traversal', $this->statement['expr']);
                }
            } else {
                /**
                 * Anonymous value variable.
                 */
                $variable = $compilationContext->symbolTable->getTempVariableForWrite('variable', $compilationContext);
                $variable->increaseUses();
            }

            $variable->setMustInitNull(true);
            $variable->setIsInitialized(true, $compilationContext);
            $variable->setDynamicTypes('undefined');
        }

        /*
         * Variables are initialized in a different way inside cycle
         */
        ++$compilationContext->insideCycle;

        $codePrinter->output($iteratorVariable->getName().' = zephir_get_iterator('.$compilationContext->backend->getVariableCode($exprVariable).' TSRMLS_CC);');

        $codePrinter->output($iteratorVariable->getName().'->funcs->rewind('.$iteratorVariable->getName().' TSRMLS_CC);');
        $codePrinter->output('for (;'.$iteratorVariable->getName().'->funcs->valid('.$iteratorVariable->getName().' TSRMLS_CC) == SUCCESS && !EG(exception); '.$iteratorVariable->getName().'->funcs->move_forward('.$iteratorVariable->getName().' TSRMLS_CC)) {');

        if (isset($this->statement['key'])) {
            $compilationContext->symbolTable->mustGrownStack(true);
            $codePrinter->output("\t".'ZEPHIR_GET_IMKEY('.$this->statement['key'].', '.$iteratorVariable->getName().');');
        }

        if (isset($this->statement['value'])) {
            $compilationContext->symbolTable->mustGrownStack(true);
            $codePrinter->increaseLevel();
            $codePrinter->output('{');
            $codePrinter->increaseLevel();
            $compilationContext->backend->forStatementIterator($iteratorVariable, $variable, $compilationContext);
            $codePrinter->decreaseLevel();
            $codePrinter->output('}');
            $codePrinter->decreaseLevel();
        }

        /*
         * Compile statements in the 'for' block
         */
        if (isset($this->statement['statements'])) {
            $st = new StatementsBlock($this->statement['statements']);
            $st->isLoop(true);
            if (isset($this->statement['key'])) {
                $st->getMutateGatherer()->increaseMutations($this->statement['key']);
            }
            $st->getMutateGatherer()->increaseMutations($this->statement['value']);
            $st->compile($compilationContext);
        }

        /*
         * Restore the cycle counter
         */
        --$compilationContext->insideCycle;

        $codePrinter->output('}');

        $compilationContext->backend->destroyIterator($iteratorVariable, $compilationContext);
    }
1179640
function createExecutor(serverUrl) {
  let client = serverUrl.then(url => new http.HttpClient(url));
  let executor = new http.Executor(client);
  configureExecutor(executor);
  return executor;
}
152486
private SomeAuditedObject create(final String name, ExecutionContext executionContext) {
        return executionContext.add(this, someAuditedObjects.create(name));
    }
50752
public static function fromParts( $context, $node, $dataPool, $baseIter )
	{
		$result = new ExprNodeIterator();
		$result->fromExprNodeIteratorParts( $context, $node, $dataPool, $baseIter );
		return $result;
	}
339997
protected static function executeFields(ExecutionContext $context, ObjectType $parent, $source, $fields)
    {
        return self::executeFieldsSerially($context, $parent, $source, $fields);
    }
612598
public function optimize($exprRaw, CompilationContext $compilationContext)
    {
        $conditions = $this->optimizeNot($exprRaw, $compilationContext);

        if (false !== $conditions) {
            return $conditions;
        }

        /*
         * Discard first level parentheses
         */
        if ('list' == $exprRaw['type']) {
            $expr = new Expression($exprRaw['left']);
        } else {
            $expr = new Expression($exprRaw);
        }

        $expr->setReadOnly(true);
        $expr->setEvalMode(true);
        $compiledExpression = $expr->compile($compilationContext);

        /*
         * Possible corrupted expression?
         */
        if (!\is_object($compiledExpression)) {
            throw new CompilerException('Corrupted expression: '.$exprRaw['type'], $exprRaw);
        }

        /*
         * Generate the condition according to the value returned by the evaluated expression
         */
        switch ($compiledExpression->getType()) {
            case 'null':
                $this->unreachable = true;

                return '0';

            case 'int':
            case 'uint':
            case 'long':
            case 'ulong':
            case 'double':
                $code = $compiledExpression->getCode();
                if (is_numeric($code)) {
                    if ('1' == $code) {
                        $this->unreachableElse = true;
                    } else {
                        $this->unreachable = true;
                    }
                }

                return $code;

            case 'char':
            case 'uchar':
                return $compiledExpression->getCode();

            case 'bool':
                $code = $compiledExpression->getBooleanCode();
                if ('1' == $code) {
                    $this->unreachableElse = true;
                } else {
                    if ('0' == $code) {
                        $this->unreachable = true;
                    }
                }

                return $code;

            case 'variable':
                $variableRight = $compilationContext->symbolTable->getVariableForRead($compiledExpression->getCode(), $compilationContext, $exprRaw);
                $possibleValue = $variableRight->getPossibleValue();
                if (\is_object($possibleValue)) {
                    $possibleValueBranch = $variableRight->getPossibleValueBranch();
                    if ($possibleValueBranch instanceof Branch) {
                        /*
                         * Check if the possible value was assigned in the root branch
                         */
                        if (Branch::TYPE_ROOT == $possibleValueBranch->getType()) {
                            if ($possibleValue instanceof LiteralCompiledExpression) {
                                switch ($possibleValue->getType()) {
                                    case 'null':
                                        $this->unreachable = true;
                                        break;

                                    case 'bool':
                                        if ('0' == $possibleValue->getBooleanCode()) {
                                            $this->unreachable = true;
                                        } else {
                                            $this->unreachableElse = true;
                                        }
                                        break;

                                    case 'int':
                                        if (!(int) ($possibleValue->getCode())) {
                                            $this->unreachable = true;
                                        } else {
                                            $this->unreachableElse = true;
                                        }
                                        break;

                                    case 'double':
                                        if (!(float) ($possibleValue->getCode())) {
                                            $this->unreachable = true;
                                        } else {
                                            $this->unreachableElse = true;
                                        }
                                        break;

                                    default:
                                        //echo $possibleValue->getType();
                                }
                            }
                        }
                    }
                }

                $this->usedVariables[] = $variableRight->getName();

                /*
                 * Evaluate the variable
                 */
                switch ($variableRight->getType()) {
                    case 'int':
                    case 'uint':
                    case 'char':
                    case 'uchar':
                    case 'long':
                    case 'ulong':
                        return $variableRight->getName();

                    case 'string':
                        $variableRightCode = $compilationContext->backend->getVariableCode($variableRight);

                        return '!('.$compilationContext->backend->ifVariableValueUndefined($variableRight, $compilationContext, true, false).') && Z_STRLEN_P('.$variableRightCode.')';

                    case 'bool':
                        return $variableRight->getName();

                    case 'double':
                        return $variableRight->getName();

                    case 'variable':
                        $compilationContext->headersManager->add('kernel/operators');
                        $variableRightCode = $compilationContext->backend->getVariableCode($variableRight);

                        return 'zephir_is_true('.$variableRightCode.')';

                    default:
                        throw new CompilerException("Variable can't be evaluated ".$variableRight->getType(), $exprRaw);
                }
                break;

            default:
                throw new CompilerException('Expression '.$compiledExpression->getType()." can't be evaluated", $exprRaw);
        }
    }
181499
public function compile(Expression $expr, CompilationContext $compilationContext)
    {
        $expression = $expr->getExpression();

        $exprVariable = new Expression($expression['variable']);
        $exprVariable->setReadOnly(true);
        $exprCompiledVariable = $exprVariable->compile($compilationContext);

        $builtInType = false;
        switch ($exprCompiledVariable->getType()) {
            case 'variable':
                $variableVariable = $compilationContext->symbolTable->getVariableForRead(
                    $exprCompiledVariable->getCode(),
                    $compilationContext,
                    $expression
                );
                switch ($variableVariable->getType()) {
                    case 'variable':
                        $caller = $variableVariable;
                        break;
                    default:
                        /* Check if there is a built-in type optimizer available */
                        $builtInTypeClass = 'Zephir\Types\\'.ucfirst($variableVariable->getType()).'Type';
                        if (class_exists($builtInTypeClass)) {
                            /**
                             * @var \Zephir\Types\AbstractType
                             */
                            $builtInType = new $builtInTypeClass();
                            $caller = $exprCompiledVariable;
                        } else {
                            throw new CompilerException(
                                'Methods cannot be called on variable type: '.$variableVariable->getType(),
                                $expression
                            );
                        }
                }
                break;
            default:
                /* Check if there is a built-in type optimizer available */
                $builtInTypeClass = 'Zephir\Types\\'.ucfirst($exprCompiledVariable->getType()).'Type';
                if (class_exists($builtInTypeClass)) {
                    $builtInType = new $builtInTypeClass();
                    $caller = $exprCompiledVariable;
                } else {
                    throw new CompilerException(
                        'Cannot use expression: '.$exprCompiledVariable->getType().' as method caller',
                        $expression['variable']
                    );
                }
        }

        $codePrinter = $compilationContext->codePrinter;

        $type = $expression['call-type'];

        /*
         * In normal method calls and dynamic string method calls we just use the name given by the user
         */
        if (self::CALL_NORMAL == $type || self::CALL_DYNAMIC_STRING == $type) {
            $methodName = strtolower($expression['name']);
        } else {
            $variableMethod = $compilationContext->symbolTable->getVariableForRead(
                $expression['name'],
                $compilationContext,
                $expression
            );

            if (\is_object($builtInType)) {
                throw new CompilerException(
                    'Dynamic method invocation for type: '.$variableMethod->getType().' is not supported',
                    $expression
                );
            }

            if ($variableMethod->isNotVariableAndString()) {
                throw new CompilerException(
                    'Cannot use variable type: '.$variableMethod->getType().' as dynamic method name',
                    $expression
                );
            }
        }

        $symbolVariable = null;

        /**
         * Create temporary variable if needed.
         */
        $mustInit = false;
        $isExpecting = $expr->isExpectingReturn();
        if ($isExpecting) {
            $symbolVariable = $expr->getExpectingVariable();
            if (\is_object($symbolVariable)) {
                $readDetector = new ReadDetector($expression);
                if ($caller == $symbolVariable || $readDetector->detect($symbolVariable->getName(), $expression)) {
                    $symbolVariable = $compilationContext->symbolTable->getTempVariableForObserveOrNullify(
                        'variable',
                        $compilationContext,
                        $expression
                    );
                } else {
                    $mustInit = true;
                }
            } else {
                $symbolVariable = $compilationContext->symbolTable->getTempVariableForObserveOrNullify(
                    'variable',
                    $compilationContext,
                    $expression
                );
            }
        }

        /*
         * Method calls only return zvals so we need to validate the target variable is also a zval
         */
        if (!$builtInType) {
            if ($isExpecting) {
                if (!$symbolVariable->isVariable()) {
                    throw new CompilerException(
                        'Returned values by functions can only be assigned to variant variables',
                        $expression
                    );
                }

                /*
                 * At this point, we don't know the exact dynamic type returned by the method call
                 */
                $symbolVariable->setDynamicTypes('undefined');
            }
        } else {
            return $builtInType->invokeMethod($methodName, $caller, $compilationContext, $this, $expression);
        }

        $check = true;
        if (isset($expression['check'])) {
            $check = $expression['check'];
        }

        /*
         * Try to check if the method exist in the callee, only when method call is self::CALL_NORMAL
         */
        if (self::CALL_NORMAL == $type) {
            if ('this' == $variableVariable->getRealName()) {
                $classDefinition = $compilationContext->classDefinition;
                if (!$classDefinition->hasMethod($methodName)) {
                    if ($check) {
                        $found = false;

                        if ($classDefinition->isAbstract()) {
                            $interfaces = $classDefinition->getImplementedInterfaces();
                        } else {
                            $interfaces = null;
                        }

                        if (\is_array($interfaces)) {
                            $compiler = $compilationContext->compiler;
                            foreach ($interfaces as $interface) {
                                $classInterfaceDefinition = $compiler->getClassDefinition($interface);

                                if (!$classInterfaceDefinition) {
                                    $classInterfaceDefinition = $compiler->getInternalClassDefinition($interface);
                                    if (!$classInterfaceDefinition) {
                                        throw new CompilerException(
                                            "Couldn't locate internal or external interface: ".$interface,
                                            $expression
                                        );
                                    }
                                }

                                if ($classInterfaceDefinition->hasMethod($methodName)) {
                                    $found = true;
                                    $classMethod = $classInterfaceDefinition->getMethod($methodName);
                                    break;
                                }
                            }
                        }

                        if (!$found) {
                            $possibleMethod = $classDefinition->getPossibleMethodName($expression['name']);
                            if ($possibleMethod && $expression['name'] != $possibleMethod) {
                                throw new CompilerException(
                                    sprintf(
                                        "Class '%s' does not implement method: '%s'. Did you mean '%s'?",
                                        $classDefinition->getCompleteName(),
                                        $expression['name'],
                                        $possibleMethod
                                    ),
                                    $expression
                                );
                            }

                            throw new CompilerException(
                                sprintf(
                                    "Class '%s' does not implement method: '%s'",
                                    $classDefinition->getCompleteName(),
                                    $expression['name']
                                ),
                                $expression
                            );
                        }
                    }
                } else {
                    if ($check) {
                        $classMethod = $classDefinition->getMethod($methodName);
                    }
                }

                if ($check) {
                    /*
                     * Private methods must be called in their declaration scope
                     */
                    if ($classMethod->isPrivate()) {
                        if ($classMethod->getClassDefinition() !== $classDefinition) {
                            throw new CompilerException(
                                "Cannot call private method '".$expression['name']."' out of its scope",
                                $expression
                            );
                        }
                    }

                    /*
                     * Try to produce an exception if method is called with a wrong number of parameters
                     */
                    if (isset($expression['parameters'])) {
                        $callNumberParameters = \count($expression['parameters']);
                    } else {
                        $callNumberParameters = 0;
                    }

                    $expectedNumberParameters = $classMethod->getNumberOfRequiredParameters();
                    if (!$expectedNumberParameters && $callNumberParameters > 0) {
                        $numberParameters = $classMethod->getNumberOfParameters();
                        if ($callNumberParameters > $numberParameters) {
                            throw new CompilerException(
                                sprintf(
                                    "Method '%s::%s' called with a wrong number of parameters, ".
                                    'the method has: %d, passed: %d',
                                    $classDefinition->getCompleteName(),
                                    $expression['name'],
                                    $expectedNumberParameters,
                                    $callNumberParameters
                                ),
                                $expression
                            );
                        }
                    }

                    if ($callNumberParameters < $expectedNumberParameters) {
                        throw new CompilerException(
                            sprintf(
                                "Method '%s::%s' called with a wrong number of parameters, ".
                                'the method has: %d, passed: %d',
                                $classDefinition->getCompleteName(),
                                $expression['name'],
                                $expectedNumberParameters,
                                $callNumberParameters
                            ),
                            $expression
                        );
                    }

                    $method = $classMethod;
                }
            } else {
                /*
                 * Variables whose dynamic type is 'object' can be used
                 * to determine method existence in compile time
                 */
                if ($check && $variableVariable->hasAnyDynamicType('object')) {
                    $classTypes = $variableVariable->getClassTypes();

                    if (\count($classTypes)) {
                        $numberImplemented = 0;
                        $compiler = $compilationContext->compiler;
                        foreach ($classTypes as $classType) {
                            if ($compiler->isClass($classType) ||
                                $compiler->isInterface($classType) ||
                                $compiler->isBundledClass($classType) ||
                                $compiler->isBundledInterface($classType)
                            ) {
                                if ($compiler->isClass($classType) || $compiler->isInterface($classType)) {
                                    $classDefinition = $compiler->getClassDefinition($classType);
                                } else {
                                    $classDefinition = $compiler->getInternalClassDefinition($classType);
                                }

                                if (!$classDefinition) {
                                    throw new CompilerException(
                                        'Cannot locate class definition for class '.$classType,
                                        $expression
                                    );
                                }

                                if (!$classDefinition->hasMethod($methodName)) {
                                    if (!$classDefinition->isInterface()) {
                                        if (1 == \count($classTypes)) {
                                            throw new CompilerException(
                                                sprintf(
                                                    "Class '%s' does not implement method: '%s'",
                                                    $classType,
                                                    $expression['name']
                                                ),
                                                $expression
                                            );
                                        }
                                    }
                                    continue;
                                }

                                $method = $classDefinition->getMethod($methodName);

                                /*
                                 * Private methods must be called in their declaration scope
                                 */
                                if ($method->isPrivate()) {
                                    if ($method->getClassDefinition() != $classDefinition) {
                                        throw new CompilerException(
                                            sprintf(
                                                "Cannot call private method '%s' out of its scope",
                                                $expression['name']
                                            ),
                                            $expression
                                        );
                                    }
                                }

                                /*
                                 * Check visibility for protected methods
                                 */
                                if ($method->isProtected() &&
                                    $method->getClassDefinition() != $classDefinition &&
                                    $method->getClassDefinition() != $classDefinition->getExtendsClass()
                                ) {
                                    throw new CompilerException(
                                        sprintf(
                                            "Cannot call protected method '%s' out of its scope",
                                            $expression['name']
                                        ),
                                        $expression
                                    );
                                }

                                /*
                                 * Try to produce an exception if a method is called with a wrong number of parameters
                                 * We only check extension parameters if methods are extension methods
                                 * Internal methods may have invalid Reflection information
                                 */
                                if ($method instanceof ClassMethod && !$method->isBundled()) {
                                    if (isset($expression['parameters'])) {
                                        $callNumberParameters = \count($expression['parameters']);
                                    } else {
                                        $callNumberParameters = 0;
                                    }

                                    $classMethod = $classDefinition->getMethod($methodName);
                                    $expectedNumberParameters = $classMethod->getNumberOfRequiredParameters();

                                    if (!$expectedNumberParameters && $callNumberParameters > 0) {
                                        $numberParameters = $classMethod->getNumberOfParameters();
                                        if ($callNumberParameters > $numberParameters) {
                                            $className = $classDefinition->getCompleteName();
                                            throw new CompilerException(
                                                sprintf(
                                                    "Method '%s::%s' called with a wrong number of parameters, ".
                                                    'the method has: %d, passed: %s',
                                                    $className,
                                                    $expression['name'],
                                                    $expectedNumberParameters,
                                                    $callNumberParameters
                                                ),
                                                $expression
                                            );
                                        }
                                    }

                                    if ($callNumberParameters < $expectedNumberParameters) {
                                        throw new CompilerException(
                                            sprintf(
                                                "Method '%s::%s' called with a wrong number of parameters, ".
                                                'the method has: %d, passed: %d',
                                                $classDefinition->getCompleteName(),
                                                $expression['name'],
                                                $expectedNumberParameters,
                                                $callNumberParameters
                                            ),
                                            $expression
                                        );
                                    }
                                }

                                /*
                                 * The method is checked in the first class that implements the method
                                 * We could probably have collisions here
                                 */
                                ++$numberImplemented;
                                break;
                            } else {
                                ++$numberImplemented;
                                $compilationContext->logger->warning(
                                    'Class "'.$classType.'" does not exist at compile time',
                                    ['nonexistent-class', $expression]
                                );
                            }
                        }

                        if (0 == $numberImplemented) {
                            if (!$classDefinition->isInterface()) {
                                if (\count($classTypes) > 1) {
                                    throw new CompilerException(
                                        sprintf(
                                            "None of classes: '%s' implement method: '%s'",
                                            implode(' or ', $classTypes),
                                            $expression['name']
                                        ),
                                        $expression
                                    );
                                } else {
                                    throw new CompilerException(
                                        sprintf(
                                            "Class '%s' does not implement method: '%s'",
                                            $classTypes[0],
                                            $expression['name']
                                        ),
                                        $expression
                                    );
                                }
                            } else {
                                // @TODO, raise an exception here?
                            }
                        }
                    }
                }
            }
        }

        if (isset($method)) {
            $this->reflection = $method;
        }

        /*
         * Transfer the return type-hint to the returned variable
         */
        if ($isExpecting) {
            if (isset($method)) {
                if ($method instanceof ClassMethod) {
                    if ($method->isVoid()) {
                        throw new CompilerException(
                            sprintf(
                                "Method '%s::%s' is marked as '%s' and it does not return anything",
                                $classDefinition->getCompleteName(),
                                $expression['name'],
                                Types::T_VOID
                            ),
                            $expression
                        );
                    }

                    $returnClassTypes = $method->getReturnClassTypes();

                    if (null !== $returnClassTypes) {
                        $symbolVariable->setDynamicTypes('object');
                        foreach ($returnClassTypes as &$returnClassType) {
                            $returnClassType = $compilationContext->getFullName($returnClassType);
                        }
                        $symbolVariable->setClassTypes($returnClassTypes);
                    }

                    $returnTypes = $method->getReturnTypes();
                    if (null !== $returnTypes) {
                        foreach ($returnTypes as $dataType => $returnType) {
                            $symbolVariable->setDynamicTypes($dataType);
                        }
                    }
                }
            }
        }

        /*
         * Some parameters in internal methods receive parameters as references
         */
        if (isset($expression['parameters'])) {
            $references = [];
            if (self::CALL_NORMAL == $type || self::CALL_DYNAMIC_STRING == $type) {
                if (isset($method)) {
                    if ($method instanceof \ReflectionMethod) {
                        $position = 0;
                        foreach ($method->getParameters() as $parameter) {
                            if ($parameter->isPassedByReference()) {
                                $references[$position] = true;
                            }
                            ++$position;
                        }
                    }
                }
            }
        }

        /*
         * Include fcall header
         */
        $compilationContext->headersManager->add('kernel/fcall');

        /*
         * Call methods must grown the stack
         */
        $compilationContext->symbolTable->mustGrownStack(true);

        /*
         * Mark references
         */
        $params = [];
        if (isset($expression['parameters'])) {
            $params = $this->getResolvedParams(
                $expression['parameters'],
                $compilationContext,
                $expression,
                isset($method) ? $method : null
            );

            if (\count($references)) {
                foreach ($params as $position => $param) {
                    if (isset($references[$position])) {
                        $compilationContext->codePrinter->output('Z_SET_ISREF_P('.$param.');');
                    }
                }
            }

            // We check here if a correct parameter type is passed to the called method
            if (self::CALL_NORMAL == $type) {
                if (isset($method) && $method instanceof ClassMethod && isset($expression['parameters'])) {
                    $resolvedTypes = $this->getResolvedTypes();
                    $resolvedDynamicTypes = $this->getResolvedDynamicTypes();

                    foreach ($method->getParameters() as $n => $parameter) {
                        if (isset($parameter['data-type'])) {
                            if (!isset($resolvedTypes[$n])) {
                                continue;
                            }

                            /*
                             * If the passed parameter is different to the expected type we show a warning
                             */
                            if ($resolvedTypes[$n] != $parameter['data-type']) {
                                $template = sprintf(
                                    'Passing possible incorrect type for parameter: %s::%s(%s), '.
                                    'passing: %s, expecting: %s',
                                    $classDefinition->getCompleteName(),
                                    $method->getName(),
                                    $parameter['name'],
                                    $resolvedTypes[$n],
                                    $parameter['data-type']
                                );

                                switch ($resolvedTypes[$n]) {
                                    case 'bool':
                                    case 'boolean':
                                        switch ($parameter['data-type']) {
                                            /* compatible types */
                                            case 'bool':
                                            case 'boolean':
                                            case 'variable':
                                                break;

                                            default:
                                                $compilationContext->logger->warning(
                                                    $template,
                                                    ['possible-wrong-parameter', $expression]
                                                );
                                                break;
                                        }
                                        break;

                                    case 'array':
                                        switch ($parameter['data-type']) {
                                            /* compatible types */
                                            case 'array':
                                            case 'variable':
                                                break;

                                            case 'callable':
                                                /*
                                                 * Array can be a callable type, example: [$this, "method"]
                                                 *
                                                 * @todo we need to check this array if can...
                                                 */
                                                break;

                                            default:
                                                $compilationContext->logger->warning(
                                                    $template,
                                                    ['possible-wrong-parameter', $expression]
                                                );
                                                break;
                                        }
                                        break;

                                    case 'callable':
                                        switch ($parameter['data-type']) {
                                            /* compatible types */
                                            case 'callable':
                                            case 'variable':
                                                break;

                                            default:
                                                $compilationContext->logger->warning(
                                                    $template,
                                                    ['possible-wrong-parameter', $expression]
                                                );
                                                break;
                                        }
                                        break;

                                    case 'string':
                                        switch ($parameter['data-type']) {
                                            /* compatible types */
                                            case 'string':
                                            case 'variable':
                                                break;

                                            default:
                                                $compilationContext->logger->warning(
                                                    $template,
                                                    ['possible-wrong-parameter', $expression]
                                                );
                                                break;
                                        }
                                        break;

                                    /*
                                     * Passing polymorphic variables to static typed parameters
                                     * could lead to potential unexpected type coercions
                                     */
                                    case 'variable':
                                        if ($resolvedDynamicTypes[$n] != $parameter['data-type']) {
                                            if ('undefined' == $resolvedDynamicTypes[$n]) {
                                                $compilationContext->logger->warning(
                                                    sprintf(
                                                        'Passing possible incorrect type for parameter: %s::%s(%s), '.
                                                        'passing: undefined, expecting: %s',
                                                        $classDefinition->getCompleteName(),
                                                        $method->getName(),
                                                        $parameter['name'],
                                                        $parameter['data-type']
                                                    ),
                                                    ['possible-wrong-parameter-undefined', $expression]
                                                );
                                            }
                                        }
                                        break;
                                }
                            }
                        }
                    }
                }
            }
        }

        // Add the last call status to the current symbol table
        $this->addCallStatusFlag($compilationContext);

        // Initialize non-temporary variables
        if ($mustInit) {
            $symbolVariable->setMustInitNull(true);
            $symbolVariable->trackVariant($compilationContext);
        }

        // Generate the code according to the call type
        if (self::CALL_NORMAL == $type || self::CALL_DYNAMIC_STRING == $type) {
            $realMethod = $this->getRealCalledMethod($compilationContext, $variableVariable, $methodName);

            $isInternal = false;
            if (\is_object($realMethod[1])) {
                $realMethod[1] = $realMethod[1]->getOptimizedMethod();
                $method = $realMethod[1];
                $isInternal = $realMethod[1]->isInternal();
                if ($isInternal && $realMethod[0] > 1) {
                    throw new CompilerException(
                        "Cannot resolve method: '".$expression['name']."' in polymorphic variable",
                        $expression
                    );
                }
            }

            if (!$isInternal) {
                // Check if the method call can have an inline cache
                $methodCache = $compilationContext->cacheManager->getMethodCache();

                $cachePointer = $methodCache->get(
                    $compilationContext,
                    $methodName,
                    $variableVariable
                );

                $compilationContext->backend->callMethod(
                    $isExpecting ? $symbolVariable : null,
                    $variableVariable,
                    $methodName,
                    $cachePointer,
                    \count($params) ? $params : null,
                    $compilationContext
                );
            } else {
                //TODO: also move to backend
                if ($isExpecting) {
                    $symbolCode = $compilationContext->backend->getVariableCodePointer($symbolVariable);
                }
                $variableCode = $compilationContext->backend->getVariableCode($variableVariable);
                $paramCount = \count($params);
                $paramsStr = $paramCount ? ', '.implode(', ', $params) : '';

                if ($isExpecting) {
                    if ('return_value' == $symbolVariable->getName()) {
                        $macro = $compilationContext->backend->getFcallManager()->getMacro(false, true, $paramCount);
                        $codePrinter->output($macro.'('.$variableCode.', '.$method->getInternalName().$paramsStr.');');
                    } else {
                        $macro = $compilationContext->backend->getFcallManager()->getMacro(false, 2, $paramCount);
                        $codePrinter->output(
                            $macro.'('.$symbolCode.', '.$variableCode.', '.$method->getInternalName().$paramsStr.');'
                        );
                    }
                } else {
                    $macro = $compilationContext->backend->getFcallManager()->getMacro(false, false, $paramCount);
                    $codePrinter->output($macro.'('.$variableCode.', '.$method->getInternalName().$paramsStr.');');
                }
            }
        } else {
            if (self::CALL_DYNAMIC == $type) {
                switch ($variableMethod->getType()) {
                    case 'string':
                    case 'variable':
                        break;
                    default:
                        throw new Exception(
                            sprintf('Cannot use variable type: %s as method caller', $variableMethod->getType())
                        );
                }

                $cachePointer = 'NULL, 0';

                $compilationContext->backend->callMethod(
                    $isExpecting ? $symbolVariable : null,
                    $variableVariable,
                    $variableMethod,
                    $cachePointer,
                    \count($params) ? $params : null,
                    $compilationContext
                );
            }
        }

        // Temporary variables must be copied if they have more than one reference
        foreach ($this->getMustCheckForCopyVariables() as $checkVariable) {
            $codePrinter->output('zephir_check_temp_parameter('.$checkVariable.');');
        }

        // We can mark temporary variables generated as idle
        foreach ($this->getTemporalVariables() as $tempVariable) {
            $tempVariable->setIdle(true);
        }

        // Release parameters marked as references
        if (isset($expression['parameters'])) {
            if (\count($references)) {
                foreach ($params as $position => $param) {
                    if (isset($references[$position])) {
                        $compilationContext->codePrinter->output('Z_UNSET_ISREF_P('.$param.');');
                    }
                }
            }
        }

        $this->addCallStatusOrJump($compilationContext);

        if ($isExpecting) {
            return new CompiledExpression('variable', $symbolVariable->getRealName(), $expression);
        }

        return new CompiledExpression('null', null, $expression);
    }
1331439
protected function _actionBrowse(AnCommandContext $context)
    {
        $entities = parent::_actionBrowse($context);

        $entities->order($this->sort);

        return $entities;
    }
515269
public function execute($name, AnCommandContext $context)
    {
        $parts = explode('.', $name);

        if ($parts[0] == 'before') {
            $value = pick($this->{$this->getIdentifiableKey()}, $context->data->{$this->getIdentifiableKey()});

            if ($value) {
                $parent = $this->getParentRepository()->fetch($value);

                $this->setParent($parent);

                //set the entity owner as the context actor of the controller
                if ($parent && $this->getRepository()->isOwnable() && $this->isOwnable()) {
                    $this->setActor($parent->owner);
                }

                $context->data['parent'] = $parent;
            }
        }
    }
936398
public function compile(CompilationContext $compilationContext)
    {
        $expression = $this->expression;
        $type = $expression['type'];
        $compilableExpression = null;

        switch ($type) {
            case 'null':
                return new LiteralCompiledExpression('null', null, $expression);

            case 'int':
            case 'integer':
                return new LiteralCompiledExpression('int', $expression['value'], $expression);

            case 'long':
            case 'double':
            case 'bool':
                return new LiteralCompiledExpression($type, $expression['value'], $expression);

            case 'string':
                return new LiteralCompiledExpression('string', str_replace(PHP_EOL, '\\n', $expression['value']), $expression);
            case 'istring':
                return new LiteralCompiledExpression('istring', str_replace(PHP_EOL, '\\n', $expression['value']), $expression);

            case 'char':
                if (!\strlen($expression['value'])) {
                    throw new CompilerException('Invalid empty char literal', $expression);
                }
                if (\strlen($expression['value']) > 2) {
                    if (\strlen($expression['value']) > 10) {
                        throw new CompilerException("Invalid char literal: '".substr($expression['value'], 0, 10)."...'", $expression);
                    } else {
                        throw new CompilerException("Invalid char literal: '".$expression['value']."'", $expression);
                    }
                }

                return new LiteralCompiledExpression('char', $expression['value'], $expression);

            case 'variable':
                $var = $compilationContext->symbolTable->getVariable($expression['value']);
                if ($var) {
                    if ('this' == $var->getRealName()) {
                        $var = 'this';
                    } else {
                        $var = $var->getName();
                    }
                } else {
                    $var = $expression['value'];
                }

                return new CompiledExpression('variable', $var, $expression);

            case 'constant':
                $compilableExpression = new Constants();
                break;

            case 'empty-array':
                return $this->emptyArray($expression, $compilationContext);

            case 'array-access':
                $compilableExpression = new NativeArrayAccess();
                $compilableExpression->setNoisy($this->isNoisy());
                break;

            case 'property-access':
                $compilableExpression = new PropertyAccess();
                $compilableExpression->setNoisy($this->isNoisy());
                break;

            case 'property-string-access':
            case 'property-dynamic-access':
                $compilableExpression = new PropertyDynamicAccess();
                $compilableExpression->setNoisy($this->isNoisy());
                break;

            case 'static-constant-access':
                $compilableExpression = new StaticConstantAccess();
                break;

            case 'static-property-access':
                $compilableExpression = new StaticPropertyAccess();
                break;

            case 'fcall':
                $functionCall = new FunctionCall();

                return $functionCall->compile($this, $compilationContext);

            case 'mcall':
                $methodCall = new MethodCall();

                return $methodCall->compile($this, $compilationContext);

            case 'scall':
                $staticCall = new StaticCall();

                return $staticCall->compile($this, $compilationContext);

            case 'isset':
                $compilableExpression = new IssetOperator();
                break;

            case 'fetch':
                $compilableExpression = new FetchOperator();
                break;

            case 'empty':
                $compilableExpression = new EmptyOperator();
                break;

            case 'array':
                $compilableExpression = new NativeArray();
                break;

            case 'new':
                $compilableExpression = new NewInstanceOperator();
                break;

            case 'new-type':
                $compilableExpression = new NewInstanceTypeOperator();
                break;

            case 'not':
                $compilableExpression = new NotOperator();
                break;

            case 'bitwise_not':
                $compilableExpression = new BitwiseNotOperator();
                break;

            case 'equals':
                $compilableExpression = new EqualsOperator();
                break;

            case 'not-equals':
                $compilableExpression = new NotEqualsOperator();
                break;

            case 'identical':
                $compilableExpression = new IdenticalOperator();
                break;

            case 'not-identical':
                $compilableExpression = new NotIdenticalOperator();
                break;

            case 'greater':
                $compilableExpression = new GreaterOperator();
                break;

            case 'less':
                $compilableExpression = new LessOperator();
                break;

            case 'less-equal':
                $compilableExpression = new LessEqualOperator();
                break;

            case 'greater-equal':
                $compilableExpression = new GreaterEqualOperator();
                break;

            case 'add':
                $compilableExpression = new AddOperator();
                break;

            case 'minus':
                $compilableExpression = new MinusOperator();
                break;

            case 'sub':
                $compilableExpression = new SubOperator();
                break;

            case 'mul':
                $compilableExpression = new MulOperator();
                break;

            case 'div':
                $compilableExpression = new DivOperator();
                break;

            case 'mod':
                $compilableExpression = new ModOperator();
                break;

            case 'and':
                $compilableExpression = new AndOperator();
                break;

            case 'or':
                $compilableExpression = new OrOperator();
                break;

            case 'bitwise_and':
                $compilableExpression = new BitwiseAndOperator();
                break;

            case 'bitwise_or':
                $compilableExpression = new BitwiseOrOperator();
                break;

            case 'bitwise_xor':
                $compilableExpression = new BitwiseXorOperator();
                break;

            case 'bitwise_shiftleft':
                $compilableExpression = new ShiftLeftOperator();
                break;

            case 'bitwise_shiftright':
                $compilableExpression = new ShiftRightOperator();
                break;

            case 'concat':
                $expr = new ConcatOperator();
                $expr->setExpectReturn($this->expecting, $this->expectingVariable);

                return $expr->compile($expression, $compilationContext);

            case 'irange':
                $compilableExpression = new RangeInclusiveOperator();
                break;

            case 'erange':
                $compilableExpression = new RangeExclusiveOperator();
                break;

            case 'list':
                if ('list' == $expression['left']['type']) {
                    $compilationContext->logger->warning(
                        'Unnecessary extra parentheses',
                        ['extra-parentheses', $expression]
                    );
                }
                $numberPrints = $compilationContext->codePrinter->getNumberPrints();
                $expr = new self($expression['left']);
                $expr->setExpectReturn($this->expecting, $this->expectingVariable);
                $resolved = $expr->compile($compilationContext);
                if (($compilationContext->codePrinter->getNumberPrints() - $numberPrints) <= 1) {
                    if (false !== strpos($resolved->getCode(), ' ')) {
                        return new CompiledExpression($resolved->getType(), '('.$resolved->getCode().')', $expression);
                    }
                }

                return $resolved;

            case 'cast':
                $compilableExpression = new CastOperator();
                break;

            case 'type-hint':
                $expr = new TypeHintOperator();
                $expr->setReadOnly($this->isReadOnly());
                $expr->setExpectReturn($this->expecting, $this->expectingVariable);

                return $expr->compile($expression, $compilationContext);

            case 'instanceof':
                $compilableExpression = new InstanceOfOperator();
                break;

            case 'clone':
                $compilableExpression = new CloneOperator();
                break;

            case 'ternary':
                $compilableExpression = new TernaryOperator();
                break;

            case 'short-ternary':
                $expr = new ShortTernaryOperator();
                $expr->setReadOnly($this->isReadOnly());
                $expr->setExpectReturn($this->expecting, $this->expectingVariable);

                return $expr->compile($expression, $compilationContext);

            case 'likely':
                if (!$this->evalMode) {
                    throw new CompilerException("'likely' operator can only be used in evaluation expressions", $expression);
                }
                $expr = new LikelyOperator();
                $expr->setReadOnly($this->isReadOnly());

                return $expr->compile($expression, $compilationContext);

            case 'unlikely':
                if (!$this->evalMode) {
                    throw new CompilerException("'unlikely' operator can only be used in evaluation expressions", $expression);
                }
                $expr = new UnlikelyOperator();
                $expr->setReadOnly($this->isReadOnly());

                return $expr->compile($expression, $compilationContext);

            case 'typeof':
                $compilableExpression = new TypeOfOperator();
                break;

            case 'require':
                $compilableExpression = new RequireOperator();
                break;

            case 'closure':
                $compilableExpression = new Closure();
                break;

            case 'closure-arrow':
                $compilableExpression = new ClosureArrow();
                break;

            case 'reference':
                $compilableExpression = new Reference();
                break;

            default:
                throw new CompilerException('Unknown expression: '.$type, $expression);
        }

        if (!$compilableExpression) {
            throw new CompilerException('Unknown expression passed as compilableExpression', $expression);
        }
        $compilableExpression->setReadOnly($this->isReadOnly());
        $compilableExpression->setExpectReturn($this->expecting, $this->expectingVariable);

        return $compilableExpression->compile($expression, $compilationContext);
    }
695375
public function compile($expression, CompilationContext $compilationContext)
    {
        $conditions = $this->optimizeTypeOf($expression, $compilationContext);
        if (false !== $conditions) {
            return $conditions;
        }

        if (!isset($expression['left'])) {
            throw new CompilerException('Missing left part of the expression', $expression);
        }

        if (!isset($expression['right'])) {
            throw new CompilerException('Missing right part of the expression', $expression);
        }

        $leftExpr = new Expression($expression['left']);
        $leftExpr->setReadOnly(true);
        $left = $leftExpr->compile($compilationContext);

        $rightExpr = new Expression($expression['right']);
        $rightExpr->setReadOnly(true);
        $right = $rightExpr->compile($compilationContext);

        switch ($left->getType()) {
            case 'null':
                switch ($right->getType()) {
                    case 'null':
                        return new CompiledExpression('bool', '(0 '.$this->operator.' 0)', $expression);

                    case 'int':
                    case 'uint':
                    case 'long':
                    case 'ulong':
                        return new CompiledExpression('bool', '(0 '.$this->operator.' '.$right->getCode().')', $expression);

                    case 'char':
                    case 'uchar':
                        return new CompiledExpression('bool', '(\'\\0\' '.$this->operator.' \''.$right->getCode().'\')', $expression);

                    case 'double':
                        return new CompiledExpression('bool', '(0 '.$this->operator.' (int) '.$right->getCode().')', $expression);

                    case 'variable':
                        $variableRight = $compilationContext->symbolTable->getVariableForRead($right->getCode(), $compilationContext, $expression['left']);
                        switch ($variableRight->getType()) {
                            case 'int':
                            case 'uint':
                            case 'long':
                            case 'ulong':
                            case 'double':
                                $compilationContext->headersManager->add('kernel/operators');

                                return new CompiledExpression('bool', '0 '.$this->operator.' '.$variableRight->getName(), $expression);

                            case 'variable':
                                $compilationContext->headersManager->add('kernel/operators');
                                $condition = $compilationContext->backend->getTypeofCondition($variableRight, $this->operator, 'null', $compilationContext);

                                return new CompiledExpression('bool', $condition, $expression);

                            default:
                                throw new CompilerException('Unknown type: '.$variableRight->getType(), $expression['right']);
                        }
                        break;

                    default:
                        throw new CompilerException('Unknown type: '.$right->getType(), $expression);
                }
                break;

            case 'int':
            case 'uint':
            case 'long':
            case 'double':
            case 'ulong':
            case 'char':
            case 'uchar':
                switch ($right->getType()) {
                    case 'null':
                        return new CompiledExpression('bool', $left->getCode().' '.$this->operator, $expression);

                    case 'int':
                    case 'uint':
                    case 'long':
                    case 'ulong':
                        return new CompiledExpression('bool', $left->getCode().' '.$this->operator.' '.$right->getCode(), $expression);

                    case 'char':
                    case 'uchar':
                        return new CompiledExpression('bool', $left->getCode().' '.$this->operator.' \''.$right->getCode().'\'', $expression);

                    case 'double':
                        return new CompiledExpression('bool', $left->getCode().' '.$this->operator.' (int) '.$right->getCode(), $expression);

                    case 'variable':
                        $variableRight = $compilationContext->symbolTable->getVariableForRead($right->getCode(), $compilationContext, $expression['left']);
                        switch ($variableRight->getType()) {
                            case 'int':
                            case 'uint':
                            case 'long':
                            case 'ulong':
                            case 'double':
                                $compilationContext->headersManager->add('kernel/operators');

                                return new CompiledExpression('bool', $left->getCode().' '.$this->operator.' '.$variableRight->getName(), $expression);

                            case 'variable':
                                $compilationContext->headersManager->add('kernel/operators');
                                $variableCode = $compilationContext->backend->getVariableCode($variableRight);

                                return new CompiledExpression('bool', $this->zvalLongNegOperator.'('.$variableCode.', '.$left->getCode().')', $expression);

                            default:
                                throw new CompilerException('Unknown type: '.$variableRight->getType(), $expression['right']);
                        }
                        break;

                    default:
                        throw new CompilerException('Cannot compare '.$left->getType().' with '.$right->getType(), $expression);
                }
                break;

            case 'bool':
                switch ($right->getType()) {
                    case 'null':
                        return new CompiledExpression('bool', $left->getBooleanCode().' '.$this->operator.' 0', $expression);

                    case 'int':
                    case 'uint':
                    case 'long':
                    case 'ulong':
                        return new CompiledExpression('bool', $left->getBooleanCode().' '.$this->operator.' '.$right->getCode(), $expression);

                    case 'char':
                    case 'uchar':
                        return new CompiledExpression('bool', $left->getBooleanCode().' '.$this->operator.' \''.$right->getCode().'\'', $expression);

                    case 'double':
                        return new CompiledExpression('bool', $left->getBooleanCode().' '.$this->operator.' (int) '.$right->getCode(), $expression);

                    case 'bool':
                        return new CompiledExpression('bool', $left->getBooleanCode().' '.$this->operator.' '.$right->getBooleanCode(), $expression);

                    case 'variable':
                        $variableRight = $compilationContext->symbolTable->getVariableForRead($right->getCode(), $compilationContext, $expression['left']);
                        switch ($variableRight->getType()) {
                            case 'int':
                            case 'uint':
                            case 'long':
                            case 'ulong':
                            case 'double':
                                $compilationContext->headersManager->add('kernel/operators');

                                return new CompiledExpression('bool', $left->getBooleanCode().' '.$this->operator.' '.$variableRight->getName(), $expression);

                            case 'variable':
                                $compilationContext->headersManager->add('kernel/operators');
                                $boolOperator = '1' == $left->getBooleanCode() ? $this->zvalBoolTrueOperator : $this->zvalBoolFalseOperator;
                                $variableRight = $compilationContext->backend->getVariableCode($variableRight);

                                return new CompiledExpression('bool', $boolOperator.'('.$variableRight.')', $expression);
                            default:
                                throw new CompilerException('Unknown type: '.$variableRight->getType(), $expression['right']);
                        }
                        break;

                    default:
                        throw new CompilerException('Cannot compare '.$left->getType().' with '.$right->getType(), $expression);
                }
                break;

            case 'string':
                $variableLeft = $compilationContext->symbolTable->getTempLocalVariableForWrite('variable', $compilationContext, $expression);
                $variableLeftCode = $compilationContext->backend->getVariableCode($variableLeft);
                $compilationContext->backend->assignString($variableLeft, $left->getCode(), $compilationContext, true, false);
                switch ($right->getType()) {
                    case 'string':
                    case 'null':
                        $rightStr = 'null' == $right->getType() ? '' : $right->getCode();
                        $compilationContext->headersManager->add('kernel/operators');

                        return new CompiledExpression('bool', $this->zvalStringOperator.'('.$variableLeftCode.', "'.$rightStr.'")', $expression['left']);
                        break;

                    case 'variable':
                        $variableRight = $compilationContext->symbolTable->getVariableForRead($right->getCode(), $compilationContext, $expression['left']);
                        switch ($variableRight->getType()) {
                            case 'string':
                            case 'variable':
                                $compilationContext->headersManager->add('kernel/operators');
                                $variableRight = $compilationContext->backend->getVariableCode($variableRight);

                                return new CompiledExpression('bool', $this->zvalOperator.'('.$variableLeftCode.', '.$variableRight.')', $expression);
                                break;

                            default:
                                throw new CompilerException('Unknown type: '.$variableRight->getType(), $expression['right']);
                        }
                        break;

                    default:
                        throw new CompilerException('Unknown type: '.$right->getType(), $expression['left']);
                }
                break;

            case 'variable':
                $variable = $compilationContext->symbolTable->getVariableForRead($left->getCode(), $compilationContext, $expression['left']);
                $variableCode = $compilationContext->backend->getVariableCode($variable);
                switch ($variable->getType()) {
                    case 'int':
                    case 'uint':
                    case 'long':
                    case 'ulong':
                    case 'char':
                    case 'uchar':
                        switch ($right->getType()) {
                            case 'int':
                            case 'uint':
                            case 'long':
                            case 'ulong':
                            case 'double':
                                return new CompiledExpression('bool', $left->getCode().' '.$this->operator.' '.$right->getCode(), $expression);

                            case 'char':
                            case 'uchar':
                                return new CompiledExpression('bool', $left->getCode().' '.$this->operator.' \''.$right->getCode().'\'', $expression);

                            case 'bool':
                                return new CompiledExpression('bool', $left->getCode().' '.$this->operator.' '.$right->getBooleanCode(), $expression);

                            case 'variable':
                                $variableRight = $compilationContext->symbolTable->getVariableForRead($right->getCode(), $compilationContext, $expression['left']);
                                switch ($variableRight->getType()) {
                                    case 'int':
                                    case 'uint':
                                    case 'long':
                                    case 'ulong':
                                    case 'char':
                                    case 'uchar':
                                    case 'double':
                                        return new CompiledExpression('bool', $variable->getName().' '.$this->operator.' '.$variableRight->getName(), $expression);

                                    case 'variable':
                                        $compilationContext->headersManager->add('kernel/operators');
                                        $variableRightCode = $compilationContext->backend->getVariableCode($variableRight);
                                        $variableCode = $compilationContext->backend->getVariableCode($variable);

                                        return new CompiledExpression('bool', $this->zvalLongNegOperator.'('.$variableRightCode.', '.$variableCode.')', $expression);
                                        break;

                                    default:
                                        throw new CompilerException('Unknown type: '.$variableRight->getType(), $expression['right']);
                                }
                                break;

                            default:
                                throw new CompilerException('Cannot compare variable: '.$variable->getType().' with: '.$right->getType(), $expression);
                        }
                        break;

                    case 'double':
                        switch ($right->getType()) {
                            case 'int':
                            case 'uint':
                            case 'long':
                            case 'ulong':
                            case 'double':
                                return new CompiledExpression('bool', $left->getCode().' '.$this->operator.' '.$right->getCode(), $expression);

                            case 'bool':
                                return new CompiledExpression('bool', $left->getCode().' '.$this->operator.' '.$right->getBooleanCode(), $expression);

                            case 'char':
                            case 'uchar':
                                return new CompiledExpression('bool', $left->getCode().' '.$this->operator.' \''.$right->getCode().'\'', $expression);

                            case 'variable':
                                $variableRight = $compilationContext->symbolTable->getVariableForRead($right->getCode(), $compilationContext, $expression['left']);
                                switch ($variableRight->getType()) {
                                    case 'int':
                                    case 'uint':
                                    case 'long':
                                    case 'ulong':
                                    case 'double':
                                        return new CompiledExpression('bool', $variable->getName().' '.$this->operator.' '.$variableRight->getName(), $expression);

                                    case 'variable':
                                        $compilationContext->headersManager->add('kernel/operators');
                                        $variableRightCode = $compilationContext->backend->getVariableCode($variableRight);
                                        $variableCode = $compilationContext->backend->getVariableCode($variable);

                                        return new CompiledExpression('bool', $this->zvalDoubleNegOperator.'('.$variableRightCode.', '.$variableCode.')', $expression);

                                    default:
                                        throw new CompilerException('Unknown type: '.$variableRight->getType(), $expression['right']);
                                }
                                break;

                            default:
                                throw new CompilerException('Cannot compare variable: '.$variable->getType().' with: '.$right->getType(), $expression);
                        }
                        break;

                    case 'bool':
                        switch ($right->getType()) {
                            case 'int':
                                return new CompiledExpression('bool', $left->getCode().' '.$this->operator.' '.$right->getCode(), $expression['left']);

                            case 'bool':
                                return new CompiledExpression('bool', $left->getCode().' '.$this->operator.' '.$right->getBooleanCode(), $expression['left']);

                            case 'null':
                                return new CompiledExpression('bool', $left->getCode().' '.$this->operator.' 0', $expression['left']);

                            case 'variable':
                                $variableRight = $compilationContext->symbolTable->getVariableForRead($right->getCode(), $compilationContext, $expression['left']);

                                switch ($variableRight->getType()) {
                                    case 'int':
                                    case 'uint':
                                    case 'long':
                                    case 'ulong':
                                    case 'bool':
                                    case 'double':
                                        return new CompiledExpression('bool', $variable->getName().' '.$this->operator.' '.$variableRight->getName(), $expression);

                                    case 'variable':
                                        $compilationContext->headersManager->add('kernel/operators');
                                        $boolOperator = '1' == $left->getBooleanCode() ? $this->zvalBoolTrueOperator : $this->zvalBoolFalseOperator;
                                        $variableRightCode = $compilationContext->backend->getVariableCode($variableRight);

                                        return new CompiledExpression('bool', $boolOperator.'('.$variableRightCode.')', $expression);

                                    default:
                                        throw new CompilerException('Unknown type: '.$variableRight->getType(), $expression['right']);
                                }
                                break;

                            default:
                                throw new CompilerException('Cannot compare variable: '.$variable->getType().' with: '.$right->getType(), $expression);
                        }
                        break;

                    case 'array':
                        switch ($right->getType()) {
                            case 'null':
                                $compilationContext->headersManager->add('kernel/operators');

                                return new CompiledExpression('bool', $this->zvalStringOperator.'('.$variableCode.', "")', $expression['left']);

                            case 'variable':
                                $variableRight = $compilationContext->symbolTable->getVariableForRead($right->getCode(), $compilationContext, $expression['left']);
                                switch ($variableRight->getType()) {
                                    case 'string':
                                    case 'variable':
                                    case 'array':
                                        $compilationContext->headersManager->add('kernel/operators');
                                        $variableRight = $compilationContext->backend->getVariableCode($variableRight);

                                        return new CompiledExpression('bool', $this->zvalOperator.'('.$variableCode.', '.$variableRight.')', $expression);

                                    default:
                                        throw new CompilerException('Unknown type: '.$variableRight->getType(), $expression['right']);
                                }
                                break;

                            default:
                                throw new CompilerException('Unknown type: '.$right->getType(), $expression['left']);
                        }
                        break;

                    case 'string':
                        switch ($right->getType()) {
                            case 'null':
                                $compilationContext->headersManager->add('kernel/operators');

                                return new CompiledExpression('bool', $this->zvalStringOperator.'('.$variableCode.', "")', $expression['left']);

                            case 'string':
                                $compilationContext->headersManager->add('kernel/operators');

                                return new CompiledExpression('bool', $this->zvalStringOperator.'('.$variableCode.', "'.$right->getCode().'")', $expression['left']);

                            case 'variable':
                                $variableRight = $compilationContext->symbolTable->getVariableForRead($right->getCode(), $compilationContext, $expression['left']);
                                switch ($variableRight->getType()) {
                                    case 'string':
                                    case 'variable':
                                        $compilationContext->headersManager->add('kernel/operators');
                                        $variableRight = $compilationContext->backend->getVariableCode($variableRight);

                                        return new CompiledExpression('bool', $this->zvalOperator.'('.$variableCode.', '.$variableRight.')', $expression);

                                    default:
                                        throw new CompilerException('Unknown type: '.$variableRight->getType(), $expression['right']);
                                }
                                break;

                            default:
                                throw new CompilerException('Unknown type: '.$right->getType(), $expression['left']);
                        }
                        break;

                    case 'variable':
                        switch ($right->getType()) {
                            case 'null':
                                $compilationContext->headersManager->add('kernel/operators');
                                $condition = $compilationContext->backend->getTypeofCondition($variable, $this->operator, 'null', $compilationContext);

                                return new CompiledExpression('bool', $condition, $expression['left']);

                            case 'int':
                            case 'uint':
                            case 'long':
                            case 'ulong':
                            case 'double':
                                $compilationContext->headersManager->add('kernel/operators');

                                return new CompiledExpression('bool', $this->zvalLongOperator.'('.$variableCode.', '.$right->getCode().')', $expression['left']);

                            case 'char':
                            case 'uchar':
                                $compilationContext->headersManager->add('kernel/operators');

                                return new CompiledExpression('bool', $this->zvalLongOperator.'('.$variableCode.', \''.$right->getCode().'\')', $expression['left']);

                            case 'bool':
                                $compilationContext->headersManager->add('kernel/operators');
                                $zvalBoolOperator = 'true' == $right->getCode() ? $this->zvalBoolTrueOperator : $this->zvalBoolFalseOperator;

                                return new CompiledExpression('bool', $zvalBoolOperator.'('.$variableCode.')', $expression['left']);

                            case 'string':
                                $compilationContext->headersManager->add('kernel/operators');

                                return new CompiledExpression('bool', $this->zvalStringOperator.'('.$variableCode.', "'.$right->getCode().'")', $expression['left']);

                            case 'variable':
                                $variableRight = $compilationContext->symbolTable->getVariableForRead($right->getCode(), $compilationContext, $expression['left']);
                                switch ($variableRight->getType()) {
                                    case 'int':
                                    case 'uint':
                                    case 'long':
                                    case 'ulong':
                                        $compilationContext->headersManager->add('kernel/operators');

                                        return new CompiledExpression('bool', $this->zvalLongOperator.'('.$variableCode.', '.$variableRight->getName().')', $expression);

                                    case 'double':
                                        $compilationContext->headersManager->add('kernel/operators');

                                        return new CompiledExpression('bool', $this->zvalDoubleOperator.'('.$variableCode.', '.$variableRight->getName().')', $expression);

                                    case 'bool':
                                        $compilationContext->headersManager->add('kernel/operators');

                                        return new CompiledExpression('bool', $this->zvalBoolOperator.'('.$variableCode.', '.$variableRight->getName().')', $expression);

                                    case 'string':
                                    case 'variable':
                                    case 'array':
                                        $compilationContext->headersManager->add('kernel/operators');
                                        $variableRight = $compilationContext->backend->getVariableCode($variableRight);

                                        return new CompiledExpression('bool', $this->zvalOperator.'('.$variableCode.', '.$variableRight.')', $expression);

                                    default:
                                        throw new CompilerException('Unknown type: '.$variableRight->getType(), $expression['right']);
                                }
                                break;

                            default:
                                throw new CompilerException('Unknown type: '.$right->getType(), $expression['left']);
                        }
                        break;

                    default:
                        throw new CompilerException('Unknown type: '.$variable->getType(), $expression);
                }
                break;

            default:
                throw new CompilerException('Unknown type: '.$left->getType(), $expression);
        }
    }
1059537
protected function execute(Context $context)
    {
        $this->logger->debug('kernel.execute: execute logic');

        // prepare params
        $params = $context->params;
        $params[] = $context;

        // execute logic method
        $result = call_user_func_array($context->logic->method, $params);
        $this->logger->debug('kernel.execute: #' . $context->logic->name . ' executed');

        // user response
        if($result instanceof Response) {
            $context->response = $result;
            $this->logger->debug('kernel.execute: response provided as result of execution');
        }
        // raw response
        else {
            $context->response->raw = true;
            $context->response->content = $result;
            $this->logger->debug('kernel.execute: raw content provided as result of execution');
        }

        return $context;
    }
1336776
static ExecutorService makeContextAware(ExecutorService delegate, CurrentTraceContext traceCtx) {
    class TracingCurrentRequestContextExecutorService extends WrappingExecutorService {

      @Override protected ExecutorService delegate() {
        return delegate;
      }

      @Override protected <C> Callable<C> wrap(Callable<C> task) {
        return RequestContext.current().makeContextAware(traceCtx.wrap(task));
      }

      @Override protected Runnable wrap(Runnable task) {
        return RequestContext.current().makeContextAware(traceCtx.wrap(task));
      }
    }
    return new TracingCurrentRequestContextExecutorService();
  }