Skip to content

Commit 0a1b533

Browse files
committed
Add missing emta
1 parent e865ba8 commit 0a1b533

File tree

9 files changed

+127
-32
lines changed

9 files changed

+127
-32
lines changed

specs/class/conditional.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ class A
6464
}
6565

6666
PHP
67-
,
67+
],
6868

69-
'Declaration in a namespace: prefix each namespace' => <<<'PHP'
69+
'Declaration in a namespace' => <<<'PHP'
7070
<?php
7171
7272
namespace Foo;
@@ -86,7 +86,7 @@ class A
8686
}
8787

8888
PHP
89-
],
89+
,
9090

9191
'Declaration of a whitelisted class' => [
9292
'whitelist' => ['Foo\A'],
@@ -110,7 +110,7 @@ class A
110110
}
111111

112112
PHP
113-
],
113+
],
114114

115115
'Multiple declarations in different namespaces' => <<<'PHP'
116116
<?php

specs/func-declaration/global.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ function foo()
9292

9393
'Function declaration in the global namespace' => [
9494
'whitelist' => ['X\Y', 'BAR_CONST'],
95+
'registered-functions' => [
96+
['foo', 'Humbug\foo'],
97+
],
9598
'payload' => <<<'PHP'
9699
<?php
97100
@@ -156,6 +159,9 @@ function foo(\Humbug\Foo $arg0, \Humbug\Foo $arg1, \Humbug\Foo\Bar $arg2, \Humbu
156159

157160
'Function declaration in the global namespace with globally whitelisted constants' => [
158161
'whitelist-global-constants' => true,
162+
'registered-functions' => [
163+
['foo', 'Humbug\foo'],
164+
],
159165
'payload' => <<<'PHP'
160166
<?php
161167
@@ -174,6 +180,9 @@ function foo(string $foo = \FOO_CONST)
174180

175181
'Function declaration in the global namespace with use statements' => [
176182
'whitelist' => ['X\Y'],
183+
'registered-functions' => [
184+
['foo', 'Humbug\foo'],
185+
],
177186
'payload' => <<<'PHP'
178187
<?php
179188
@@ -259,6 +268,9 @@ function foo(string $arg0, ?string $arg1, ?string $arg2 = null, \Humbug\Foo $arg
259268

260269
'Function declarations with return types in the global namespace with use statements' => [
261270
'whitelist' => ['X\Y'],
271+
'registered-functions' => [
272+
['foo', 'Humbug\foo'],
273+
],
262274
'payload' => <<<'PHP'
263275
<?php
264276

specs/func-declaration/namespace.php

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ function foo()
4545

4646
'Simple whitelisted function' => [
4747
'whitelist' => ['Acme\foo'],
48+
'registered-functions' => [
49+
['Acme\foo', 'Humbug\Acme\foo'],
50+
],
4851
'payload' => <<<'PHP'
4952
<?php
5053
@@ -61,26 +64,6 @@ function foo()
6164
{
6265
}
6366

64-
PHP
65-
],
66-
67-
'Simple whitelisted function with global functions non whitelisted' => [
68-
'whitelist-global-functions' => false,
69-
'whitelist' => ['foo'],
70-
'payload' => <<<'PHP'
71-
<?php
72-
73-
function foo() {}
74-
75-
----
76-
<?php
77-
78-
namespace Humbug;
79-
80-
function foo()
81-
{
82-
}
83-
8467
PHP
8568
],
8669

specs/function/global-scope-single-part-namespaced-func-with-single-level-use.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ class Foo
7070

7171
'Whitelisted namespaced function call imported with a partial use statement in the global scope' => [
7272
'whitelist' => ['Foo\main'],
73+
'registered-functions' => [
74+
['Foo\main', 'Humbug\Foo\main'],
75+
],
7376
'payload' => <<<'PHP'
7477
<?php
7578
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Humbug\PhpScoper\PhpParser\Node;
6+
use PhpParser\Node\Identifier;
7+
use PhpParser\Node\Name;
8+
9+
/**
10+
* Small wrapper to treat an identifier as a name node.
11+
*/
12+
final class NamedIdentifier extends Name
13+
{
14+
private $originalNode;
15+
16+
public static function create(Identifier $node): self
17+
{
18+
$instance = new self($node->name, $node->getAttributes());
19+
$instance->originalNode = $node;
20+
21+
return $instance;
22+
}
23+
24+
public function getOriginalNode(): Identifier
25+
{
26+
return $this->originalNode;
27+
}
28+
}

src/PhpParser/NodeVisitor/Collection/UseStmtCollection.php

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@
1515
namespace Humbug\PhpScoper\PhpParser\NodeVisitor\Collection;
1616

1717
use ArrayIterator;
18+
use function count;
19+
use Humbug\PhpScoper\PhpParser\Node\NamedIdentifier;
1820
use Humbug\PhpScoper\PhpParser\NodeVisitor\ParentNodeAppender;
1921
use IteratorAggregate;
22+
use PhpParser\Node;
2023
use PhpParser\Node\Expr\ConstFetch;
2124
use PhpParser\Node\Expr\FuncCall;
2225
use PhpParser\Node\Name;
2326
use PhpParser\Node\Stmt\ClassLike;
27+
use PhpParser\Node\Stmt\Function_;
2428
use PhpParser\Node\Stmt\Use_;
2529
use PhpParser\Node\Stmt\UseUse;
2630
use function Humbug\PhpScoper\clone_node;
@@ -68,8 +72,8 @@ public function findStatementForNode(?Name $namespaceName, Name $node): ?Name
6872
$parentNode = ParentNodeAppender::findParent($node);
6973

7074
if ($parentNode instanceof ClassLike
71-
&& $node->hasAttribute('original_node')
72-
&& $node->getAttribute('original_node') === $parentNode->name
75+
&& $node instanceof NamedIdentifier
76+
&& $node->getOriginalNode() === $parentNode->name
7377
) {
7478
// The current node can either be the class like name or one of its elements, e.g. extends or implements.
7579
// In the first case, the node was original an Identifier.
@@ -86,7 +90,7 @@ public function findStatementForNode(?Name $namespaceName, Name $node): ?Name
8690
}
8791

8892
if ($name === $useStatement->getAlias()->toLowerString()) {
89-
if ($parentNode instanceof FuncCall && 1 === count($node->parts)) {
93+
if ($this->isFunctionName($node, $parentNode)) {
9094
if (Use_::TYPE_FUNCTION === $use_->type) {
9195
return $useStatement->name;
9296
}
@@ -122,4 +126,22 @@ public function getIterator(): iterable
122126
{
123127
return new ArrayIterator($this->nodes);
124128
}
129+
130+
private function isFunctionName(Name $node, ?Node $parentNode): bool
131+
{
132+
if (null === $parentNode || 1 !== count($node->parts)) {
133+
return false;
134+
}
135+
136+
if ($parentNode instanceof FuncCall) {
137+
return true;
138+
}
139+
140+
if (false === ($parentNode instanceof Function_)) {
141+
return false;
142+
}
143+
/** @var Function_ $parentNode */
144+
145+
return $node instanceof NamedIdentifier && $node->getOriginalNode() === $parentNode->name;
146+
}
125147
}

src/PhpParser/NodeVisitor/FunctionIdentifierRecorder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function enterNode(Node $node): Node
5454

5555
$parent = ParentNodeAppender::getParent($node);
5656

57-
if (false === ($parent instanceof Function_)) {
57+
if (false === ($parent instanceof Function_) || $node === $parent->returnType) {
5858
return $node;
5959
}
6060

src/PhpParser/NodeVisitor/Resolver/FullyQualifiedNameResolver.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
namespace Humbug\PhpScoper\PhpParser\NodeVisitor\Resolver;
1616

17+
use Humbug\PhpScoper\PhpParser\Node\NamedIdentifier;
1718
use Humbug\PhpScoper\PhpParser\NodeVisitor\Collection\NamespaceStmtCollection;
1819
use Humbug\PhpScoper\PhpParser\NodeVisitor\Collection\UseStmtCollection;
1920
use Humbug\PhpScoper\PhpParser\NodeVisitor\NameStmtPrefixer;
@@ -53,10 +54,7 @@ public function resolveName(Node $node): ResolvedValue
5354
}
5455

5556
if ($node instanceof Identifier) {
56-
$attributes = $node->getAttributes();
57-
$attributes['original_node'] = $node;
58-
59-
$node = new Name($node->name, $attributes);
57+
$node = NamedIdentifier::create($node);
6058
}
6159

6260
$namespaceName = $this->namespaceStatements->findNamespaceForNode($node);

tests/Scoper/PhpScoperSpecTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
namespace Humbug\PhpScoper\Scoper;
1616

17+
use function array_diff;
18+
use function array_keys;
1719
use function array_map;
1820
use function current;
1921
use Generator;
@@ -22,6 +24,7 @@
2224
use Humbug\PhpScoper\Reflector;
2325
use Humbug\PhpScoper\Scoper;
2426
use Humbug\PhpScoper\Whitelist;
27+
use function is_array;
2528
use LogicException;
2629
use const PHP_EOL;
2730
use PhpParser\Error as PhpParserError;
@@ -50,6 +53,26 @@ class PhpScoperSpecTest extends TestCase
5053
private const SPECS_PATH = __DIR__.'/../../specs';
5154
private const SECONDARY_SPECS_PATH = __DIR__.'/../../_specs';
5255

56+
private const SPECS_META_KEYS = [
57+
'title',
58+
'prefix',
59+
'whitelist',
60+
'whitelist-global-constants',
61+
'whitelist-global-functions',
62+
'registered-classes',
63+
'registered-functions',
64+
];
65+
66+
private const SPECS_SPEC_KEYS = [
67+
'prefix',
68+
'whitelist',
69+
'whitelist-global-constants',
70+
'whitelist-global-functions',
71+
'registered-classes',
72+
'registered-functions',
73+
'payload',
74+
];
75+
5376
/**
5477
* This test is to ensure no file is left in _specs for the CI. It is fine otherwise for this test to fail locally
5578
* when developing something.
@@ -196,6 +219,32 @@ private function parseSpecFile(array $meta, $fixtureTitle, $fixtureSet): Generat
196219

197220
$payloadParts = preg_split("/\n----(?:\n|$)/", $payload);
198221

222+
$this->assertSame(
223+
[],
224+
$diff = array_diff(
225+
array_keys($meta),
226+
self::SPECS_META_KEYS
227+
),
228+
sprintf(
229+
'Expected the keys found in the meta section to be known keys, unknown keys: "%s"',
230+
implode('", "', $diff)
231+
)
232+
);
233+
234+
if (is_array($fixtureSet)) {
235+
$this->assertSame(
236+
[],
237+
$diff = array_diff(
238+
array_keys($fixtureSet),
239+
self::SPECS_SPEC_KEYS
240+
),
241+
sprintf(
242+
'Expected the keys found in the spec section to be known keys, unknown keys: "%s"',
243+
implode('", "', $diff)
244+
)
245+
);
246+
}
247+
199248
yield [
200249
$spec,
201250
$payloadParts[0], // Input

0 commit comments

Comments
 (0)