Skip to content

Commit

Permalink
Fixed "type mismatch" errors
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterWoshid committed May 11, 2024
2 parents 67a5d91 + c6617f6 commit 359207a
Show file tree
Hide file tree
Showing 14 changed files with 163 additions and 375 deletions.
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"name": "okapi/aop",
"description": "PHP AOP is a PHP library that provides a powerful Aspect Oriented Programming (AOP) implementation for PHP.",
"version": "1.2.10",
"type": "library",
"homepage": "https://github.com/okapi-web/php-aop",
"license": "MIT",
Expand Down
6 changes: 0 additions & 6 deletions src/AopKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use Okapi\Aop\Core\Container\{AspectManager, TransformerManager};
use Okapi\Aop\Core\Options;
use Okapi\Aop\Core\Processor\AspectProcessor;
use Okapi\Aop\Core\Transformer\NetteReflectionWithBetterReflection;
use Okapi\CodeTransformer\CodeTransformerKernel;
use Okapi\CodeTransformer\Core\AutoloadInterceptor\ClassLoader as CodeTransformerClassLoader;
use Okapi\CodeTransformer\Core\Cache\CachePaths as CodeTransformerCachePaths;
Expand Down Expand Up @@ -110,11 +109,6 @@ protected static function registerDependencyInjection(): void
*/
protected function preInit(): void
{
// Add internal transformers
$this->transformerManager->addTransformers([
NetteReflectionWithBetterReflection::class,
]);

// Add the aspects
$this->aspectManager->addAspects($this->aspects);

Expand Down
2 changes: 1 addition & 1 deletion src/Attributes/After.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*
* This attribute is used to mark a method as an after advice.
*/
#[Attribute(Attribute::TARGET_METHOD)]
#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
class After extends MethodAdvice
{
}
2 changes: 1 addition & 1 deletion src/Attributes/Around.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*
* This attribute is used to mark a method as an around advice.
*/
#[Attribute(Attribute::TARGET_METHOD)]
#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
class Around extends MethodAdvice
{
}
2 changes: 1 addition & 1 deletion src/Attributes/Before.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*
* This attribute is used to mark a method as a before advice.
*/
#[Attribute(Attribute::TARGET_METHOD)]
#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
class Before extends MethodAdvice
{
}
48 changes: 0 additions & 48 deletions src/Core/.phpstorm.meta.php

This file was deleted.

54 changes: 0 additions & 54 deletions src/Core/Transform/ProxiedClassModifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,17 +203,6 @@ private function changeVisibility(): void
private function replaceSelfType(): void
{
$this->nodeCallbacks[] = function (Node $node) {
// Replace parameter object types with the proxied class name
if ($node instanceof Node\Parameter
&& $node->typeDeclarationList instanceof Node\DelimitedList\QualifiedNameList
) {
foreach ($node->typeDeclarationList->children as $type) {
if ($type instanceof Node\QualifiedName) {
$this->replaceParameterSelfType($type);
}
}
}

// Replace return object types with the proxied class name
if ($node instanceof Node\MethodDeclaration
&& $node->returnTypeList instanceof Node\DelimitedList\QualifiedNameList
Expand All @@ -234,49 +223,6 @@ private function replaceSelfType(): void
};
}

/**
* Replace the parameter self type with the proxied class name.
*
* @param Node\QualifiedName $qualifiedName
*
* @return void
*
* @noinspection PhpDocMissingThrowsInspection
*/
private function replaceParameterSelfType(
Node\QualifiedName $qualifiedName,
): void {
$typeText = $qualifiedName->getText();

// Self
if ($typeText === 'self') {
$this->edit(
$qualifiedName,
$this->proxiedClassName,
);

return;
}

// Other classes that have a proxy
/** @noinspection PhpUnhandledExceptionInspection */
$fullClassName = '\\' . $qualifiedName->getResolvedName()
->getFullyQualifiedNameText();
$proxyClassName = $fullClassName
. $this->cachePaths::PROXIED_SUFFIX;

// Autoload the class with class_exists,
// so we can check if the proxy exists
if (class_exists($fullClassName)
&& class_exists($proxyClassName)
) {
$this->edit(
$qualifiedName,
$proxyClassName,
);
}
}

/**
* Replace the return self type with the proxied class name.
*
Expand Down
98 changes: 22 additions & 76 deletions src/Core/Transform/WovenClassBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
use Nette\PhpGenerator\ClassType;
use Nette\PhpGenerator\Factory;
use Nette\PhpGenerator\Method;
use Nette\PhpGenerator\Parameter;
use Nette\PhpGenerator\PhpNamespace;
use Nette\PhpGenerator\PromotedParameter;
use Nette\PhpGenerator\Property;
use Nette\Utils\Type;
use Okapi\Aop\Core\Cache\CachePaths;
use Okapi\Aop\Core\Container\AdviceContainer;
use Okapi\Aop\Core\Container\AdviceType\MethodAdviceContainer;
use Okapi\Aop\Core\JoinPoint\JoinPoint;
use Okapi\Aop\Core\JoinPoint\JoinPointInjector;
use Okapi\CodeTransformer\Core\DI;
use Okapi\CodeTransformer\Transformer\Code;
use Roave\BetterReflection\Reflection\Adapter\ReflectionMethod;
use Roave\BetterReflection\Reflection\ReflectionMethod as BetterReflectionMethod;

/**
Expand Down Expand Up @@ -206,24 +206,31 @@ private function buildMethods(): array
* @param BetterReflectionMethod $refMethod
*
* @return Method
*
* @noinspection PhpDocMissingThrowsInspection
*/
private function buildMethod(BetterReflectionMethod $refMethod): Method
{
$method = (new Factory)->fromMethodReflection($refMethod);
/** @noinspection PhpUnhandledExceptionInspection */
$method = (new Factory)->fromMethodReflection(
new ReflectionMethod($refMethod),
);

$methodName = $refMethod->getName();

// Replace parameter and return types with the proxied class
$declaringClass = $refMethod->getDeclaringClass();
$fullClassName = '\\' . $declaringClass->getNamespaceName()
. '\\' . $declaringClass->getShortName();
$proxiedClassName = $fullClassName . $this->cachePaths::PROXIED_SUFFIX;
foreach ($method->getParameters() as $parameter) {
$this->replaceParameterType($parameter, $proxiedClassName);
}
if ($method->getReturnType() === 'self') {
$method->setReturnType(
$proxiedClassName,
);
// ReadOnly Hack: https://github.com/nette/php-generator/issues/158
foreach ($refMethod->getParameters() as $refParameter) {
if ($refParameter->isPromoted()
&& ($declaringClass = $refParameter->getDeclaringClass())
&& ($refParameterName = $refParameter->getName())
&& $declaringClass->hasProperty($refParameterName)
&& ($property = $declaringClass->getProperty($refParameterName))
&& $property->isReadOnly()
) {
/** @var PromotedParameter $parameter */
$parameter = $method->getParameter($refParameterName);
$parameter->setReadOnly();
}
}

// Add "return" if the method has a return type
Expand Down Expand Up @@ -260,67 +267,6 @@ private function buildMethod(BetterReflectionMethod $refMethod): Method
return $method;
}

/**
* Replace the parameter type with the proxied class.
*
* @param Parameter|Type $parameterOrType
* @param string $proxiedClassName
*
* @return void
*/
private function replaceParameterType(
Parameter|Type $parameterOrType,
string $proxiedClassName
): void {
$objectType = $parameterOrType instanceof Parameter
? $parameterOrType->getType(true)
: $parameterOrType;
if (!$objectType) {
return;
}

$typeString = $this->getTypeString($objectType, $proxiedClassName);
$parameterOrType->setType($typeString);
}

/**
* Get the parameter array as a string.
*
* @param Type $type
* @param string $proxiedClassName
*
* @return string
*/
private function getTypeString(Type $type, string $proxiedClassName): string
{
// If the type is a union or intersection, we need to replace each type
if ($type->isUnion() || $type->isIntersection()) {
$typeNames = array_map(function ($type) use ($proxiedClassName) {
return $this->getTypeString($type, $proxiedClassName);
}, $type->getTypes());
$glue = $type->isUnion() ? '|' : '&';
return implode($glue, $typeNames);
} elseif ($type->getSingleName() === 'self') {
// If the type is "self", we need to replace it with the proxied
// class
return $proxiedClassName;
} elseif ($type->isClass()) {
// If the type is a class, we need to check if the class
// is a proxy
$typeFullClassName = '\\' . $type->getSingleName();
$typeProxiedClassName =
$typeFullClassName . $this->cachePaths::PROXIED_SUFFIX;

if (class_exists($typeFullClassName)
&& class_exists($typeProxiedClassName)
) {
return $typeProxiedClassName;
}
}

return $type->getSingleName();
}

/**
* Create an associative array with the parameter name as key and the
* parameter as value.
Expand Down
Loading

0 comments on commit 359207a

Please sign in to comment.