Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 28 additions & 26 deletions Library/Detectors/ReadDetector.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@
* the LICENSE file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Zephir\Detectors;

use Zephir\Variable;

use function in_array;
use function is_array;

/**
* ReadDetector.
*
Expand All @@ -23,52 +28,49 @@
*/
class ReadDetector
{
public function detect($variable, array $expression)
// TODO: Move params from detect() to constructor()

/**
* @param string $variable
* @param array $expression
* @return bool
*/
public function detect(string $variable, array $expression): bool
{
if (!isset($expression['type'])) {
return false;
}

/* Remove branch from variable name */
/**
* Remove branch from variable name
*/
$pos = strpos($variable, Variable::BRANCH_MAGIC);
if ($pos > -1) {
$variable = substr($variable, 0, $pos);
}

if ('variable' == $expression['type']) {
if ($variable == $expression['value']) {
return true;
}
if ('variable' === $expression['type'] && $variable === $expression['value']) {
return true;
}

if ('fcall' == $expression['type'] || 'mcall' == $expression['type'] || 'scall' == $expression['type']) {
if (isset($expression['parameters'])) {
foreach ($expression['parameters'] as $parameter) {
if (\is_array($parameter['parameter'])) {
if ('variable' == $parameter['parameter']['type']) {
if ($variable == $parameter['parameter']['value']) {
return true;
}
if (in_array($expression['type'], ['fcall', 'mcall', 'scall']) && isset($expression['parameters'])) {
foreach ($expression['parameters'] as $parameter) {
if (is_array($parameter['parameter'])) {
if ('variable' === $parameter['parameter']['type']) {
if ($variable === $parameter['parameter']['value']) {
return true;
}
}
}
}
}

if (isset($expression['left'])) {
if (\is_array($expression['left'])) {
if (true === $this->detect($variable, $expression['left'])) {
return true;
}
}
if (isset($expression['left']) && is_array($expression['left']) && $this->detect($variable, $expression['left'])) {
return true;
}

if (isset($expression['right'])) {
if (\is_array($expression['right'])) {
if (true === $this->detect($variable, $expression['right'])) {
return true;
}
}
if (isset($expression['right']) && is_array($expression['right']) && $this->detect($variable, $expression['right'])) {
return true;
}

return false;
Expand Down
75 changes: 41 additions & 34 deletions Library/Expression.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Zephir;

use ReflectionException;
use Zephir\Exception\CompilerException;
use Zephir\Expression\Closure;
use Zephir\Expression\ClosureArrow;
Expand Down Expand Up @@ -64,32 +65,35 @@
use Zephir\Operators\Unary\MinusOperator;
use Zephir\Operators\Unary\NotOperator;

use function strlen;

/**
* Zephir\Expressions.
*
* Represents an expression. Most language constructs in a language are expressions
*/
class Expression
{
protected $expression;
protected array $expression;

protected $expecting = true;
protected bool $expecting = true;

protected $readOnly = false;
protected bool $readOnly = false;

protected $noisy = true;
protected bool $noisy = true;

/**
* @deprecated
*
* @var bool
*/
protected $stringOperation = false;
protected bool $stringOperation = false;

/** @var Variable */
protected $expectingVariable;
/**
* @var Variable|null
*/
protected ?Variable $expectingVariable = null;

protected $evalMode = false;
protected bool $evalMode = false;

/**
* Expression constructor.
Expand All @@ -106,7 +110,7 @@ public function __construct(array $expression)
*
* @return array
*/
public function getExpression()
public function getExpression(): array
{
return $this->expression;
}
Expand All @@ -115,10 +119,10 @@ public function getExpression()
* Sets if the variable must be resolved into a direct variable symbol
* create a temporary value or ignore the return value.
*
* @param bool $expecting
* @param Variable $expectingVariable
* @param bool $expecting
* @param Variable|null $expectingVariable
*/
public function setExpectReturn($expecting, Variable $expectingVariable = null)
public function setExpectReturn(bool $expecting, Variable $expectingVariable = null)
{
$this->expecting = $expecting;
$this->expectingVariable = $expectingVariable;
Expand All @@ -129,7 +133,7 @@ public function setExpectReturn($expecting, Variable $expectingVariable = null)
*
* @param bool $readOnly
*/
public function setReadOnly($readOnly)
public function setReadOnly(bool $readOnly): void
{
$this->readOnly = $readOnly;
}
Expand All @@ -139,7 +143,7 @@ public function setReadOnly($readOnly)
*
* @return bool
*/
public function isReadOnly()
public function isReadOnly(): bool
{
return $this->readOnly;
}
Expand All @@ -150,7 +154,7 @@ public function isReadOnly()
*
* @return bool
*/
public function isExpectingReturn()
public function isExpectingReturn(): bool
{
return $this->expecting;
}
Expand All @@ -159,9 +163,9 @@ public function isExpectingReturn()
* Returns the variable which is expected to return the
* result of the expression evaluation.
*
* @return Variable
* @return Variable|null
*/
public function getExpectingVariable()
public function getExpectingVariable(): ?Variable
{
return $this->expectingVariable;
}
Expand All @@ -171,7 +175,7 @@ public function getExpectingVariable()
*
* @param bool $noisy
*/
public function setNoisy($noisy)
public function setNoisy(bool $noisy): void
{
$this->noisy = $noisy;
}
Expand All @@ -181,7 +185,7 @@ public function setNoisy($noisy)
*
* @return bool
*/
public function isNoisy()
public function isNoisy(): bool
{
return $this->noisy;
}
Expand All @@ -194,7 +198,7 @@ public function isNoisy()
*
* @param bool $stringOperation
*/
public function setStringOperation($stringOperation)
public function setStringOperation(bool $stringOperation): void
{
$this->stringOperation = $stringOperation;
}
Expand All @@ -207,7 +211,7 @@ public function setStringOperation($stringOperation)
*
* @return bool
*/
public function isStringOperation()
public function isStringOperation(): bool
{
return $this->stringOperation;
}
Expand All @@ -217,7 +221,7 @@ public function isStringOperation()
*
* @param bool $evalMode
*/
public function setEvalMode($evalMode)
public function setEvalMode(bool $evalMode): void
{
$this->evalMode = $evalMode;
}
Expand All @@ -230,9 +234,9 @@ public function setEvalMode($evalMode)
*
* @return CompiledExpression
*/
public function emptyArray($expression, CompilationContext $compilationContext)
public function emptyArray(array $expression, CompilationContext $compilationContext): CompiledExpression
{
/*
/**
* Resolves the symbol that expects the value
*/
if ($this->expecting) {
Expand All @@ -246,14 +250,14 @@ public function emptyArray($expression, CompilationContext $compilationContext)
$symbolVariable = $compilationContext->symbolTable->getTempVariableForWrite('variable', $compilationContext, $expression);
}

/*
/**
* Variable that receives property accesses must be polymorphic
*/
if (!$symbolVariable->isVariable() && 'array' != $symbolVariable->getType()) {
throw new CompilerException('Cannot use variable: '.$symbolVariable->getName().'('.$symbolVariable->getType().') to create empty array', $expression);
}

/*
/**
* Mark the variable as an 'array'
*/
$symbolVariable->setDynamicTypes('array');
Expand All @@ -268,9 +272,9 @@ public function emptyArray($expression, CompilationContext $compilationContext)
*
* @param CompilationContext $compilationContext
*
* @throws CompilerException|Exception
*
* @return CompiledExpression
* @throws Exception
* @throws ReflectionException
*/
public function compile(CompilationContext $compilationContext): CompiledExpression
{
Expand All @@ -297,11 +301,12 @@ public function compile(CompilationContext $compilationContext): CompiledExpress
return new LiteralCompiledExpression('istring', str_replace(PHP_EOL, '\\n', $expression['value']), $expression);

case 'char':
if (!\strlen($expression['value'])) {
if (!strlen($expression['value'])) {
throw new CompilerException('Invalid empty char literal', $expression);
}
if (\strlen($expression['value']) > 2) {
if (\strlen($expression['value']) > 10) {

if (strlen($expression['value']) > 2) {
if (strlen($expression['value']) > 10) {
throw new CompilerException("Invalid char literal: '".substr($expression['value'], 0, 10)."...'", $expression);
} else {
throw new CompilerException("Invalid char literal: '".$expression['value']."'", $expression);
Expand All @@ -313,7 +318,7 @@ public function compile(CompilationContext $compilationContext): CompiledExpress
case 'variable':
$var = $compilationContext->symbolTable->getVariable($expression['value']);
if ($var) {
if ('this' == $var->getRealName()) {
if ('this' === $var->getRealName()) {
$var = 'this';
} else {
$var = $var->getName();
Expand Down Expand Up @@ -501,12 +506,13 @@ public function compile(CompilationContext $compilationContext): CompiledExpress
break;

case 'list':
if ('list' == $expression['left']['type']) {
if ('list' === $expression['left']['type']) {
$compilationContext->logger->warning(
'Unnecessary extra parentheses',
['extra-parentheses', $expression]
);
}

$numberPrints = $compilationContext->codePrinter->getNumberPrints();
$expr = new self($expression['left']);
$expr->setExpectReturn($this->expecting, $this->expectingVariable);
Expand Down Expand Up @@ -594,6 +600,7 @@ public function compile(CompilationContext $compilationContext): CompiledExpress
if (!$compilableExpression) {
throw new CompilerException('Unknown expression passed as compilableExpression', $expression);
}

$compilableExpression->setReadOnly($this->isReadOnly());
$compilableExpression->setExpectReturn($this->expecting, $this->expectingVariable);

Expand Down
12 changes: 8 additions & 4 deletions Library/Optimizers/FunctionCall/ImplodeOptimizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@
* the LICENSE file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Zephir\Optimizers\FunctionCall;

use function Zephir\add_slashes;
use Zephir\Call;
use Zephir\CompilationContext;
use Zephir\CompiledExpression;
use Zephir\Exception\CompilerException;
use Zephir\Optimizers\OptimizerAbstract;

use function count;
use function Zephir\add_slashes;

/**
* ImplodeOptimizer.
*
Expand All @@ -40,11 +44,11 @@ public function optimize(array $expression, Call $call, CompilationContext $cont
return false;
}

if (2 != \count($expression['parameters'])) {
if (2 !== count($expression['parameters'])) {
return false;
}

/*
/**
* Process the expected symbol to be returned
*/
$call->processExpectedReturn($context);
Expand All @@ -54,7 +58,7 @@ public function optimize(array $expression, Call $call, CompilationContext $cont
throw new CompilerException('Returned values by functions can only be assigned to variant variables', $expression);
}

if ('string' == $expression['parameters'][0]['parameter']['type']) {
if ('string' === $expression['parameters'][0]['parameter']['type']) {
$str = add_slashes($expression['parameters'][0]['parameter']['value']);
unset($expression['parameters'][0]);
}
Expand Down
Loading