Check if a variable is declared in the current symbol table.

@param string             $name
@param CompilationContext $compilationContext

@return bool
195053
public function hasVariable($name, CompilationContext $compilationContext = null)
    {
        return false !== $this->getVariable($name, $compilationContext ?: $this->compilationContext);
    }
711152
protected function evalAttribute(Context $context, $name) {
		$expression = $this->getAttribute($name, false);
		if($expression) {
			return $this->evaluate($context, $expression);
		}
		return false;
	}
511614
public function initVariant(CompilationContext $compilationContext)
    {
        if ($this->numberSkips) {
            --$this->numberSkips;

            return;
        }

        /*
         * Variables are allocated for the first time using ZEPHIR_INIT_VAR
         * the second, third, etc times are allocated using ZEPHIR_INIT_NVAR
         * Variables initialized for the first time in a cycle are always initialized using ZEPHIR_INIT_NVAR
         */
        if ('this_ptr' != $this->getName() && 'return_value' != $this->getName()) {
            if (false === $this->initBranch) {
                $this->initBranch = $compilationContext->currentBranch;
            }

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

            if (!$this->isLocalOnly()) {
                $compilationContext->symbolTable->mustGrownStack(true);
                if ($compilationContext->insideCycle) {
                    $this->mustInitNull = true;
                    $compilationContext->backend->initVar($this, $compilationContext, true, true);
                } else {
                    if ($this->variantInits > 0) {
                        if (0 === $this->initBranch) {
                            $compilationContext->codePrinter->output('ZEPHIR_INIT_BNVAR('.$this->getName().');');
                        } else {
                            $this->mustInitNull = true;
                            $compilationContext->backend->initVar($this, $compilationContext, true, true);
                        }
                    } else {
                        $compilationContext->backend->initVar($this, $compilationContext);
                    }
                }
            } else {
                if ($this->variantInits > 0 || $compilationContext->insideCycle) {
                    $this->mustInitNull = true;
                    $compilationContext->codePrinter->output('ZEPHIR_SINIT_NVAR('.$this->getName().');');
                } else {
                    $compilationContext->codePrinter->output('ZEPHIR_SINIT_VAR('.$this->getName().');');
                }
            }

            ++$this->variantInits;
            $this->associatedClass = null;
        }
    }
91995
public function trackVariant(CompilationContext $compilationContext)
    {
        if ($this->numberSkips) {
            --$this->numberSkips;

            return;
        }

        /*
         * Variables are allocated for the first time using ZEPHIR_INIT_VAR
         * the second, third, etc times are allocated using ZEPHIR_INIT_NVAR
         * Variables initialized for the first time in a cycle are always initialized using ZEPHIR_INIT_NVAR
         */
        if ('this_ptr' != $this->getName() && 'return_value' != $this->getName()) {
            if (false === $this->initBranch) {
                $this->initBranch = $compilationContext->currentBranch;
            }

            if (!$this->isLocalOnly()) {
                $compilationContext->symbolTable->mustGrownStack(true);
                if ($compilationContext->insideCycle) {
                    $this->mustInitNull = true;
                } else {
                    if ($this->variantInits > 0) {
                        if (1 !== $this->initBranch) {
                            $this->mustInitNull = true;
                        }
                    }
                }
            } else {
                if ($this->variantInits > 0 || $compilationContext->insideCycle) {
                    $this->mustInitNull = true;
                }
            }

            ++$this->variantInits;
        }
    }
445150
public function initNonReferenced(CompilationContext $compilationContext)
    {
        $compilationContext->headersManager->add('kernel/memory');
        $compilationContext->codePrinter->output('ZEPHIR_INIT_ZVAL_NREF('.$this->getName().');');
    }
221508
public function get(CompilationContext $compilationContext, $methodName, Variable $caller)
    {
        $compiler = $compilationContext->compiler;

        $numberPoly = 0;

        if ('this' == $caller->getRealName()) {
            $classDefinition = $compilationContext->classDefinition;
            if ($classDefinition->hasMethod($methodName)) {
                ++$numberPoly;
                $method = $classDefinition->getMethod($methodName);
            }
        } else {
            $classTypes = $caller->getClassTypes();
            foreach ($classTypes as $classType) {
                if ($compiler->isClass($classType) || $compiler->isInterface($classType) || $compiler->isBundledClass($classType) || $compiler->isBundledInterface($classType)) {
                    if ($compiler->isInterface($classType)) {
                        continue;
                    }

                    if ($compiler->isClass($classType)) {
                        $classDefinition = $compiler->getClassDefinition($classType);
                    } else {
                        $classDefinition = $compiler->getInternalClassDefinition($classType);
                    }

                    if (!$classDefinition) {
                        continue;
                    }

                    if ($classDefinition->hasMethod($methodName) && !$classDefinition->isInterface()) {
                        ++$numberPoly;
                        $method = $classDefinition->getMethod($methodName);
                    }
                }
            }
        }

        if (!$numberPoly) {
            // Try to generate a cache based on the fact the variable is not modified within the loop block
            if ($compilationContext->insideCycle && !$caller->isTemporal()) {
                if (\count($compilationContext->cycleBlocks) && 'variable' == $caller->getType()) {
                    $currentBlock = $compilationContext->cycleBlocks[\count($compilationContext->cycleBlocks) - 1];

                    if (0 == $currentBlock->getMutateGatherer(true)->getNumberOfMutations($caller->getName())) {
                        $functionCache = $compilationContext->symbolTable->getTempVariableForWrite('zephir_fcall_cache_entry', $compilationContext);
                        $functionCache->setMustInitNull(true);
                        $functionCache->setReusable(false);

                        return '&'.$functionCache->getName().', 0';
                    }
                }
            }

            return 'NULL, 0';
        }

        if (!($method instanceof \ReflectionMethod)) {
            if ($method->getClassDefinition()->isExternal()) {
                return 'NULL, 0';
            }

            $completeName = $method->getClassDefinition()->getCompleteName();
            if (isset($this->cache[$completeName][$method->getName()])) {
                return $this->cache[$completeName][$method->getName()].', '.SlotsCache::getExistingMethodSlot($method);
            }

            $gatherer = $this->gatherer;
            if (\is_object($gatherer)) {
                $number = $gatherer->getNumberOfMethodCalls($method->getClassDefinition()->getCompleteName(), $method->getName());
            } else {
                $number = 0;
            }

            $staticCacheable = !$method->getClassDefinition()->isInterface() && ($compilationContext->currentMethod == $method || $method->getClassDefinition()->isFinal() || $method->isFinal() || $method->isPrivate());
            if ($number > 1 || $compilationContext->insideCycle) {
                $cacheable = true;
            } else {
                $cacheable = false;
            }
        } else {
            $staticCacheable = false;
            $cacheable = false;
        }

        // Recursive methods require warm-up
        if ($compilationContext->currentMethod == $method) {
            if (!$compilationContext->methodWarmUp) {
                $compilationContext->methodWarmUp = new MethodCallWarmUp();
            }
        }

        if ('this_ptr' != $caller->getName()) {
            $associatedClass = $caller->getAssociatedClass();
            if ($this->isClassCacheable($associatedClass)) {
                $staticCacheable = true;
            }
        }

        if ($staticCacheable) {
            $cacheSlot = SlotsCache::getMethodSlot($method);
        } else {
            $cacheSlot = '0';
        }

        if ($cacheable) {
            $functionCacheVar = $compilationContext->symbolTable->getTempVariableForWrite('zephir_fcall_cache_entry', $compilationContext);
            $functionCacheVar->setMustInitNull(true);
            $functionCacheVar->setReusable(false);
            $functionCache = '&'.$functionCacheVar->getName();
        } else {
            $functionCache = 'NULL';
        }

        if (!($method instanceof \ReflectionMethod)) {
            $this->cache[$completeName][$method->getName()] = $functionCache;
        }

        return $functionCache.', '.$cacheSlot;
    }
511195
public function compileFunction(CompilationContext $compilationContext, FunctionDefinition $functionDefinition)
    {
        /** Make sure we do not produce calls like ZEPHIR_CALL_SELF */
        $bakClassDefinition = $compilationContext->classDefinition;
        $compilationContext->classDefinition = null;
        $compilationContext->currentMethod = $functionDefinition;

        $codePrinter = $compilationContext->codePrinter;
        $codePrinter->output('PHP_FUNCTION('.$functionDefinition->getInternalName().') {');
        $functionDefinition->compile($compilationContext);
        $codePrinter->output('}');
        $codePrinter->outputBlankLine();

        /* Restore */
        $compilationContext->classDefinition = $bakClassDefinition;
        $compilationContext->currentMethod = null;
    }
1043534
public function hasProperty($name)
    {
        $result = false;

        //Handle computed properties
        if(!parent::offsetExists($name))
        {
            if(!empty($name))
            {
                $properties = $this->getComputedProperties();

                if(isset($properties[$name])) {
                    $result = true;
                }
            }
        }
        else $result = true;

        return $result;
    }
1285190
public function optimizeTypeOf($expr, CompilationContext $compilationContext)
    {
        if (!isset($expr['left'])) {
            return false;
        }

        if (!isset($expr['right']) && !isset($expr['right']['value'])) {
            return false;
        }

        if ('typeof' == $expr['left']['type']) {
            if ('string' != $expr['right']['type']) {
                $compilationContext->logger->warning(
                    "Possible invalid comparison for 'typeof' operator with non-string",
                    ['invalid-typeof-comparison', $expr['right']]
                );

                return false;
            }

            if (isset($expr['type'])) {
                switch ($expr['type']) {
                    case 'identical':
                    case 'equals':
                        $operator = '==';
                        break;

                    case 'not-identical':
                    case 'not-equals':
                        $operator = '!=';
                        break;

                    default:
                        return false;
                }
            }

            $expression = new Expression($expr['left']['left']);
            $condition = $expression->compile($compilationContext);
            $variableVariable = $compilationContext->symbolTable->getVariableForRead($condition->getCode(), $compilationContext, $expr);

            if ('string' != $expr['right']['type']) {
                throw new CompilerException('Right expression of typeof operator must be "string" type', $expr['right']);
            }

            $value = strtolower($expr['right']['value']);

            switch ($variableVariable->getType()) {
                case 'double':
                    switch ($value) {
                        case 'double':
                        case 'float':
                            $condition = '1 '.$operator.' 1';
                            break;

                        default:
                            $condition = '1 '.$operator.' 0';
                            break;
                    }
                    break;

                case 'int':
                case 'integer':
                case 'long':
                    switch ($value) {
                        case 'int':
                        case 'integer':
                        case 'long':
                            $condition = '1 '.$operator.' 1';
                            break;

                        default:
                            $condition = '1 '.$operator.' 0';
                            break;
                    }
                    break;

                case 'bool':
                    switch ($value) {
                        case 'bool':
                        case 'boolean':
                            $condition = '1 '.$operator.' 1';
                            break;

                        default:
                            $condition = '1 '.$operator.' 0';
                            break;
                    }
                    break;

                case 'array':
                    switch ($value) {
                        case 'array':
                            $condition = '1 '.$operator.' 1';
                            break;

                        default:
                            $condition = '1 '.$operator.' 0';
                            break;
                    }
                    break;

                case 'string':
                    switch ($value) {
                        case 'string':
                            $condition = '1 '.$operator.' 1';
                            break;

                        default:
                            $condition = '1 '.$operator.' 0';
                            break;
                    }
                    break;

                case 'variable':
                    $condition = $compilationContext->backend->getTypeofCondition($variableVariable, $operator, $value, $compilationContext);
                    break;

                default:
                    return false;
            }

            return new CompiledExpression('bool', $condition, $expr);
        }

        return false;
    }
134678
public function compile($expression, CompilationContext $compilationContext)
    {
        /*
         * Resolves the symbol that expects the value
         */
        if ($this->expecting) {
            if ($this->expectingVariable) {
                $symbolVariable = $this->expectingVariable;
                if ('variable' != $symbolVariable->getType() && 'array' != $symbolVariable->getType()) {
                    throw new CompilerException('Cannot use variable type: '.$symbolVariable->getType().' as an array', $expression);
                }
            } else {
                $symbolVariable = $compilationContext->symbolTable->getTempVariableForWrite('array', $compilationContext, $expression);
            }
        } else {
            $symbolVariable = $compilationContext->symbolTable->getTempVariableForWrite('array', $compilationContext, $expression);
        }

        if (!isset($expression['left'])) {
            if ($this->expectingVariable) {
                $symbolVariable->initVariant($compilationContext);
            }
            /*+
             * Mark the variable as an array
             */
            $symbolVariable->setDynamicTypes('array');

            return new CompiledExpression('array', $symbolVariable->getRealName(), $expression);
        }

        $codePrinter = $compilationContext->codePrinter;

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

        /**
         * This calculates a prime number bigger than the current array size to possibly
         * reduce hash collisions when adding new members to the array.
         */
        $arrayLength = \count($expression['left']);
        if ($arrayLength >= 33 && \function_exists('gmp_nextprime')) {
            $arrayLength = gmp_strval(gmp_nextprime($arrayLength - 1));
        }
        $oldSymbolVariable = $symbolVariable;
        if ($this->expectingVariable && $symbolVariable->geVariantInits() >= 1) {
            $symbolVariable = $compilationContext->symbolTable->addTemp('variable', $compilationContext);
            $symbolVariable->initVariant($compilationContext);
            $compilationContext->backend->initArray($symbolVariable, $compilationContext, $arrayLength > 0 ? $arrayLength : null);
            $symbolVariable->setDynamicTypes('array');
        } else {
            if ($this->expectingVariable) {
                $symbolVariable->initVariant($compilationContext);
            }
            /*+
             * Mark the variable as an array
             */
            $symbolVariable->setDynamicTypes('array');
            $compilationContext->backend->initArray($symbolVariable, $compilationContext, $arrayLength > 0 ? $arrayLength : null);
        }
        foreach ($expression['left'] as $item) {
            if (isset($item['key'])) {
                $key = null;
                $exprKey = new Expression($item['key']);
                $resolvedExprKey = $exprKey->compile($compilationContext);

                switch ($resolvedExprKey->getType()) {
                    case 'string':
                        $expr = new Expression($item['value']);
                        $resolvedExpr = $expr->compile($compilationContext);
                        switch ($resolvedExpr->getType()) {
                            case 'int':
                            case 'uint':
                            case 'long':
                            case 'ulong':
                            case 'double':
                                $compilationContext->backend->addArrayEntry($symbolVariable, $resolvedExprKey, $resolvedExpr, $compilationContext);
                                break;

                            case 'bool':
                                $compilationContext->headersManager->add('kernel/array');
                                if ('true' == $resolvedExpr->getCode()) {
                                    $compilationContext->backend->updateArray($symbolVariable, $resolvedExprKey, 'true', $compilationContext, 'PH_COPY | PH_SEPARATE');
                                } else {
                                    $compilationContext->backend->updateArray($symbolVariable, $resolvedExprKey, 'false', $compilationContext, 'PH_COPY | PH_SEPARATE');
                                }
                                break;

                            case 'string':
                                $compilationContext->backend->addArrayEntry($symbolVariable, $resolvedExprKey, $resolvedExpr, $compilationContext);
                                break;

                            case 'null':
                                $compilationContext->backend->updateArray($symbolVariable, $resolvedExprKey, 'null', $compilationContext, 'PH_COPY | PH_SEPARATE');
                                break;

                            case 'array':
                            case 'variable':
                                $valueVariable = $this->getArrayValue($resolvedExpr, $compilationContext);
                                $compilationContext->backend->updateArray($symbolVariable, $resolvedExprKey, $valueVariable, $compilationContext, 'PH_COPY | PH_SEPARATE');
                                if ($valueVariable->isTemporal()) {
                                    $valueVariable->setIdle(true);
                                }
                                break;

                            default:
                                throw new CompilerException('Invalid value type: '.$resolvedExpr->getType(), $item['value']);
                        }
                        break;

                    case 'int':
                    case 'uint':
                    case 'long':
                    case 'ulong':
                        $expr = new Expression($item['value']);
                        $resolvedExpr = $expr->compile($compilationContext);
                        switch ($resolvedExpr->getType()) {
                            case 'int':
                            case 'uint':
                            case 'long':
                            case 'ulong':
                            case 'double':
                            case 'string':
                                $compilationContext->backend->addArrayEntry($symbolVariable, $resolvedExprKey, $resolvedExpr, $compilationContext);
                                break;

                            case 'bool':
                                if ('true' == $resolvedExpr->getCode()) {
                                    $compilationContext->backend->updateArray($symbolVariable, $resolvedExprKey, 'true', $compilationContext, 'PH_COPY');
                                } else {
                                    $compilationContext->backend->updateArray($symbolVariable, $resolvedExprKey, 'false', $compilationContext, 'PH_COPY');
                                }
                                break;

                            case 'null':
                                $compilationContext->backend->updateArray($symbolVariable, $resolvedExprKey, 'null', $compilationContext, 'PH_COPY');
                                break;

                            case 'array':
                            case 'variable':
                                $valueVariable = $this->getArrayValue($resolvedExpr, $compilationContext);
                                $compilationContext->backend->updateArray($symbolVariable, $resolvedExprKey, $valueVariable, $compilationContext, 'PH_COPY');
                                if ($valueVariable->isTemporal()) {
                                    $valueVariable->setIdle(true);
                                }
                                break;

                            default:
                                throw new CompilerException('Invalid value type: '.$item['value']['type'], $item['value']);
                        }
                        break;

                    case 'variable':
                        $variableVariable = $compilationContext->symbolTable->getVariableForRead($resolvedExprKey->getCode(), $compilationContext, $item['key']);
                        switch ($variableVariable->getType()) {
                            case 'int':
                            case 'uint':
                            case 'long':
                            case 'ulong':
                                $expr = new Expression($item['value']);
                                $resolvedExpr = $expr->compile($compilationContext);
                                switch ($resolvedExpr->getType()) {
                                    case 'int':
                                    case 'uint':
                                    case 'long':
                                    case 'ulong':
                                    case 'bool':
                                    case 'double':
                                    case 'null':
                                    case 'string':
                                        $compilationContext->backend->addArrayEntry($symbolVariable, $resolvedExprKey, $resolvedExpr, $compilationContext);
                                        break;

                                    case 'variable':
                                        $valueVariable = $this->getArrayValue($resolvedExpr, $compilationContext);
                                        $compilationContext->backend->updateArray($symbolVariable, $resolvedExprKey, $valueVariable, $compilationContext, 'PH_COPY');
                                        if ($valueVariable->isTemporal()) {
                                            $valueVariable->setIdle(true);
                                        }
                                        break;

                                    default:
                                        throw new CompilerException('Invalid value type: '.$item['value']['type'], $item['value']);
                                }
                                break;

                            case 'string':
                                $expr = new Expression($item['value']);
                                $resolvedExpr = $expr->compile($compilationContext);
                                switch ($resolvedExpr->getType()) {
                                    case 'int':
                                    case 'uint':
                                    case 'long':
                                    case 'ulong':
                                        $codePrinter->output('add_assoc_long_ex('.$symbolVariable->getName().', Z_STRVAL_P('.$resolvedExprKey->getCode().'), Z_STRLEN_P('.$item['key']['value'].'), '.$resolvedExpr->getCode().');');
                                        break;

                                    case 'double':
                                        $codePrinter->output('add_assoc_double_ex('.$symbolVariable->getName().', Z_STRVAL_P('.$resolvedExprKey->getCode().'), Z_STRLEN_P('.$item['key']['value'].'), '.$resolvedExpr->getCode().');');
                                        break;

                                    case 'bool':
                                        $codePrinter->output('add_assoc_bool_ex('.$symbolVariable->getName().', Z_STRVAL_P('.$resolvedExprKey->getCode().'), Z_STRLEN_P('.$item['key']['value'].'), '.$resolvedExpr->getBooleanCode().');');
                                        break;

                                    case 'string':
                                        $compilationContext->backend->addArrayEntry($symbolVariable, $resolvedExprKey, $resolvedExpr, $compilationContext);
                                        break;

                                    case 'null':
                                        $codePrinter->output('add_assoc_null_ex('.$symbolVariable->getName().', Z_STRVAL_P('.$resolvedExprKey->getCode().'), Z_STRLEN_P('.$item['key']['value'].') + 1);');
                                        break;

                                    case 'variable':
                                        $valueVariable = $this->getArrayValue($resolvedExpr, $compilationContext);
                                        $compilationContext->backend->updateArray($symbolVariable, $resolvedExprKey, $resolvedExpr, $compilationContext);
                                        if ($valueVariable->isTemporal()) {
                                            $valueVariable->setIdle(true);
                                        }
                                        break;

                                    default:
                                        throw new CompilerException('Invalid value type: '.$resolvedExpr->getType(), $item['value']);
                                }
                                break;

                            case 'variable':
                                $expr = new Expression($item['value']);
                                $resolvedExpr = $expr->compile($compilationContext);
                                switch ($resolvedExpr->getType()) {
                                    case 'null':
                                    case 'bool':
                                        $valueVariable = $this->getArrayValue($resolvedExpr, $compilationContext);
                                        $compilationContext->backend->updateArray($symbolVariable, $variableVariable, $valueVariable, $compilationContext);

                                        if ($valueVariable->isTemporal()) {
                                            $valueVariable->setIdle(true);
                                        }
                                        break;

                                    case 'variable':
                                        $valueVariable = $this->getArrayValue($resolvedExpr, $compilationContext);
                                        $compilationContext->backend->updateArray($symbolVariable, $variableVariable, $valueVariable, $compilationContext);

                                        if ($valueVariable->isTemporal()) {
                                            $valueVariable->setIdle(true);
                                        }
                                        break;

                                    default:
                                        throw new CompilerException('Invalid value type: '.$item['value']['type'], $item['value']);
                                }
                                break;

                            default:
                                throw new CompilerException('Cannot use variable type: '.$variableVariable->getType().' as array index', $item['key']);
                        }
                        break;

                    default:
                        throw new CompilerException('Invalid key type: '.$resolvedExprKey->getType(), $item['key']);
                }
            } else {
                $expr = new Expression($item['value']);
                $resolvedExpr = $expr->compile($compilationContext);
                $itemVariable = $this->getArrayValue($resolvedExpr, $compilationContext);
                $symbol = $compilationContext->backend->getVariableCode($symbolVariable);
                $item = $compilationContext->backend->resolveValue($itemVariable, $compilationContext);
                $codePrinter->output('zephir_array_fast_append('.$symbol.', '.$item.');');
                if ($itemVariable->isTemporal()) {
                    $itemVariable->setIdle(true);
                }
            }
        }

        return new CompiledExpression('array', $symbolVariable->getRealName(), $expression);
    }
293594
public function active($name, Context $context)
    {
        if (null === $toggle = $this->collection->get($name)) {
            return false;
        }

        return $toggle->activeFor($context);
    }
850990
public function get($className, $dynamic, CompilationContext $compilationContext)
    {
        /*
         * Creates a guard variable if the class name is not dynamic
         */
        if (!$dynamic) {
            $zendClassEntry = $compilationContext->symbolTable->addTemp('static_zend_class_entry', $compilationContext);
            $zendClassEntry->setMustInitNull(true);

            $compilationContext->backend->fetchClass($zendClassEntry, $className, true, $compilationContext);
        } else {
            $zendClassEntry = $compilationContext->symbolTable->addTemp('zend_class_entry', $compilationContext);
            $compilationContext->backend->fetchClass($zendClassEntry, $className, false, $compilationContext);
        }

        return $zendClassEntry;
    }
528257
private function isIgnoredAnnotation($name)
    {
        if ($this->ignoreNotImportedAnnotations || isset($this->ignoredAnnotationNames[$name])) {
            return true;
        }

        foreach (array_keys($this->ignoredAnnotationNamespaces) as $ignoredAnnotationNamespace) {
            $ignoredAnnotationNamespace = rtrim($ignoredAnnotationNamespace, '\\') . '\\';

            if (0 === stripos(rtrim($name, '\\') . '\\', $ignoredAnnotationNamespace)) {
                return true;
            }
        }

        return false;
    }
498304
public function compile(CompilationContext $compilationContext)
    {
        $compilationContext->codePrinter->output('while (1) {');

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

        /*
         * Compile statements in the 'loop' block
         */
        if (!isset($this->statement['statements'])) {
            throw new CompilerException("Infinite loop without at least a 'break' statement is not allowed", $this->statement);
        }

        $st = new StatementsBlock($this->statement['statements']);

        /**
         * Check if the block contain at least a break statement.
         */
        $loopBreakPass = new LoopBreakPass();
        $loopBreakPass->pass($st);
        if (!$loopBreakPass->hasBreak()) {
            throw new CompilerException("Infinite loop without at least a 'break' statement is not allowed", $this->statement);
        }

        $st->isLoop(true);
        $st->compile($compilationContext, false, Branch::TYPE_LOOP_INFINITE);

        --$compilationContext->insideCycle;

        $compilationContext->codePrinter->output('}');
    }
49569
public function compileRange($exprRaw, CompilationContext $compilationContext)
    {
        if (!\count($exprRaw['parameters'])) {
            return false;
        }

        if (\count($exprRaw['parameters']) > 3) {
            return false;
        }

        $functionCall = new FunctionCall();
        $parameters = $functionCall->getResolvedParamsAsExpr($exprRaw['parameters'], $compilationContext, $exprRaw);

        if (2 != \count($parameters) && 3 != \count($parameters)) {
            throw new CompilerException('Wrong number of parameters', $this->statement['expr']);
        }

        if ('variable' != $parameters[0]->getType()) {
            if (!$parameters[0]->isIntCompatibleType()) {
                return false;
            }
        }

        if ('variable' != $parameters[1]->getType()) {
            if (!$parameters[1]->isIntCompatibleType()) {
                return false;
            }
        }

        $codePrinter = $compilationContext->codePrinter;
        $exprBuilder = BuilderFactory::getInstance();

        /*
         * Initialize 'key' variable
         */
        if (isset($this->statement['key'])) {
            /**
             * This variable is used to check if the loop is in its first iteration.
             */
            $keyVariable = $compilationContext->symbolTable->getTempVariableForWrite('long', $compilationContext, $this->statement);
            $keyVariable->increaseUses();
        }

        /**
         * This variable is used to check if the loop is in its first iteration.
         */
        $flagVariable = $compilationContext->symbolTable->getTempVariableForWrite('bool', $compilationContext, $this->statement);

        if ('variable' != $parameters[0]->getType()) {
            $tempVariable = $compilationContext->symbolTable->addTemp($parameters[0]->getType(), $compilationContext);
        } else {
            $rangeVariable = $compilationContext->symbolTable->getVariableForRead($parameters[0]->getCode(), $compilationContext, $this->statement['expr']);
            $tempVariable = $compilationContext->symbolTable->addTemp($rangeVariable->getType(), $compilationContext);
        }

        /*
         * Create a copy of the current value in the end of the range to avoid modify the range
         * inside the cycle
         */
        if ('variable' != $parameters[1]->getType()) {
            $upperBoundVariable = $compilationContext->symbolTable->getTempVariable($parameters[1]->getType(), $compilationContext);
        } else {
            $rangeVariable = $compilationContext->symbolTable->getVariableForRead($parameters[1]->getCode(), $compilationContext, $this->statement['expr']);
            $upperBoundVariable = $compilationContext->symbolTable->getTempVariable($rangeVariable->getType(), $compilationContext);
        }

        /**
         * Create an implicit 'let' operation to set the current value in the upper bound of the range.
         */
        $builderLet = $exprBuilder->statements()->let();
        $builderLet->setAssignments([$exprBuilder->operators()
            ->assignVariable($upperBoundVariable->getName(), $exprBuilder->literal($parameters[1]->getType(), $parameters[1]->getCode())
                ->setFile($this->statement['file'])
                ->setLine($this->statement['line'])
                ->setChar($this->statement['char']))
            ->setFile($this->statement['file'])
            ->setLine($this->statement['line'])
            ->setChar($this->statement['char']),
        ]);

        $statement = new LetStatement($builderLet->build());
        $statement->compile($compilationContext);

        if ($this->statement['reverse']) {
            /*
             * Create an implicit 'let' operation for the initialize expression
             */
            $builderLet->setAssignments([$exprBuilder->operators()
                ->assignVariable($tempVariable->getName(), $exprBuilder->variable($upperBoundVariable->getName())
                    ->setFile($this->statement['file'])
                    ->setLine($this->statement['line'])
                    ->setChar($this->statement['char']))
                ->setFile($this->statement['file'])
                ->setLine($this->statement['line'])
                ->setChar($this->statement['char']),
            ]);
            $statement = new LetStatement($builderLet->build());
        } else {
            /*
             * Create an implicit 'let' operation for the initialize expression
             */
            $builderLet->setAssignments([$exprBuilder->operators()
                ->assignVariable($tempVariable->getName(), $exprBuilder->literal($parameters[0]->getType(), $parameters[0]->getCode())
                    ->setFile($this->statement['file'])
                    ->setLine($this->statement['line'])
                    ->setChar($this->statement['char']))
                ->setFile($this->statement['file'])
                ->setLine($this->statement['line'])
                ->setChar($this->statement['char']),
            ]);
            $statement = new LetStatement($builderLet->build());
        }

        $statement->compile($compilationContext);

        /*
         * Initialize 'key' variable
         */
        if (isset($this->statement['key'])) {
            $codePrinter->output($keyVariable->getName().' = 0;');
        }
        $codePrinter->output($flagVariable->getName().' = 0;');

        if ($this->statement['reverse']) {
            $conditionExpr = [
                'type' => 'greater-equal',
                'left' => ['type' => 'variable', 'value' => $tempVariable->getName()],
                'right' => ['type' => $parameters[0]->getType(), 'value' => $parameters[0]->getCode()],
            ];
        } else {
            $conditionExpr = [
                'type' => 'less-equal',
                'left' => ['type' => 'variable', 'value' => $tempVariable->getName()],
                'right' => ['type' => 'variable', 'value' => $upperBoundVariable->getName()],
            ];
        }

        $expr = new EvalExpression();
        $condition = $expr->optimize($conditionExpr, $compilationContext);

        $codePrinter->output('if ('.$condition.') {');
        $codePrinter->increaseLevel();

        /*
         * Inside a cycle
         */
        ++$compilationContext->insideCycle;

        $codePrinter->output('while (1) {');
        $codePrinter->increaseLevel();

        $codePrinter->output('if ('.$flagVariable->getName().') {');

        $codePrinter->increaseLevel();

        if (isset($this->statement['key'])) {
            $codePrinter->output($keyVariable->getName().'++;');
        }

        if ($this->statement['reverse']) {
            if (!isset($parameters[2])) {
                $statement = new LetStatement([
                    'type' => 'let',
                    'assignments' => [
                        [
                            'assign-type' => 'decr',
                            'variable' => $tempVariable->getName(),
                            'file' => $this->statement['file'],
                            'line' => $this->statement['line'],
                            'char' => $this->statement['char'],
                        ],
                    ],
                ]);
            } else {
                $statement = new LetStatement([
                    'type' => 'let',
                    'assignments' => [
                        [
                            'assign-type' => 'variable',
                            'operator' => 'sub-assign',
                            'variable' => $tempVariable->getName(),
                            'expr' => [
                                'type' => $parameters[2]->getType(),
                                'value' => $parameters[2]->getCode(),
                                'file' => $this->statement['file'],
                                'line' => $this->statement['line'],
                                'char' => $this->statement['char'],
                            ],
                            'file' => $this->statement['file'],
                            'line' => $this->statement['line'],
                            'char' => $this->statement['char'],
                        ],
                    ],
                ]);
            }
        } else {
            if (!isset($parameters[2])) {
                $statement = new LetStatement([
                    'type' => 'let',
                    'assignments' => [
                        [
                            'assign-type' => 'incr',
                            'variable' => $tempVariable->getName(),
                            'file' => $this->statement['file'],
                            'line' => $this->statement['line'],
                            'char' => $this->statement['char'],
                        ],
                    ],
                ]);
            } else {
                $statement = new LetStatement([
                    'type' => 'let',
                    'assignments' => [
                        [
                            'assign-type' => 'variable',
                            'operator' => 'add-assign',
                            'variable' => $tempVariable->getName(),
                            'expr' => [
                                'type' => $parameters[2]->getType(),
                                'value' => $parameters[2]->getCode(),
                                'file' => $this->statement['file'],
                                'line' => $this->statement['line'],
                                'char' => $this->statement['char'],
                            ],
                            'file' => $this->statement['file'],
                            'line' => $this->statement['line'],
                            'char' => $this->statement['char'],
                        ],
                    ],
                ]);
            }
        }
        $statement->compile($compilationContext);

        /**
         * Multi-line conditions would need to be regenerated here.
         */
        $condition = $expr->optimize($conditionExpr, $compilationContext);
        $codePrinter->output('if (!('.$condition.')) {');
        $codePrinter->output("\t".'break;');
        $codePrinter->output('}');

        $codePrinter->decreaseLevel();

        $codePrinter->output('} else {');
        $codePrinter->output("\t".$flagVariable->getName().' = 1;');
        $codePrinter->output('}');

        /*
         * Initialize 'key' variable
         */
        if (isset($this->statement['key'])) {
            /*
             * Check for anonymous variables
             */
            if ('_' != $this->statement['key']) {
                $keyVariableName = $this->statement['key'];
            } else {
                $keyVariableName = $keyVariable->getName();
            }

            /**
             * Create an implicit 'let' operation, @TODO use a builder.
             */
            $statement = new LetStatement([
                'type' => 'let',
                'assignments' => [
                    [
                        'assign-type' => 'variable',
                        'variable' => $keyVariableName,
                        'operator' => 'assign',
                        'expr' => [
                            'type' => 'variable',
                            'value' => $keyVariable->getName(),
                            'file' => $this->statement['file'],
                            'line' => $this->statement['line'],
                            'char' => $this->statement['char'],
                        ],
                        'file' => $this->statement['file'],
                        'line' => $this->statement['line'],
                        'char' => $this->statement['char'],
                    ],
                ],
            ]);

            $statement->compile($compilationContext);
        }

        /*
         * Initialize 'value' variable
         */
        if (isset($this->statement['value'])) {
            /*
             * Check for anonymous variables
             */
            if ('_' != $this->statement['value']) {
                $valueVariable = $this->statement['value'];
            } else {
                $valueVariable = $tempVariable->getName();
            }

            /**
             * Create an implicit 'let' operation, @TODO use a builder.
             */
            $statement = new LetStatement([
                'type' => 'let',
                'assignments' => [
                    [
                        'assign-type' => 'variable',
                        'variable' => $valueVariable,
                        'operator' => 'assign',
                        'expr' => [
                            'type' => 'variable',
                            'value' => $tempVariable->getName(),
                            'file' => $this->statement['file'],
                            'line' => $this->statement['line'],
                            'char' => $this->statement['char'],
                        ],
                        'file' => $this->statement['file'],
                        'line' => $this->statement['line'],
                        'char' => $this->statement['char'],
                    ],
                ],
            ]);

            $statement->compile($compilationContext);
        }

        $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('}');

        $codePrinter->decreaseLevel();

        $codePrinter->output('}');
    }
924039
public function observeVariant(CompilationContext $compilationContext)
    {
        if ($this->numberSkips) {
            --$this->numberSkips;

            return;
        }

        $name = $this->getName();
        if ('this_ptr' != $name && 'return_value' != $name) {
            if (false === $this->initBranch) {
                $this->initBranch = $compilationContext->currentBranch;
            }

            $compilationContext->headersManager->add('kernel/memory');
            $compilationContext->symbolTable->mustGrownStack(true);
            $symbol = $compilationContext->backend->getVariableCode($this);

            if ($this->variantInits > 0 || $compilationContext->insideCycle) {
                $this->mustInitNull = true;
                $compilationContext->codePrinter->output('ZEPHIR_OBS_NVAR('.$symbol.');');
            } else {
                $compilationContext->codePrinter->output('ZEPHIR_OBS_VAR('.$symbol.');');
            }

            ++$this->variantInits;
        }
    }
1263621
protected function hasImplementedPluginInterface($name)
    {
        $result = false;

        if (class_exists($name)) {
            $implements = class_implements($name);

            if (isset($implements['Yosymfony\\Spress\\Core\\Plugin\\PluginInterface'])) {
                $result = true;
            }
        }

        return $result;
    }