/**
  * @param Expr\ClosureUse $node
  *
  * @return string
  */
 public function convert(Expr\ClosureUse $node)
 {
     if ($node->byRef) {
         $this->logger->logNode('Zephir not support reference parameters for now. Stay tuned for https://github.com/phalcon/zephir/issues/203', $node, $this->dispatcher->getMetadata()->getClass());
     }
     return $this->reservedWordReplacer->replace($node->var);
 }
 /**
  * @param Stmt\ClassMethod $node
  *
  * @return string
  */
 public function convert(Stmt\ClassMethod $node)
 {
     $types = $this->typeFinder->getTypes($node, $this->dispatcher->getMetadata());
     foreach ($node->params as $param) {
         if ($param->byRef === true) {
             $this->logger->logIncompatibility('reference', sprintf('Reference not supported in parametter (var "%s")', $param->name), $param, $this->dispatcher->getMetadata()->getClass());
         }
     }
     if ($node->byRef) {
         $this->logger->logIncompatibility('reference', 'Reference not supported', $node, $this->dispatcher->getMetadata()->getClass());
     }
     $this->dispatcher->setLastMethod($node->name);
     $stmt = $this->dispatcher->pModifiers($node->type) . 'function ' . $node->name . '(';
     $varsInMethodSign = array();
     if (isset($types['params']) === true) {
         $params = array();
         foreach ($types['params'] as $type) {
             $varsInMethodSign[] = $type['name'];
             $stringType = $this->printType($type);
             $params[] = (!empty($stringType) ? $stringType . ' ' : '') . '' . $type['name'] . ($type['default'] === null ? '' : ' = ' . $this->dispatcher->p($type['default']));
         }
         $stmt .= implode(', ', $params);
     }
     $stmt .= ')';
     $stmt .= $this->printReturn($node, $types);
     $stmt .= (null !== $node->stmts ? "\n{" . $this->printVars($node, $varsInMethodSign) . $this->dispatcher->pStmts($node->stmts) . "\n}" : ';') . "\n";
     return $stmt;
 }
 /**
  * @param null|string $lastMethod
  * @param integer     $number
  */
 public function createClosureClass(Expr\Closure $node, $lastMethod, $number)
 {
     $this->logger->trace(__METHOD__ . ' ' . __LINE__, $node, $this->dispatcher->getMetadata()->getFullQualifiedNameClass());
     $name = $this->dispatcher->getMetadata()->getClass() . $lastMethod . "Closure" . $this->N2L($number);
     $this->logger->logNode(sprintf('Closure does not exist in Zephir, class "%s" with __invoke is created', $name), $node, $this->dispatcher->getMetadata()->getFullQualifiedNameClass());
     return array('name' => $name, 'code' => $this->createClass($name, $this->dispatcher->getMetadata()->getNamespace(), $node));
 }
Beispiel #4
0
 /**
  * Pretty prints a node.
  *
  * @param \PhpParser\Node $node Node to be pretty printed
  *
  * @return string Pretty printed node
  */
 public function p($node)
 {
     if (null === $node) {
         return;
     }
     $this->logger->trace('p' . $node->getType(), $node, $this->getMetadata()->getFullQualifiedNameClass());
     return $this->getClass('p' . $node->getType())->convert($node);
 }
Beispiel #5
0
 /**
  * @param Stmt\If_ $node
  *
  * @return string
  */
 public function convert(Stmt\If_ $node)
 {
     $collected = $this->assignManipulator->collectAssignInCondition($node->cond);
     $node->cond = $this->assignManipulator->transformAssignInConditionTest($node->cond);
     if (empty($node->stmts)) {
         $node->stmts = array(new Stmt\Echo_(array(new Scalar\String("not allowed"))));
         $this->logger->logNode('Empty if not allowed, add "echo not allowed"', $node, $this->dispatcher->getMetadata()->getClass());
     }
     return implode(";\n", $collected['extracted']) . "\n" . 'if ' . $this->dispatcher->p($node->cond) . ' {' . $this->dispatcher->pStmts($node->stmts) . "\n" . '}' . $this->implodeElseIfs($node);
 }
 /**
  * @param Stmt\If_ $node
  *
  * @return string
  */
 public function convert(Stmt\If_ $node)
 {
     $collected = $this->assignManipulator->collectAssignInCondition($node->cond);
     $node->cond = $this->assignManipulator->transformAssignInConditionTest($node->cond);
     if (empty($node->stmts)) {
         $node->stmts = array(new Stmt\Echo_(array(new Scalar\String_('not allowed'))));
         $this->logger->logIncompatibility('Empty if', 'Empty if not allowed, add "echo not allowed"', $node, $this->dispatcher->getMetadata()->getFullQualifiedNameClass());
     }
     return $collected->getCollected() . 'if ' . $this->dispatcher->p($node->cond) . ' {' . $this->dispatcher->pStmts($node->stmts) . "\n" . '}' . $this->implodeElseIfs($node);
 }
 /**
  * Pretty prints a node.
  *
  * @param \PhpParser\Node $node Node to be pretty printed
  *
  * @return string Pretty printed node
  */
 public function p()
 {
     $args = func_get_args();
     $node = $args[0];
     if (null === $node) {
         return;
     }
     $this->logger->trace('p' . $node->getType(), $node, $this->getMetadata()->getFullQualifiedNameClass());
     $class = $this->getClass('p' . $node->getType());
     return call_user_func_array(array($class, "convert"), $args);
 }
 /**
  * @param Stmt\Property $node
  *
  * @return string
  */
 public function convert(Stmt\Property $node)
 {
     foreach ($node->props as $key => $prop) {
         $prop->name = $this->reservedWordReplacer->replace($prop->name);
         $node->props[$key] = $prop;
     }
     if ($node->props[0]->default instanceof Expr\Array_ && $node->isStatic() === true) {
         $node->type = $node->type - Stmt\Class_::MODIFIER_STATIC;
         $this->dispatcher->moveToNonStaticVar($node->props[0]->name);
         $this->logger->logNode("Static attribute default array not supported in zephir, (see #188). Changed into non static. ", $node, $this->dispatcher->getMetadata()->getFullQualifiedNameClass());
     }
     return $this->dispatcher->pModifiers($node->type) . $this->dispatcher->pCommaSeparated($node->props) . ';';
 }
 /**
  * @param string $dir
  *
  * @return array
  */
 public function convertDirectory($dir, $recursive = true, $filterFileName = null)
 {
     $zephirCode = array();
     $fileExtension = '.php';
     $classes = array();
     $files = $this->findFiles($dir);
     $count = iterator_count($files);
     $this->logger->log('Collect class names');
     $progress = $this->logger->progress($count);
     foreach ($files as $filei) {
         $file = $filei[0];
         try {
             $classes[$file] = $this->classCollector->collect($this->parser->parse(file_get_contents($file)), $file);
         } catch (\Exception $e) {
             $this->logger->log(sprintf('<error>Could not convert file' . "\n" . '"%s"' . "\n" . 'cause : %s %s %s</error>' . "\n", $file, $e->getMessage(), $e->getFile(), $e->getLine()));
         }
         $progress->advance();
     }
     $progress->finish();
     $this->logger->log("\nConvert php to zephir");
     $progress = $this->logger->progress(count($classes));
     foreach ($classes as $phpFile => $class) {
         if ($filterFileName !== null) {
             if (basename($phpFile, '.php') !== $filterFileName) {
                 continue;
             }
         }
         $phpCode = file_get_contents($phpFile);
         $fileName = basename($phpFile, '.php');
         try {
             $converted = $this->convertCode($phpCode, $phpFile, $classes);
             $converted['class'] = $class;
         } catch (\Exception $e) {
             $this->logger->log(sprintf('Could not convert file "%s" cause : %s %s %s' . "\n", $phpFile, $e->getMessage(), $e->getFile(), $e->getLine()));
             $progress->advance();
             continue;
         }
         $zephirCode[$phpFile] = array_merge($converted, array('phpPath' => substr($phpFile, 0, strrpos($phpFile, '/')), 'fileName' => $fileName, 'fileDestination' => $converted['class'] . '.zep'));
         $zephirCode[$phpFile]['fileDestination'] = strtolower(str_replace('\\', '/', $zephirCode[$phpFile]['fileDestination']));
         foreach ($converted['additionalClass'] as $aditionalClass) {
             $zephirCode[$phpFile . $aditionalClass['name']] = array_merge(array('fileName' => $aditionalClass['name'], 'zephir' => $aditionalClass['code'], 'fileDestination' => strtolower(str_replace('\\', '/', $converted['namespace']) . '/' . $aditionalClass['name']) . '.zep', 'destination' => strtolower(str_replace('\\', '/', $converted['namespace']) . '/')));
         }
         $progress->advance();
     }
     $progress->finish();
     $this->logger->log("\n");
     return $zephirCode;
 }
Beispiel #10
0
 /**
  * @param string $actualNamespace
  * @param Tag    $tag
  *
  * @return string
  */
 private function findType(Tag $tag, $actualNamespace, array $use, array $classes)
 {
     $rawType = $tag->getType();
     if ($rawType === 'integer') {
         $rawType = 'int';
     }
     $primitiveTypes = array('string', 'int', 'integer', 'float', 'double', 'bool', 'boolean', 'array', 'null', 'callable', 'scalar', 'void', 'object');
     $excludedType = array('mixed', 'callable', 'callable[]', 'scalar', 'scalar[]', 'void', 'object', 'self', 'resource', 'true');
     if (in_array($rawType, $excludedType) === true || count(explode('|', $rawType)) !== 1) {
         return array('value' => '', 'isClass' => false);
     }
     $arrayOfPrimitiveTypes = array_map(function ($val) {
         return $val . '[]';
     }, $primitiveTypes);
     if (preg_match("/^[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*\$/", $rawType) === 0) {
         // this is a typo
         $this->logger->log(sprintf('Type "%s" does not exist in docblock', $rawType));
         $type = array('value' => '', 'isClass' => false);
     } elseif (in_array(strtolower($rawType), $primitiveTypes)) {
         $type = array('value' => strtolower($rawType), 'isClass' => false);
     } elseif (in_array(strtolower($rawType), $arrayOfPrimitiveTypes)) {
         $type = array('value' => strtolower($rawType), 'isClass' => false);
     } else {
         // considered as class
         $type = array('value' => $rawType, 'isClass' => true);
     }
     return $type;
 }
Beispiel #11
0
 /**
  * @param Assign $node
  * @param Expr   $leftNode
  * @param Expr   $rightNode
  * @param string $operatorString
  */
 private function arrayDimFetchCase($node, $leftNode, $rightNode, $operatorString, $precedence, $associativity)
 {
     $this->logger->trace(self::getType() . ' ' . __LINE__, $node, $this->dispatcher->getMetadata()->getFullQualifiedNameClass());
     $head = '';
     if ($leftNode instanceof ArrayDimFetch) {
         if (false === ($splitedArray = $this->arrayManipulator->arrayNeedToBeSplit($leftNode))) {
             $leftString = $this->dispatcher->pPrec($leftNode, $precedence, $associativity, 1);
         } else {
             $result = $this->dispatcher->pExpr_ArrayDimFetch($leftNode, true);
             $head .= $result['head'];
             $leftString = $result['lastExpr'];
         }
     } else {
         $leftString = $this->dispatcher->pPrec($leftNode, $precedence, $associativity, -1);
     }
     if ($rightNode instanceof ArrayDimFetch) {
         if (false === ($splitedArray = $this->arrayManipulator->arrayNeedToBeSplit($rightNode))) {
             $rightString = $this->dispatcher->pPrec($rightNode, $precedence, $associativity, 1);
         } else {
             $result = $this->dispatcher->pExpr_ArrayDimFetch($rightNode, true);
             $head .= $result['head'];
             $rightString = $result['lastExpr'];
         }
     } elseif ($this->isSomething($rightNode)) {
         $this->logger->trace(self::getType() . ' ' . __LINE__, $node, $this->dispatcher->getMetadata()->getFullQualifiedNameClass());
         // @TODO add test case for each
         $rightString = $this->dispatcher->pPrec($rightNode, $precedence, $associativity, 1);
     } else {
         $head .= $this->dispatcher->pPrec($rightNode, $precedence, $associativity, 1) . ";\n";
         $rightString = $this->dispatcher->p($rightNode->var);
     }
     return $head . 'let ' . $leftString . $operatorString . $rightString;
 }
 public function convert(Expr\ArrayDimFetch $node, $returnAsArray = false)
 {
     $collected = $this->arrayManipulator->arrayNeedToBeSplit($node);
     if ($node->var instanceof Expr\StaticPropertyFetch) {
         if ($node->var->class->parts[0] === 'self') {
             $node->var = new Expr\PropertyFetch(new Expr\Variable('this'), $node->var->name);
             $this->logger->logNode("Change StaticProperty into PropertyFetch due to #188", $node);
         } else {
             $this->logger->logNode("StaticProperty on array not supported, see #188", $node);
         }
     }
     if ($collected !== false) {
         return $this->splitArray($collected, $returnAsArray);
     } else {
         $result = $this->dispatcher->pVarOrNewExpr($node->var) . '[' . (null !== $node->dim ? $this->dispatcher->p($node->dim) : '') . ']';
         if ($returnAsArray === true) {
             return array('head' => '', 'lastExpr' => $result);
         } else {
             return $result;
         }
     }
 }
 /**
  * @param Expr\ArrayDimFetch $node
  */
 private function findComplexArrayDimFetch($node, $collected = array())
 {
     if ($this->isInvalidInArrayDimFetch($node) === true) {
         if ($node->dim instanceof Expr\FuncCall) {
             $this->logger->trace(__METHOD__ . ' ' . __LINE__ . ' Non supported funccall in array', $node, $this->dispatcher->getMetadata()->getClass());
         } else {
             $collected[] = array('expr' => $this->dispatcher->p($node->dim) . ";\n", 'splitTab' => true, 'var' => $this->dispatcher->p($node->dim->var));
         }
     } else {
         if ($node->dim === null) {
             $collected[] = array('expr' => $this->dispatcher->p($node->var), 'splitTab' => false);
         } else {
             $collected[] = array('expr' => $this->dispatcher->p($node->dim), 'splitTab' => false);
         }
     }
     if ($node->var instanceof Expr\ArrayDimFetch) {
         $collected = $this->findComplexArrayDimFetch($node->var, $collected);
     } else {
         $collected[] = $node->var;
     }
     return $collected;
 }
Beispiel #14
0
 /**
  * @param CodeCollectorInterface $codeCollector
  * @param Logger                 $logger
  * @param string                 $filterFileName
  *
  * @return array
  */
 public function convert(CodeCollectorInterface $codeCollector, Logger $logger, $filterFileName = null)
 {
     $zephirCode = array();
     $classes = array();
     $files = $codeCollector->getCode();
     $count = count($files);
     $codes = array();
     $logger->log('Collect class names');
     $progress = $logger->progress($count);
     foreach ($files as $fileName => $fileContent) {
         try {
             $codes[$fileName] = $this->parser->parse($fileContent);
             $classes[$fileName] = $this->classCollector->collect($codes[$fileName], $fileName);
         } catch (\Exception $e) {
             $logger->log(sprintf('<error>Could not convert file' . "\n" . '"%s"' . "\n" . 'cause : %s %s %s</error>' . "\n", $fileName, $e->getMessage(), $e->getFile(), $e->getLine()));
         }
         $progress->advance();
     }
     $progress->finish();
     $logger->log("\nConvert php to zephir");
     $progress = $logger->progress(count($classes));
     foreach ($classes as $phpFile => $class) {
         if ($filterFileName !== null) {
             if (basename($phpFile, '.php') !== $filterFileName) {
                 continue;
             }
         }
         $phpCode = $codes[$phpFile];
         $zephirFile = pathinfo($phpFile, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR . pathinfo($phpFile, PATHINFO_FILENAME) . '.zep';
         $fileName = basename($phpFile, '.php');
         try {
             $converted = $this->convertCode($phpCode, $this->classCollector, $logger, $phpFile, $classes);
             $converted['class'] = $class;
         } catch (\Exception $e) {
             $logger->log(sprintf('Could not convert file "%s" cause : %s %s %s' . "\n", $phpFile, $e->getMessage(), $e->getFile(), $e->getLine()));
             $progress->advance();
             continue;
         }
         $zephirCode[$phpFile] = array_merge($converted, array('phpPath' => substr($phpFile, 0, strrpos($phpFile, '/')), 'fileName' => $fileName, 'fileDestination' => $zephirFile));
         $zephirCode[$phpFile]['fileDestination'] = str_replace('\\', '/', $zephirCode[$phpFile]['fileDestination']);
         foreach ($converted['additionalClass'] as $aditionalClass) {
             $zephirCode[$phpFile . $aditionalClass['name']] = array_merge(array('fileName' => $aditionalClass['name'], 'zephir' => $aditionalClass['code'], 'fileDestination' => str_replace('\\', '/', $converted['namespace']) . '/' . $aditionalClass['name'] . '.zep', 'destination' => str_replace('\\', '/', $converted['namespace']) . '/'));
         }
         $progress->advance();
     }
     $progress->finish();
     $logger->log("\n");
     return $zephirCode;
 }