Esempio n. 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);
 }
Esempio n. 2
0
 private function initializeArray($compilationContext)
 {
     $classDefinition = $this->classDefinition;
     $parentClassDefinition = $classDefinition->getExtendsClassDefinition();
     if (!$this->isStatic()) {
         $constructParentMethod = $parentClassDefinition ? $parentClassDefinition->getInitMethod() : null;
         $constructMethod = $classDefinition->getInitMethod();
     } else {
         $constructParentMethod = $parentClassDefinition ? $parentClassDefinition->getStaticInitMethod() : null;
         $constructMethod = $classDefinition->getStaticInitMethod();
     }
     if ($constructMethod) {
         $statementsBlock = $constructMethod->getStatementsBlock();
         if ($statementsBlock) {
             $statements = $statementsBlock->getStatements();
             $letStatement = $this->getLetStatement()->get();
             $needLetStatementAdded = true;
             foreach ($statements as $statement) {
                 if ($statement === $letStatement) {
                     $needLetStatementAdded = false;
                     break;
                 }
             }
             $this->removeInitializationStatements($statements);
             if ($needLetStatementAdded) {
                 $newStatements = array();
                 /**
                  * Start from let statement
                  */
                 $newStatements[] = $letStatement;
                 foreach ($statements as $statement) {
                     $newStatements[] = $statement;
                 }
                 $statementsBlock->setStatements($newStatements);
                 $constructMethod->setStatementsBlock($statementsBlock);
                 $classDefinition->updateMethod($constructMethod);
             }
         } else {
             $statementsBlockBuilder = new StatementsBlockBuilder(array($this->getLetStatement()), false);
             $constructMethod->setStatementsBlock(new StatementsBlock($statementsBlockBuilder->get()));
             $classDefinition->updateMethod($constructMethod);
         }
     } else {
         $statements = array();
         if ($constructParentMethod) {
             $statements = $constructParentMethod->getStatementsBlock()->getStatements();
         }
         $this->removeInitializationStatements($statements);
         $statements[] = $this->getLetStatement()->get();
         $statementsBlock = new StatementsBlock($statements);
         if ($this->isStatic()) {
             $classDefinition->addStaticInitMethod($statementsBlock);
         } else {
             $classDefinition->addInitMethod($statementsBlock);
         }
     }
 }
Esempio n. 3
0
 /**
  * Produce the code to register a property
  *
  * @param CompilationContext $compilationContext
  * @throws CompilerException
  */
 public function compile(CompilationContext $compilationContext)
 {
     switch ($this->defaultValue['type']) {
         case 'long':
         case 'int':
         case 'string':
         case 'double':
         case 'bool':
             $this->declareProperty($compilationContext, $this->defaultValue['type'], $this->defaultValue['value']);
             break;
         case 'array':
         case 'empty-array':
             $classDefinition = $this->classDefinition;
             if ($this->isStatic()) {
                 $methodName = 'zephir_init_static_properties';
                 $visibility = array('internal');
             } else {
                 $methodName = 'zephir_init_properties';
                 $visibility = array('internal');
                 /* Make sure a constructor exists, so that properties are initialized */
                 $method = $classDefinition->getMethod('__construct');
                 if (!$method || $method->getClassDefinition() != $classDefinition) {
                     $classDefinition->setIsGeneratedConstructor(true);
                     $classDefinition->getEventsManager()->dispatch('setMethod', array(new ClassMethod($classDefinition, array('public'), '__construct', null, null), null));
                 }
             }
             $constructParentMethod = null;
             $constructMethod = $classDefinition->getMethod($methodName);
             /**
              * Make sure we do not steal the construct method of the parent,
              * but initialize our own with the inherited statements to ensure
              * valid property initialization
              */
             if ($constructMethod && $constructMethod->getClassDefinition() != $classDefinition) {
                 $constructParentMethod = $constructMethod;
                 $constructMethod = null;
             }
             if ($constructMethod) {
                 $statementsBlock = $constructMethod->getStatementsBlock();
                 if ($statementsBlock) {
                     $statements = $statementsBlock->getStatements();
                     $letStatement = $this->getLetStatement()->get();
                     $needLetStatementAdded = true;
                     foreach ($statements as $statement) {
                         if ($statement === $letStatement) {
                             $needLetStatementAdded = false;
                             break;
                         }
                     }
                     if ($needLetStatementAdded) {
                         $newStatements = array();
                         /**
                          * Start from let statement
                          */
                         $newStatements[] = $letStatement;
                         foreach ($statements as $statement) {
                             $newStatements[] = $statement;
                         }
                         $statementsBlock->setStatements($newStatements);
                         $constructMethod->setStatementsBlock($statementsBlock);
                         $classDefinition->getEventsManager()->dispatch('setMethod', array($constructMethod));
                     }
                 } else {
                     $statementsBlockBuilder = new StatementsBlockBuilder(array($this->getLetStatement()), false);
                     $constructMethod->setStatementsBlock(new StatementsBlock($statementsBlockBuilder->get()));
                     $classDefinition->getEventsManager()->dispatch('setMethod', array($constructMethod));
                 }
             } else {
                 $statements = array();
                 if ($constructParentMethod) {
                     $statements = $constructParentMethod->getStatementsBlock()->getStatements();
                 }
                 $statements[] = $this->getLetStatement()->get();
                 $statementsBlock = new StatementsBlock($statements);
                 $classDefinition->getEventsManager()->dispatch('setMethod', array(new ClassMethod($classDefinition, $visibility, $methodName, null, $statementsBlock), null));
                 return false;
             }
             //continue
         //continue
         case 'null':
             $this->declareProperty($compilationContext, $this->defaultValue['type'], null);
             break;
         case 'static-constant-access':
             $expression = new Expression($this->defaultValue);
             $compiledExpression = $expression->compile($compilationContext);
             $this->declareProperty($compilationContext, $compiledExpression->getType(), $compiledExpression->getCode());
             break;
         default:
             throw new CompilerException('Unknown default type: ' . $this->defaultValue['type'], $this->original);
     }
 }
Esempio n. 4
0
 /**
  * Produce the code to register a property
  *
  * @param CompilationContext $compilationContext
  * @throws CompilerException
  */
 public function compile(CompilationContext $compilationContext)
 {
     switch ($this->_defaultValue['type']) {
         case 'long':
         case 'int':
         case 'string':
         case 'double':
         case 'bool':
             $this->declareProperty($compilationContext, $this->_defaultValue['type'], $this->_defaultValue['value']);
             break;
         case 'array':
         case 'empty-array':
             if ($this->isStatic()) {
                 throw new CompilerException('Cannot define static property with default value: ' . $this->_defaultValue['type'], $this->_original);
             }
             $constructMethod = $compilationContext->classDefinition->getMethod('__construct');
             if ($constructMethod) {
                 $statementsBlock = $constructMethod->getStatementsBlock();
                 if ($statementsBlock) {
                     $statements = $statementsBlock->getStatements();
                     $letStatement = $this->getLetStatement()->get();
                     $needLetStatementAdded = true;
                     foreach ($statements as $statement) {
                         if ($statement === $letStatement) {
                             $needLetStatementAdded = false;
                             break;
                         }
                     }
                     if ($needLetStatementAdded) {
                         $statements[] = $letStatement;
                         $statementsBlock->setStatements($statements);
                         $constructMethod->setStatementsBlock($statementsBlock);
                         $compilationContext->classDefinition->getEventsManager()->dispatch('setMethod', array($constructMethod));
                     }
                 } else {
                     $statementsBlockBuilder = new StatementsBlockBuilder(array($this->getLetStatement()), false);
                     $constructMethod->setStatementsBlock(new StatementsBlock($statementsBlockBuilder->get()));
                     $compilationContext->classDefinition->getEventsManager()->dispatch('setMethod', array($constructMethod));
                 }
             } else {
                 $statementsBlock = new StatementsBlock(array($this->getLetStatement()->get()));
                 $compilationContext->classDefinition->getEventsManager()->dispatch('setMethod', array(new ClassMethod($compilationContext->classDefinition, array('public'), '__construct', null, $statementsBlock), null));
                 return false;
             }
             //continue
         //continue
         case 'null':
             $this->declareProperty($compilationContext, $this->_defaultValue['type'], null);
             break;
         case 'static-constant-access':
             $expression = new Expression($this->_defaultValue);
             $compiledExpression = $expression->compile($compilationContext);
             $this->declareProperty($compilationContext, $compiledExpression->getType(), $compiledExpression->getCode());
             break;
         default:
             throw new CompilerException('Unknown default type: ' . $this->_defaultValue['type'], $this->_original);
     }
 }