Skip to content

Commit

Permalink
Merge pull request #49 from yiisoft/30-implicit-abstract
Browse files Browse the repository at this point in the history
Disallow rendering of interfaces since they are never used, cleanup
  • Loading branch information
arogachev committed Jul 8, 2022
2 parents 44c7687 + 20d2998 commit c7663e9
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 200 deletions.
28 changes: 23 additions & 5 deletions src/ClassConfigFactory.php
Expand Up @@ -48,7 +48,6 @@ public function getClassConfig(string $className): ClassConfig
name: $reflection->getName(),
shortName: $reflection->getShortName(),
parent: (string) $reflection->getParentClass(),
interfaces: $reflection->getInterfaceNames(),
methods: $this->getMethodConfigs($reflection),
);
}
Expand All @@ -64,29 +63,48 @@ private function getMethodConfigs(ReflectionClass $class): array
{
$methods = [];
foreach ($class->getMethods() as $method) {
$methods[$method->getName()] = $this->getMethodConfig($method);
$methods[$method->getName()] = $this->getMethodConfig($class, $method);
}

return $methods;
}

/**
* Gets single method config for individual method reflection.
* Gets single method config for individual class / method reflection pair.
*
* @param ReflectionClass $class Reflection of a class.
* @param ReflectionMethod $method Reflection of a method.
*
* @return MethodConfig Single method config.
*/
private function getMethodConfig(ReflectionMethod $method): MethodConfig
private function getMethodConfig(ReflectionClass $class, ReflectionMethod $method): MethodConfig
{
return new MethodConfig(
modifiers: Reflection::getModifierNames($method->getModifiers()),
modifiers: $this->getMethodModifiers($class, $method),
name: $method->getName(),
parameters: $this->getMethodParameterConfigs($method),
returnType: $this->getMethodReturnTypeConfig($method),
);
}

/**
* Gets the set of method modifiers for a given class / method reflection pair
*
* @param ReflectionClass $class Reflection of a class.
* @param ReflectionMethod $method Reflection of a method.
*
* @return string[] List of method modifiers.
*/
private function getMethodModifiers(ReflectionClass $class, ReflectionMethod $method): array
{
$modifiers = Reflection::getModifierNames($method->getModifiers());
if (!$class->isInterface()) {
return $modifiers;
}

return array_values(array_filter($modifiers, static fn (string $modifier) => $modifier !== 'abstract'));
}

/**
* Gets the complete set of parameter configs for a given method reflection.
*
Expand Down
41 changes: 11 additions & 30 deletions src/ClassRenderer.php
Expand Up @@ -4,6 +4,7 @@

namespace Yiisoft\Proxy;

use InvalidArgumentException;
use Yiisoft\Proxy\Config\ClassConfig;
use Yiisoft\Proxy\Config\MethodConfig;
use Yiisoft\Proxy\Config\ParameterConfig;
Expand All @@ -19,7 +20,7 @@ final class ClassRenderer
*
* @see renderClassSignature()
*/
private string $classSignatureTemplate = '{{modifiers}} {{classType}} {{name}}{{extends}}{{parent}}{{implements}}';
private string $classSignatureTemplate = '{{modifiers}}class {{name}} extends {{parent}}';
/**
* @var string A template for rendering proxy method signature.
*
Expand All @@ -42,6 +43,14 @@ final class ClassRenderer
*/
public function render(ClassConfig $classConfig): string
{
if ($classConfig->isInterface) {
throw new InvalidArgumentException('Rendering of interfaces is not supported.');
}

if (!$classConfig->parent) {
throw new InvalidArgumentException('Class config is missing a parent.');
}

return trim($this->renderClassSignature($classConfig))
. "\n"
. '{'
Expand All @@ -50,49 +59,21 @@ public function render(ClassConfig $classConfig): string
}

/**
* Renders class / interface signature using {@see $classSignatureTemplate}.
* Renders class signature using {@see $classSignatureTemplate}.
*
* @param ClassConfig $classConfig Class config.
*
* @return string Class signature as a string.
*/
private function renderClassSignature(ClassConfig $classConfig): string
{
$classType = $classConfig->isInterface
? 'interface'
: 'class';
$extends = $classConfig->parent
? ' extends '
: '';

return strtr($this->classSignatureTemplate, [
'{{modifiers}}' => $this->renderModifiers($classConfig->modifiers),
'{{classType}}' => $classType,
'{{name}}' => $classConfig->shortName,
'{{extends}}' => $extends,
'{{parent}}' => $classConfig->parent,
'{{implements}}' => $this->renderImplements($classConfig->interfaces),
]);
}

/**
* Renders implements section. Used for interfaces Only
*
* @param string[] $interfaces A list of interfaces' names with namespaces.
*
* @return string Implements section as a string. Empty string is returned when no interfaces were passed.
*
* @see ClassConfig::$interfaces
*/
private function renderImplements(array $interfaces): string
{
if ($interfaces === []) {
return '';
}

return ' implements ' . implode(', ', $interfaces);
}

/**
* Renders modifiers section.
*
Expand Down
4 changes: 0 additions & 4 deletions src/Config/ClassConfig.php
Expand Up @@ -36,10 +36,6 @@ public function __construct(
* @var string Full parent class name including namespace. Empty string means class have no parent class.
*/
public string $parent,
/**
* @var string[] A list of interfaces this class implements or interface extends from.
*/
public array $interfaces,
/**
* @var MethodConfig[] A map where key is a {@see $name} and value is {@see MethodConfig} instance.
* @psalm-var array<string, MethodConfig>
Expand Down
1 change: 0 additions & 1 deletion src/ProxyManager.php
Expand Up @@ -92,7 +92,6 @@ private function generateProxyClassConfig(ClassConfig $classConfig, string $pare
{
if ($classConfig->isInterface) {
$classConfig->isInterface = false;
$classConfig->interfaces = [$classConfig->name];
}

$classConfig->parent = $parentProxyClass;
Expand Down
16 changes: 0 additions & 16 deletions tests/ClassConfigFactoryTest.php
Expand Up @@ -34,15 +34,9 @@ public function testGetClassConfigForInterface(): void
name: 'Yiisoft\Proxy\Tests\Stub\NodeInterface',
shortName: 'NodeInterface',
parent: '',
interfaces: [
'Countable',
'Yiisoft\Proxy\Tests\Stub\NodeParentInterface',
'Yiisoft\Proxy\Tests\Stub\NodeGrandParentInterface',
],
methods: [
'nodeInterfaceMethod1' => new MethodConfig(
modifiers: [
'abstract',
'public',
'static',
],
Expand Down Expand Up @@ -141,7 +135,6 @@ interfaces: [
),
'nodeInterfaceMethod2' => new MethodConfig(
modifiers: [
'abstract',
'public',
],
name: 'nodeInterfaceMethod2',
Expand All @@ -150,7 +143,6 @@ interfaces: [
),
'nodeInterfaceMethod3' => new MethodConfig(
modifiers: [
'abstract',
'public',
],
name: 'nodeInterfaceMethod3',
Expand Down Expand Up @@ -229,7 +221,6 @@ interfaces: [
),
'count' => new MethodConfig(
modifiers: [
'abstract',
'public',
],
name: 'count',
Expand All @@ -243,7 +234,6 @@ interfaces: [
),
'parentMethod1' => new MethodConfig(
modifiers: [
'abstract',
'public',
],
name: 'parentMethod1',
Expand All @@ -255,7 +245,6 @@ interfaces: [
),
'parentMethod2' => new MethodConfig(
modifiers: [
'abstract',
'public',
],
name: 'parentMethod2',
Expand All @@ -264,7 +253,6 @@ interfaces: [
),
'grandParentMethod1' => new MethodConfig(
modifiers: [
'abstract',
'public',
],
name: 'grandParentMethod1',
Expand All @@ -276,7 +264,6 @@ interfaces: [
),
'grandParentMethod2' => new MethodConfig(
modifiers: [
'abstract',
'public',
],
name: 'grandParentMethod2',
Expand All @@ -288,7 +275,6 @@ interfaces: [
),
'grandParentMethod3' => new MethodConfig(
modifiers: [
'abstract',
'public',
],
name: 'grandParentMethod3',
Expand All @@ -300,7 +286,6 @@ interfaces: [
),
'grandParentMethod4' => new MethodConfig(
modifiers: [
'abstract',
'public',
],
name: 'grandParentMethod4',
Expand All @@ -327,7 +312,6 @@ public function testGetClassConfigForClass(): void
name: 'Yiisoft\Proxy\Tests\Stub\Graph',
shortName: 'Graph',
parent: '',
interfaces: ['Yiisoft\Proxy\Tests\Stub\GraphInterface'],
methods: [
'nodesCount' => new MethodConfig(
modifiers: ['public'],
Expand Down

0 comments on commit c7663e9

Please sign in to comment.