Skip to content

Commit 1275a48

Browse files
authored
Bring better performances (#329)
- Remove the deprecated `Humbug\PhpScoper\Console\Configuration` and make the parent `Humbug\PhpScoper\Configuration` final - Replace usage of `uniqid` by `bin2hex(random_bytes())` - Move namespace related `PhpParser` classes under `PhpParser\NamespaceStmt` - Similar change as namespaces for use statements - Introduce `NamespaceManipulator` and `UseStmtManipulator` in order to add the original name of the statement as an attribute and leverage this instead of (deep) cloning the whole node; this avoid to have to rely on heavy `serialize`/`unserialize` calls - Heavily simplify the `Reflector` class by leveraging the phpstorm stub maps (which is generated by BetterReflection at the moment) instead of requiring to retrieve the whole reflection class for a given symbol Closes #321
1 parent 6c036d4 commit 1275a48

25 files changed

+231
-387
lines changed

src/Configuration.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,7 @@
3636
use function realpath;
3737
use function sprintf;
3838

39-
/**
40-
* @final
41-
* TODO: make this class as final as soon as the underlying deprecated class is removed.
42-
*/
43-
class Configuration
39+
final class Configuration
4440
{
4541
private const PREFIX_KEYWORD = 'prefix';
4642
private const WHITELISTED_FILES_KEYWORD = 'files-whitelist';

src/Console/Command/AddPrefixCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,6 @@ private function makeAbsolutePath(string $path): string
478478

479479
private function generateRandomPrefix(): string
480480
{
481-
return uniqid('_PhpScoper', false);
481+
return '_PhpScoper'.bin2hex(random_bytes(6));
482482
}
483483
}

src/Console/Configuration.php

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/Container.php

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,11 @@
2323
use Humbug\PhpScoper\Scoper\SymfonyScoper;
2424
use PhpParser\Parser;
2525
use PhpParser\ParserFactory;
26-
use Roave\BetterReflection\Reflector\ClassReflector;
27-
use Roave\BetterReflection\Reflector\ConstantReflector;
28-
use Roave\BetterReflection\Reflector\FunctionReflector;
29-
use Roave\BetterReflection\SourceLocator\Ast\Locator;
30-
use Roave\BetterReflection\SourceLocator\SourceStubber\AggregateSourceStubber;
31-
use Roave\BetterReflection\SourceLocator\SourceStubber\PhpStormStubsSourceStubber;
32-
use Roave\BetterReflection\SourceLocator\SourceStubber\ReflectionSourceStubber;
33-
use Roave\BetterReflection\SourceLocator\Type\MemoizingSourceLocator;
34-
use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator;
3526

3627
final class Container
3728
{
3829
private $parser;
3930
private $reflector;
40-
private $functionReflector;
4131
private $scoper;
4232

4333
public function getScoper(): Scoper
@@ -73,34 +63,7 @@ public function getParser(): Parser
7363
public function getReflector(): Reflector
7464
{
7565
if (null === $this->reflector) {
76-
$phpParser = $this->getParser();
77-
78-
$astLocator = new Locator(
79-
$phpParser,
80-
function (): FunctionReflector {
81-
return $this->functionReflector;
82-
}
83-
);
84-
85-
$sourceLocator = new MemoizingSourceLocator(
86-
new PhpInternalSourceLocator(
87-
$astLocator,
88-
new AggregateSourceStubber(
89-
new PhpStormStubsSourceStubber($phpParser),
90-
new ReflectionSourceStubber()
91-
)
92-
)
93-
);
94-
95-
$classReflector = new ClassReflector($sourceLocator);
96-
97-
$this->functionReflector = new FunctionReflector($sourceLocator, $classReflector);
98-
99-
$this->reflector = new Reflector(
100-
$classReflector,
101-
$this->functionReflector,
102-
new ConstantReflector($sourceLocator, $classReflector)
103-
);
66+
$this->reflector = new Reflector();
10467
}
10568

10669
return $this->reflector;

src/PhpParser/NodeVisitor/FunctionIdentifierRecorder.php renamed to src/PhpParser/NodeVisitor/NamespaceStmt/FunctionIdentifierRecorder.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
* file that was distributed with this source code.
1313
*/
1414

15-
namespace Humbug\PhpScoper\PhpParser\NodeVisitor;
15+
namespace Humbug\PhpScoper\PhpParser\NodeVisitor\NamespaceStmt;
1616

17+
use Humbug\PhpScoper\PhpParser\NodeVisitor\ParentNodeAppender;
1718
use Humbug\PhpScoper\PhpParser\NodeVisitor\Resolver\FullyQualifiedNameResolver;
1819
use Humbug\PhpScoper\Reflector;
1920
use Humbug\PhpScoper\Whitelist;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the humbug/php-scoper package.
7+
*
8+
* Copyright (c) 2017 Théo FIDRY <[email protected]>,
9+
* Pádraic Brady <[email protected]>
10+
*
11+
* For the full copyright and license information, please view the LICENSE
12+
* file that was distributed with this source code.
13+
*/
14+
15+
namespace Humbug\PhpScoper\PhpParser\NodeVisitor\NamespaceStmt;
16+
17+
use PhpParser\Node\Name;
18+
use PhpParser\Node\Stmt\Namespace_;
19+
use PhpParser\NodeVisitorAbstract;
20+
21+
/**
22+
* @private
23+
*/
24+
final class NamespaceManipulator extends NodeVisitorAbstract
25+
{
26+
private const ORIGINAL_NAME_ATTRIBUTE = 'originalName';
27+
28+
public static function hasOriginalName(Namespace_ $namespace): bool
29+
{
30+
return $namespace->hasAttribute(self::ORIGINAL_NAME_ATTRIBUTE);
31+
}
32+
33+
public static function getOriginalName(Namespace_ $namespace): ?Name
34+
{
35+
if (false === self::hasOriginalName($namespace)) {
36+
return $namespace->name;
37+
}
38+
39+
return $namespace->getAttribute(self::ORIGINAL_NAME_ATTRIBUTE);
40+
}
41+
42+
public static function setOriginalName(Namespace_ $namespace, ?Name $originalName): void
43+
{
44+
$namespace->setAttribute(self::ORIGINAL_NAME_ATTRIBUTE, $originalName);
45+
}
46+
47+
private function __construct()
48+
{
49+
}
50+
}

src/PhpParser/NodeVisitor/Collection/NamespaceStmtCollection.php renamed to src/PhpParser/NodeVisitor/NamespaceStmt/NamespaceStmtCollection.php

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* file that was distributed with this source code.
1313
*/
1414

15-
namespace Humbug\PhpScoper\PhpParser\NodeVisitor\Collection;
15+
namespace Humbug\PhpScoper\PhpParser\NodeVisitor\NamespaceStmt;
1616

1717
use ArrayIterator;
1818
use Countable;
@@ -43,14 +43,13 @@ final class NamespaceStmtCollection implements IteratorAggregate, Countable
4343
private $mapping = [];
4444

4545
/**
46-
* @param Namespace_ $node New namespace, may have been prefixed.
47-
* @param Namespace_ $originalName Original unchanged namespace.
46+
* @param Namespace_ $namespace New namespace, may have been prefixed.
4847
*/
49-
public function add(Namespace_ $node, Namespace_ $originalName): void
48+
public function add(Namespace_ $namespace): void
5049
{
51-
$this->nodes[] = $originalName;
50+
$this->nodes[] = $namespace;
5251

53-
$this->mapping[(string) $node->name] = $originalName->name;
52+
$this->mapping[(string) $namespace->name] = NamespaceManipulator::getOriginalName($namespace);
5453
}
5554

5655
public function findNamespaceForNode(Node $node): ?Name
@@ -61,16 +60,16 @@ public function findNamespaceForNode(Node $node): ?Name
6160

6261
// Shortcut if there is only one namespace
6362
if (1 === count($this->nodes)) {
64-
return $this->nodes[0]->name;
63+
return NamespaceManipulator::getOriginalName($this->nodes[0]);
6564
}
6665

67-
return $this->getNodeNamespace($node);
66+
return $this->getNodeNamespaceName($node);
6867
}
6968

7069
public function findNamespaceByName(string $name): ?Name
7170
{
7271
foreach ($this->nodes as $node) {
73-
if ((string) $node->name === $name) {
72+
if ((string) NamespaceManipulator::getOriginalName($node) === $name) {
7473
return $node->name;
7574
}
7675
}
@@ -82,7 +81,7 @@ public function getCurrentNamespaceName(): ?Name
8281
{
8382
$lastNode = end($this->nodes);
8483

85-
return false === $lastNode ? null : $lastNode->name;
84+
return false === $lastNode ? null : NamespaceManipulator::getOriginalName($lastNode);
8685
}
8786

8887
/**
@@ -93,7 +92,7 @@ public function count(): int
9392
return count($this->nodes);
9493
}
9594

96-
private function getNodeNamespace(Node $node): ?Name
95+
private function getNodeNamespaceName(Node $node): ?Name
9796
{
9897
if (false === ParentNodeAppender::hasParent($node)) {
9998
return null;
@@ -105,7 +104,7 @@ private function getNodeNamespace(Node $node): ?Name
105104
return $this->mapping[(string) $parentNode->name];
106105
}
107106

108-
return $this->getNodeNamespace($parentNode);
107+
return $this->getNodeNamespaceName($parentNode);
109108
}
110109

111110
/**

src/PhpParser/NodeVisitor/NamespaceStmtPrefixer.php renamed to src/PhpParser/NodeVisitor/NamespaceStmt/NamespaceStmtPrefixer.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@
1212
* file that was distributed with this source code.
1313
*/
1414

15-
namespace Humbug\PhpScoper\PhpParser\NodeVisitor;
15+
namespace Humbug\PhpScoper\PhpParser\NodeVisitor\NamespaceStmt;
1616

17-
use Humbug\PhpScoper\PhpParser\NodeVisitor\Collection\NamespaceStmtCollection;
1817
use Humbug\PhpScoper\Whitelist;
1918
use PhpParser\Node;
2019
use PhpParser\Node\Name;
2120
use PhpParser\Node\Stmt\Namespace_;
2221
use PhpParser\NodeVisitorAbstract;
23-
use function Humbug\PhpScoper\clone_node;
2422

2523
/**
2624
* Prefixes the relevant namespaces.
@@ -63,15 +61,15 @@ public function enterNode(Node $node): Node
6361

6462
private function prefixNamespaceStmt(Namespace_ $namespace): Node
6563
{
66-
$originalNamespace = $namespace;
67-
6864
if ($this->shouldPrefixStmt($namespace)) {
69-
$originalNamespace = clone_node($namespace);
65+
$originalName = $namespace->name;
7066

7167
$namespace->name = Name::concat($this->prefix, $namespace->name);
68+
69+
NamespaceManipulator::setOriginalName($namespace, $originalName);
7270
}
7371

74-
$this->namespaceStatements->add($namespace, $originalNamespace);
72+
$this->namespaceStatements->add($namespace);
7573

7674
return $namespace;
7775
}

src/PhpParser/NodeVisitor/ParentNodeAppender.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
/**
2222
* Appends the parent node as an attribute to each node. This allows to have more context in the other visitors when
2323
* inspecting a node.
24-
* TODO: rename to ParentNodeAppender.
2524
*
2625
* @private
2726
*/

src/PhpParser/NodeVisitor/Resolver/FullyQualifiedNameResolver.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
namespace Humbug\PhpScoper\PhpParser\NodeVisitor\Resolver;
1616

1717
use Humbug\PhpScoper\PhpParser\Node\NamedIdentifier;
18-
use Humbug\PhpScoper\PhpParser\NodeVisitor\Collection\NamespaceStmtCollection;
19-
use Humbug\PhpScoper\PhpParser\NodeVisitor\Collection\UseStmtCollection;
18+
use Humbug\PhpScoper\PhpParser\NodeVisitor\NamespaceStmt\NamespaceStmtCollection;
2019
use Humbug\PhpScoper\PhpParser\NodeVisitor\NameStmtPrefixer;
2120
use Humbug\PhpScoper\PhpParser\NodeVisitor\ParentNodeAppender;
21+
use Humbug\PhpScoper\PhpParser\NodeVisitor\UseStmt\UseStmtCollection;
2222
use PhpParser\Node;
2323
use PhpParser\Node\Expr\ConstFetch;
2424
use PhpParser\Node\Expr\FuncCall;

0 commit comments

Comments
 (0)