Skip to content
Snippets Groups Projects
Commit 17d8d2cf authored by David Prévot's avatar David Prévot
Browse files

New upstream version 4.0.0

parents c9b80ac5 462699a1
Branches
Tags upstream/4.0.0
No related merge requests found
Showing with 151 additions and 185 deletions
......@@ -7,7 +7,7 @@ on:
name: "CI"
env:
COMPOSER_ROOT_VERSION: "3.2-dev"
COMPOSER_ROOT_VERSION: "4.0-dev"
permissions:
contents: read
......@@ -28,7 +28,7 @@ jobs:
php-version: 8.1
coverage: none
- name: Run friendsofphp/php-cs-fixer
- name: Run PHP-CS-Fixer
run: ./tools/php-cs-fixer fix --dry-run --show-progress=dots --using-cache=no --verbose
type-checker:
......@@ -46,10 +46,10 @@ jobs:
php-version: 8.1
coverage: none
- name: Update dependencies with composer
- name: Install dependencies with Composer
run: ./tools/composer update --no-interaction --no-ansi --no-progress
- name: Run vimeo/psalm
- name: Run Psalm
run: ./tools/psalm --config=.psalm/config.xml --no-progress --shepherd --show-info=false --stats
tests:
......@@ -61,9 +61,6 @@ jobs:
fail-fast: false
matrix:
php-version:
- "7.3"
- "7.4"
- "8.0"
- "8.1"
- "8.2"
- "8.3"
......@@ -78,17 +75,17 @@ jobs:
php-version: "${{ matrix.php-version }}"
coverage: "pcov"
- name: "Cache dependencies installed with composer"
- name: "Cache dependencies installed with Composer"
uses: "actions/cache@v2"
with:
path: "~/.composer/cache"
key: "php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }}"
restore-keys: "php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-"
- name: "Install dependencies with composer"
- name: "Install dependencies with Composer"
run: "./tools/composer update --no-ansi --no-interaction --no-progress"
- name: "Run tests with phpunit/phpunit"
- name: "Run tests with PHPUnit"
run: "vendor/bin/phpunit --coverage-clover=coverage.xml"
- name: "Send code coverage report to Codecov.io"
......
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="php-cs-fixer" version="^3.0" installed="3.11.0" location="./tools/php-cs-fixer" copy="true"/>
<phar name="psalm" version="^4.0" installed="4.27.0" location="./tools/psalm" copy="true"/>
<phar name="composer" version="^2.0.3" installed="2.4.2" location="./tools/composer" copy="true"/>
<phar name="infection" version="^0.26.6" installed="0.26.15" location="./tools/infection" copy="true"/>
<phar name="php-cs-fixer" version="^3.0" installed="3.14.3" location="./tools/php-cs-fixer" copy="true"/>
<phar name="psalm" version="^5.0" installed="5.6.0" location="./tools/psalm" copy="true"/>
<phar name="composer" version="^2.0.3" installed="2.5.1" location="./tools/composer" copy="true"/>
<phar name="infection" version="^0.26.6" installed="0.26.18" location="./tools/infection" copy="true"/>
</phive>
......@@ -54,13 +54,15 @@ $config->setFinder($finder)
'yield',
],
],
'braces' => true,
'braces' => [
'position_after_anonymous_constructs' => 'next',
],
'cast_spaces' => true,
'class_attributes_separation' => [
'elements' => [
'const' => 'one',
'method' => 'one',
'property' => 'one'
'property' => 'only_if_meta'
]
],
'class_definition' => true,
......@@ -86,6 +88,7 @@ $config->setFinder($finder)
'function_declaration' => true,
'function_to_constant' => true,
'function_typehint_space' => true,
'get_class_to_class_keyword' => true,
'global_namespace_import' => [
'import_classes' => true,
'import_constants' => true,
......@@ -117,9 +120,16 @@ $config->setFinder($finder)
'multiline_whitespace_before_semicolons' => true,
'native_constant_invocation' => false,
'native_function_casing' => false,
'native_function_invocation' => false,
'native_function_invocation' => [
'include' => [
'@internal',
],
],
'native_function_type_declaration_casing' => true,
'new_with_braces' => false,
'new_with_braces' => [
'named_class' => false,
'anonymous_class' => false,
],
'no_alias_functions' => true,
'no_alias_language_construct_call' => true,
'no_alternative_syntax' => true,
......@@ -149,14 +159,14 @@ $config->setFinder($finder)
'no_superfluous_phpdoc_tags' => [
'allow_mixed' => true,
],
'no_trailing_comma_in_list_call' => true,
'no_trailing_comma_in_singleline_array' => true,
'no_trailing_comma_in_singleline' => true,
'no_trailing_whitespace' => true,
'no_trailing_whitespace_in_comment' => true,
'no_trailing_whitespace_in_string' => true,
'no_unneeded_control_parentheses' => true,
'no_unneeded_curly_braces' => true,
'no_unneeded_final_method' => true,
'no_unneeded_import_alias' => true,
'no_unreachable_default_argument_value' => true,
'no_unset_cast' => true,
'no_unset_on_property' => true,
......@@ -293,7 +303,7 @@ $config->setFinder($finder)
'property',
],
],
'void_return' => false,
'void_return' => true,
'whitespace_after_comma_in_array' => true,
]);
......
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.x-dev@">
<files psalm-version="5.6.0@e784128902dfe01d489c4123d69918a9f3c1eac5">
<file src="src/ReflectionMapper.php">
<InvalidReturnType occurrences="1">
<DocblockTypeContradiction>
<code>$_type instanceof ReflectionIntersectionType</code>
<code>assert($_type instanceof ReflectionNamedType || $_type instanceof ReflectionIntersectionType)</code>
</DocblockTypeContradiction>
<InvalidReturnType>
<code>Type</code>
</InvalidReturnType>
<RedundantConditionGivenDocblockType occurrences="1">
<RedundantCondition>
<code>$name !== ''</code>
</RedundantCondition>
<RedundantConditionGivenDocblockType>
<code>$returnType instanceof ReflectionIntersectionType</code>
<code>assert($_type instanceof ReflectionNamedType || $_type instanceof ReflectionIntersectionType)</code>
<code>assert($_type instanceof ReflectionNamedType)</code>
</RedundantConditionGivenDocblockType>
</file>
<file src="src/type/IntersectionType.php">
<PropertyTypeCoercion>
<code>$types</code>
</PropertyTypeCoercion>
</file>
<file src="src/type/ObjectType.php">
<ArgumentTypeCoercion occurrences="1">
<ArgumentTypeCoercion>
<code>$this-&gt;className-&gt;qualifiedName()</code>
</ArgumentTypeCoercion>
</file>
<file src="src/type/SimpleType.php">
<MissingParamType occurrences="1">
<code>$value</code>
</MissingParamType>
<MissingReturnType occurrences="1">
<code>value</code>
</MissingReturnType>
</file>
<file src="src/type/StaticType.php">
<ArgumentTypeCoercion occurrences="1">
<ArgumentTypeCoercion>
<code>$this-&gt;className-&gt;qualifiedName()</code>
</ArgumentTypeCoercion>
</file>
<file src="src/type/Type.php">
<MissingParamType occurrences="1">
<code>$value</code>
</MissingParamType>
<file src="src/type/UnionType.php">
<PropertyTypeCoercion>
<code>$types</code>
</PropertyTypeCoercion>
</file>
</files>
......@@ -4,7 +4,9 @@
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
resolveFromConfigFile="false"
findUnusedCode="false"
errorBaseline=".psalm/baseline.xml"
findUnusedBaselineEntry="true"
>
<projectFiles>
<directory name="src" />
......
......@@ -2,6 +2,12 @@
All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [4.0.0] - 2023-02-03
### Removed
* This component is no longer supported on PHP 7.3, PHP 7.4 and PHP 8.0
## [3.2.1] - 2023-02-03
### Fixed
......@@ -147,6 +153,7 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt
* Initial release based on [code contributed by Michel Hartmann to PHPUnit](https://github.com/sebastianbergmann/phpunit/pull/3673)
[4.0.0]: https://github.com/sebastianbergmann/type/compare/3.2.1...4.0.0
[3.2.1]: https://github.com/sebastianbergmann/type/compare/3.2.0...3.2.1
[3.2.0]: https://github.com/sebastianbergmann/type/compare/3.1.0...3.2.0
[3.1.0]: https://github.com/sebastianbergmann/type/compare/3.0.0...3.1.0
......
sebastian/type
BSD 3-Clause License
Copyright (c) 2019-2022, Sebastian Bergmann <sebastian@phpunit.de>.
Copyright (c) 2019-2023, Sebastian Bergmann
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Sebastian Bergmann nor the names of his
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# sebastian/type
[![Latest Stable Version](https://poser.pugx.org/sebastian/type/v/stable.png)](https://packagist.org/packages/sebastian/type)
[![CI Status](https://github.com/sebastianbergmann/type/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/type/actions)
[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/type/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/type)
[![codecov](https://codecov.io/gh/sebastianbergmann/type/branch/main/graph/badge.svg)](https://codecov.io/gh/sebastianbergmann/type)
# sebastian/type
Collection of value objects that represent the types of the PHP type system.
......
# Security Policy
This library is intended to be used in development environments only. For instance, it is used by the testing framework PHPUnit. There is no reason why this library should be installed on a webserver.
**If you upload this library to a webserver then your deployment process is broken. On a more general note, if your `vendor` directory is publicly accessible on your webserver then your deployment process is also broken.**
## Security Contact Information
After the above, if you still would like to report a security vulnerability, please email `sebastian@phpunit.de`.
......@@ -16,14 +16,14 @@
},
"prefer-stable": true,
"require": {
"php": ">=7.3"
"php": ">=8.1"
},
"require-dev": {
"phpunit/phpunit": "^9.5"
"phpunit/phpunit": "^10.0"
},
"config": {
"platform": {
"php": "7.3.0"
"php": "8.1.0"
},
"optimize-autoloader": true,
"sort-packages": true
......@@ -44,7 +44,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
"dev-main": "4.0-dev"
}
}
}
{
"source": {
"directories": [
"src"
]
},
"mutators": {
"@default": true
},
"minMsi": 100,
"minCoveredMsi": 100
}
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd"
bootstrap="vendor/autoload.php"
cacheResultFile=".phpunit.cache/test-results"
cacheDirectory=".phpunit.cache"
executionOrder="depends,defects"
forceCoversAnnotation="true"
beStrictAboutCoversAnnotation="true"
requireCoverageMetadata="true"
beStrictAboutCoverageMetadata="true"
beStrictAboutOutputDuringTests="true"
convertDeprecationsToExceptions="true"
failOnRisky="true"
failOnWarning="true"
colors="true"
verbose="true">
colors="true">
<testsuites>
<testsuite name="default">
<directory>tests/unit</directory>
</testsuite>
</testsuites>
<coverage cacheDirectory=".phpunit.cache/code-coverage"
processUncoveredFiles="true">
<coverage>
<include>
<directory suffix=".php">src</directory>
</include>
......
......@@ -14,12 +14,8 @@ final class Parameter
/**
* @psalm-var non-empty-string
*/
private $name;
/**
* @var Type
*/
private $type;
private string $name;
private Type $type;
/**
* @psalm-param non-empty-string $name
......
......@@ -10,7 +10,7 @@
namespace SebastianBergmann\Type;
use function assert;
use ReflectionFunctionAbstract;
use ReflectionFunction;
use ReflectionIntersectionType;
use ReflectionMethod;
use ReflectionNamedType;
......@@ -22,7 +22,7 @@ final class ReflectionMapper
/**
* @psalm-return list<Parameter>
*/
public function fromParameterTypes(ReflectionFunctionAbstract $functionOrMethod): array
public function fromParameterTypes(ReflectionFunction|ReflectionMethod $functionOrMethod): array
{
$parameters = [];
......@@ -68,7 +68,7 @@ final class ReflectionMapper
return $parameters;
}
public function fromReturnType(ReflectionFunctionAbstract $functionOrMethod): Type
public function fromReturnType(ReflectionFunction|ReflectionMethod $functionOrMethod): Type
{
if (!$this->hasReturnType($functionOrMethod)) {
return new UnknownType;
......@@ -91,7 +91,7 @@ final class ReflectionMapper
}
}
private function mapNamedType(ReflectionNamedType $type, ReflectionFunctionAbstract $functionOrMethod): Type
private function mapNamedType(ReflectionNamedType $type, ReflectionFunction|ReflectionMethod $functionOrMethod): Type
{
if ($functionOrMethod instanceof ReflectionMethod && $type->getName() === 'self') {
return ObjectType::fromName(
......@@ -124,7 +124,7 @@ final class ReflectionMapper
);
}
private function mapUnionType(ReflectionUnionType $type, ReflectionFunctionAbstract $functionOrMethod): Type
private function mapUnionType(ReflectionUnionType $type, ReflectionFunction|ReflectionMethod $functionOrMethod): Type
{
$types = [];
......@@ -143,7 +143,7 @@ final class ReflectionMapper
return new UnionType(...$types);
}
private function mapIntersectionType(ReflectionIntersectionType $type, ReflectionFunctionAbstract $functionOrMethod): Type
private function mapIntersectionType(ReflectionIntersectionType $type, ReflectionFunction|ReflectionMethod $functionOrMethod): Type
{
$types = [];
......@@ -156,29 +156,21 @@ final class ReflectionMapper
return new IntersectionType(...$types);
}
private function hasReturnType(ReflectionFunctionAbstract $functionOrMethod): bool
private function hasReturnType(ReflectionFunction|ReflectionMethod $functionOrMethod): bool
{
if ($functionOrMethod->hasReturnType()) {
return true;
}
if (!method_exists($functionOrMethod, 'hasTentativeReturnType')) {
return false;
}
return $functionOrMethod->hasTentativeReturnType();
}
private function returnType(ReflectionFunctionAbstract $functionOrMethod): ?ReflectionType
private function returnType(ReflectionFunction|ReflectionMethod $functionOrMethod): ?ReflectionType
{
if ($functionOrMethod->hasReturnType()) {
return $functionOrMethod->getReturnType();
}
if (!method_exists($functionOrMethod, 'getTentativeReturnType')) {
return null;
}
return $functionOrMethod->getTentativeReturnType();
}
}
......@@ -17,15 +17,8 @@ use ReflectionClass;
final class TypeName
{
/**
* @var ?string
*/
private $namespaceName;
/**
* @var string
*/
private $simpleName;
private ?string $namespaceName;
private string $simpleName;
public static function fromQualifiedName(string $fullClassName): self
{
......
......@@ -17,26 +17,20 @@ use function function_exists;
use function is_array;
use function is_object;
use function is_string;
use function str_contains;
use Closure;
use ReflectionClass;
use ReflectionException;
use ReflectionObject;
final class CallableType extends Type
{
/**
* @var bool
*/
private $allowsNull;
private bool $allowsNull;
public function __construct(bool $nullable)
{
$this->allowsNull = $nullable;
}
/**
* @throws RuntimeException
*/
public function isAssignable(Type $other): bool
{
if ($this->allowsNull && $other instanceof NullType) {
......@@ -94,34 +88,16 @@ final class CallableType extends Type
private function isClosure(ObjectType $type): bool
{
return !$type->className()->isNamespaced() && $type->className()->simpleName() === Closure::class;
return $type->className()->qualifiedName() === Closure::class;
}
/**
* @throws RuntimeException
*/
private function hasInvokeMethod(ObjectType $type): bool
{
$className = $type->className()->qualifiedName();
assert(class_exists($className));
try {
$class = new ReflectionClass($className);
// @codeCoverageIgnoreStart
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
// @codeCoverageIgnoreEnd
}
if ($class->hasMethod('__invoke')) {
return true;
}
assert(class_exists($className));
return false;
return (new ReflectionClass($className))->hasMethod('__invoke');
}
private function isFunction(SimpleType $type): bool
......@@ -163,7 +139,7 @@ final class CallableType extends Type
}
if (is_string($type->value())) {
if (strpos($type->value(), '::') === false) {
if (!str_contains($type->value(), '::')) {
return false;
}
......@@ -186,27 +162,21 @@ final class CallableType extends Type
[$className, $methodName] = $type->value();
}
assert(isset($className) && is_string($className) && class_exists($className));
assert(isset($className) && is_string($className));
assert(isset($methodName) && is_string($methodName));
try {
$class = new ReflectionClass($className);
if (!class_exists($className)) {
return false;
}
if ($class->hasMethod($methodName)) {
$method = $class->getMethod($methodName);
$class = new ReflectionClass($className);
return $method->isPublic() && $method->isStatic();
}
// @codeCoverageIgnoreStart
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
// @codeCoverageIgnoreEnd
if (!$class->hasMethod($methodName)) {
return false;
}
return false;
$method = $class->getMethod($methodName);
return $method->isPublic() && $method->isStatic();
}
}
......@@ -11,10 +11,7 @@ namespace SebastianBergmann\Type;
final class GenericObjectType extends Type
{
/**
* @var bool
*/
private $allowsNull;
private bool $allowsNull;
public function __construct(bool $nullable)
{
......
......@@ -20,7 +20,7 @@ final class IntersectionType extends Type
/**
* @psalm-var non-empty-list<Type>
*/
private $types;
private array $types;
/**
* @throws RuntimeException
......
......@@ -13,14 +13,10 @@ use function assert;
use function class_exists;
use function is_iterable;
use ReflectionClass;
use ReflectionException;
final class IterableType extends Type
{
/**
* @var bool
*/
private $allowsNull;
private bool $allowsNull;
public function __construct(bool $nullable)
{
......@@ -46,19 +42,10 @@ final class IterableType extends Type
if ($other instanceof ObjectType) {
$className = $other->className()->qualifiedName();
assert(class_exists($className));
try {
return (new ReflectionClass($className))->isIterable();
// @codeCoverageIgnoreStart
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
(int) $e->getCode(),
$e
);
// @codeCoverageIgnoreEnd
}
return (new ReflectionClass($className))->isIterable();
}
return false;
......
......@@ -14,15 +14,8 @@ use function strcasecmp;
final class ObjectType extends Type
{
/**
* @var TypeName
*/
private $className;
/**
* @var bool
*/
private $allowsNull;
private TypeName $className;
private bool $allowsNull;
public function __construct(TypeName $className, bool $allowsNull)
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment