Skip to content

Commit

Permalink
Merge pull request #2230 from zephir-lang/#1259-unset-property-via-va…
Browse files Browse the repository at this point in the history
…riable

#1259 - Fix unset property via variable
  • Loading branch information
AlexNDRmac committed Apr 25, 2021
2 parents 4a29bea + 660dd4b commit 5d2ec1d
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 29 deletions.
35 changes: 24 additions & 11 deletions Library/Statements/UnsetStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,34 @@ public function compile(CompilationContext $compilationContext): void
*/
private function generateUnsetPropertyFromObject(array $expression, CompilationContext $compilationContext): CompilationContext
{
$expr = new Expression($expression['left']);
$expr = new Expression($expression['right']);
$expr->setReadOnly(true);
$exprVar = $expr->compile($compilationContext);
$variable = $compilationContext->symbolTable->getVariableForWrite($exprVar->getCode(), $compilationContext, $this->statement);

$temporaryVariableRef = $compilationContext->backend->getVariableCode($variable);

// TODO: Add more types check when parser will support them, see ArrayAccessTest.zep
switch ($expression['right']['type']) {
case 'string':
$compilationContext->codePrinter->output('ZVAL_STR('.$temporaryVariableRef.', "'.$expression['right']['value'].'");');
switch ($exprVar->getType()) {
case 'variable':
$variable = $compilationContext->symbolTable->getVariableForRead($exprVar->getCode(), $compilationContext, $this->statement);
$variableRef = $compilationContext->backend->getVariableCode($variable);
break;

case 'int':
$compilationContext->codePrinter->output('ZVAL_LONG('.$temporaryVariableRef.', '.$expression['right']['value'].');');
default:
$expr = new Expression($expression['left']);
$expr->setReadOnly(true);
$exprVar = $expr->compile($compilationContext);
$variable = $compilationContext->symbolTable->getVariableForWrite($exprVar->getCode(), $compilationContext, $this->statement);

$variableRef = $compilationContext->backend->getVariableCode($variable);

// TODO: Add more types check when parser will support them, see ArrayAccessTest.zep
switch ($expression['right']['type']) {
case 'string':
$compilationContext->codePrinter->output('ZVAL_STR('.$variableRef.', "'.$expression['right']['value'].'");');
break;

case 'int':
$compilationContext->codePrinter->output('ZVAL_LONG('.$variableRef.', '.$expression['right']['value'].');');
break;
}
break;
}

Expand All @@ -127,7 +140,7 @@ private function generateUnsetPropertyFromObject(array $expression, CompilationC

$compilationContext->headersManager->add('kernel/object');
$compilationContext->codePrinter->output(
'zephir_unset_property_array('.$variableCode.', ZEND_STRL("'.$expression['left']['right']['value'].'"), '.$temporaryVariableRef.');'
'zephir_unset_property_array('.$variableCode.', ZEND_STRL("'.$expression['left']['right']['value'].'"), '.$variableRef.');'
);

return $compilationContext;
Expand Down
8 changes: 3 additions & 5 deletions ext/stub/arrayaccessobj.zep.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 89 additions & 8 deletions ext/stub/arrayaccesstest.zep.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions ext/stub/arrayaccesstest.zep.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 3 additions & 5 deletions ext/stub/unsettest.zep.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions stub/arrayaccesstest.zep
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ namespace Stub;
class ArrayAccessTest
{
protected data;
protected assigedFromMethod;
protected unsetData = [
"key_a": "marcin",
"key_b": "paula",
Expand All @@ -28,6 +29,22 @@ class ArrayAccessTest
return arr["two"];
}

public function unsetByKeyFromArray(string! key, array data) -> array
{
unset data[key];

return data;
}

public function unsetByKeyFromProperty(string! key, array dataFromProperty) -> array
{
let this->assigedFromMethod = dataFromProperty;

unset this->assigedFromMethod[key];

return this->assigedFromMethod;
}

/**
* @issue https://github.com/zephir-lang/zephir/issues/645
*/
Expand Down
16 changes: 16 additions & 0 deletions tests/Extension/ArrayAccessTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,22 @@ public function testTest(): void
$this->assertSame(2, $class->get());
}

public function testUnsetByKeyFromArray(): void
{
$class = new \Stub\ArrayAccessTest();

$this->assertSame([], $class->unsetByKeyFromArray('not-exist', []));
}

public function testUnsetByKeyFromProperty(): void
{
$class = new \Stub\ArrayAccessTest();

$this->assertSame([], $class->unsetByKeyFromProperty('ok', ['ok' => true]));
$this->assertSame(['another' => 'value'], $class->unsetByKeyFromProperty('ok', ['ok' => true, 'another' => 'value']));
$this->assertSame([], $class->unsetByKeyFromProperty('not-exist', []));
}

/**
* @issue https://github.com/zephir-lang/zephir/issues/645
*/
Expand Down

0 comments on commit 5d2ec1d

Please sign in to comment.