/** * @param array $stmts * @param ClassCollector $classCollector * @param Logger $logger * @param string $fileName * @param array $classCollected * * @return array */ public function nodeToZephir(array $stmts, ClassCollector $classCollector, Logger $logger, $fileName = null, array $classCollected = array()) { $classInformation = ClassInformationFactory::getInstance(); $metadata = $classInformation->getClassesMetdata($stmts); $this->implementsExist($metadata, $classCollector); return array('code' => $this->dispatcher->convert($stmts, $metadata, $classCollector, $logger), 'namespace' => $metadata->getNamespace(), 'additionalClass' => $this->findAdditionalClasses($stmts, $logger)); }
/** * @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); }
public function convert(Stmt\Do_ $node) { $condition = clone $node; $collected = $this->assignManipulator->collectAssignInCondition($condition->cond); $node->cond = $this->assignManipulator->transformAssignInConditionTest($node->cond); return 'do {' . $this->dispatcher->pStmts($node->stmts) . $collected->getCollected() . "\n" . '} while (' . $this->dispatcher->p($node->cond) . ');'; }
public function convert($node) { if ($node instanceof Expr) { return '{' . $this->dispatcher->p($node) . '}'; } else { return $this->reservedWordReplacer->replace($node); } }
public function convert(Stmt\Do_ $node) { $condition = clone $node; $collected = $this->assignManipulator->collectAssignInCondition($condition->cond); $collected = !empty($collected['extracted']) ? "\n" . implode("\n", $collected['extracted']) : ''; $node->cond = $this->assignManipulator->transformAssignInConditionTest($node->cond); return 'do {' . $this->dispatcher->pStmts($node->stmts) . $collected . "\n" . '} while (' . $this->dispatcher->p($node->cond) . ');'; }
/** * @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; } return $this->dispatcher->pModifiers($node->type) . $this->dispatcher->pCommaSeparated($node->props) . ';'; }
/** * @param Expr\Array_ $node * @param bool $returnAsArray * * @return string|array */ public function convert(Expr\Array_ $node, $returnAsArray = false) { $collected = $this->assignManipulator->collectAssignInCondition($node->items); $node->items = $this->assignManipulator->transformAssignInConditionTest($node->items); $collected['expr'] = '[' . $this->dispatcher->pCommaSeparated($node->items) . ']'; if ($returnAsArray === true) { return $collected; } else { return (!empty($collected['extracted']) ? implode(";\n", $collected['extracted']) . "\n" : '') . $collected['expr']; } }
/** * @param Expr\FuncCall $node * * @return string */ public function convert(Expr\FuncCall $node) { $collected = $this->assignManipulator->collectAssignInCondition($node->args); $node->args = $this->assignManipulator->transformAssignInConditionTest($node->args); if ($node->name instanceof Expr\Variable) { $instanciation = '{' . $this->dispatcher->p($node->name) . '}'; } else { $instanciation = $this->dispatcher->p($node->name); } return $collected->getCollected() . $instanciation . '(' . $this->dispatcher->pCommaSeparated($node->args) . ')'; }
/** * @param Expr\Array_ $node * @param bool $returnAsArray * * @return string|array */ public function convert(Expr\Array_ $node, $returnAsArray = false) { $collected = $this->assignManipulator->collectAssignInCondition($node->items); $node->items = $this->assignManipulator->transformAssignInConditionTest($node->items); $collected->setExpr('[' . $this->dispatcher->pCommaSeparated($node->items) . ']'); if ($returnAsArray === true) { return $collected; } else { return $collected->getCollected() . $collected->getExpr(); } }
/** * @param Expr\FuncCall $node * * @return string */ public function convert(Expr\FuncCall $node) { $collected = $this->assignManipulator->collectAssignInCondition($node->args); $node->args = $this->assignManipulator->transformAssignInConditionTest($node->args); if ($node->name instanceof Expr\Variable) { $instanciation = '{' . $this->dispatcher->p($node->name) . '}'; } else { $instanciation = $this->dispatcher->p($node->name); } return (!empty($collected['extracted']) ? implode(";\n", $collected['extracted']) . "\n" : '') . $instanciation . '(' . $this->dispatcher->pCommaSeparated($node->args) . ')'; }
public function convert(Stmt\Class_ $node) { $this->classManipulator->registerClassImplements($node); $node->name = $this->reservedWordReplacer->replace($node->name); $addArrayPlusMethod = false; foreach ($this->nodeFetcher->foreachNodes($node->stmts) as $stmt) { if ($stmt['node'] instanceof AssignOp\Plus && $stmt['node']->expr instanceof Array_) { $addArrayPlusMethod = true; break; } } return $this->dispatcher->pModifiers($node->type) . 'class ' . $node->name . (null !== $node->extends ? ' extends ' . $this->dispatcher->p($node->extends) : '') . (!empty($node->implements) ? ' implements ' . $this->dispatcher->pCommaSeparated($node->implements) : '') . "\n" . '{' . $this->dispatcher->pStmts($node->stmts) . "\n" . ($addArrayPlusMethod === true ? $this->printArrayPlusMethod() : '') . '}'; }
/** * @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 Expr\Ternary $node * @param string $returnAsArray * * @return string */ public function convert(Expr\Ternary $node, $returnAsArray = false) { // a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator. // this is okay because the part between ? and : never needs parentheses. $collected = $this->assignManipulator->collectAssignInCondition($node->cond); $node->cond = $this->assignManipulator->transformAssignInConditionTest($node->cond); $collected['expr'] = $this->dispatcher->pInfixOp('Expr_Ternary', $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->dispatcher->p($node->if) . ' ' : '') . ': ', $node->else); if ($returnAsArray === true) { return $collected; } else { return implode(";\n", $collected['extracted']) . "\n" . $collected['expr']; } }
/** * @param string $name * @param string $namespace */ private function createClass($name, $namespace, Expr\Closure $node) { $class = "namespace {$namespace};\n\nclass {$name}\n{\n"; foreach ($node->uses as $use) { $class .= " private " . $use->var . ";\n"; } $class .= "\n public function __construct(" . (!empty($node->uses) ? '' . $this->dispatcher->pCommaSeparated($node->uses) : '') . ")\n {\n "; foreach ($node->uses as $use) { $class .= " let this->" . $use->var . " = " . $use->var . ";\n"; } $class .= "\n }\n\n public function __invoke(" . $this->dispatcher->pCommaSeparated($node->params) . ")\n {" . $this->dispatcher->pStmts($this->convertUseToMemberAttribute($node->stmts, $node->uses)) . "\n }\n}\n "; return $class; }
public function convert(Stmt\Interface_ $node) { $node->name = $this->reservedWordReplacer->replace($node->name); $extendsStmt = ''; if (!empty($node->extends)) { $extendsStmt = ' extends '; $extends = array(); foreach ($node->extends as $extend) { $extends[] = $this->classManipulator->findRightClass($extend, $this->dispatcher->getMetadata()); } $extendsStmt .= implode(', ', $extends); } return 'interface ' . $node->name . $extendsStmt . "\n" . '{' . $this->dispatcher->pStmts($node->stmts) . "\n" . '}'; }
/** * @param Stmt\If_ $node * * @return string */ private function implodeElseIfs(Stmt\If_ $node) { $elseCount = 0; $toReturn = ''; foreach ($node->elseifs as $elseIf) { $collected = $this->assignManipulator->collectAssignInCondition($elseIf->cond); if (!empty($collected['extracted'])) { $elseCount++; $toReturn .= ' else { ' . "\n" . $this->dispatcher->p(new Stmt\If_($elseIf->cond, array('stmts' => $elseIf->stmts))) . "\n"; } else { $toReturn .= $this->dispatcher->pStmt_ElseIf($elseIf); } } $toReturn .= null !== $node->else ? $this->dispatcher->p($node->else) : ''; return $toReturn . str_repeat('}', $elseCount); }
/** * @param mixed $stmt * @param ArrayDto $arrayDto * @param string $parentClass * * @return array */ private function extract($stmt, ArrayDto $arrayDto, array $parentClass = array()) { if ($stmt instanceof Expr\Assign) { if ($stmt->expr instanceof Expr\BinaryOp) { $stmt->expr = $stmt->expr->left; $arrayDto->addCollected($this->dispatcher->pExpr_Assign($stmt)); } else { $arrayDto->addCollected($this->dispatcher->pExpr_Assign($stmt)); } } elseif ($this->isVarModification($stmt) && !in_array("PhpParser\\Node\\Expr\\Assign", $parentClass)) { $arrayDto->addCollected($this->dispatcher->p($stmt)); } elseif ($this->isVarCreation($stmt) && !in_array("PhpParser\\Node\\Expr\\ArrayItem", $parentClass) && !in_array("PhpParser\\Node\\Expr\\Assign", $parentClass)) { $arrayDto->addCollected('let tmpArray' . md5(serialize($stmt->items)) . ' = ' . $this->dispatcher->p($stmt)); } return $arrayDto; }
/** * @param array|\ArrayIterator $node * * @return array|\ArrayIterator */ private function findModifiedToNonStaticVar($node) { if (is_array($node) === true) { $nodes = $node; } elseif (is_string($node) === false && method_exists($node, 'getIterator') === true) { $nodes = $node->getIterator(); } else { return $node; } foreach ($nodes as $key => &$stmt) { if ($stmt instanceof Expr\ClassConstFetch) { $isMovedToNonStatic = $this->dispatcher->isMovedToNonStaticVar($stmt->name); if ($isMovedToNonStatic === true) { $var = new Expr\Variable('this->' . $stmt->name); if (is_array($node) === true) { $node[$key] = $var; } else { $node->{$key} = $var; } } } else { $stmt = $this->findModifiedToNonStaticVar($stmt); if (is_array($node) === true) { $node[$key] = $stmt; } else { $node->{$key} = $stmt; } } } return $node; }
/** * @param mixed $stmt * @param array $collected * @param string $parentClass * * @return array */ private function extract($stmt, array $collected, $parentClass = '') { if ($stmt instanceof Expr\Assign) { if ($stmt->expr instanceof Expr\BinaryOp) { $stmt->expr = $stmt->expr->left; $collected['extracted'][] = $this->dispatcher->pExpr_Assign($stmt) . ";"; } else { $collected['extracted'][] = $this->dispatcher->pExpr_Assign($stmt) . ";"; } } elseif ($this->isVarModification($stmt)) { $collected['extracted'][] = $this->dispatcher->p($stmt) . ";"; } elseif ($this->isVarCreation($stmt) && $parentClass != "PhpParser\\Node\\Expr\\ArrayItem") { $collected['extracted'][] = 'let tmpArray' . md5(serialize($stmt->items)) . ' = ' . $this->dispatcher->p($stmt) . ";"; } return $collected; }
/** * @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; }
/** * @param Stmt\ClassMethod $node * * @return string */ public function convert(Stmt\ClassMethod $node) { $types = $this->typeFinder->getTypes($node, $this->dispatcher->getMetadata()); $this->dispatcher->setLastMethod($node->name); $stmt = $this->dispatcher->pModifiers($node->type) . 'function ' . ($node->byRef ? '&' : '') . $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; }
private function addAsTmp(array $createAsTmp, $varname) { if (!isset(self::$createdVars[$this->dispatcher->getLastMethod()])) { self::$createdVars[$this->dispatcher->getLastMethod()] = array(); } if (isset(self::$createdVars[$this->dispatcher->getLastMethod()][$varname])) { self::$createdVars[$this->dispatcher->getLastMethod()][$varname]++; $createAsTmp[$varname] = self::$createdVars[$this->dispatcher->getLastMethod()][$varname]; } else { self::$createdVars[$this->dispatcher->getLastMethod()][$varname] = 1; $createAsTmp[$varname] = 1; } return $createAsTmp; }
/** * @param bool $returnAsArray */ private function splitArray(array $collected, $returnAsArray) { $var = $collected[0]; unset($collected[0]); $lastExpr = null; $head = "var tmpArray;\n"; $lastSplitTable = true; foreach ($collected as $expr) { if ($expr['splitTab'] === true) { $head .= $expr['expr']; if ($expr !== end($collected)) { $head .= 'let tmpArray = '; $head .= $this->dispatcher->p($var) . '[' . $expr['var'] . ']'; } else { $lastExpr = $this->dispatcher->p($var) . '[' . $expr['var'] . ']'; } $lastSplitTable = true; } else { if ($lastSplitTable === true) { if ($expr !== end($collected)) { $head .= 'let tmpArray = '; $head .= $this->dispatcher->p($var) . '[' . $expr['expr'] . ']'; } else { $lastExpr = $this->dispatcher->p($var) . '[' . $expr['expr'] . ']'; } } } if ($expr !== end($collected)) { $head .= ';' . "\n"; } } if ($returnAsArray === true) { return array('head' => $head, 'lastExpr' => $lastExpr); } else { return $head . $lastExpr; } }
/** * @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; }
/** * @param Name $node * * @return Ambigous <string, unknown> */ public function convert(Name $node) { return $this->classManipulator->findRightClass($node, $this->dispatcher->getMetadata()); }
/** * @param Expr\MethodCall $node * * @return string */ public function convert(Expr\MethodCall $node) { $collected = $this->assignManipulator->collectAssignInCondition($node->args); $node->args = $this->assignManipulator->transformAssignInConditionTest($node->args); return $collected->getCollected() . $this->dispatcher->pVarOrNewExpr($node->var) . '->' . $this->dispatcher->pObjectProperty($node->name) . '(' . $this->dispatcher->pCommaSeparated($node->args) . ')'; }
/** * @param Stmt\While_ $node * * @return string */ public function convert(Stmt\While_ $node) { $collected = $this->assignManipulator->collectAssignInCondition($node->cond); $node->cond = $this->assignManipulator->transformAssignInConditionTest($node->cond); return implode(";\n", $collected['extracted']) . "\n" . 'while (' . $this->dispatcher->p($node->cond) . ') {' . $this->dispatcher->pStmts($node->stmts) . "\n" . implode(";\n", $collected['extracted']) . "\n" . '}'; }
/** * @param Stmt\Return_ $node * * @return string */ public function convert(Stmt\Return_ $node) { $collected = $this->assignManipulator->collectAssignInCondition($node->expr); $node->expr = $this->assignManipulator->transformAssignInConditionTest($node->expr); return implode(";\n", $collected['extracted']) . "\n" . 'return' . (null !== $node->expr ? ' ' . $this->dispatcher->p($node->expr) : '') . ';'; }
/** * @param \ArrayIterator|array $node * @param array $vars * * @return \ArrayIterator|array */ private function collectVars($node, array $vars = array()) { $noFetcher = new NodeFetcher(); foreach ($noFetcher->foreachNodes($node) as &$stmt) { if ($stmt['node'] instanceof Expr\Assign) { if ($stmt['node']->var instanceof Expr\PropertyFetch === false && $stmt['node']->var instanceof Expr\StaticPropertyFetch === false && $stmt['node']->var instanceof Expr\ArrayDimFetch === false && $stmt['node']->var instanceof Expr\List_ === false) { if (is_object($stmt['node']->var->name) === false) { // if true it is a dynamic var $vars[] = $stmt['node']->var->name; } } elseif ($stmt['node']->var instanceof Expr\List_ === true) { $varInList = array(); foreach ($stmt['node']->var->vars as $var) { if (null !== $var) { $varInList[] = $this->dispatcher->p($var); if ($var instanceof Expr\ArrayDimFetch === false) { $vars[] = $this->dispatcher->p($var); } } } $vars[] = 'tmpList' . str_replace(array('[', ']', '"'), '', implode('', $varInList)); } } elseif ($stmt['node'] instanceof Stmt\Foreach_) { if (null !== $stmt['node']->keyVar) { $vars[] = $stmt['node']->keyVar->name; } $vars[] = $stmt['node']->valueVar->name; } elseif ($stmt['node'] instanceof Stmt\For_) { foreach ($stmt['node']->init as $init) { if ($init instanceof Expr\Assign) { $vars[] = $init->var->name; } } } elseif ($stmt['node'] instanceof Stmt\If_) { foreach ($this->nodeFetcher->foreachNodes($stmt['node']->cond) as $nodeData) { $node = $nodeData['node']; if ($node instanceof Expr\Array_) { $vars[] = 'tmpArray' . md5(serialize($node->items)); } } } elseif ($stmt['node'] instanceof Stmt\Catch_) { $vars[] = $stmt['node']->var; } elseif ($stmt['node'] instanceof Stmt\Return_ && $stmt['node']->expr instanceof Expr\Array_) { $vars[] = 'tmpArray' . md5(serialize($stmt['node']->expr->items)); } elseif ($stmt['node'] instanceof Stmt\Static_) { foreach ($stmt['node']->vars as $var) { $vars[] = $var->name; } } elseif ($stmt['node'] instanceof Arg && $stmt['node']->value instanceof Expr\Array_) { $vars[] = 'tmpArray' . md5(serialize($stmt['node']->value->items)); } if ($stmt['node'] instanceof Expr\ArrayDimFetch && !in_array("PhpParser\\Node\\Expr\\ArrayDimFetch", $stmt['parentClass'])) { $varCreatedInArray = $this->dispatcher->pExpr_ArrayDimFetch($stmt['node'], true); foreach ($varCreatedInArray['vars'] as $var) { $vars[] = $var; } } } $vars = array_map(array($this->reservedWordReplacer, 'replace'), $vars); return $vars; }
/** * @param Stmt\Return_ $node * * @return string */ public function convert(Stmt\Return_ $node) { $collected = $this->assignManipulator->collectAssignInCondition($node->expr); $node->expr = $this->assignManipulator->transformAssignInConditionTest($node->expr); return $collected->getCollected() . 'return' . (null !== $node->expr ? ' ' . $this->dispatcher->p($node->expr) : '') . ';'; }