From ccaf406af4e58b0486bd926055bc8b6dfe1eac4a Mon Sep 17 00:00:00 2001 From: smoench Date: Fri, 30 Oct 2020 11:50:46 +0100 Subject: [PATCH] fix internal constants --- .github/workflows/build.yml | 1 + composer.lock | 8 +- specs/exp/coalescing-assignment.php | 1 + specs/func-arrow/global-scope-arrow-func.php | 1 + .../namespace-arrow-func-with-use-stmt.php | 1 + specs/func-arrow/namespace-arrow-func.php | 1 + specs/misc/match.php | 57 ++++++++++ src/Container.php | 3 +- src/Reflector.php | 103 ++++++++++-------- tests/ReflectorTest.php | 5 + tests/Scoper/PhpScoperSpecTest.php | 9 +- 11 files changed, 137 insertions(+), 53 deletions(-) create mode 100644 specs/misc/match.php diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 002efca1f..6cd9f2bf6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,6 +12,7 @@ jobs: runs-on: ubuntu-latest name: Build and test strategy: + fail-fast: false matrix: php: [ "7.2", "7.4" ] composer-version: [ "1" ] diff --git a/composer.lock b/composer.lock index 0c8d5fb8b..7b4878e3f 100644 --- a/composer.lock +++ b/composer.lock @@ -77,12 +77,12 @@ "source": { "type": "git", "url": "https://github.com/JetBrains/phpstorm-stubs.git", - "reference": "147255f02ed786e1febaa641f86cfb9f656a3fda" + "reference": "5b7def27af1f88c009f137b4c4a38bb4732a3713" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JetBrains/phpstorm-stubs/zipball/147255f02ed786e1febaa641f86cfb9f656a3fda", - "reference": "147255f02ed786e1febaa641f86cfb9f656a3fda", + "url": "https://api.github.com/repos/JetBrains/phpstorm-stubs/zipball/5b7def27af1f88c009f137b4c4a38bb4732a3713", + "reference": "5b7def27af1f88c009f137b4c4a38bb4732a3713", "shasum": "" }, "require-dev": { @@ -114,7 +114,7 @@ "stubs", "type" ], - "time": "2020-07-28T12:16:34+00:00" + "time": "2020-09-14T12:37:46+00:00" }, { "name": "nikic/php-parser", diff --git a/specs/exp/coalescing-assignment.php b/specs/exp/coalescing-assignment.php index 58c1b8be6..b541a01cd 100644 --- a/specs/exp/coalescing-assignment.php +++ b/specs/exp/coalescing-assignment.php @@ -14,6 +14,7 @@ return [ 'meta' => [ + 'minPhpVersion' => 70400, 'title' => 'Null coalescing assignment operator', // Default values. If not specified will be the one used 'prefix' => 'Humbug', diff --git a/specs/func-arrow/global-scope-arrow-func.php b/specs/func-arrow/global-scope-arrow-func.php index 3f98062c5..4451f14f3 100644 --- a/specs/func-arrow/global-scope-arrow-func.php +++ b/specs/func-arrow/global-scope-arrow-func.php @@ -14,6 +14,7 @@ return [ 'meta' => [ + 'minPhpVersion' => 70400, 'title' => 'Arrow function in the global namespace', // Default values. If not specified will be the one used 'prefix' => 'Humbug', diff --git a/specs/func-arrow/namespace-arrow-func-with-use-stmt.php b/specs/func-arrow/namespace-arrow-func-with-use-stmt.php index a0d977f19..c92f7397e 100644 --- a/specs/func-arrow/namespace-arrow-func-with-use-stmt.php +++ b/specs/func-arrow/namespace-arrow-func-with-use-stmt.php @@ -14,6 +14,7 @@ return [ 'meta' => [ + 'minPhpVersion' => 70400, 'title' => 'Arrow function in a namespace with use statements', // Default values. If not specified will be the one used 'prefix' => 'Humbug', diff --git a/specs/func-arrow/namespace-arrow-func.php b/specs/func-arrow/namespace-arrow-func.php index 437bcd4e1..419bd5280 100644 --- a/specs/func-arrow/namespace-arrow-func.php +++ b/specs/func-arrow/namespace-arrow-func.php @@ -14,6 +14,7 @@ return [ 'meta' => [ + 'minPhpVersion' => 70400, 'title' => 'Arrow function in a namespace', // Default values. If not specified will be the one used 'prefix' => 'Humbug', diff --git a/specs/misc/match.php b/specs/misc/match.php new file mode 100644 index 000000000..fa221957c --- /dev/null +++ b/specs/misc/match.php @@ -0,0 +1,57 @@ +, + * Pádraic Brady + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +return [ + 'meta' => [ + 'title' => 'Match', + // Default values. If not specified will be the one used + 'prefix' => 'Humbug', + 'whitelist' => [], + 'whitelist-global-constants' => false, + 'whitelist-global-classes' => false, + 'whitelist-global-functions' => false, + 'registered-classes' => [], + 'registered-functions' => [], + ], + 'match' => <<<'PHP' +parser) { - $this->parser = (new ParserFactory())->create(ParserFactory::ONLY_PHP7); + $this->parser = (new ParserFactory())->create(ParserFactory::ONLY_PHP7, new Lexer()); } return $this->parser; diff --git a/src/Reflector.php b/src/Reflector.php index 21d00921c..899fe1546 100644 --- a/src/Reflector.php +++ b/src/Reflector.php @@ -14,10 +14,10 @@ namespace Humbug\PhpScoper; +use JetBrains\PHPStormStub\PhpStormStubsMap; use function array_fill_keys; use function array_keys; use function array_merge; -use JetBrains\PHPStormStub\PhpStormStubsMap; use function strtolower; /** @@ -27,55 +27,55 @@ final class Reflector { private const MISSING_CLASSES = [ // https://github.com/JetBrains/phpstorm-stubs/pull/594 - 'parallel\Channel', - 'parallel\Channel\Error', - 'parallel\Channel\Error\Closed', - 'parallel\Channel\Error\Existence', - 'parallel\Channel\Error\IllegalValue', - 'parallel\Error', - 'parallel\Events', - 'parallel\Events\Error', - 'parallel\Events\Error\Existence', - 'parallel\Events\Error\Timeout', - 'parallel\Events\Event', - 'parallel\Events\Event\Type', - 'parallel\Events\Input', - 'parallel\Events\Input\Error', - 'parallel\Events\Input\Error\Existence', - 'parallel\Events\Input\Error\IllegalValue', - 'parallel\Future', - 'parallel\Future\Error', - 'parallel\Future\Error\Cancelled', - 'parallel\Future\Error\Foreign', - 'parallel\Future\Error\Killed', - 'parallel\Runtime', - 'parallel\Runtime\Bootstrap', - 'parallel\Runtime\Error', - 'parallel\Runtime\Error\Bootstrap', - 'parallel\Runtime\Error\Closed', - 'parallel\Runtime\Error\IllegalFunction', - 'parallel\Runtime\Error\IllegalInstruction', - 'parallel\Runtime\Error\IllegalParameter', - 'parallel\Runtime\Error\IllegalReturn', + 'parallel\Channel' => 0, + 'parallel\Channel\Error' => 0, + 'parallel\Channel\Error\Closed' => 0, + 'parallel\Channel\Error\Existence' => 0, + 'parallel\Channel\Error\IllegalValue' => 0, + 'parallel\Error' => 0, + 'parallel\Events' => 0, + 'parallel\Events\Error' => 0, + 'parallel\Events\Error\Existence' => 0, + 'parallel\Events\Error\Timeout' => 0, + 'parallel\Events\Event' => 0, + 'parallel\Events\Event\Type' => 0, + 'parallel\Events\Input' => 0, + 'parallel\Events\Input\Error' => 0, + 'parallel\Events\Input\Error\Existence' => 0, + 'parallel\Events\Input\Error\IllegalValue' => 0, + 'parallel\Future' => 0, + 'parallel\Future\Error' => 0, + 'parallel\Future\Error\Cancelled' => 0, + 'parallel\Future\Error\Foreign' => 0, + 'parallel\Future\Error\Killed' => 0, + 'parallel\Runtime' => 0, + 'parallel\Runtime\Bootstrap' => 0, + 'parallel\Runtime\Error' => 0, + 'parallel\Runtime\Error\Bootstrap' => 0, + 'parallel\Runtime\Error\Closed' => 0, + 'parallel\Runtime\Error\IllegalFunction' => 0, + 'parallel\Runtime\Error\IllegalInstruction' => 0, + 'parallel\Runtime\Error\IllegalParameter' => 0, + 'parallel\Runtime\Error\IllegalReturn' => 0, ]; private const MISSING_FUNCTIONS = []; private const MISSING_CONSTANTS = [ - 'STDIN', - 'STDOUT', - 'STDERR', + 'STDIN' => 0, + 'STDOUT' => 0, + 'STDERR' => 0, // Added in PHP 7.4 - 'T_BAD_CHARACTER', - 'T_FN', - 'T_COALESCE_EQUAL', + 'T_BAD_CHARACTER' => 70400, + 'T_FN' => 70400, + 'T_COALESCE_EQUAL' => 70400, // Added in PHP 8.0 - 'T_NAME_QUALIFIED', - 'T_NAME_FULLY_QUALIFIED', - 'T_NAME_RELATIVE', - 'T_MATCH', - 'T_NULLSAFE_OBJECT_OPERATOR', - 'T_ATTRIBUTE', + 'T_NAME_QUALIFIED' => 80000, + 'T_NAME_FULLY_QUALIFIED' => 80000, + 'T_NAME_RELATIVE' => 80000, + 'T_MATCH' => 80000, + 'T_NULLSAFE_OBJECT_OPERATOR' => 80000, + 'T_ATTRIBUTE' => 80000, ]; private static $CLASSES; @@ -87,7 +87,7 @@ final class Reflector /** * @param array|null $symbols * @param array $source - * @param string[] $missingSymbols + * @param array $missingSymbols */ private static function initSymbolList(?array &$symbols, array $source, array $missingSymbols): void { @@ -95,10 +95,19 @@ private static function initSymbolList(?array &$symbols, array $source, array $m return; } + $excludingSymbols = array_keys( + array_filter($missingSymbols, static function ($version) { + return PHP_VERSION_ID < $version; + }) + ); + $symbols = array_fill_keys( - array_merge( - array_keys($source), - $missingSymbols + array_diff( + array_merge( + array_keys($source), + array_keys($missingSymbols) + ), + $excludingSymbols ), true ); diff --git a/tests/ReflectorTest.php b/tests/ReflectorTest.php index cdec21727..d62c0f9e6 100644 --- a/tests/ReflectorTest.php +++ b/tests/ReflectorTest.php @@ -162,5 +162,10 @@ public function provideConstants(): Generator 'FTP_ASCII', true, ]; + + yield 'T_MATCH constant' => [ + 'T_MATCH', + PHP_VERSION_ID >= 80000, + ]; } } diff --git a/tests/Scoper/PhpScoperSpecTest.php b/tests/Scoper/PhpScoperSpecTest.php index 2ac0ee09a..0f6edf3c7 100644 --- a/tests/Scoper/PhpScoperSpecTest.php +++ b/tests/Scoper/PhpScoperSpecTest.php @@ -50,6 +50,7 @@ class PhpScoperSpecTest extends TestCase private const SECONDARY_SPECS_PATH = __DIR__.'/../../_specs'; private const SPECS_META_KEYS = [ + 'minPhpVersion', 'title', 'prefix', 'whitelist', @@ -93,8 +94,13 @@ public function test_can_scope_valid_files( Whitelist $whitelist, ?string $expected, array $expectedRegisteredClasses, - array $expectedRegisteredFunctions + array $expectedRegisteredFunctions, + ?int $minPhpVersion ): void { + if (null !== $minPhpVersion && $minPhpVersion > PHP_VERSION_ID) { + $this->markTestSkipped(sprintf('Min PHP version not matched for spec %s', $spec)); + } + $filePath = 'file.php'; $patchers = [create_fake_patcher()]; $scoper = $this->createScoper(); @@ -285,6 +291,7 @@ private function parseSpecFile(string $file, array $meta, $fixtureTitle, $fixtur '' === $payloadParts[1] ? null : $payloadParts[1], // Expected output; null means an exception is expected, $fixtureSet['registered-classes'] ?? $meta['registered-classes'], $fixtureSet['registered-functions'] ?? $meta['registered-functions'], + $meta['minPhpVersion'] ?? null ]; }