69 Commits

Author SHA1 Message Date
Grégoire Paris
fa587178be Merge pull request #49 from alexpott/php8-compatibility
PHP 8 compatibility
2020-10-27 22:46:55 +01:00
Alex Pott
dc269e064a doctrine/coding-standard needs a PHP 8.0 compatible version 2020-10-27 21:35:12 +00:00
Alex Pott
a8d82251c6 Fix up things after merging 1.2.x 2020-10-27 21:27:25 +00:00
Alex Pott
f3ade869eb Ensure phpstan runs with locked dependencies 2020-10-27 22:05:39 +01:00
Alex Pott
06eec07aa3 Ignore compatibility files in phpstan 2020-10-27 22:05:39 +01:00
Alex Pott
2336d15b1a Update dist to use a more recent PHP 8.0 2020-10-27 22:04:16 +01:00
Alex Pott
a82bebf801 Initial commit 2020-10-27 22:04:16 +01:00
Grégoire Paris
e65c2eb6a8 Merge pull request #51 from doctrine/greg0ire-patch-1
Setup release workflow
2020-10-27 22:01:47 +01:00
Grégoire Paris
e3c48f5fbd Merge pull request #50 from greg0ire/migrate-cs-to-ga
Migrate cs to ga
2020-10-27 21:55:50 +01:00
Grégoire Paris
cac3bcb8fc Migrate to Github Actions for coding standard 2020-10-27 21:47:11 +01:00
Grégoire Paris
db4b566464 Setup release workflow 2020-10-27 21:45:16 +01:00
Grégoire Paris
486d0cbea5 Upgrade doctrine/coding-standard
It depends on a library that needs to be upgraded so that we can use
Composer 2
2020-10-27 21:40:39 +01:00
Claudio Zizza
cea2760c34 Merge pull request #48 from doctrine/default-branch-website-config
Move website config to default branch
2020-10-05 14:03:36 +02:00
Claudio Zizza
4f143d5384 Move website config to default branch
Adapts the website config to be compatible with the doctrine/doctrine-website#356 changes
2020-10-03 20:14:44 +02:00
Grégoire Paris
efdbb0f82a Merge pull request #44 from greg0ire/scrutinizer➡codecov
Use CodeCov instead of Scrutinizer
2020-06-20 15:00:11 +02:00
Grégoire Paris
edfb312da0 Use CodeCov instead of Scrutinizer 2020-06-20 14:12:43 +02:00
Grégoire Paris
344bc74ba8 Merge remote-tracking branch 'origin/1.1.x' into 1.2.x 2020-05-27 18:45:57 +02:00
Grégoire Paris
1b33070b49 Merge pull request #33 from DieterHolvoet/issue-32
Fix Trying to access array offset on value of type null
2020-04-26 13:02:52 +02:00
Dieter Holvoet
41a2f0f445 Add type check to prevent PHP 7.4 warnings
PHP 7.4 introduces a "Trying to access array offset on value of type ..." warning for accessing null/bool/int/float/resource (everything but array, string and object) as if it were an array. This commit fixes an instance where this warning is emitted.

Fixes #32.
2020-04-26 12:57:05 +02:00
Grégoire Paris
d11bac73db Merge pull request #40 from pgrimaud/master
Fix typo in lib/Doctrine/Common/Reflection/TypedNoDefaultReflectionProperty.php
2020-04-18 23:41:10 +02:00
Pierre Grimaud
1c7272c98a Fix typos 2020-04-18 23:34:26 +02:00
Grégoire Paris
8f7fdc01b3 Merge pull request #38 from greg0ire/validate-composer-json
Validate composer json
2020-03-30 18:19:46 +02:00
Benjamin Eberlei
55e71912df Merge pull request #37 from doctrine/GH-36-BugfixTypedNullable
[GH-36] Bugfix: TypedNoDefaultReflectionProperty::setValue NULL when null allowed
2020-03-27 12:06:43 +01:00
Benjamin Eberlei
fbc77cc1c8 [GH-36] Be on the safe side and check property has a type. 2020-03-25 10:09:58 +01:00
Grégoire Paris
79de2517ba Sort packages alphabetically 2020-03-24 09:21:01 +01:00
Grégoire Paris
827618c360 Validate composer files 2020-03-24 09:20:26 +01:00
Benjamin Eberlei
1a5837f909 [Build] Attempt at fix. 2020-03-23 20:41:18 +01:00
Benjamin Eberlei
1ab281861b [GH-36] Bugfix: TypedNoDefaultReflectionProperty::setValue NULL when null allowed. 2020-03-23 17:33:08 +01:00
Benjamin Eberlei
b699ecc7f2 Merge pull request #35 from doctrine/GH-34-SetValueUnitialized
[GH-34] Instead of NULL, unitialize typed properties without default.
2020-03-21 12:34:59 +01:00
Benjamin Eberlei
cd4811c644 [GH-34] Instead of NULL, unitialize typed properties without default. 2020-03-16 09:38:51 +01:00
Maciej Malarz
aa0689034e Merge pull request #31 from Spomky/patch-1
No doc files for distribution
2020-02-28 21:27:16 +01:00
Florent Morselli
2fc2828857 No doc files for distribution
This PR adds the folder `/docs` in .gitattributes so that it will not be present in distribution
2020-02-28 14:43:01 +01:00
Claudio Zizza
c7588e0baa Merge pull request #30 from doctrine/patch-1
Update of project config for latest version
2020-01-29 22:57:36 +01:00
Claudio Zizza
d9cf1f3deb Update of project config for latest version
Because of a failing website build the config for the
latest version was adapted to the same version
syntax like in other Doctrine projects.
2020-01-29 00:23:19 +01:00
Andreas Braun
12fea966b2 Update branch-alias to 1.2.x-dev 2020-01-18 13:09:54 +01:00
Andreas Braun
c390808aca Update maintained branches 2020-01-18 13:09:53 +01:00
Benjamin Eberlei
bc420ead87 Run PHPStan with PHP 7.4 for typed properties related checks. 2020-01-08 20:53:19 +01:00
Benjamin Eberlei
68b6aa3299 Merge branch 'add_reflection_typed_no_default_property_class' 2020-01-08 20:47:06 +01:00
Grégoire Paris
895c94dcee Merge pull request #28 from andreybolonin/patch-2
Use php 7.4 image instead of 7.4snapshot
2020-01-04 18:34:07 +01:00
Andrey Bolonin
45270d8e58 Use php 7.4 image instead of 7.4snapshot 2020-01-04 19:09:00 +02:00
Andreas Braun
76bb6bc20a Merge pull request #26 from sspat/fix_annotation_parsing_for_classes_creating_anon_classes
Fix reading docblocks for classes containing anonymous classes
2019-12-03 16:26:53 +01:00
Patrik Foldes
9acbb8ccce Replaced isset with ReflectionProperty::isInitialized #23 2019-12-03 16:23:51 +01:00
Patrik Foldes
8299ca45da Changed the property access syntax again #23 2019-12-03 16:23:51 +01:00
Patrik Foldes
7fba840747 Changed dynamic property name access syntax #23 2019-12-03 16:23:51 +01:00
Patrik Foldes
bbf9810b57 Changed test assertion method #23 2019-12-03 16:23:51 +01:00
Patrik Foldes
6efdc3f15a Added php 7.4 specific tests directory to composer autoloading config #23 2019-12-03 16:23:51 +01:00
Patrik Foldes
0ac0da52c1 Updated phpunit and travis configs to work with tests containing code in php 7.4 syntax #23 2019-12-03 16:23:50 +01:00
Patrik Foldes
70707057f6 Added reflection class for handling typed properties without default value #23 2019-12-03 16:22:57 +01:00
Andreas Braun
f3e4e24667 Merge pull request #25 from doctrine/update-dependencies
Update dependencies for CI build
2019-12-03 16:14:59 +01:00
Andreas Braun
2c2888effb Resolve version conflict with doctrine/common 2019-12-03 16:03:00 +01:00
Patrik Foldes
512a4f0ec1 Fix for issue #19 2019-12-03 17:00:27 +03:00
Andreas Braun
07b0d59986 Simplify phpstan call on travis-ci 2019-12-02 21:17:43 +01:00
Andreas Braun
5eefae4186 Update dependencies 2019-12-02 21:15:19 +01:00
Andreas Braun
7a2c95aa7c Merge pull request #22 from sspat/fix_php74_and_windows_test_errors
Fixed tests to work with php 7.4 and on windows #21
2019-12-02 14:05:25 +01:00
Patrik Foldes
859446e967 Fixed code style #21 2019-12-02 15:14:36 +03:00
Patrik Foldes
81f27df605 Added PHP 7.4 to travis builds #21 2019-12-02 15:14:24 +03:00
Patrik Foldes
de66230870 Fixed tests to work with php 7.4 and on windows #21 2019-12-02 14:41:27 +03:00
Jonathan H. Wage
4a97a22032 Merge pull request #17 from doctrine/update-chat-link
Update chat link from Gitter to Slack.
2018-12-12 14:24:29 -06:00
Jonathan H. Wage
6e00e048a8 Update chat link from Gitter to Slack. 2018-12-12 20:23:23 +00:00
Marco Pivetta
ad11fb5d5d Merge pull request #15 from Majkl578/php7.3
CI: Test against PHP 7.3
2018-10-15 13:19:19 +02:00
Michael Moravec
a5c4170bcc CI: Test against PHP 7.3 2018-10-13 21:06:16 +02:00
Marco Pivetta
12b6dfcab6 Merge pull request #14 from carusogabriel/composer-update
Run composer update to sync new dependencies
2018-09-28 01:09:42 +02:00
Gabriel Caruso
e4286e5a08 Run composer update to sync new dependencies 2018-09-25 22:32:31 -03:00
Jonathan H. Wage
ca1b0e4137 Merge pull request #13 from carusogabriel/doctrine-cs-v5
Apply Doctrine CS v5
2018-09-25 21:29:03 -04:00
Gabriel Caruso
093041f967 Apply Doctrine CS v5 2018-09-25 22:16:34 -03:00
Jonathan H. Wage
9848bff07d Merge pull request #12 from doctrine/doctrine-project-json
Add .doctrine-project.json to root of the project.
2018-08-31 17:54:33 -05:00
Jonathan H. Wage
fe6a06f31d Add .doctrine-project.json to root of the project. 2018-08-31 21:07:09 +01:00
Marco Pivetta
d1db8cee08 Merge pull request #10 from doctrine/add-common-conflict
Add conflict on doctrine/common for <2.9@dev
2018-06-15 09:55:29 +02:00
Jonathan H. Wage
b5ab045685 Add conflict on doctrine/common for <2.9@dev 2018-06-14 19:50:14 +01:00
37 changed files with 2058 additions and 695 deletions

36
.doctrine-project.json Normal file
View File

@@ -0,0 +1,36 @@
{
"active": true,
"name": "Reflection",
"slug": "reflection",
"docsSlug": "doctrine-reflection",
"versions": [
{
"name": "1.3",
"branchName": "master",
"slug": "latest",
"upcoming": true
},
{
"name": "1.2",
"branchName": "1.2.x",
"slug": "1.2",
"current": true,
"aliases": [
"current",
"stable"
]
},
{
"name": "1.1",
"branchName": "1.1.x",
"slug": "1.1",
"maintained": false
},
{
"name": "1.0",
"branchName": "1.0",
"slug": "1.0",
"maintained": false
}
]
}

1
.gitattributes vendored
View File

@@ -1,3 +1,4 @@
/docs export-ignore
/tests export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore

50
.github/workflows/coding-standards.yml vendored Normal file
View File

@@ -0,0 +1,50 @@
name: "Coding Standards"
on:
pull_request:
branches:
- "*.x"
- "master"
push:
branches:
- "*.x"
- "master"
env:
COMPOSER_ROOT_VERSION: "1.2"
jobs:
coding-standards:
name: "Coding Standards"
runs-on: "ubuntu-20.04"
strategy:
matrix:
php-version:
- "7.4"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "${{ matrix.php-version }}"
tools: "cs2pr"
- name: "Cache dependencies installed with Composer"
uses: "actions/cache@v2"
with:
path: "~/.composer/cache"
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
- name: "Install dependencies with Composer"
run: "composer install --no-interaction --no-progress --no-suggest"
# https://github.com/doctrine/.github/issues/3
- name: "Run PHP_CodeSniffer"
run: "vendor/bin/phpcs -q --no-colors --report=checkstyle | cs2pr"

View File

@@ -0,0 +1,45 @@
name: "Automatic Releases"
on:
milestone:
types:
- "closed"
jobs:
release:
name: "Git tag, release & create merge-up PR"
runs-on: "ubuntu-20.04"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Release"
uses: "laminas/automatic-releases@v1"
with:
command-name: "laminas:automatic-releases:release"
env:
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
- name: "Create Merge-Up Pull Request"
uses: "laminas/automatic-releases@v1"
with:
command-name: "laminas:automatic-releases:create-merge-up-pull-request"
env:
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
- name: "Create new milestones"
uses: "laminas/automatic-releases@v1"
with:
command-name: "laminas:automatic-releases:create-milestones"
env:
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}

View File

@@ -1,29 +0,0 @@
build:
nodes:
analysis:
environment:
php:
version: 7.1
cache:
disabled: false
directories:
- ~/.composer/cache
project_setup:
override: true
tests:
override:
- php-scrutinizer-run
- phpcs-run
dependencies:
override:
- composer install -noa
tools:
external_code_coverage:
timeout: 600
build_failure_conditions:
- 'elements.rating(<= C).new.exists' # No new classes/methods with a rating of C or worse allowed
- 'issues.label("coding-style").new.exists' # No new coding style issues allowed
- 'issues.severity(>= MAJOR).new.exists' # New issues of major or higher severity
- 'project.metric_change("scrutinizer.test_coverage", < 0)' # Code Coverage decreased from previous inspection

View File

@@ -1,7 +1,11 @@
dist: trusty
dist: xenial
sudo: false
language: php
env:
global:
- COMPOSER_ROOT_VERSION=1.2
cache:
directories:
- $HOME/.composer/cache
@@ -9,12 +13,15 @@ cache:
php:
- 7.1
- 7.2
- 7.3
- 7.4
- nightly
before_install:
- mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{,.disabled} || echo "xdebug not available"
install:
- composer validate --strict
- rm composer.lock
- travis_retry composer update -n --prefer-dist
@@ -31,15 +38,12 @@ jobs:
- if [[ ! $(php -m | grep -si xdebug) ]]; then echo "xdebug required for coverage"; exit 1; fi
script:
- ./vendor/bin/phpunit --coverage-clover clover.xml
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover clover.xml
- stage: Coding standard
install:
- travis_retry composer install -n --prefer-dist
script:
- ./vendor/bin/phpcs
after_success:
- bash <(curl -s https://codecov.io/bash)
- stage: Lint
script: vendor/bin/phpstan analyse -l 3 -c phpstan.neon lib tests
install:
# Use lock file for install so old version of phpstan is used.
- travis_retry composer install -n --prefer-dist
php: 7.4
script: vendor/bin/phpstan analyse

View File

@@ -1,8 +1,7 @@
# Doctrine Reflection
[![Build Status](https://travis-ci.org/doctrine/reflection.svg)](https://travis-ci.org/doctrine/reflection)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/doctrine/reflection/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/doctrine/reflection/?branch=master)
[![Code Coverage](https://scrutinizer-ci.com/g/doctrine/reflection/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/doctrine/reflection/?branch=master)
[![Code Coverage](https://codecov.io/gh/doctrine/dbal/branch/reflection/graph/badge.svg)](https://codecov.io/gh/doctrine/reflection/branch/master)
The Doctrine Reflection project is a simple library used by the various Doctrine projects which adds some additional functionality on top of the reflection functionality that comes with PHP. It allows you to get the reflection information about classes, methods and properties statically.

View File

@@ -1,8 +1,11 @@
{
"name": "doctrine/reflection",
"type": "library",
"description": "Doctrine Reflection component",
"keywords": ["reflection"],
"description": "The Doctrine Reflection project is a simple library used by the various Doctrine projects which adds some additional functionality on top of the reflection functionality that comes with PHP. It allows you to get the reflection information about classes, methods and properties statically.",
"keywords": [
"reflection",
"static"
],
"homepage": "https://www.doctrine-project.org/projects/reflection.html",
"license": "MIT",
"authors": [
@@ -14,17 +17,19 @@
{"name": "Marco Pivetta", "email": "ocramius@gmail.com"}
],
"require": {
"php": "^7.1",
"php": "^7.1 || ^8.0",
"ext-tokenizer": "*",
"doctrine/annotations": "^1.0"
},
"require-dev": {
"phpstan/phpstan": "^0.9.2",
"phpstan/phpstan-phpunit": "^0.9.4",
"phpunit/phpunit": "^7.0",
"doctrine/coding-standard": "^4.0",
"doctrine/common": "^2.8",
"squizlabs/php_codesniffer": "^3.0"
"doctrine/coding-standard": "^6.0 || ^8.2.0",
"doctrine/common": "^2.10",
"phpstan/phpstan": "^0.11.0 || ^0.12.20",
"phpstan/phpstan-phpunit": "^0.11.0 || ^0.12.16",
"phpunit/phpunit": "^7.5 || ^9.1.5"
},
"conflict": {
"doctrine/common": "<2.9"
},
"autoload": {
"psr-4": {
@@ -33,12 +38,16 @@
},
"autoload-dev": {
"psr-4": {
"Doctrine\\Tests\\": "tests/Doctrine/Tests"
"Doctrine\\Tests\\": "tests/Doctrine/Tests",
"Doctrine\\Tests_PHP74\\": "tests/Doctrine/Tests_PHP74"
}
},
"config": {
"sort-packages": true
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
"dev-master": "1.2.x-dev"
}
}
}

2085
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,7 @@ If this documentation is not helping to answer questions you have about
Doctrine Reflection don't panic. You can get help from different sources:
- The `Doctrine Mailing List <https://groups.google.com/group/doctrine-user>`_
- Gitter chat room `#doctrine/reflection <https://gitter.im/doctrine/reflection>`_
- Slack chat room `#reflection <https://www.doctrine-project.org/slack>`_
- Report a bug on `GitHub <https://github.com/doctrine/reflection/issues>`_.
- On `StackOverflow <https://stackoverflow.com/questions/tagged/doctrine-reflection>`_

View File

@@ -0,0 +1,24 @@
<?php
namespace Doctrine\Common\Reflection\Compatibility\Php7;
use ReflectionException;
trait ReflectionClass
{
/**
* {@inheritDoc}
*/
public function getConstants()
{
throw new ReflectionException('Method not implemented');
}
/**
* {@inheritDoc}
*/
public function newInstance($args)
{
throw new ReflectionException('Method not implemented');
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Doctrine\Common\Reflection\Compatibility\Php7;
use ReflectionException;
trait ReflectionMethod
{
/**
* {@inheritDoc}
*/
public function invoke($object, $parameter = null)
{
throw new ReflectionException('Method not implemented');
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Doctrine\Common\Reflection\Compatibility\Php8;
use ReflectionException;
trait ReflectionClass
{
/**
* {@inheritDoc}
*/
public function getConstants(?int $filter = null)
{
throw new ReflectionException('Method not implemented');
}
/**
* {@inheritDoc}
*/
public function newInstance(mixed ...$args)
{
throw new ReflectionException('Method not implemented');
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Doctrine\Common\Reflection\Compatibility\Php8;
use ReflectionException;
trait ReflectionMethod
{
/**
* {@inheritDoc}
*/
public function invoke(?object $object, mixed ...$args)
{
throw new ReflectionException('Method not implemented');
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Doctrine\Common\Reflection\Compatibility;
use const PHP_VERSION_ID;
use function class_alias;
if (PHP_VERSION_ID >= 80000) {
class_alias('Doctrine\Common\Reflection\Compatibility\Php8\ReflectionClass', 'Doctrine\Common\Reflection\Compatibility\ReflectionClass');
} else {
class_alias('Doctrine\Common\Reflection\Compatibility\Php7\ReflectionClass', 'Doctrine\Common\Reflection\Compatibility\ReflectionClass');
}
if (false) {
class ReflectionClass
{
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Doctrine\Common\Reflection\Compatibility;
use const PHP_VERSION_ID;
use function class_alias;
if (PHP_VERSION_ID >= 80000) {
class_alias('Doctrine\Common\Reflection\Compatibility\Php8\ReflectionMethod', 'Doctrine\Common\Reflection\Compatibility\ReflectionMethod');
} else {
class_alias('Doctrine\Common\Reflection\Compatibility\Php7\ReflectionMethod', 'Doctrine\Common\Reflection\Compatibility\ReflectionMethod');
}
if (false) {
class ReflectionMethod
{
}
}

View File

@@ -2,12 +2,16 @@
namespace Doctrine\Common\Reflection;
use ReflectionClass;
use ReflectionMethod;
use ReflectionProperty;
interface ReflectionProviderInterface
{
/**
* Gets the ReflectionClass equivalent for this class.
*
* @return \ReflectionClass
* @return ReflectionClass
*/
public function getReflectionClass();
@@ -16,7 +20,7 @@ interface ReflectionProviderInterface
*
* @param string $name
*
* @return \ReflectionMethod
* @return ReflectionMethod
*/
public function getReflectionMethod($name);
@@ -25,7 +29,7 @@ interface ReflectionProviderInterface
*
* @param string $name
*
* @return \ReflectionProperty
* @return ReflectionProperty
*/
public function getReflectionProperty($name);
}

View File

@@ -7,7 +7,6 @@ use ReflectionProperty;
/**
* PHP Runtime Reflection Public Property - special overrides for public properties.
*
*/
class RuntimePublicReflectionProperty extends ReflectionProperty
{
@@ -39,6 +38,7 @@ class RuntimePublicReflectionProperty extends ReflectionProperty
*
* Avoids triggering lazy loading via `__set` if the provided object
* is a {@see \Doctrine\Common\Proxy\Proxy}.
*
* @link https://bugs.php.net/bug.php?id=63463
*/
public function setValue($object, $value = null)

View File

@@ -2,11 +2,14 @@
namespace Doctrine\Common\Reflection;
use Doctrine\Common\Reflection\Compatibility\ReflectionClass as CompatibilityReflectionClass;
use ReflectionClass;
use ReflectionException;
class StaticReflectionClass extends ReflectionClass
{
use CompatibilityReflectionClass;
/**
* The static reflection parser object.
*
@@ -83,14 +86,6 @@ class StaticReflectionClass extends ReflectionClass
throw new ReflectionException('Method not implemented');
}
/**
* {@inheritDoc}
*/
public function getConstants()
{
throw new ReflectionException('Method not implemented');
}
/**
* {@inheritDoc}
*/
@@ -371,14 +366,6 @@ class StaticReflectionClass extends ReflectionClass
throw new ReflectionException('Method not implemented');
}
/**
* {@inheritDoc}
*/
public function newInstance($args)
{
throw new ReflectionException('Method not implemented');
}
/**
* {@inheritDoc}
*/

View File

@@ -2,11 +2,14 @@
namespace Doctrine\Common\Reflection;
use Doctrine\Common\Reflection\Compatibility\ReflectionMethod as CompatibilityReflectionMethod;
use ReflectionException;
use ReflectionMethod;
class StaticReflectionMethod extends ReflectionMethod
{
use CompatibilityReflectionMethod;
/**
* The PSR-0 parser object.
*
@@ -89,7 +92,7 @@ class StaticReflectionMethod extends ReflectionMethod
/**
* {@inheritDoc}
*/
public function getClosure($object)
public function getClosure($object = null)
{
throw new ReflectionException('Method not implemented');
}
@@ -110,14 +113,6 @@ class StaticReflectionMethod extends ReflectionMethod
throw new ReflectionException('Method not implemented');
}
/**
* {@inheritDoc}
*/
public function invoke($object, $parameter = null)
{
throw new ReflectionException('Method not implemented');
}
/**
* {@inheritDoc}
*/

View File

@@ -8,6 +8,7 @@ use const T_CLASS;
use const T_DOC_COMMENT;
use const T_EXTENDS;
use const T_FUNCTION;
use const T_NEW;
use const T_PAAMAYIM_NEKUDOTAYIM;
use const T_PRIVATE;
use const T_PROTECTED;
@@ -18,6 +19,7 @@ use const T_VAR;
use const T_VARIABLE;
use function array_merge;
use function file_get_contents;
use function is_array;
use function ltrim;
use function preg_match;
use function sprintf;
@@ -161,7 +163,7 @@ class StaticReflectionParser implements ReflectionProviderInterface
$docComment = $token[1];
break;
case T_CLASS:
if ($last_token !== T_PAAMAYIM_NEKUDOTAYIM) {
if ($last_token !== T_PAAMAYIM_NEKUDOTAYIM && $last_token !== T_NEW) {
$this->docComment['class'] = $docComment;
$docComment = '';
}
@@ -188,6 +190,9 @@ class StaticReflectionParser implements ReflectionProviderInterface
while (($token = $tokenParser->next()) && $token[0] !== T_STRING) {
continue;
}
if ($token === null) {
break;
}
$methodName = $token[1];
$this->docComment['method'][$methodName] = $docComment;
$docComment = '';
@@ -221,7 +226,7 @@ class StaticReflectionParser implements ReflectionProviderInterface
break;
}
$last_token = $token[0];
$last_token = is_array($token) ? $token[0] : false;
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace Doctrine\Common\Reflection;
use ReflectionProperty;
/**
* PHP Typed No Default Reflection Property - special override for typed properties without a default value.
*/
class TypedNoDefaultReflectionProperty extends ReflectionProperty
{
/**
* {@inheritDoc}
*
* Checks that a typed property is initialized before accessing its value.
* This is necessary to avoid PHP error "Error: Typed property must not be accessed before initialization".
* Should be used only for reflecting typed properties without a default value.
*/
public function getValue($object = null)
{
return $object !== null && $this->isInitialized($object) ? parent::getValue($object) : null;
}
/**
* {@inheritDoc}
*
* Works around the problem with setting typed no default properties to
* NULL which is not supported, instead unset() to uninitialize.
*
* @link https://github.com/doctrine/orm/issues/7999
*/
public function setValue($object, $value = null)
{
if ($value === null && $this->hasType() && ! $this->getType()->allowsNull()) {
$propertyName = $this->getName();
$unsetter = function () use ($propertyName) {
unset($this->$propertyName);
};
$unsetter = $unsetter->bindTo($object, $this->getDeclaringClass()->getName());
$unsetter();
return;
}
parent::setValue($object, $value);
}
}

View File

@@ -1,6 +0,0 @@
includes:
- vendor/phpstan/phpstan-phpunit/extension.neon
parameters:
ignoreErrors:
- '#Doctrine\\Common\\Reflection\\StaticReflection[a-zA-Z0-9_]+::__construct\(\) does not call parent constructor from Reflection[a-zA-Z0-9_]+#'

14
phpstan.neon.dist Normal file
View File

@@ -0,0 +1,14 @@
parameters:
level: 3
paths:
- %rootDir%/../../../lib
- %rootDir%/../../../tests
ignoreErrors:
- '#Doctrine\\Common\\Reflection\\StaticReflection[a-zA-Z0-9_]+::__construct\(\) does not call parent constructor from Reflection[a-zA-Z0-9_]+#'
excludes_analyse:
- lib/Doctrine/Common/Reflection/Compatibility/ReflectionClass.php
- lib/Doctrine/Common/Reflection/Compatibility/ReflectionMethod.php
includes:
- vendor/phpstan/phpstan-phpunit/extension.neon

View File

@@ -8,7 +8,8 @@
>
<testsuites>
<testsuite name="Doctrine Event Manager Test Suite">
<directory>./tests/Doctrine/</directory>
<directory>./tests/Doctrine/Tests</directory>
<directory phpVersion="7.4" phpVersionOperator=">=">./tests/Doctrine/Tests_PHP74</directory>
</testsuite>
</testsuites>

View File

@@ -0,0 +1,19 @@
<?php
namespace Doctrine\Tests\Common\Reflection;
use Doctrine\Common\Annotations\Annotation;
/**
* @Annotation(
* key = "value"
* )
*/
class AnnotationClassWithAnonymousClass
{
public function foo()
{
$new_class = new class () {
};
}
}

View File

@@ -3,6 +3,7 @@
namespace Doctrine\Tests\Common\Reflection;
use Doctrine\Common\Annotations\Annotation;
use stdClass;
/**
* @Annotation(
@@ -11,10 +12,10 @@ use Doctrine\Common\Annotations\Annotation;
*/
class AnnotationClassWithScopeResolution
{
public const FOO = \stdClass::class;
public const FOO = stdClass::class;
/**
* Example with comment.
*/
public const BAR = \stdClass::class;
public const BAR = stdClass::class;
}

View File

@@ -4,6 +4,7 @@ namespace Doctrine\Tests\Common\Reflection;
use Doctrine\Common\Reflection\Psr0FindFile;
use PHPUnit\Framework\TestCase;
use const DIRECTORY_SEPARATOR;
use function sprintf;
use function strlen;
use function substr;
@@ -17,7 +18,7 @@ class Psr0FindFileTest extends TestCase
{
$file = $this->psr0FindFile->findFile(NoParent::class);
self::assertSame(sprintf('%s/NoParent.php', __DIR__), $file);
self::assertSame(sprintf('%s%sNoParent.php', __DIR__, DIRECTORY_SEPARATOR), $file);
}
public function testFindFileNotFound() : void
@@ -29,14 +30,14 @@ class Psr0FindFileTest extends TestCase
{
$file = $this->psr0FindFile->findFile('\Doctrine\Tests\Common\Reflection\NoParent');
self::assertSame(sprintf('%s/NoParent.php', __DIR__), $file);
self::assertSame(sprintf('%s%sNoParent.php', __DIR__, DIRECTORY_SEPARATOR), $file);
}
public function testFindFileFromPearLikeClassName() : void
{
$file = $this->psr0FindFile->findFile('Doctrine_Tests_Common_Reflection_NoParent');
self::assertSame(sprintf('%s/NoParent.php', __DIR__), $file);
self::assertSame(sprintf('%s%sNoParent.php', __DIR__, DIRECTORY_SEPARATOR), $file);
}
protected function setUp() : void

View File

@@ -2,6 +2,7 @@
namespace Doctrine\Tests\Common\Reflection;
use Closure;
use Doctrine\Common\Proxy\Proxy;
use Doctrine\Common\Reflection\RuntimePublicReflectionProperty;
use PHPUnit\Framework\TestCase;
@@ -39,7 +40,7 @@ class RuntimePublicReflectionPropertyTest extends TestCase
{
$getCheckMock = $this->getMockBuilder('stdClass')->setMethods(['callGet'])->getMock();
$getCheckMock->expects($this->never())->method('callGet');
$initializer = function () use ($getCheckMock) {
$initializer = static function () use ($getCheckMock) {
call_user_func($getCheckMock);
};
@@ -60,7 +61,7 @@ class RuntimePublicReflectionPropertyTest extends TestCase
{
$setCheckMock = $this->getMockBuilder('stdClass')->setMethods(['neverCallSet'])->getMock();
$setCheckMock->expects($this->never())->method('neverCallSet');
$initializer = function () use ($setCheckMock) {
$initializer = static function () use ($setCheckMock) {
call_user_func([$setCheckMock, 'neverCallSet']);
};
@@ -81,7 +82,7 @@ class RuntimePublicReflectionPropertyTest extends TestCase
$setCheckMock = $this->getMockBuilder('stdClass')->setMethods(['callSet'])->getMock();
$setCheckMock->expects($this->once())->method('callSet');
$initializer = function () use ($setCheckMock) {
$initializer = static function () use ($setCheckMock) {
call_user_func([$setCheckMock, 'callSet']);
};
@@ -99,7 +100,7 @@ class RuntimePublicReflectionPropertyTest extends TestCase
*/
class RuntimePublicReflectionPropertyTestProxyMock implements Proxy
{
/** @var \Closure|null */
/** @var Closure|null */
private $initializer = null;
/** @var bool */
@@ -119,7 +120,7 @@ class RuntimePublicReflectionPropertyTestProxyMock implements Proxy
/**
* {@inheritDoc}
*/
public function __setInitializer(?\Closure $initializer = null)
public function __setInitializer(?Closure $initializer = null)
{
$this->initializer = $initializer;
}
@@ -200,7 +201,7 @@ class RuntimePublicReflectionPropertyTestProxyMock implements Proxy
/**
* {@inheritDoc}
*/
public function __setCloner(?\Closure $cloner = null)
public function __setCloner(?Closure $cloner = null)
{
}

View File

@@ -56,7 +56,7 @@ class StaticReflectionClassTest extends TestCase
public function testGetMethod() : void
{
$staticReflectionMethod = $this->createMock(StaticReflectionMethod::class);
$staticReflectionMethod = $this->createPartialMock(StaticReflectionMethod::class, []);
$this->staticReflectionParser->expects($this->once())
->method('getReflectionMethod')
@@ -79,9 +79,9 @@ class StaticReflectionClassTest extends TestCase
}
/**
* @dataProvider getNotImplementedMethods
*
* @param mixed[] $args
*
* @dataProvider getNotImplementedMethods
*/
public function testNotImplemented(string $method, array $args) : void
{

View File

@@ -27,7 +27,7 @@ class StaticReflectionMethodTest extends TestCase
public function testGetDeclaringClass() : void
{
$staticReflectionClass = $this->createMock(StaticReflectionClass::class);
$staticReflectionClass = $this->createPartialMock(StaticReflectionClass::class, []);
$this->staticReflectionParser->expects($this->once())
->method('getReflectionClass')
@@ -47,7 +47,7 @@ class StaticReflectionMethodTest extends TestCase
public function testGetDocComment() : void
{
$staticReflectionClass = $this->createMock(StaticReflectionClass::class);
$staticReflectionClass = $this->createPartialMock(StaticReflectionClass::class, []);
$this->staticReflectionParser->expects($this->once())
->method('getDocComment')
@@ -59,7 +59,7 @@ class StaticReflectionMethodTest extends TestCase
public function testGetUseStatements() : void
{
$staticReflectionClass = $this->createMock(StaticReflectionClass::class);
$staticReflectionClass = $this->createPartialMock(StaticReflectionClass::class, []);
$this->staticReflectionParser->expects($this->once())
->method('getUseStatements')
@@ -69,9 +69,9 @@ class StaticReflectionMethodTest extends TestCase
}
/**
* @dataProvider getNotImplementedMethods
*
* @param mixed[] $args
*
* @dataProvider getNotImplementedMethods
*/
public function testNotImplemented(string $method, array $args) : void
{

View File

@@ -13,13 +13,13 @@ use function substr;
class StaticReflectionParserTest extends DoctrineTestCase
{
/**
* @dataProvider parentClassData
*
* @param bool $classAnnotationOptimize
* @param string $parsedClassName
* @param string $expectedClassName
*
* @return void
*
* @dataProvider parentClassData
*/
public function testParentClass($classAnnotationOptimize, $parsedClassName, $expectedClassName)
{
@@ -89,7 +89,7 @@ class StaticReflectionParserTest extends DoctrineTestCase
{
$testsRoot = substr(__DIR__, 0, -strlen(__NAMESPACE__) - 1);
$paths = [
'Doctrine\\Tests' => [$testsRoot],
'Doctrine\\Tests' => [$testsRoot],
];
$staticReflectionParser = new StaticReflectionParser($class, new Psr0FindFile($paths), $classAnnotationOptimize);
$expectedDocComment = '/**
@@ -101,7 +101,7 @@ class StaticReflectionParserTest extends DoctrineTestCase
}
/**
* @return string[]|bool[]
* @return array<array<bool|string>>
*/
public function classAnnotationOptimize()
{
@@ -110,6 +110,8 @@ class StaticReflectionParserTest extends DoctrineTestCase
[ExampleAnnotationClass::class, true],
[AnnotationClassWithScopeResolution::class, false],
[AnnotationClassWithScopeResolution::class, true],
[AnnotationClassWithAnonymousClass::class, false],
[AnnotationClassWithAnonymousClass::class, true],
];
}
}

View File

@@ -27,7 +27,7 @@ class StaticReflectionPropertyTest extends TestCase
public function testGetDeclaringClass() : void
{
$staticReflectionClass = $this->createMock(StaticReflectionClass::class);
$staticReflectionClass = $this->createPartialMock(StaticReflectionClass::class, []);
$this->staticReflectionParser->expects($this->once())
->method('getReflectionClass')
@@ -38,7 +38,7 @@ class StaticReflectionPropertyTest extends TestCase
public function testGetDocComment() : void
{
$staticReflectionClass = $this->createMock(StaticReflectionClass::class);
$staticReflectionClass = $this->createPartialMock(StaticReflectionClass::class, []);
$this->staticReflectionParser->expects($this->once())
->method('getDocComment')
@@ -50,7 +50,7 @@ class StaticReflectionPropertyTest extends TestCase
public function testGetUseStatements() : void
{
$staticReflectionClass = $this->createMock(StaticReflectionClass::class);
$staticReflectionClass = $this->createPartialMock(StaticReflectionClass::class, []);
$this->staticReflectionParser->expects($this->once())
->method('getUseStatements')
@@ -60,9 +60,9 @@ class StaticReflectionPropertyTest extends TestCase
}
/**
* @dataProvider getNotImplementedMethods
*
* @param mixed[] $args
*
* @dataProvider getNotImplementedMethods
*/
public function testNotImplemented(string $method, array $args) : void
{

View File

@@ -14,7 +14,7 @@ use function strtr;
error_reporting(E_ALL | E_STRICT);
// register silently failing autoloader
spl_autoload_register(function ($class) {
spl_autoload_register(static function ($class) {
if (strpos($class, 'Doctrine\Tests\\') !== 0) {
return;
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Doctrine\Tests_PHP74\Common\Reflection\Dummies;
trait TokenParserAnonymousFunctionTestClass
{
protected function method()
{
return static function ($value) {
return $value;
};
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Doctrine\Tests_PHP74\Common\Reflection;
use Doctrine\Common\Reflection\Psr0FindFile;
use Doctrine\Common\Reflection\StaticReflectionParser;
use Doctrine\Tests_PHP74\Common\Reflection\Dummies\TokenParserAnonymousFunctionTestClass;
use PHPUnit\Framework\TestCase;
use function strlen;
use function substr;
class TokenParserAnonymousFunctionTest extends TestCase
{
public function testGetValue() : void
{
$testsRoot = substr(__DIR__, 0, -strlen(__NAMESPACE__) - 1);
$paths = [
'Doctrine\\Tests_PHP74' => [$testsRoot],
];
$staticReflectionParser = new StaticReflectionParser(TokenParserAnonymousFunctionTestClass::class, new Psr0FindFile($paths));
self::assertEquals('', $staticReflectionParser->getDocComment());
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Doctrine\Tests_PHP74\Common\Reflection;
use Doctrine\Common\Reflection\TypedNoDefaultReflectionProperty;
use PHPUnit\Framework\TestCase;
class TypedNoDefaultReflectionPropertyTest extends TestCase
{
public function testGetValue() : void
{
$object = new TypedNoDefaultReflectionPropertyTestClass();
$reflProperty = new TypedNoDefaultReflectionProperty(TypedNoDefaultReflectionPropertyTestClass::class, 'test');
self::assertNull($reflProperty->getValue($object));
$object->test = 'testValue';
self::assertSame('testValue', $reflProperty->getValue($object));
unset($object->test);
self::assertNull($reflProperty->getValue($object));
}
public function testSetValueNull() : void
{
$reflection = new TypedNoDefaultReflectionProperty(TypedFoo::class, 'id');
$reflection->setAccessible(true);
$object = new TypedFoo();
$object->setId(1);
self::assertTrue($reflection->isInitialized($object));
$reflection->setValue($object, null);
self::assertNull($reflection->getValue($object));
self::assertFalse($reflection->isInitialized($object));
}
public function testSetValueNullOnNullableProperty() : void
{
$reflection = new TypedNoDefaultReflectionProperty(TypedNullableFoo::class, 'value');
$reflection->setAccessible(true);
$object = new TypedNullableFoo();
$reflection->setValue($object, null);
self::assertNull($reflection->getValue($object));
self::assertTrue($reflection->isInitialized($object));
self::assertNull($object->getValue());
}
}
class TypedNoDefaultReflectionPropertyTestClass
{
public string $test;
}
class TypedFoo
{
private int $id;
public function setId($id)
{
$this->id = $id;
}
}
class TypedNullableFoo
{
private ?string $value;
public function setValue($value)
{
$this->value = $value;
}
public function getValue()
{
return $this->value;
}
}