Represents a class/interface and their properties and methods
Beispiel #1
0
 /**
  * Creates a closure
  *
  * @param array $expression
  * @param CompilationContext $compilationContext
  * @return CompiledExpression
  * @throws \Zephir\CompilerException
  */
 public function compile(array $expression, CompilationContext $compilationContext)
 {
     $classDefinition = new ClassDefinition($compilationContext->config->get('namespace'), self::$id . '__closure');
     $classDefinition->setIsFinal(true);
     $compilerFile = new CompilerFileAnonymous($classDefinition, $compilationContext->config, $compilationContext->logger);
     $compilationContext->compiler->addClassDefinition($compilerFile, $classDefinition);
     /**
      * Builds parameters using the only parameter available
      */
     $parameters = new ClassMethodParameters(array(array('type' => 'parameter', 'name' => $expression['left']['value'], 'const' => 0, 'data-type' => 'variable', 'mandatory' => 0, 'reference' => 0, 'file' => $expression['left']['file'], 'line' => $expression['left']['line'], 'char' => $expression['left']['char'])));
     $statementBlock = new StatementsBlockBuilder(array(new ReturnStatementBuilder(new RawExpressionBuilder($expression['right']))));
     $block = $statementBlock->get();
     $classMethod = new ClassMethod($classDefinition, array('public', 'final'), '__invoke', $parameters, new StatementsBlock($block), null, null, $expression);
     $classDefinition->addMethod($classMethod, $block);
     $compilationContext->headersManager->add('kernel/object');
     if ($this->expecting) {
         if ($this->expectingVariable) {
             $symbolVariable = $this->expectingVariable;
         } else {
             $symbolVariable = $compilationContext->symbolTable->getTempVariableForWrite('variable', $compilationContext, $expression);
         }
     } else {
         $symbolVariable = $compilationContext->symbolTable->getTempVariableForWrite('variable', $compilationContext, $expression);
     }
     $symbolVariable->initVariant($compilationContext);
     $compilationContext->codePrinter->output('zephir_create_closure_ex(' . $symbolVariable->getName() . ', NULL, ' . $classDefinition->getClassEntry() . ', SS("__invoke") TSRMLS_CC);');
     self::$id++;
     return new CompiledExpression('variable', $symbolVariable->getRealName(), $expression);
 }
Beispiel #2
0
 /**
  * Creates a closure
  *
  * @param array $expression
  * @param CompilationContext $compilationContext
  * @return CompiledExpression
  * @throws \Zephir\CompilerException
  */
 public function compile(array $expression, CompilationContext $compilationContext)
 {
     $classDefinition = new ClassDefinition($compilationContext->config->get('namespace'), self::$id . '__closure');
     $classDefinition->setIsFinal(true);
     $compilerFile = new CompilerFileAnonymous($classDefinition, $compilationContext->config, $compilationContext->logger);
     $compilationContext->compiler->addClassDefinition($compilerFile, $classDefinition);
     if (isset($expression['left'])) {
         $parameters = new ClassMethodParameters($expression['left']);
     } else {
         $parameters = null;
     }
     if (isset($expression['right'])) {
         $block = $expression['right'];
     } else {
         $block = array();
     }
     $classMethod = new ClassMethod($classDefinition, array('public', 'final'), '__invoke', $parameters, new StatementsBlock($block), null, null, $expression);
     $classDefinition->addMethod($classMethod, $block);
     $compilationContext->headersManager->add('kernel/object');
     if ($this->expecting) {
         if ($this->expectingVariable) {
             $symbolVariable = $this->expectingVariable;
         } else {
             $symbolVariable = $compilationContext->symbolTable->getTempVariableForWrite('variable', $compilationContext, $expression);
         }
     } else {
         $symbolVariable = $compilationContext->symbolTable->getTempVariableForWrite('variable', $compilationContext, $expression);
     }
     $symbolVariable->initVariant($compilationContext);
     $compilationContext->backend->createClosure($symbolVariable, $classDefinition, $compilationContext);
     self::$id++;
     return new CompiledExpression('variable', $symbolVariable->getRealName(), $expression);
 }
Beispiel #3
0
 /**
  * Creates a closure
  *
  * @param array $expression
  * @param CompilationContext $compilationContext
  * @return CompiledExpression
  * @throws \Zephir\CompilerException
  */
 public function compile(array $expression, CompilationContext $compilationContext)
 {
     $classDefinition = new ClassDefinition($compilationContext->config->get('namespace'), self::$id . '__closure');
     $classDefinition->setIsFinal(true);
     $compilerFile = new CompilerFileAnonymous($classDefinition, $compilationContext->config, $compilationContext->logger);
     $compilationContext->compiler->addClassDefinition($compilerFile, $classDefinition);
     /**
      * Builds parameters using the only parameter available
      */
     $parameters = new ClassMethodParameters(array(array('type' => 'parameter', 'name' => $expression['left']['value'], 'const' => 0, 'data-type' => 'variable', 'mandatory' => 0, 'reference' => 0, 'file' => $expression['left']['file'], 'line' => $expression['left']['line'], 'char' => $expression['left']['char'])));
     $exprBuilder = BuilderFactory::getInstance();
     $statementBlockBuilder = $exprBuilder->statements()->block(array($exprBuilder->statements()->returnX($exprBuilder->raw($expression['right']))));
     $block = $statementBlockBuilder->build();
     $classMethod = new ClassMethod($classDefinition, array('public', 'final'), '__invoke', $parameters, new StatementsBlock($block), null, null, $expression);
     $classDefinition->addMethod($classMethod, $block);
     $compilationContext->headersManager->add('kernel/object');
     if ($this->expecting) {
         if ($this->expectingVariable) {
             $symbolVariable = $this->expectingVariable;
         } else {
             $symbolVariable = $compilationContext->symbolTable->getTempVariableForWrite('variable', $compilationContext, $expression);
         }
     } else {
         $symbolVariable = $compilationContext->symbolTable->getTempVariableForWrite('variable', $compilationContext, $expression);
     }
     $symbolVariable->initVariant($compilationContext);
     $compilationContext->backend->createClosure($symbolVariable, $classDefinition, $compilationContext);
     self::$id++;
     return new CompiledExpression('variable', $symbolVariable->getRealName(), $expression);
 }
Beispiel #4
0
 /**
  * @return LetStatementBuilder
  */
 protected function getLetStatement()
 {
     if (!$this->isStatic()) {
         return new LetStatementBuilder(array('assign-type' => 'object-property', 'operator' => 'assign', 'variable' => 'this', 'property' => $this->name, 'file' => $this->original['default']['file'], 'line' => $this->original['default']['line'], 'char' => $this->original['default']['char']), $this->original['default']);
     }
     return new LetStatementBuilder(array('assign-type' => 'static-property', 'operator' => 'assign', 'variable' => '\\' . $this->classDefinition->getCompleteName(), 'property' => $this->name, 'file' => $this->original['default']['file'], 'line' => $this->original['default']['line'], 'char' => $this->original['default']['char']), $this->original['default']);
 }
Beispiel #5
0
 /**
  * @return LetStatementBuilder
  */
 protected function getLetStatement()
 {
     if ($this->isStatic()) {
         return new LetStatementBuilder(array('assign-type' => 'static-property', 'operator' => 'assign', 'variable' => '\\' . $this->classDefinition->getCompleteName(), 'property' => $this->name, 'file' => $this->original['default']['file'], 'line' => $this->original['default']['line'], 'char' => $this->original['default']['char']), $this->original['default']);
     }
     $lsb = new LetStatementBuilder(array('assign-type' => 'object-property', 'operator' => 'assign', 'variable' => 'this', 'property' => $this->name, 'file' => $this->original['default']['file'], 'line' => $this->original['default']['line'], 'char' => $this->original['default']['char']), $this->original['default']);
     return new IfStatementBuilder(new BinaryOperatorBuilder('equals', new BinaryOperatorBuilder('property-access', new VariableBuilder('this'), new LiteralBuilder('string', $this->name)), new LiteralBuilder('null', null)), new StatementsBlockBuilder(array($lsb)));
 }
Beispiel #6
0
 public function getOptimizedMethod()
 {
     $optimizedName = $this->getName() . '_zephir_internal_call';
     $optimizedMethod = $this->classDefinition->getMethod($optimizedName, false);
     if (!$optimizedMethod || !$this->optimizable) {
         return $this;
     }
     return $optimizedMethod;
 }
Beispiel #7
0
 /**
  * Checks if the class is suitable for caching
  *
  * @param ClassDefinition $classDefinition
  * @return boolean
  */
 private function isClassCacheable($classDefinition)
 {
     if ($classDefinition instanceof ClassDefinition) {
         return true;
     }
     if ($classDefinition instanceof \ReflectionClass) {
         if ($classDefinition->isInternal() && $classDefinition->isInstantiable()) {
             $extension = $classDefinition->getExtension();
             switch ($extension->getName()) {
                 case 'Reflection':
                 case 'Core':
                 case 'SPL':
                     return true;
             }
         }
     }
     return false;
 }
Beispiel #8
0
 /**
  * @return $this|ExpressionLetStatement
  */
 protected function getLetStatement()
 {
     $exprBuilder = BuilderFactory::getInstance();
     if ($this->isStatic()) {
         $className = '\\' . $this->classDefinition->getCompleteName();
         $expr = $exprBuilder->raw($this->original['default']);
         return $exprBuilder->statements()->let(array($exprBuilder->operators()->assignStaticProperty($className, $this->name, $expr)->setFile($this->original['default']['file'])->setLine($this->original['default']['line'])->setChar($this->original['default']['char'])));
     }
     $lsb = $exprBuilder->statements()->let(array($exprBuilder->operators()->assignProperty('this', $this->name, $exprBuilder->raw($this->original['default']))->setFile($this->original['default']['file'])->setLine($this->original['default']['line'])->setChar($this->original['default']['char'])));
     return $exprBuilder->statements()->ifX()->setCondition($exprBuilder->operators()->binary(BinaryOperator::OPERATOR_EQUALS, $exprBuilder->operators()->binary(BinaryOperator::OPERATOR_ACCESS_PROPERTY, $exprBuilder->variable('this'), $exprBuilder->literal(Types::STRING, $this->name)), $exprBuilder->literal(Types::NULL_)))->setStatements($exprBuilder->statements()->block(array($lsb)));
 }
Beispiel #9
0
    protected function buildClass(ClassDefinition $class)
    {
        $source = <<<EOF
<?php

namespace {$class->getNamespace()};


EOF;
        if ($class->isFinal()) {
            $source .= 'final ';
        } elseif ($class->isAbstract()) {
            $source .= 'abstract ';
        }
        $source .= $class->getType() . ' ' . $class->getName();
        if ($extendsClassDefinition = $class->getExtendsClassDefinition()) {
            $source .= ' extends \\' . $extendsClassDefinition->getCompleteName();
        }
        if ($implementedInterfaces = $class->getImplementedInterfaces()) {
            $interfaces = array_map(function ($val) {
                return '\\' . $val;
            }, $implementedInterfaces);
            $source .= ' implements ' . join(', ', $interfaces);
        }
        $source .= PHP_EOL . '{' . PHP_EOL;
        foreach ($class->getConstants() as $constant) {
            $source .= $this->buildConstant($constant) . PHP_EOL;
        }
        foreach ($class->getProperties() as $property) {
            $source .= $this->buildProperty($property) . PHP_EOL;
        }
        $source .= PHP_EOL;
        foreach ($class->getMethods() as $method) {
            $source .= $this->buildMethod($method, $class->getType() === 'interface') . "\n\n";
        }
        return $source . '}' . PHP_EOL;
    }
Beispiel #10
0
 public function getData()
 {
     $nsPieces = explode('\\', $this->class->getNamespace());
     $nsPathes = array();
     $nsStr = "";
     foreach ($nsPieces as $n) {
         if (strlen($nsStr) > 0) {
             $nsStr .= '\\';
         }
         $nsStr .= $n;
         $nsPathes[$n] = $nsStr;
     }
     return array("classDefinition" => $this->class, "compilerFile" => $this->compilerFile, "className" => $this->class->getName(), "classNamespace" => $this->class->getNamespace(), "fullName" => $this->class->getCompleteName(), "methods" => $this->class->getMethods(), "namespacePieces" => $nsPathes);
 }
Beispiel #11
0
 /**
  * Creates a definition for a class
  *
  * @param CompilationContext $compilationContext
  * @param string $namespace
  * @param array $topStatement
  * @param array $docblock
  */
 public function preCompileClass(CompilationContext $compilationContext, $namespace, $topStatement, $docblock)
 {
     $classDefinition = new ClassDefinition($namespace, $topStatement['name']);
     $classDefinition->setIsExternal($this->_external);
     if (isset($topStatement['extends'])) {
         $classDefinition->setExtendsClass($this->getFullName($topStatement['extends']));
     }
     if (isset($topStatement['implements'])) {
         foreach ($topStatement['implements'] as &$implement) {
             $implement['value'] = $this->getFullName($implement['value']);
         }
         $classDefinition->setImplementsInterfaces($topStatement['implements']);
     }
     if (isset($topStatement['abstract'])) {
         $classDefinition->setIsAbstract($topStatement['abstract']);
     }
     if (isset($topStatement['final'])) {
         $classDefinition->setIsFinal($topStatement['final']);
     }
     if (is_array($docblock)) {
         $classDefinition->setDocBlock($docblock["value"]);
     }
     if (isset($topStatement['definition'])) {
         $definition = $topStatement['definition'];
         if (isset($definition['properties'])) {
             foreach ($definition['properties'] as $property) {
                 /**
                  * Add property to the definition
                  */
                 $classDefinition->addProperty(new ClassProperty($classDefinition, $property['visibility'], $property['name'], isset($property['default']) ? $property['default'] : null, isset($property['docblock']) ? $property['docblock'] : null, $property));
                 /**
                  * Check and process shortcuts
                  */
                 if (isset($property['shortcuts'])) {
                     $this->_processShorcuts($property, $classDefinition);
                 }
             }
         }
         /**
          * Register constants
          */
         if (isset($definition['constants'])) {
             foreach ($definition['constants'] as $constant) {
                 $classDefinition->addConstant(new ClassConstant($constant['name'], isset($constant['default']) ? $constant['default'] : null, isset($constant['docblock']) ? $constant['docblock'] : null));
             }
         }
         /**
          * Register methods
          */
         if (isset($definition['methods'])) {
             foreach ($definition['methods'] as $method) {
                 $classDefinition->addMethod(new ClassMethod($classDefinition, $method['visibility'], $method['name'], isset($method['parameters']) ? new ClassMethodParameters($method['parameters']) : null, isset($method['statements']) ? new StatementsBlock($method['statements']) : null, isset($method['docblock']) ? $method['docblock'] : null, isset($method['return-type']) ? $method['return-type'] : null, $method), $method);
             }
         }
     }
     $this->_classDefinition = $classDefinition;
     /**
      * Assign current class definition to the compilation context
      */
     $compilationContext->classDefinition = $classDefinition;
     /**
      * Run pre-compilation passes
      */
     $classDefinition->preCompile($compilationContext);
 }
Beispiel #12
0
    /**
     * Build class
     *
     * @param ClassDefinition $class
     * @param string $indent
     * @return string
     */
    protected function buildClass(ClassDefinition $class, $indent)
    {
        $source = <<<EOF
<?php

namespace {$class->getNamespace()};


EOF;
        $source .= new DocBlock($class->getDocBlock(), '') . "\n";
        if ($class->isFinal()) {
            $source .= 'final ';
        } elseif ($class->isAbstract()) {
            $source .= 'abstract ';
        }
        $source .= $class->getType() . ' ' . $class->getName();
        if ($class->getExtendsClass()) {
            $extendsClassDefinition = $class->getExtendsClassDefinition();
            if (!$extendsClassDefinition) {
                throw new \RuntimeException('Class "' . $class->getName() . '" does not have a extendsClassDefinition');
            }
            $source .= ' extends ' . ($extendsClassDefinition->isBundled() ? '' : '\\') . $extendsClassDefinition->getCompleteName();
        }
        if ($implementedInterfaces = $class->getImplementedInterfaces()) {
            $interfaces = array_map(function ($val) {
                return '\\' . $val;
            }, $implementedInterfaces);
            $keyword = $class->getType() == 'interface' ? ' extends ' : ' implements ';
            $source .= $keyword . join(', ', $interfaces);
        }
        $source .= PHP_EOL . '{' . PHP_EOL;
        foreach ($class->getConstants() as $constant) {
            $source .= $this->buildConstant($constant, $indent) . PHP_EOL . PHP_EOL;
        }
        foreach ($class->getProperties() as $property) {
            $source .= $this->buildProperty($property, $indent) . PHP_EOL . PHP_EOL;
        }
        $source .= PHP_EOL;
        foreach ($class->getMethods() as $method) {
            if ($method->isInternal()) {
                continue;
            }
            $source .= $this->buildMethod($method, $class->getType() === 'interface', $indent) . "\n\n";
        }
        return $source . '}' . PHP_EOL;
    }
Beispiel #13
0
 /**
  * Calls static methods on the some class context
  *
  * @param string $methodName
  * @param array $expression
  * @param Variable $symbolVariable
  * @param boolean $mustInit
  * @param boolean $isExpecting
  * @param ClassDefinition $classDefinition
  * @param CompilationContext $compilationContext
  * @param ClassMethod $method
  */
 protected function callFromClass($methodName, array $expression, $symbolVariable, $mustInit, $isExpecting, ClassDefinition $classDefinition, CompilationContext $compilationContext, ClassMethod $method)
 {
     $codePrinter = $compilationContext->codePrinter;
     if ($classDefinition->isBundled()) {
         //if (!$compilationContext->symbolTable->hasVariable($variableName)) {
         $classEntryVariable = $compilationContext->symbolTable->addTemp('zend_class_entry', $compilationContext);
         $compilationContext->backend->fetchClass($classEntryVariable, 'SL("' . str_replace('\\', '\\\\', $classDefinition->getName()) . '")', false, $compilationContext);
         //}
         //$classEntryVariable = $compilationContext->symbolTable->getVariableForWrite($variableName, $compilationContext, $expression);
         $classEntry = $classEntryVariable->getName();
     } else {
         $classEntry = $classDefinition->getClassEntry($compilationContext);
     }
     /**
      * Call static methods must grown the stack
      */
     $compilationContext->symbolTable->mustGrownStack(true);
     if ($mustInit) {
         $symbolVariable->setMustInitNull(true);
         $symbolVariable->trackVariant($compilationContext);
     }
     if ($method) {
         $method = $method->getOptimizedMethod();
     }
     /**
      * Check if the  method call can have an inline cache
      */
     $methodCache = $compilationContext->cacheManager->getStaticMethodCache();
     $cachePointer = $methodCache->get($compilationContext, isset($method) ? $method : null);
     if (isset($expression['parameters']) && count($expression['parameters'])) {
         $params = $this->getResolvedParams($expression['parameters'], $compilationContext, $expression);
     } else {
         $params = array();
     }
     if ($symbolVariable) {
         $symbol = $compilationContext->backend->getVariableCodePointer($symbolVariable);
     }
     $paramCount = count($params);
     $paramsStr = $paramCount ? ', ' . join(', ', $params) : '';
     if ($method->isInternal()) {
         $ce = $classDefinition->getClassEntry($compilationContext);
         if ($isExpecting) {
             if ($symbolVariable->getName() == 'return_value') {
                 $macro = $compilationContext->backend->getFcallManager()->getMacro(true, true, $paramCount);
                 $codePrinter->output($macro . '(' . $ce . ', ' . $method->getInternalName() . $paramsStr . ');');
             } else {
                 $macro = $compilationContext->backend->getFcallManager()->getMacro(true, 2, $paramCount);
                 $codePrinter->output($macro . '(' . $symbol . ', ' . $ce . ', ' . $method->getInternalName() . $paramsStr . ');');
             }
         } else {
             $macro = $compilationContext->backend->getFcallManager()->getMacro(true, false, $paramCount);
             $codePrinter->output($macro . '(' . $ce . ', ' . $method->getInternalName() . $paramsStr . ');');
         }
     } else {
         if ($isExpecting) {
             if ($symbolVariable->getName() == 'return_value') {
                 $codePrinter->output('ZEPHIR_RETURN_CALL_CE_STATIC(' . $classEntry . ', "' . $methodName . '", ' . $cachePointer . $paramsStr . ');');
             } else {
                 $codePrinter->output('ZEPHIR_CALL_CE_STATIC(' . $symbol . ', ' . $classEntry . ', "' . $methodName . '", ' . $cachePointer . $paramsStr . ');');
             }
         } else {
             $codePrinter->output('ZEPHIR_CALL_CE_STATIC(NULL, ' . $classEntry . ', "' . $methodName . '", ' . $cachePointer . $paramsStr . ');');
         }
     }
     /**
      * Temporary variables must be copied if they have more than one reference
      */
     foreach ($this->getMustCheckForCopyVariables() as $checkVariable) {
         $codePrinter->output('zephir_check_temp_parameter(' . $checkVariable . ');');
     }
     $this->addCallStatusOrJump($compilationContext);
 }
Beispiel #14
0
 /**
  * Builds a class definition from reflection
  *
  * @param \ReflectionClass $class
  *
  * @return ClassDefinition
  */
 public static function buildFromReflection(\ReflectionClass $class)
 {
     $classDefinition = new ClassDefinition($class->getNamespaceName(), $class->getName());
     $methods = $class->getMethods();
     if (count($methods) > 0) {
         foreach ($methods as $method) {
             $parameters = array();
             foreach ($method->getParameters() as $row) {
                 $params = array('type' => 'parameter', 'name' => $row->getName(), 'const' => 0, 'data-type' => 'variable', 'mandatory' => !$row->isOptional());
                 if (!$params['mandatory']) {
                     try {
                         $params['default'] = $row->getDefaultValue();
                     } catch (\ReflectionException $e) {
                         // TODO: dummy default value
                         $params['default'] = true;
                     }
                 }
                 $parameters[] = $params;
             }
             $classMethod = new ClassMethod($classDefinition, array(), $method->getName(), new ClassMethodParameters($parameters));
             $classMethod->setIsStatic($method->isStatic());
             $classMethod->setIsBundled(true);
             $classDefinition->addMethod($classMethod);
         }
     }
     $constants = $class->getConstants();
     if (count($constants) > 0) {
         foreach ($constants as $constantName => $constantValue) {
             $type = self::_convertPhpConstantType(gettype($constantValue));
             $classConstant = new ClassConstant($constantName, array('value' => $constantValue, 'type' => $type), null);
             $classDefinition->addConstant($classConstant);
         }
     }
     $properties = $class->getProperties();
     if (count($properties) > 0) {
         foreach ($properties as $property) {
             $visibility = array();
             if ($property->isPublic()) {
                 $visibility[] = 'public';
             }
             if ($property->isPrivate()) {
                 $visibility[] = 'private';
             }
             if ($property->isProtected()) {
                 $visibility[] = 'protected';
             }
             if ($property->isStatic()) {
                 $visibility[] = 'static';
             }
             $classProperty = new ClassProperty($classDefinition, $visibility, $property->getName(), null, null, null);
             $classDefinition->addProperty($classProperty);
         }
     }
     $classDefinition->setIsBundled(true);
     return $classDefinition;
 }
Beispiel #15
0
 public static function sourceUrl(ClassDefinition $c)
 {
     return "/source/" . str_replace("\\", "/", $c->getCompleteName()) . ".html";
 }
Beispiel #16
0
 /**
  * Returns class the class definition from a given class name
  *
  * @param string $className
  *
  * @return ClassDefinition
  */
 public function getInternalClassDefinition($className)
 {
     if (!isset(self::$internalDefinitions[$className])) {
         $reflection = new \ReflectionClass($className);
         self::$internalDefinitions[$className] = ClassDefinition::buildFromReflection($reflection);
     }
     return self::$internalDefinitions[$className];
 }
Beispiel #17
0
 /**
  * Calls static methods on the some class context
  *
  * @param string $methodName
  * @param array $expression
  * @param Variable $symbolVariable
  * @param boolean $mustInit
  * @param boolean $isExpecting
  * @param ClassDefinition $classDefinition
  * @param CompilationContext $compilationContext
  * @param ClassMethod $method
  */
 protected function callFromClass($methodName, array $expression, $symbolVariable, $mustInit, $isExpecting, ClassDefinition $classDefinition, CompilationContext $compilationContext, $method)
 {
     $codePrinter = $compilationContext->codePrinter;
     if ($classDefinition->isInternal()) {
         $variableName = str_replace('\\', '_', $classDefinition->getSCName('local'));
         if (!$compilationContext->symbolTable->hasVariable($variableName)) {
             $classEntryVariable = $compilationContext->symbolTable->addVariable('zend_class_entry', $variableName, $compilationContext);
             $codePrinter->output($classEntryVariable->getName() . ' = zend_fetch_class(SL("\\\\' . str_replace('\\', '\\\\', $classDefinition->getName()) . '"), ZEND_FETCH_CLASS_AUTO TSRMLS_CC);');
         }
         $classEntryVariable = $compilationContext->symbolTable->getVariableForWrite($variableName, 'zend_class_entry', $compilationContext);
         $classEntry = $classEntryVariable->getName();
     } else {
         $classEntry = $classDefinition->getClassEntry();
     }
     /**
      * Call static methods must grown the stack
      */
     $compilationContext->symbolTable->mustGrownStack(true);
     if ($mustInit) {
         $symbolVariable->setMustInitNull(true);
         $symbolVariable->trackVariant($compilationContext);
     }
     /**
      * Check if the  method call can have an inline cache
      */
     $methodCache = $compilationContext->cacheManager->getStaticMethodCache();
     $cachePointer = $methodCache->get($compilationContext, isset($method) ? $method : null);
     if (isset($expression['parameters']) && count($expression['parameters'])) {
         $params = $this->getResolvedParams($expression['parameters'], $compilationContext, $expression);
     } else {
         $params = array();
     }
     if (!count($params)) {
         if ($isExpecting) {
             if ($symbolVariable->getName() == 'return_value') {
                 $codePrinter->output('ZEPHIR_RETURN_CALL_CE_STATIC(' . $classEntry . ', "' . $methodName . '", ' . $cachePointer . ');');
             } else {
                 $codePrinter->output('ZEPHIR_CALL_CE_STATIC(&' . $symbolVariable->getName() . ', ' . $classEntry . ', "' . $methodName . '", ' . $cachePointer . ');');
             }
         } else {
             $codePrinter->output('ZEPHIR_CALL_CE_STATIC(NULL, ' . $classEntry . ', "' . $methodName . '", ' . $cachePointer . ');');
         }
     } else {
         if ($isExpecting) {
             if ($symbolVariable->getName() == 'return_value') {
                 $codePrinter->output('ZEPHIR_RETURN_CALL_CE_STATIC(' . $classEntry . ', "' . $methodName . '", ' . $cachePointer . ', ' . join(', ', $params) . ');');
             } else {
                 $codePrinter->output('ZEPHIR_CALL_CE_STATIC(&' . $symbolVariable->getName() . ', ' . $classEntry . ', "' . $methodName . '", ' . $cachePointer . ', ' . join(', ', $params) . ');');
             }
         } else {
             $codePrinter->output('ZEPHIR_CALL_CE_STATIC(NULL, ' . $classEntry . ', "' . $methodName . '", ' . $cachePointer . ', ' . join(', ', $params) . ');');
         }
     }
     /**
      * Temporary variables must be copied if they have more than one reference
      */
     foreach ($this->getMustCheckForCopyVariables() as $checkVariable) {
         $codePrinter->output('zephir_check_temp_parameter(' . $checkVariable . ');');
     }
     $this->addCallStatusOrJump($compilationContext);
 }