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