Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Changelog
* [Feature] **PHP 8.1+ enum interception** — instance and static methods on both unit (pure) and backed enums can now be intercepted by aspects. The enum body is extracted into a trait (`Foo__AopProxied`); a proxy enum re-declares the cases and dispatches intercepted methods via per-method `static $__joinPoint` caching. Built-in enum methods (`cases`, `from`, `tryFrom`) and initialization joinpoints are never woven.
* [Feature] `self::` in proxied classes now resolves to the proxy class naturally (via PHP trait semantics), removing the need for `SelfValueTransformer`.
* [Feature] **First-class callable syntax** — generated proxy code and invocation constructors use PHP 8.1+ first-class callable syntax (`$this->__aop__method(...)`, `parent::method(...)`, `\func(...)`) to reference original method and function bodies, eliminating the need for `Closure::bind` at construction time.
* [BC BREAK] Removed DeclareError support, including the `DeclareError` attribute, `DeclareErrorInterceptor`, and `PointcutBuilder::declareError()`. Use `Before` or `Around` interceptors to emit user warnings or throw exceptions instead.
* [Removed] `SelfValueTransformer` and `SelfValueVisitor` — no longer needed with the trait-based engine.
* [Performance] **Direct static joinpoint initialization** — leveraging PHP 8.3+ support for dynamic expressions in static variable initializers, all generated proxy method bodies now initialize their static joinpoint variables directly.

Expand Down
1 change: 0 additions & 1 deletion demos/Demo/Aspect/AwesomeAspectKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class AwesomeAspectKernel extends AspectKernel
*/
protected function configureAop(AspectContainer $container): void
{
$container->registerAspect(new DeclareErrorAspect());
$container->registerAspect(new CachingAspect());
$container->registerAspect(new LoggingAspect());
$container->registerAspect(new IntroductionAspect());
Expand Down
28 changes: 0 additions & 28 deletions demos/Demo/Aspect/DeclareErrorAspect.php

This file was deleted.

40 changes: 0 additions & 40 deletions demos/Demo/Example/ErrorDemo.php

This file was deleted.

10 changes: 0 additions & 10 deletions demos/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
<li><a href="?showcase=fluent-interface">Fluent Interface</a></li>
<li><a href="?showcase=human-advices">Human live advices</a></li>
<li><a href="?showcase=dynamic-traits">Dynamic traits and interfaces</a></li>
<li><a href="?showcase=declare-errors">Declare runtime errors</a></li>
</ul>
</li>
<li><a href="http://go.aopphp.com/docs/" target="_blank">Documentation</a></li>
Expand Down Expand Up @@ -120,7 +119,6 @@

use Demo\Example\CacheableDemo;
use Demo\Example\DynamicMethodsDemo;
use Demo\Example\ErrorDemo;
use Demo\Example\FunctionDemo;
use Demo\Example\HumanDemo;
use Demo\Example\IntroductionDemo;
Expand Down Expand Up @@ -217,14 +215,6 @@
$example->testStringable();
break;

case 'declare-errors':
$aspectName = 'Demo\Aspect\DeclareErrorAspect';

$example = new ErrorDemo();
$example->oldMethod();
$example->notSoGoodMethod();
break;

default:
}
?>
Expand Down
2 changes: 1 addition & 1 deletion src/Aop/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Proxy generators use TypeGenerator::renderTypeForPhpDoc() to emit V as 2nd gener

## Attributes (src/Lang/Attribute/)
- Advice: #[Before], #[After], #[Around], #[AfterThrowing]
- Declaration: #[Aspect], #[Pointcut], #[DeclareError], #[DeclareParents]
- Declaration: #[Aspect], #[Pointcut], #[DeclareParents]
- Base: AbstractAttribute, AbstractInterceptor, Interceptor (interface)

## Features (src/Aop/Features.php)
Expand Down
98 changes: 0 additions & 98 deletions src/Aop/Framework/DeclareErrorInterceptor.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/Aop/Pointcut/AttributePointcut.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ final public function matches(
$instanceToCheck = $reflector;
}

if (!isset($instanceToCheck) || $instanceToCheck instanceof ReflectionFileNamespace) {
if ($instanceToCheck instanceof ReflectionFileNamespace) {
return false;
}

Expand Down
13 changes: 0 additions & 13 deletions src/Aop/Support/PointcutBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
use Go\Aop\Framework\AfterThrowingInterceptor;
use Go\Aop\Framework\AroundInterceptor;
use Go\Aop\Framework\BeforeInterceptor;
use Go\Aop\Framework\DeclareErrorInterceptor;
use Go\Core\AspectContainer;

/**
Expand Down Expand Up @@ -72,18 +71,6 @@ public function around(string $pointcutExpression, Closure $adviceToInvoke): voi
$this->registerAdviceInContainer($pointcutExpression, $interceptor);
}

/**
* Declares the error message for specific pointcut expression with concrete error level
*
* @param non-empty-string $message Error message to show for this intercepton
* @param positive-int $errorLevel Default level of error, only E_USER_* constants
*/
public function declareError(string $pointcutExpression, string $message, int $errorLevel = E_USER_ERROR): void
{
$interceptor = new DeclareErrorInterceptor($message, $errorLevel, $pointcutExpression);
$this->registerAdviceInContainer($pointcutExpression, $interceptor);
}

/**
* General method to register advices
*/
Expand Down
24 changes: 0 additions & 24 deletions src/Core/IntroductionAspectExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@

use Go\Aop\Advice;
use Go\Aop\Aspect;
use Go\Aop\Framework\DeclareErrorInterceptor;
use Go\Aop\Framework\TraitIntroductionInfo;
use Go\Aop\Pointcut;
use Go\Aop\Support\GenericPointcutAdvisor;
use Go\Lang\Attribute\AbstractAttribute;
use Go\Lang\Attribute\DeclareError;
use Go\Lang\Attribute\DeclareParents;
use ReflectionClass;
use ReflectionProperty;
Expand Down Expand Up @@ -51,11 +49,6 @@ public function load(Aspect $aspect, ReflectionClass $reflectionAspect): array
$advisor = new GenericPointcutAdvisor($pointcut, $advice);

$loadedItems[$propertyId] = $advisor;
} elseif ($attribute instanceof DeclareError) {
$pointcut = $this->parsePointcut($aspect, $reflectionAspect, $attribute->expression);
$advice = $this->getAdvice($attribute, $aspect, $aspectProperty);

$loadedItems[$propertyId] = new GenericPointcutAdvisor($pointcut, $advice);
} else {
throw new UnexpectedValueException('Unsupported attribute class: ' . get_class($attribute));
}
Expand All @@ -76,27 +69,10 @@ protected function getAdvice(
ReflectionProperty $aspectProperty
): Advice {
return match (true) {
$interceptorAttribute instanceof DeclareError =>
$this->createDeclareErrorAdvice($aspectProperty, $interceptorAttribute),
$interceptorAttribute instanceof DeclareParents =>
new TraitIntroductionInfo($interceptorAttribute->traitName, $interceptorAttribute->interfaceName),
default =>
throw new UnexpectedValueException('Unsupported attribute class: ' . get_class($interceptorAttribute)),
};
}

/**
* Creates a DeclareErrorInterceptor after validating the property's default value.
*
* @throws \UnexpectedValueException if the property default value is not a non-empty string
*/
private function createDeclareErrorAdvice(ReflectionProperty $aspectProperty, DeclareError $attribute): DeclareErrorInterceptor
{
$errorMessage = $aspectProperty->getDefaultValue();
if (!is_string($errorMessage) || $errorMessage === '') {
throw new \UnexpectedValueException('DeclareError property must have a non-empty string default value');
}

return new DeclareErrorInterceptor($errorMessage, $attribute->level, $attribute->expression);
}
}
34 changes: 0 additions & 34 deletions src/Lang/Attribute/DeclareError.php

This file was deleted.

Loading
Loading