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); }
/** * 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; }
/** * 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); }
/** * 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); }
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; }