Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fixed issue #1667
  • Loading branch information
sergeyklay committed Oct 22, 2018
1 parent 1c878c3 commit b791567
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 17 deletions.
38 changes: 23 additions & 15 deletions Library/ArgInfoDefinition.php
Expand Up @@ -38,7 +38,7 @@ class ArgInfoDefinition
private $booleanDefinition = '_IS_BOOL';

/** @var bool */
private $rightFormat = true;
private $richFormat = true;

public function __construct(
$name,
Expand All @@ -62,9 +62,9 @@ public function setBooleanDefinition($definition)
$this->booleanDefinition = (string)$definition;
}

public function setRightFormat($flag)
public function setRichFormat($flag)
{
$this->rightFormat = (bool)$flag;
$this->richFormat = (bool)$flag;
}

/**
Expand All @@ -74,8 +74,8 @@ public function setRightFormat($flag)
*/
public function render()
{
if ($this->rightFormat && $this->method->isReturnTypesHintDetermined()) {
$this->rightRenderStart();
if ($this->richFormat && $this->method->isReturnTypesHintDetermined()) {
$this->richRenderStart();

if ($this->hasParameters() == false) {
$this->codePrinter->output('ZEND_END_ARG_INFO()');
Expand All @@ -100,7 +100,7 @@ public function render()
}
}

private function rightRenderStart()
private function richRenderStart()
{
if (array_key_exists('object', $this->method->getReturnTypes())) {
$class = 'NULL';
Expand Down Expand Up @@ -167,7 +167,7 @@ private function rightRenderStart()

private function renderEnd()
{
$flag = $this->rightFormat ? '1' : '0';
$flag = $this->richFormat ? '1' : '0';

foreach ($this->parameters->getParameters() as $parameter) {
switch ("{$flag}:" . $parameter['data-type']) {
Expand All @@ -178,7 +178,7 @@ private function renderEnd()
"\tZEND_ARG_ARRAY_INFO(%d, %s, %d)",
$this->passByReference($parameter),
$parameter['name'],
$this->hasDefaultValue($parameter)
(int)$this->allowNull($parameter)
)
);
break;
Expand All @@ -194,7 +194,7 @@ private function renderEnd()
$this->passByReference($parameter),
$parameter['name'],
Utils::escapeClassName($this->compilationContext->getFullName($value)),
$this->hasDefaultValue($parameter)
(int)$this->allowNull($parameter)
)
);
break;
Expand All @@ -221,7 +221,7 @@ private function renderEnd()
$this->passByReference($parameter),
$parameter['name'],
$this->booleanDefinition,
$this->hasDefaultValue($parameter)
(int)$this->allowNull($parameter)
)
);
break;
Expand All @@ -235,7 +235,7 @@ private function renderEnd()
"\tZEND_ARG_TYPE_INFO(%d, %s, IS_LONG, %d)",
$this->passByReference($parameter),
$parameter['name'],
$this->hasDefaultValue($parameter)
(int)$this->allowNull($parameter)
)
);
break;
Expand All @@ -245,7 +245,7 @@ private function renderEnd()
"\tZEND_ARG_TYPE_INFO(%d, %s, IS_DOUBLE, %d)",
$this->passByReference($parameter),
$parameter['name'],
$this->hasDefaultValue($parameter)
(int)$this->allowNull($parameter)
)
);
break;
Expand All @@ -256,7 +256,7 @@ private function renderEnd()
"\tZEND_ARG_TYPE_INFO(%d, %s, IS_STRING, %d)",
$this->passByReference($parameter),
$parameter['name'],
$this->hasDefaultValue($parameter)
(int)$this->allowNull($parameter)
)
);
break;
Expand All @@ -278,9 +278,17 @@ private function hasParameters()
return $this->parameters !== null && count($this->parameters->getParameters()) > 0;
}

private function hasDefaultValue($parameter)
private function allowNull($parameter)
{
return isset($parameter['default']) ? 1 : 0;
if (!isset($parameter['default']) || !is_array(isset($parameter['default']))) {
return false;
}

if ($parameter['default']['type'] == 'null') {
return true;
}

return false;
}

private function passByReference($parameter)
Expand Down
2 changes: 1 addition & 1 deletion Library/ClassDefinition.php
Expand Up @@ -1251,7 +1251,7 @@ public function compile(CompilationContext $compilationContext)
);

$argInfo->setBooleanDefinition($this->compiler->backend->isZE3() ? '_IS_BOOL' : 'IS_BOOL');
$argInfo->setRightFormat($this->compiler->backend->isZE3());
$argInfo->setRichFormat($this->compiler->backend->isZE3());

$argInfo->render();
}
Expand Down
2 changes: 1 addition & 1 deletion Library/Compiler.php
Expand Up @@ -2107,7 +2107,7 @@ public function generateFunctionInformation()
$headerPrinter->output('PHP_FUNCTION(' . $funcName . ');');

$argInfo->setBooleanDefinition($this->backend->isZE3() ? '_IS_BOOL' : 'IS_BOOL');
$argInfo->setRightFormat($this->backend->isZE3());
$argInfo->setRichFormat($this->backend->isZE3());

$argInfo->render();

Expand Down
6 changes: 6 additions & 0 deletions test/typehinting/testabstract.zep
@@ -0,0 +1,6 @@
namespace Test\TypeHinting;

abstract class TestAbstract
{
abstract public function testFunc(array text = [], string text2 = "", boolean flag = true, int optional = null);
}
50 changes: 50 additions & 0 deletions unit-tests/Extension/TypeHinting/AbstractTest.php
@@ -0,0 +1,50 @@
<?php

/**
* This file is part of the Zephir.
*
* (c) Zephir Team <team@zephir-lang.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Extension\TypeHinting;

use PHPUnit\Framework\SkippedTestError;
use TestConcreteClass;
use Zephir\Support\TestCase;

class AbstractTest extends TestCase
{
/**
* {@inheritdoc}
*
* @return void
*/
public static function setUpBeforeClass()
{
if (PHP_VERSION_ID < 70000) {
throw new SkippedTestError("Scalar type hint are avalibale in PHP 7 only");
}
}

/**
* @test
* @link https://github.com/phalcon/zephir/issues/1667
*/
public function shouldCreateCompatibleChildClassUsingTypeHintedParams()
{
$childClass = new TestConcreteClass();

$this->assertEquals(
[[1667], '/', true, null],
$childClass->testFunc([1667], '/', true, null)
);

$this->assertEquals(
[['issue'], '\\', true, 1667],
$childClass->testFunc(['issue'], '\\', true, 1667)
);
}
}
20 changes: 20 additions & 0 deletions unit-tests/fixtures/mocks/TestConcreteClass.php
@@ -0,0 +1,20 @@
<?php

/**
* This file is part of the Zephir package.
*
* (c) Zephir Team <team@zephir-lang.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

use Test\TypeHinting\TestAbstract;

class TestConcreteClass extends TestAbstract
{
public function testFunc(array $text = [], string $text2 = '', bool $flag = true, int $optional = null)
{
return func_get_args();
}
}

0 comments on commit b791567

Please sign in to comment.