Skip to content

Commit

Permalink
retry...
Browse files Browse the repository at this point in the history
  • Loading branch information
theofidry committed May 18, 2024
1 parent ccf574d commit 4ca5680
Show file tree
Hide file tree
Showing 20 changed files with 387 additions and 26 deletions.
18 changes: 18 additions & 0 deletions .makefile/e2e.file
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,24 @@ e2e_040: $(PHP_SCOPER_PHAR_BIN)

diff fixtures/set040-polyfills/expected-output build/set040/output

.PHONY: e2e_041
m: # Runs end-to-end tests for the fixture set e2e_041 — Codebase using a polyfill
e2e_041: $(PHP_SCOPER_PHAR_BIN)
rm -rf fixtures/set041-exposed-symbols-hierarchy/vendor || true
composer --working-dir=fixtures/set041-exposed-symbols-hierarchy dump-autoload

$(PHP_SCOPER_PHAR) add-prefix . \
--working-dir=fixtures/set041-exposed-symbols-hierarchy \
--output-dir=../../build/set041 \
--force \
--no-interaction \
--stop-on-failure
composer --working-dir=build/set041 dump-autoload

php build/set041/index.php > build/set041/output || true

diff fixtures/set041-exposed-symbols-hierarchy/expected-output build/set041/output


#
# Rules from files
Expand Down
108 changes: 108 additions & 0 deletions _specs/expose-hierarchy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

declare(strict_types=1);

/*
* This file is part of the humbug/php-scoper package.
*
* Copyright (c) 2017 Théo FIDRY <[email protected]>,
* Pádraic Brady <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

use Humbug\PhpScoper\SpecFramework\Config\Meta;
use Humbug\PhpScoper\SpecFramework\Config\SpecWithConfig;

return [
'meta' => new Meta(
title: 'Ensures the exposed symbols follow the required hierarchy.',
exposeClasses: ['/.h*/'],
),

'PHP 8.1 Polyfill (right order)' => SpecWithConfig::create(
spec: <<<'PHP'
<?php
interface Stringeable {}
class PhpTokens implements Stringeable {}
----
<?php
namespace Humbug;
interface Stringeable
{
}
\class_alias('Humbug\Stringeable', 'Stringeable', \false);
class PhpTokens implements \Humbug\Stringeable
{
}
\class_alias('Humbug\PhpTokens', 'PhpTokens', \false);

PHP,
expectedRecordedClasses: [
['Stringeable', 'Humbug\Stringeable'],
['PhpTokens', 'Humbug\PhpTokens'],
],
),

'PHP 8.1 Polyfill (wrong order)' => SpecWithConfig::create(
spec: <<<'PHP'
<?php
class PhpTokens implements Stringeable {}
interface Stringeable {}
----
<?php
namespace Humbug;
class PhpTokens implements \Humbug\Stringeable
{
}
\class_alias('Humbug\PhpTokens', 'PhpTokens', \false);
interface Stringeable
{
}
\class_alias('Humbug\Stringeable', 'Stringeable', \false);

PHP,
expectedRecordedClasses: [
['Stringeable', 'Humbug\Stringeable'],
['PhpTokens', 'Humbug\PhpTokens'],
],
),

'simple case with extend' => SpecWithConfig::create(
spec: <<<'PHP'
<?php
class Frame extends Window {}
abstract class Window implements ObjectInterface {}
interface ObjectInterface {}
----
<?php
namespace Humbug;
class PhpTokens implements \Humbug\Stringeable
{
}
\class_alias('Humbug\PhpTokens', 'PhpTokens', \false);
interface Stringeable
{
}
\class_alias('Humbug\Stringeable', 'Stringeable', \false);

PHP,
expectedRecordedClasses: [
['Stringeable', 'Humbug\Stringeable'],
['PhpTokens', 'Humbug\PhpTokens'],
],
),
];
10 changes: 10 additions & 0 deletions fixtures/set041-exposed-symbols-hierarchy/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"bin": "index.php",
"autoload": {
"psr-4": {
"Set041\\Polyfill\\": "polyfill/",
"": "src/"
},
"classmap": ["stubs"]
}
}
18 changes: 18 additions & 0 deletions fixtures/set041-exposed-symbols-hierarchy/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions fixtures/set041-exposed-symbols-hierarchy/expected-output
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
OK.
10 changes: 10 additions & 0 deletions fixtures/set041-exposed-symbols-hierarchy/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php declare(strict_types=1);

require file_exists(__DIR__.'/vendor/scoper-autoload.php')
? __DIR__.'/vendor/scoper-autoload.php'
: __DIR__.'/vendor/autoload.php';

new Frame();
new Window();

echo "OK.".PHP_EOL;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Set041\Polyfill;

final class PhpTokenLike implements \StringeableLike
{
}
13 changes: 13 additions & 0 deletions fixtures/set041-exposed-symbols-hierarchy/scoper.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php declare(strict_types=1);

return [
'exclude-files' => [
__DIR__.'/index.php',
],
'expose-classes' => [
'Set041\Polyfill\PhpTokenLike',
],
'exclude-classes' => [
'StringeableLike',
],
];
5 changes: 5 additions & 0 deletions fixtures/set041-exposed-symbols-hierarchy/src/Component.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php declare(strict_types=1);

abstract class Component implements ObjectInterface
{
}
5 changes: 5 additions & 0 deletions fixtures/set041-exposed-symbols-hierarchy/src/Frame.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php declare(strict_types=1);

class Frame extends Window implements ObjectInterface
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php declare(strict_types=1);

interface ObjectInterface
{
}
5 changes: 5 additions & 0 deletions fixtures/set041-exposed-symbols-hierarchy/src/Window.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php declare(strict_types=1);

class Window extends Component
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

if (\PHP_VERSION_ID < PHP_INT_MIN) {
interface StringableLike
{
}
}
110 changes: 110 additions & 0 deletions specs/misc/expose-hierarchy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

declare(strict_types=1);

/*
* This file is part of the humbug/php-scoper package.
*
* Copyright (c) 2017 Théo FIDRY <[email protected]>,
* Pádraic Brady <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

use Humbug\PhpScoper\SpecFramework\Config\Meta;
use Humbug\PhpScoper\SpecFramework\Config\SpecWithConfig;

return [
'meta' => new Meta(
title: 'Ensures the exposed symbols follow the required hierarchy.',
exposeClasses: ['/.h*/'],
),

'PHP 8.1 Polyfill (right order)' => SpecWithConfig::create(
spec: <<<'PHP'
<?php
interface Stringeable {}
class PhpTokens implements Stringeable {}
----
<?php
namespace Humbug;
interface Stringeable
{
}
\class_alias('Humbug\Stringeable', 'Stringeable', \false);
class PhpTokens implements \Humbug\Stringeable
{
}
\class_alias('Humbug\PhpTokens', 'PhpTokens', \false);

PHP,
expectedRecordedClasses: [
['Stringeable', 'Humbug\Stringeable'],
['PhpTokens', 'Humbug\PhpTokens'],
],
),

'PHP 8.1 Polyfill (wrong order)' => SpecWithConfig::create(
spec: <<<'PHP'
<?php
class PhpTokens implements Stringeable {}
interface Stringeable {}
----
<?php
namespace Humbug;
class PhpTokens implements \Humbug\Stringeable
{
}
\class_alias('Humbug\PhpTokens', 'PhpTokens', \false);
interface Stringeable
{
}
\class_alias('Humbug\Stringeable', 'Stringeable', \false);

PHP,
expectedRecordedClasses: [
['Stringeable', 'Humbug\Stringeable'],
['PhpTokens', 'Humbug\PhpTokens'],
],
),

'simple case with extend' => SpecWithConfig::create(
spec: <<<'PHP'
<?php
class Frame extends Window {}
abstract class Window implements ObjectInterface {}
interface Component extends FrameInterface, ObjectInterface {}
interface FrameInterface {}
interface ObjectInterface {}
----
<?php
namespace Humbug;
class PhpTokens implements \Humbug\Stringeable
{
}
\class_alias('Humbug\PhpTokens', 'PhpTokens', \false);
interface Stringeable
{
}
\class_alias('Humbug\Stringeable', 'Stringeable', \false);

PHP,
expectedRecordedClasses: [
['Stringeable', 'Humbug\Stringeable'],
['PhpTokens', 'Humbug\PhpTokens'],
],
),
];
27 changes: 27 additions & 0 deletions src/PhpParser/NodeVisitor/ClassIdentifierRecorder.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Interface_;
use PhpParser\NodeVisitorAbstract;
use function array_filter;
use function array_merge;

/**
* Records the classes that need to be aliased.
Expand Down Expand Up @@ -70,12 +72,37 @@ public function enterNode(Node $node): Node
$this->symbolsRegistry->recordClass(
$resolvedName,
FullyQualifiedFactory::concat($this->prefix, $resolvedName),
self::getDependencies($parent),
);
}

return $node;
}

/**
* @return FullyQualified[]
*/
private static function getDependencies(Class_|Interface_ $node): array
{
return match(true) {
$node instanceof Class_ => self::getClassDependencies($node),
$node instanceof Interface_ => $node->extends,
};
}

private static function getClassDependencies(Class_ $class_): array
{
$dependencies = [];

if (null !== $class_->extends) {
$dependencies[] = [$class_->extends];
}

$dependencies[] = $class_->implements;

return [...$dependencies];
}

private function shouldBeAliased(string $resolvedName): bool
{
if ($this->enrichedReflector->isExposedClass($resolvedName)) {
Expand Down
Loading

0 comments on commit 4ca5680

Please sign in to comment.