Skip to content

Commit

Permalink
fix: swoft-cloud/swoft/issues/1246 optimize proxy class generate logic
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Apr 12, 2020
1 parent bac7277 commit e1f68c0
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 52 deletions.
7 changes: 3 additions & 4 deletions src/proxy/src/Ast/Parser.php
@@ -1,11 +1,8 @@
<?php declare(strict_types=1);


namespace Swoft\Proxy\Ast;

use Exception;
use function file_exists;
use function file_get_contents;
use PhpParser\ErrorHandler;
use PhpParser\Lexer;
use PhpParser\NodeTraverser;
Expand All @@ -14,6 +11,8 @@
use PhpParser\PrettyPrinter\Standard;
use Swoft\Proxy\Exception\ProxyException;
use Swoft\Stdlib\Helper\ComposerHelper;
use function file_exists;
use function file_get_contents;

/**
* Class Parser
Expand Down Expand Up @@ -126,4 +125,4 @@ private function getCodeByClassName(string $className): string

return file_get_contents($file);
}
}
}
9 changes: 6 additions & 3 deletions src/proxy/src/Ast/Visitor/Visitor.php
@@ -1,13 +1,16 @@
<?php declare(strict_types=1);


namespace Swoft\Proxy\Ast\Visitor;


use PhpParser\NodeVisitorAbstract;
use Swoft\Proxy\Contract\VisitorInterface;

/**
* Class Visitor
*
* @package Swoft\Proxy\Ast\Visitor
*/
abstract class Visitor extends NodeVisitorAbstract implements VisitorInterface
{

}
}
3 changes: 1 addition & 2 deletions src/proxy/src/Contract/VisitorInterface.php
@@ -1,6 +1,5 @@
<?php declare(strict_types=1);


namespace Swoft\Proxy\Contract;

/**
Expand All @@ -19,4 +18,4 @@ public function getProxyName(): string;
* @return string
*/
public function getProxyClassName(): string;
}
}
66 changes: 42 additions & 24 deletions src/proxy/src/Proxy.php
@@ -1,20 +1,30 @@
<?php declare(strict_types=1);


namespace Swoft\Proxy;


use function file_put_contents;
use const PHP_EOL;
use function sprintf;
use Swoft\Proxy\Ast\Parser;
use Swoft\Proxy\Ast\Visitor\Visitor;
use Swoft\Proxy\Contract\VisitorInterface;
use Swoft\Proxy\Exception\ProxyException;
use Swoft\Stdlib\Helper\Sys;
use function file_put_contents;
use function sprintf;
use const PHP_EOL;

/**
* Class Proxy
*
* @package Swoft\Proxy
*/
class Proxy
{
/**
* Optimize logic
* - Save classes that have been parsed and generated to avoid repeated parsing and loading
*
* @var array
*/
private static $caches = [];

/**
* New class name by proxy
*
Expand All @@ -26,19 +36,17 @@ class Proxy
*/
public static function newClassName(string $className, Visitor $visitor): string
{
$parser = new Parser();

$visitorClassName = get_class($visitor);
if (!$visitor instanceof VisitorInterface) {
throw new ProxyException(
sprintf('%s is not instance of %s', $visitorClassName, VisitorInterface::class)
);
if (isset(self::$caches[$className])) {
return self::$caches[$className];
}

$parser->addNodeVisitor($visitorClassName, $visitor);
$parser = new Parser();
$parser->addNodeVisitor(get_class($visitor), $visitor);

$proxyCode = $parser->parse($className);
$proxyName = $visitor->getProxyName();
// New proxy class name
$newClassName = $visitor->getProxyClassName();

// Proxy file and proxy code
$proxyFile = sprintf('%s/%s.php', Sys::getTempDir(), $proxyName);
Expand All @@ -50,18 +58,28 @@ public static function newClassName(string $className, Visitor $visitor): string
throw new ProxyException(sprintf('Proxy file(%s) generate fail', $proxyFile));
}

// Load proxy php file
// Load new proxy class file.
self::loadProxyClass($proxyFile);

// Ensure proxy class is loaded
if (!class_exists($newClassName)) {
throw new ProxyException(sprintf('Proxy class(%s) is not exist!', $newClassName));
}

// Add cache, mark has been required.
self::$caches[$className] = $newClassName;
return $newClassName;
}

/**
* @param string $proxyFile
*/
private static function loadProxyClass(string $proxyFile): void
{
/** @noinspection PhpIncludeInspection */
require $proxyFile;

// Remove proxy file
unlink($proxyFile);

// Proxy class
$proxyClassName = $visitor->getProxyClassName();
if (!class_exists($proxyClassName)) {
throw new ProxyException(sprintf('Proxy class(%s) is not exist!', $proxyClassName));
}

return $proxyClassName;
}
}
}
4 changes: 1 addition & 3 deletions src/proxy/test/unit/ProxyTest.php
@@ -1,9 +1,7 @@
<?php declare(strict_types=1);


namespace SwoftTest\Proxy\Unit;


use PHPUnit\Framework\TestCase;

/**
Expand All @@ -17,4 +15,4 @@ public function testA()
{
$this->assertTrue(true);
}
}
}
2 changes: 0 additions & 2 deletions src/rpc-client/src/Annotation/Parser/ReferenceParser.php
@@ -1,9 +1,7 @@
<?php declare(strict_types=1);


namespace Swoft\Rpc\Client\Annotation\Parser;


use PhpDocReader\AnnotationException;
use PhpDocReader\PhpDocReader;
use ReflectionException;
Expand Down
2 changes: 1 addition & 1 deletion src/rpc-client/src/Concern/ServiceTrait.php
Expand Up @@ -20,7 +20,6 @@
*/
trait ServiceTrait
{

/**
* @param string $interfaceClass
* @param string $methodName
Expand All @@ -30,6 +29,7 @@ trait ServiceTrait
* @throws ConnectionPoolException
* @throws RpcClientException
* @throws RpcResponseException
* @noinspection MagicMethodsValidityInspection
*/
protected function __proxyCall(string $interfaceClass, string $methodName, array $params)
{
Expand Down
29 changes: 16 additions & 13 deletions src/rpc-client/src/Proxy/Ast/ProxyVisitor.php
Expand Up @@ -8,9 +8,9 @@
use PhpParser\NodeTraverser;
use Swoft\Proxy\Ast\Visitor\Visitor;
use Swoft\Rpc\Client\Concern\ServiceTrait;
use Swoft\Stdlib\Helper\Str;
use function array_unshift;
use function sprintf;
use function uniqid;

/**
* Class ProxyVisitor
Expand All @@ -20,28 +20,28 @@
class ProxyVisitor extends Visitor
{
/**
* Namespace
* Namespace. eg: "App\Rpc\Lib"
*
* @var string
*/
private $namespace = '';

/**
* New class name
* New class name suffix. eg: "IGNORE_5e92a0ad04171"
*
* @var string
*/
private $proxyId;

/**
* Origin class name
* Origin interface class name. eg: "App\Rpc\Lib\UserInterface"
*
* @var string
*/
private $originalInterfaceName = '';

/**
* Proxy class name without namespace
* Proxy class name without namespace. eg: "UserInterface_IGNORE_5e92a0ad04171"
*
* @var string
*/
Expand All @@ -57,13 +57,15 @@ class ProxyVisitor extends Visitor
/**
* ProxyVisitor constructor.
*
* TODO 鎻愬墠浼犲叆鍘熺被鍚嶏紝鍙互鐩存帴寰楀埌 namespace, proxyName, originalInterfaceName
*
* @param string $proxyId
* @param string $TraitClassName
* @param string $traitClassName
*/
public function __construct(string $proxyId = '', string $TraitClassName = ServiceTrait::class)
public function __construct(string $proxyId = '', string $traitClassName = ServiceTrait::class)
{
$this->serviceTrait = $TraitClassName;
$this->proxyId = $proxyId ?: uniqid();
$this->serviceTrait = $traitClassName;
$this->proxyId = $proxyId ?: Str::getUniqid();
}

/**
Expand All @@ -83,7 +85,8 @@ public function enterNode(Node $node)

// Origin interface node
if ($node instanceof Node\Stmt\Interface_) {
$name = $node->name->toString();
$name = $node->name->toString();

$this->proxyName = sprintf('%s_%s', $name, $this->proxyId);
$this->originalInterfaceName = sprintf('%s\\%s', $this->namespace, $name);

Expand Down Expand Up @@ -141,10 +144,10 @@ public function afterTraverse(array $nodes)
/** @var Node\Stmt\Class_ $classNode */
$classNode = $nodeFinder->findFirstInstanceOf($nodes, Node\Stmt\Class_::class);

$traitNode = $this->getTraitNode();
$originalMethodNode = $this->getOriginalClassNameMethodNode();
$traitNode = $this->getTraitNode();
$orgMethodNode = $this->getOriginalClassNameMethodNode();

array_unshift($classNode->stmts, $traitNode, $originalMethodNode);
array_unshift($classNode->stmts, $traitNode, $orgMethodNode);
return $nodes;
}

Expand Down

0 comments on commit e1f68c0

Please sign in to comment.