Skip to content

Commit

Permalink
Refactored Exception\*NotExist exception messages, added required con…
Browse files Browse the repository at this point in the history
…structor parameters

Closes #9
  • Loading branch information
vudaltsov committed Mar 3, 2024
1 parent 9aa53c0 commit 1f72a57
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 17 deletions.
7 changes: 7 additions & 0 deletions src/Reflection/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.4.0

- [BC break] Added required parameter `Typhoon\Reflection\Exception\MethodDoesNotExist::__construct(class-string $class)`.
- [BC break] Added required parameter `Typhoon\Reflection\Exception\PropertyDoesNotExist::__construct(class-string $class)`.
- [BC break] Added required parameter `Typhoon\Reflection\Exception\ParameterDoesNotExist::__construct(AtFunction|AtMethod $at)`.
- [BC break] Added required parameter `Typhoon\Reflection\Exception\TemplateDoesNotExist::__construct(AtClass|AtFunction|AtMethod $at)`.

## [Unreleased]

- Implemented `getType()`, `getReturnType()`, `getTentativeReturnType()`, `hasTentativeReturnType()`, `hasReturnType()`.
10 changes: 6 additions & 4 deletions src/Reflection/ClassReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Typhoon\Reflection\Metadata\PropertyMetadata;
use Typhoon\Reflection\TypeResolver\TemplateResolver;
use Typhoon\Type\Type;
use Typhoon\Type\types;
use Typhoon\Type\TypeVisitor;

/**
Expand Down Expand Up @@ -170,7 +171,7 @@ public function getInterfaces(): array

public function getMethod(string $name): MethodReflection
{
return $this->getResolvedMethods()[$name] ?? throw new MethodDoesNotExist($name);
return $this->getResolvedMethods()[$name] ?? throw new MethodDoesNotExist($this->name, $name);
}

/**
Expand Down Expand Up @@ -237,7 +238,7 @@ public function getProperties(?int $filter = null): array

public function getProperty(string $name): PropertyReflection
{
return $this->getResolvedProperties()[$name] ?? throw new PropertyDoesNotExist($name);
return $this->getResolvedProperties()[$name] ?? throw new PropertyDoesNotExist($this->name, $name);
}

public function getReflectionConstant(string $name): ClassConstantReflection|false
Expand Down Expand Up @@ -299,7 +300,8 @@ public function getStaticPropertyValue(string $name, mixed $default = null): mix
public function getTemplate(int|string $nameOrPosition): TemplateReflection
{
if (\is_int($nameOrPosition)) {
return $this->metadata->templates[$nameOrPosition] ?? throw new TemplateDoesNotExist($nameOrPosition);
return $this->metadata->templates[$nameOrPosition]
?? throw new TemplateDoesNotExist(types::atClass($this->name), $nameOrPosition);
}

foreach ($this->metadata->templates as $template) {
Expand All @@ -308,7 +310,7 @@ public function getTemplate(int|string $nameOrPosition): TemplateReflection
}
}

throw new TemplateDoesNotExist($nameOrPosition);
throw new TemplateDoesNotExist(types::atClass($this->name), $nameOrPosition);
}

/**
Expand Down
7 changes: 5 additions & 2 deletions src/Reflection/Exception/MethodDoesNotExist.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
*/
final class MethodDoesNotExist extends ReflectionException
{
public function __construct(string $name, ?\Throwable $previous = null)
/**
* @param class-string $class
*/
public function __construct(string $class, string $name, ?\Throwable $previous = null)
{
parent::__construct(sprintf('Method "%s" does not exist', $name), previous: $previous);
parent::__construct(sprintf('Method %s::%s() does not exist', self::normalizeClass($class), $name), previous: $previous);
}
}
13 changes: 11 additions & 2 deletions src/Reflection/Exception/ParameterDoesNotExist.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,25 @@
namespace Typhoon\Reflection\Exception;

use Typhoon\Reflection\ReflectionException;
use Typhoon\Type\AtFunction;
use Typhoon\Type\AtMethod;

/**
* @api
*/
final class ParameterDoesNotExist extends ReflectionException
{
public function __construct(string|int $nameOrPosition, ?\Throwable $previous = null)
public function __construct(AtFunction|AtMethod $at, string|int $nameOrPosition, ?\Throwable $previous = null)
{
parent::__construct(
sprintf('Parameter %s does not exist', \is_int($nameOrPosition) ? $nameOrPosition : sprintf('"%s"', $nameOrPosition)),
sprintf(
'%s does not have a parameter %s',
match (true) {
$at instanceof AtMethod => sprintf('%s::%s()', $at->class, $at->name),
$at instanceof AtFunction => sprintf('%s()', $at->name),
},
\is_int($nameOrPosition) ? 'at position ' . $nameOrPosition : sprintf('named "%s"', $nameOrPosition),
),
previous: $previous,
);
}
Expand Down
7 changes: 5 additions & 2 deletions src/Reflection/Exception/PropertyDoesNotExist.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
*/
final class PropertyDoesNotExist extends ReflectionException
{
public function __construct(string $name, ?\Throwable $previous = null)
/**
* @param class-string $class
*/
public function __construct(string $class, string $name, ?\Throwable $previous = null)
{
parent::__construct(sprintf('Property "%s" does not exist', $name), previous: $previous);
parent::__construct(sprintf('Property %s::$%s does not exist', self::normalizeClass($class), $name), previous: $previous);
}
}
15 changes: 13 additions & 2 deletions src/Reflection/Exception/TemplateDoesNotExist.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,27 @@
namespace Typhoon\Reflection\Exception;

use Typhoon\Reflection\ReflectionException;
use Typhoon\Type\AtClass;
use Typhoon\Type\AtFunction;
use Typhoon\Type\AtMethod;

/**
* @api
*/
final class TemplateDoesNotExist extends ReflectionException
{
public function __construct(string|int $nameOrPosition, ?\Throwable $previous = null)
public function __construct(AtClass|AtFunction|AtMethod $at, string|int $nameOrPosition, ?\Throwable $previous = null)
{
parent::__construct(
sprintf('Template %s does not exist', \is_int($nameOrPosition) ? $nameOrPosition : sprintf('"%s"', $nameOrPosition)),
sprintf(
'%s does not have a template %s',
match (true) {
$at instanceof AtClass => $at->name,
$at instanceof AtMethod => sprintf('%s::%s()', $at->class, $at->name),
$at instanceof AtFunction => sprintf('%s()', $at->name),
},
\is_int($nameOrPosition) ? 'at position ' . $nameOrPosition : sprintf('named "%s"', $nameOrPosition),
),
previous: $previous,
);
}
Expand Down
12 changes: 7 additions & 5 deletions src/Reflection/MethodReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Typhoon\Reflection\TypeReflection\TypeConverter;
use Typhoon\Reflection\TypeResolver\TemplateResolver;
use Typhoon\Type\Type;
use Typhoon\Type\types;
use Typhoon\Type\TypeVisitor;

/**
Expand Down Expand Up @@ -56,7 +57,7 @@ public static function createFromMethodName(string $method, ?TyphoonReflector $r
$parts = explode('::', $method);

if (\count($parts) !== 2) {
throw new MethodDoesNotExist($method);
throw new MethodDoesNotExist(self::class, $method);
}

return ($reflector ?? TyphoonReflector::build())->reflectClass($parts[0])->getMethod($parts[1]);
Expand Down Expand Up @@ -215,7 +216,7 @@ public function getParameter(int|string $nameOrPosition): ParameterReflection
return $parameters[$nameOrPosition];
}

throw new ParameterDoesNotExist($nameOrPosition);
throw new ParameterDoesNotExist(types::atMethod($this->class, $this->name), $nameOrPosition);
}

foreach ($parameters as $parameter) {
Expand All @@ -224,7 +225,7 @@ public function getParameter(int|string $nameOrPosition): ParameterReflection
}
}

throw new ParameterDoesNotExist($nameOrPosition);
throw new ParameterDoesNotExist(types::atMethod($this->class, $this->name), $nameOrPosition);
}

/**
Expand Down Expand Up @@ -285,7 +286,8 @@ public function getStaticVariables(): array
public function getTemplate(int|string $nameOrPosition): TemplateReflection
{
if (\is_int($nameOrPosition)) {
return $this->metadata->templates[$nameOrPosition] ?? throw new TemplateDoesNotExist($nameOrPosition);
return $this->metadata->templates[$nameOrPosition]
?? throw new TemplateDoesNotExist(types::atMethod($this->class, $this->name), $nameOrPosition);
}

foreach ($this->metadata->templates as $template) {
Expand All @@ -294,7 +296,7 @@ public function getTemplate(int|string $nameOrPosition): TemplateReflection
}
}

throw new TemplateDoesNotExist($nameOrPosition);
throw new TemplateDoesNotExist(types::atMethod($this->class, $this->name), $nameOrPosition);
}

/**
Expand Down
4 changes: 4 additions & 0 deletions tests/Reflection/ReflectorCompatibilityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ private function assertClassEquals(\ReflectionClass $native, ClassReflection $ty
$this->assertSameNames($native->getProperties(\ReflectionProperty::IS_PRIVATE), $typhoon->getProperties(PropertyReflection::IS_PRIVATE), 'class.getProperties(IS_PRIVATE).name');
$this->assertSameNames($native->getProperties(\ReflectionProperty::IS_STATIC), $typhoon->getProperties(PropertyReflection::IS_STATIC), 'class.getProperties(IS_STATIC).name');
$this->assertSameNames($native->getProperties(\ReflectionProperty::IS_READONLY), $typhoon->getProperties(PropertyReflection::IS_READONLY), 'class.getProperties(IS_READONLY).name');
$this->assertResultOrExceptionEqual(static fn(): mixed => $native->getProperty(''), static fn(): mixed => $typhoon->getProperty(''), "class.getProperty('')");
$this->assertResultOrExceptionEqual(static fn(): mixed => $native->getProperty('__'), static fn(): mixed => $typhoon->getProperty('__'), "class.getProperty('__')");

foreach ($native->getProperties() as $nativeProperty) {
self::assertTrue($typhoon->hasProperty($nativeProperty->name), "class.hasProperty({$nativeProperty->name})");
Expand All @@ -167,6 +169,8 @@ private function assertClassEquals(\ReflectionClass $native, ClassReflection $ty
$this->assertSameNames($native->getMethods(\ReflectionMethod::IS_PROTECTED), $typhoon->getMethods(MethodReflection::IS_PROTECTED), 'class.getMethods(IS_PROTECTED).name');
$this->assertSameNames($native->getMethods(\ReflectionMethod::IS_PRIVATE), $typhoon->getMethods(MethodReflection::IS_PRIVATE), 'class.getMethods(IS_PRIVATE).name');
$this->assertSameNames($native->getMethods(\ReflectionMethod::IS_STATIC), $typhoon->getMethods(MethodReflection::IS_STATIC), 'class.getMethods(IS_STATIC).name');
$this->assertResultOrExceptionEqual(static fn(): mixed => $native->getMethod(''), static fn(): mixed => $typhoon->getMethod(''), "class.getMethod('')");
$this->assertResultOrExceptionEqual(static fn(): mixed => $native->getMethod('__'), static fn(): mixed => $typhoon->getMethod('__'), "class.getMethod('__')");

foreach ($native->getMethods() as $nativeMethod) {
self::assertTrue($typhoon->hasMethod($nativeMethod->name), "hasMethod({$nativeMethod->name})");
Expand Down

0 comments on commit 1f72a57

Please sign in to comment.