/** * $a &= $b; * * @param \PhpParser\Node\Expr\AssignRef $expr * @param Context $context * @return CompiledExpression */ protected function compile($expr, Context $context) { $compiler = $context->getExpressionCompiler(); if ($expr->var instanceof VariableNode) { $name = $expr->var->name; $compiledExpression = $compiler->compile($expr->expr); $symbol = $context->getSymbol($name); if ($symbol) { $symbol->modify($compiledExpression->getType(), $compiledExpression->getValue()); } else { $symbol = new \PHPSA\Variable($name, $compiledExpression->getValue(), $compiledExpression->getType(), $context->getCurrentBranch()); $context->addVariable($symbol); } if ($expr->expr instanceof VariableNode) { $rightVarName = $expr->expr->name; $rightSymbol = $context->getSymbol($rightVarName); if ($rightSymbol) { $rightSymbol->incUse(); $symbol->setReferencedTo($rightSymbol); } else { $context->debug('Cannot fetch variable by name: ' . $rightVarName); } } $symbol->incSets(); return $compiledExpression; } $context->debug('Unknown how to pass symbol by ref'); return new CompiledExpression(); }
/** * @param \PhpParser\Node\Stmt\Catch_ $statement * @param Context $context */ public function compile($statement, Context $context) { $context->addVariable(new Variable($statement->var, null, CompiledExpression::OBJECT)); foreach ($statement->stmts as $stmt) { \PHPSA\nodeVisitorFactory($stmt, $context); } }
/** * Compile function to check it * * @param Context $context * @return bool */ public function compile(Context $context) { if ($this->compiled) { return true; } $context->setFilepath($this->filepath); $this->compiled = true; $context->scopePointer = $this->getPointer(); $context->setScope(null); $context->getEventManager()->fire(Event\StatementBeforeCompile::EVENT_NAME, new Event\StatementBeforeCompile($this->statement, $context)); if (count($this->statement->params) > 0) { /** @var Node\Param $parameter */ foreach ($this->statement->params as $parameter) { $type = CompiledExpression::UNKNOWN; if ($parameter->type) { if (is_string($parameter->type)) { $type = Types::getType($parameter->type); } elseif ($parameter->type instanceof Node\Name) { $type = CompiledExpression::OBJECT; } } $context->addVariable(new Parameter($parameter->name, null, $type, $parameter->byRef)); } } foreach ($this->statement->stmts as $st) { \PHPSA\nodeVisitorFactory($st, $context); } return true; }
/** * @param Context $context * @return boolean|null */ public function compile(Context $context) { $context->getEventManager()->fire(Event\StatementBeforeCompile::EVENT_NAME, new Event\StatementBeforeCompile($this->statement, $context)); $this->compiled = true; $context->scopePointer = $this->getPointer(); /** * It's not needed to compile empty method via it's abstract */ if ($this->isAbstract()) { /** @var ClassDefinition $scope */ $scope = $context->scope; if (!$scope->isAbstract()) { $context->notice('not-abstract-class-with-abstract-method', 'Class must be abstract', $this->statement); } return true; } if ($this->statement->params) { foreach ($this->statement->params as $parameter) { $type = CompiledExpression::UNKNOWN; if ($parameter->type) { if (is_string($parameter->type)) { $type = Types::getType($parameter->type); } elseif ($parameter->type instanceof Node\Name) { $type = CompiledExpression::OBJECT; } } $context->addVariable(new Parameter($parameter->name, null, $type, $parameter->byRef)); } } foreach ($this->statement->stmts as $st) { \PHPSA\nodeVisitorFactory($st, $context); } }
/** * @param Node\Expr\AssignRef $expr * @return CompiledExpression */ protected function passSymbolByRef(Node\Expr\AssignRef $expr) { if ($expr->var instanceof \PhpParser\Node\Expr\List_) { return new CompiledExpression(); } if ($expr->var instanceof Node\Expr\Variable) { $name = $expr->var->name; $expression = new Expression($this->context); $compiledExpression = $expression->compile($expr->expr); $symbol = $this->context->getSymbol($name); if ($symbol) { $symbol->modify($compiledExpression->getType(), $compiledExpression->getValue()); if ($expr->expr instanceof Node\Expr\Variable) { $rightVarName = $expr->expr->name; $rightSymbol = $this->context->getSymbol($rightVarName); if ($rightSymbol) { $rightSymbol->incUse(); $symbol->setReferencedTo($rightSymbol); } else { $this->context->debug('Cannot fetch variable by name: ' . $rightVarName); } } $this->context->debug('Unknown how to pass referenced to symbol: ' . get_class($expr->expr)); } else { $symbol = new Variable($name, $compiledExpression->getValue(), $compiledExpression->getType(), true); $this->context->addVariable($symbol); } $symbol->incSets(); return $compiledExpression; } $this->context->debug('Unknown how to pass symbol by ref'); return new CompiledExpression(); }
/** * @param Context $context * @return boolean|null */ public function compile(Context $context) { $this->compiled = true; $context->scopePointer = $this->getPointer(); if ($this->statement->getDocComment() === null) { $context->notice('missing-docblock', sprintf('Missing docblock for %s() method', $this->name), $this->statement); } /** * It's not needed to compile empty method via it's abstract */ if ($this->isAbstract()) { /** @var ClassDefinition $scope */ $scope = $context->scope; if (!$scope->isAbstract()) { $context->notice('not-abstract-class-with-abstract-method', 'Class must be an abstract', $this->statement); } return true; } if (count($this->statement->stmts) == 0) { return $context->notice('not-implemented-method', sprintf('Method %s() is not implemented', $this->name), $this->statement); } if (count($this->statement->params) > 0) { /** @var Node\Param $parameter */ foreach ($this->statement->params as $parameter) { $context->addVariable(new Parameter($parameter->name, CompiledExpression::UNKNOWN, null, $parameter->byRef)); } } foreach ($this->statement->stmts as $st) { \PHPSA\nodeVisitorFactory($st, $context); } }
/** * @param Node\Expr\Variable $expr * @param mixed $value * @param int $type * @return CompiledExpression */ public function declareVariable(Node\Expr\Variable $expr, $value = null, $type = CompiledExpression::UNKNOWN) { $variable = $this->context->getSymbol($expr->name); if (!$variable) { $variable = new Variable($expr->name, $value, $type, $this->context->getCurrentBranch()); $this->context->addVariable($variable); } return new CompiledExpression($variable->getType(), $variable->getValue(), $variable); }
protected function compileVariableDeclaration(CompiledExpression $variableName, CompiledExpression $value, Context $context) { switch ($variableName->getType()) { case CompiledExpression::STRING: break; default: $context->debug('Unexpected type of Variable name after compile'); return new CompiledExpression(); } $symbol = $context->getSymbol($variableName->getValue()); if ($symbol) { $symbol->modify($value->getType(), $value->getValue()); $context->modifyReferencedVariables($symbol, $value->getType(), $value->getValue()); } else { $symbol = new \PHPSA\Variable($variableName->getValue(), $value->getValue(), $value->getType(), $context->getCurrentBranch()); $context->addVariable($symbol); } $symbol->incSets(); }
/** * @param Node\Expr\Assign $expr * @return CompiledExpression|Expression */ protected function passSymbol(Node\Expr\Assign $expr) { if ($expr->var instanceof \PhpParser\Node\Expr\List_) { return new CompiledExpression(); } if ($expr->var instanceof Node\Expr\Variable) { $name = $expr->var->name; $compiledExpression = new Expression($this->context); $result = $compiledExpression->compile($expr->expr); $symbol = $this->context->getSymbol($name); if ($symbol) { $symbol->modify($result->getType(), $result->getValue()); } else { $symbol = new Variable($name, $result->getValue(), $result->getType()); $this->context->addVariable($symbol); } $symbol->incSets(); return $compiledExpression; } $this->context->debug('Unknown how to pass symbol'); return new CompiledExpression(); }
/** * Compile methods to check it * * @param Context $context */ public function compile(Context $context) { $context->setScope($this); foreach ($this->methods as $method) { $context->clearSymbols(); if (!$method->isStatic()) { $thisPtr = new Variable('this', $this, CompiledExpression::OBJECT); $thisPtr->incGets(); $context->addVariable($thisPtr); } $method->compile($context); $symbols = $context->getSymbols(); if (count($symbols) > 0) { foreach ($symbols as $name => $variable) { if ($variable->isUnused()) { $context->warning('unused-variable', sprintf('Unused variable $%s in method %s()', $variable->getName(), $method->getName())); } } } } }
/** * Compile function to check it * * @param Context $context * @return bool */ public function compile(Context $context) { if ($this->compiled) { return true; } $context->setFilepath($this->filepath); $this->compiled = true; $context->clearSymbols(); $context->scopePointer = $this->getPointer(); $context->setScope(null); if (count($this->statement->stmts) == 0) { return $context->notice('not-implemented-function', sprintf('Closure %s() is not implemented', $this->name), $this->statement); } if (count($this->statement->params) > 0) { /** @var Node\Param $parameter */ foreach ($this->statement->params as $parameter) { $type = CompiledExpression::UNKNOWN; if ($parameter->type) { if (is_string($parameter->type)) { $type = Types::getType($parameter->type); } elseif ($parameter->type instanceof Node\Name) { $type = CompiledExpression::OBJECT; } } $context->addVariable(new Parameter($parameter->name, null, $type, $parameter->byRef)); } } foreach ($this->statement->stmts as $st) { \PHPSA\nodeVisitorFactory($st, $context); } return true; }
/** * @param Context $context * @return $this */ public function compile(Context $context) { if ($this->compiled) { return true; } $this->compiled = true; $context->setFilepath($this->filepath); $context->setScope($this); $context->getEventManager()->fire(Event\StatementBeforeCompile::EVENT_NAME, new Event\StatementBeforeCompile($this->statement, $context)); // Compile event for properties foreach ($this->properties as $property) { if (!$property->default) { continue; } // fire expression event for property default $context->getEventManager()->fire(Event\ExpressionBeforeCompile::EVENT_NAME, new Event\ExpressionBeforeCompile($property->default, $context)); } // Compile event for PropertyProperty foreach ($this->properties as $property) { $context->getEventManager()->fire(Event\StatementBeforeCompile::EVENT_NAME, new Event\StatementBeforeCompile($property, $context)); } // Compile event for constants foreach ($this->constants as $const) { $context->getEventManager()->fire(Event\StatementBeforeCompile::EVENT_NAME, new Event\StatementBeforeCompile($const, $context)); } // Compiler event for property statements foreach ($this->propertyStatements as $prop) { $context->getEventManager()->fire(Event\StatementBeforeCompile::EVENT_NAME, new Event\StatementBeforeCompile($prop, $context)); } // Compile each method foreach ($this->methods as $method) { $context->clearSymbols(); if (!$method->isStatic()) { $thisPtr = new Variable('this', $this, CompiledExpression::OBJECT); $thisPtr->incGets(); $context->addVariable($thisPtr); } $method->compile($context); $symbols = $context->getSymbols(); if (count($symbols) > 0) { foreach ($symbols as $name => $variable) { if ($variable->isUnused()) { $context->warning('unused-' . $variable->getSymbolType(), sprintf('Unused ' . $variable->getSymbolType() . ' $%s in method %s()', $variable->getName(), $method->getName())); } } } } return $this; }