Skip to content

Commit

Permalink
added Helpers::getPropertyType()
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Mar 15, 2019
1 parent 9eb7e7c commit 9bd3ebb
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 5 deletions.
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -20,7 +20,7 @@
"nette/neon": "^3.0",
"nette/php-generator": "^3.2",
"nette/robot-loader": "^3.2",
"nette/utils": "^3.0"
"nette/utils": "^3.0.1"
},
"require-dev": {
"nette/tester": "^2.0",
Expand Down
5 changes: 1 addition & 4 deletions src/DI/Extensions/InjectExtension.php
Expand Up @@ -102,10 +102,7 @@ public static function getInjectProperties(string $class): array
foreach (get_class_vars($class) as $name => $foo) {
$rp = new \ReflectionProperty($class, $name);
if (DI\Helpers::parseAnnotation($rp, 'inject') !== null) {
if ($type = DI\Helpers::parseAnnotation($rp, 'var')) {
$type = Reflection::expandClassName($type, Reflection::getPropertyDeclaringClass($rp));
}
$res[$name] = $type;
$res[$name] = DI\Helpers::getPropertyType($rp);
}
}
ksort($res);
Expand Down
19 changes: 19 additions & 0 deletions src/DI/Helpers.php
Expand Up @@ -167,6 +167,25 @@ public static function getReturnType(\ReflectionFunctionAbstract $func): ?string
}


public static function getPropertyType(\ReflectionProperty $prop, &$union = null): ?string
{
$union = null;
if ($type = Reflection::getPropertyType($prop)) {
$union = $type . ($prop->getType()->allowsNull() ? '|null' : '');
return $type;
} elseif ($type = preg_replace('#\s.*#', '', (string) self::parseAnnotation($prop, 'var'))) {
$class = Reflection::getPropertyDeclaringClass($prop);
$types = array_map(function ($type) use ($class, &$nullable) {
$nullable = $nullable || substr($type, 0, 1) === '?';
return Reflection::expandClassName(ltrim($type, '?'), $class);
}, explode('|', $type));
$union = implode('|', $types) . ($nullable ? '|null' : '');
return $types[0];
}
return null;
}


public static function normalizeClass(string $type): string
{
return class_exists($type) || interface_exists($type)
Expand Down
85 changes: 85 additions & 0 deletions tests/DI/Helpers.getPropertyType.php74.phptx
@@ -0,0 +1,85 @@
<?php

/**
* Test: Nette\DI\Helpers::getPropertyType
* @phpversion 7.4
*/

declare(strict_types=1);

namespace NS
{
use Test\B;

class A
{
public $noType;
public B $classType;
public string $nativeType;
public self $selfType;
public ?B $nullableClassType;
public ?string $nullableNativeType;
public ?self $nullableSelfType;

/** @var B noise */
public $annotationClassType;

/** @var B|null|string */
public $annotationUnionType;

/** @var String */
public $annotationNativeType;

/** @var self */
public $annotationSelfType;

/** @var static */
public $annotationStaticType;

/** @var ?B */
public $annotationNullable;
}
}

namespace
{
use Nette\DI\Helpers;
use Tester\Assert;

require __DIR__ . '/../bootstrap.php';


Assert::null(Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'noType'), $union));
Assert::null($union);

Assert::same('Test\B', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'classType'), $union));
Assert::same('Test\B', $union);

Assert::same('string', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'nativeType'), $union));
Assert::same('string', $union);

Assert::same('NS\A', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'selfType'), $union));
Assert::same('NS\A', $union);

Assert::same('Test\B', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'nullableClassType'), $union));
Assert::same('Test\B|null', $union);

Assert::same('string', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'nullableNativeType'), $union));

Assert::same('NS\A', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'nullableSelfType'), $union));

Assert::same('Test\B', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'annotationClassType'), $union));
Assert::same('Test\B', $union);

Assert::same('Test\B', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'annotationUnionType'), $union));
Assert::same('Test\B|null|string', $union);

Assert::same('string', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'annotationNativeType'), $union));
Assert::same('string', $union);

Assert::same('NS\A', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'annotationSelfType'), $union));
Assert::same('NS\A', $union);

Assert::same('Test\B', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'annotationNullable'), $union));
Assert::same('Test\B|null', $union);
}
62 changes: 62 additions & 0 deletions tests/DI/Helpers.getPropertyType.phpt
@@ -0,0 +1,62 @@
<?php

/**
* Test: Nette\DI\Helpers::getPropertyType
*/

declare(strict_types=1);

namespace NS
{
use Test\B;

class A
{
public $noType;

/** @var B noise */
public $annotationClassType;

/** @var B|null|string */
public $annotationUnionType;

/** @var String */
public $annotationNativeType;

/** @var self */
public $annotationSelfType;

/** @var static */
public $annotationStaticType;

/** @var ?B */
public $annotationNullable;
}
}

namespace
{
use Nette\DI\Helpers;
use Tester\Assert;

require __DIR__ . '/../bootstrap.php';


Assert::null(Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'noType'), $union));
Assert::null($union);

Assert::same('Test\B', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'annotationClassType'), $union));
Assert::same('Test\B', $union);

Assert::same('Test\B', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'annotationUnionType'), $union));
Assert::same('Test\B|null|string', $union);

Assert::same('string', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'annotationNativeType'), $union));
Assert::same('string', $union);

Assert::same('NS\A', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'annotationSelfType'), $union));
Assert::same('NS\A', $union);

Assert::same('Test\B', Helpers::getPropertyType(new \ReflectionProperty(NS\A::class, 'annotationNullable'), $union));
Assert::same('Test\B|null', $union);
}

0 comments on commit 9bd3ebb

Please sign in to comment.