Skip to content
Snippets Groups Projects
Commit 0bce28aa authored by Jan Kuchař's avatar Jan Kuchař
Browse files

Merge branch 'update-deps' into 'master'

Update deps

See merge request !19
parents f92d5b29 414c0b6b
Branches master
No related tags found
1 merge request!19Update deps
Pipeline #59801 passed
image: grifart/php7.2-with-gulp-and-all-php-modules
image: grifart/php8.1-with-all-modules-and-various-tools
# STAGES
......@@ -46,8 +45,8 @@ test.php-syntax-check:
stage: test
script:
- composer global require jakub-onderka/php-console-highlighter jakub-onderka/php-parallel-lint
- parallel-lint src
- composer require php-parallel-lint/php-parallel-lint
- vendor/bin/parallel-lint src
# php stan
......@@ -67,8 +66,11 @@ test.phpstan:
.test.tests: &test-tests
stage: test
dependencies:
- build.composer.dev
dependencies: []
needs: []
before_script:
- composer install --no-interaction --ansi
script:
- composer run test
......@@ -80,17 +82,61 @@ test.phpstan:
- src # can contain assertion diffs
when: on_failure
test.tests.php71:
test.tests.php72:
<<: *test-tests
image: grifart/php7.1-with-gulp-and-all-php-modules
image: grifart/php7.2-with-gulp-and-all-php-modules
test.tests.php71.oldDeps:
test.tests.php72.oldDeps:
<<: *test-tests
before_script:
- composer update --prefer-lowest --no-interaction --ansi
image: grifart/php7.1-with-gulp-and-all-php-modules
- composer update --prefer-lowest --no-interaction --ansi
image: grifart/php7.2-with-gulp-and-all-php-modules
test.tests.php72:
test.tests.php73:
<<: *test-tests
image: grifart/php7.2-with-gulp-and-all-php-modules
\ No newline at end of file
image: grifart/php7.3-with-gulp-and-all-php-modules
test.tests.php73.oldDeps:
<<: *test-tests
before_script:
- composer update --prefer-lowest --no-interaction --ansi
image: grifart/php7.3-with-gulp-and-all-php-modules
test.tests.php74:
<<: *test-tests
image: grifart/php7.4-with-gulp-and-all-php-modules
test.tests.php74.oldDeps:
<<: *test-tests
before_script:
- composer update --prefer-lowest --no-interaction --ansi
image: grifart/php7.4-with-gulp-and-all-php-modules
test.tests.php80:
<<: *test-tests
image: grifart/php8.0-with-all-modules-and-various-tools
test.tests.php80.oldDeps:
<<: *test-tests
before_script:
- composer update --prefer-lowest --no-interaction --ansi
image: grifart/php8.0-with-all-modules-and-various-tools
test.tests.php81:
<<: *test-tests
image: grifart/php8.1-with-all-modules-and-various-tools
test.tests.php81.oldDeps:
<<: *test-tests
before_script:
- composer update --prefer-lowest --no-interaction --ansi
image: grifart/php8.1-with-all-modules-and-various-tools
\ No newline at end of file
......@@ -15,12 +15,12 @@
"@phpstan",
"@test"
],
"phpstan": "vendor/bin/phpstan analyze -l 7 -c phpstan.neon --error-format compact --no-interaction --ansi --no-progress -- src",
"phpstan": "vendor/bin/phpstan analyze -c phpstan.neon --error-format compact --no-interaction --ansi --no-progress -- src",
"test": "vendor/bin/tester tests --colors 1"
},
"require": {
"php": ">=7.1.0"
"php": ">=7.2.0"
},
"autoload": {
"psr-4": {
......@@ -32,10 +32,10 @@
},
"require-dev": {
"nette/tester": "^2.1.0",
"phpstan/phpstan": "^0.10.7",
"phpstan/phpstan-strict-rules": "^0.10.1",
"grifart/phpstan-oneline": "^0.2.0"
"nette/tester": "~2.4.2",
"phpstan/phpstan": "~1.6.9",
"phpstan/phpstan-strict-rules": "~1.2.3",
"grifart/phpstan-oneline": "~v0.4.2"
},
"autoload-dev": {
"files": [
......
......@@ -3,11 +3,5 @@ includes:
- vendor/grifart/phpstan-oneline/config.neon
parameters:
level: 9
ignoreErrors:
# for phpstan 0.11
# -
# message: '#Strict comparison using === between int\\|string and null will always evaluate to false#'
# path: src/Internal/Meta.php
- '#Strict comparison using === between int\\|string and null will always evaluate to false#'
\ No newline at end of file
......@@ -5,12 +5,14 @@ namespace Grifart\Enum;
/**
* Allows you to use you defined constants automatically as enum value.
* Without explicitly implementing each enum value.
*
* @phpstan-type TScalarValue string|int
*/
trait AutoInstances
{
abstract protected static function getConstantToScalar(): array;
/** @param string|int $scalar */
/** @param TScalarValue $scalar */
abstract public function __construct($scalar);
protected static function provideInstances(): array
......
......@@ -13,13 +13,15 @@ use Grifart\Enum\Internal\Meta;
* - **scalar** = scalar identifier of enum value; typically used in persistence layer to refer to particular value
* - **constant** = each value has associated class constant, which is used to refer to value from code.
* Constant name is used to generate static method for each of them. Constants are therefore usually not public.
* @phpstan-type TScalarValue string|int
*/
abstract class Enum
{
/**
* Provide values for given enum, never call this method directly.
* @return self[]
* @return static[]
*/
abstract protected static function provideInstances(): array;
......@@ -33,12 +35,14 @@ abstract class Enum
}
/**
* @return array<string,string|int>
* @return array<string,TScalarValue>
*/
protected static function getConstantToScalar(): array
{
try {
return (new \ReflectionClass(static::class))->getConstants();
/** @var array<string, TScalarValue> $constants */
$constants = (new \ReflectionClass(static::class))->getConstants();
return $constants;
} catch (\ReflectionException $e) {
throw new ReflectionFailedException($e);
}
......@@ -46,7 +50,7 @@ abstract class Enum
/**
* Builds enumeration from its scalar value.
* @param string|int $scalar
* @param TScalarValue $scalar
* @return static
* @throws MissingValueDeclarationException if there is no value for given scalar
*/
......@@ -57,13 +61,12 @@ abstract class Enum
/**
* Provides access to values using ::CONSTANT_NAME() interface.
* @param array{} $arguments And empty array, arguments not used.
* @return static
* @throws MissingValueDeclarationException
*/
public static function __callStatic(string $constantName, array $arguments): Enum
{
\assert(\count($arguments) === 0);
$value = self::getMeta(FALSE)->getValueForConstantName($constantName);
if($value === NULL) {
throw new \Error('Call to undefined method ' . static::class . '::' . $constantName . '(). Please check that you have provided constant, annotation and value.');
......@@ -71,9 +74,12 @@ abstract class Enum
return $value;
}
/**
* @return Meta<static>
*/
private static function getMeta(bool $checkIfAccessingRootDirectly = true): Meta
{
$rootClass = static::getRootClass();
$rootClass = self::getRootClass();
if ($checkIfAccessingRootDirectly && $rootClass !== static::class) {
throw new UsageException(
'You have accessed static enum method on non-root class '
......@@ -84,22 +90,29 @@ abstract class Enum
return InstanceRegister::get(
$rootClass,
function () use ($rootClass): Meta {
return Meta::from(
/** @var Meta<static> $meta */
$meta = Meta::from(
$rootClass,
static::getConstantToScalar(),
static::provideInstances()
);
return $meta;
}
);
}
/**
* @return class-string<static>
*/
private static function getRootClass(): string
{
try {
return (new \ReflectionClass(static::class))
$rootClassName = (new \ReflectionClass(static::class))
->getMethod('provideInstances')
->getDeclaringClass()
->getName();
/** @var class-string<static> $rootClassName */
return $rootClassName;
} catch (\ReflectionException $e) {
throw new ReflectionFailedException($e);
......@@ -110,11 +123,11 @@ abstract class Enum
// -------- INSTANCE IMPLEMENTATION ---------
/** @var int|string */
/** @var ?TScalarValue */
private $scalarValue;
/**
* @param int|string $scalarValue
* @param TScalarValue $scalarValue
*/
protected function __construct($scalarValue)
{
......@@ -123,10 +136,17 @@ abstract class Enum
/**
* Returns scalar representation of enum value.
* @return int|string
* @return TScalarValue
*/
public function toScalar()
{
if ($this->scalarValue === NULL) {
$rootClassName = self::getRootClass();
throw new UsageException(
"Parent constructor has not been called while constructing one of {$rootClassName} enum values."
);
}
return $this->scalarValue;
}
......@@ -162,7 +182,7 @@ abstract class Enum
}
/**
* @param int|string $theOtherScalarValue
* @param TScalarValue $theOtherScalarValue
* @return bool true if current scalar representation of value equals to given scalar value
*/
public function scalarEquals($theOtherScalarValue): bool
......
......@@ -2,6 +2,7 @@
namespace Grifart\Enum\Internal;
use Grifart\Enum\Enum;
use Grifart\Enum\UsageException;
/**
......@@ -9,6 +10,9 @@ use Grifart\Enum\UsageException;
*/
final class ConsistencyChecker
{
/**
* @param Meta<Enum> $enumMeta
*/
public static function checkAnnotations(Meta $enumMeta): void
{
self::checkCallStaticAnnotations($enumMeta);
......@@ -16,6 +20,9 @@ final class ConsistencyChecker
self::checkAbstractAndFinal($enumMeta);
}
/**
* @param Meta<Enum> $enumMeta
*/
private static function checkCallStaticAnnotations(Meta $enumMeta): void
{
$enumReflection = $enumMeta->getClassReflection();
......@@ -41,6 +48,9 @@ final class ConsistencyChecker
// todo: @method annotations without constants
}
/**
* @param Meta<Enum> $enumMeta
*/
private static function checkAllInstancesProvided(Meta $enumMeta): void
{
// todo: instances without constants
......@@ -53,6 +63,9 @@ final class ConsistencyChecker
}
}
/**
* @param Meta<Enum> $enumMeta
*/
private static function checkAbstractAndFinal(Meta $enumMeta): void
{
$enumReflection = $enumMeta->getClassReflection();
......
......@@ -2,27 +2,44 @@
namespace Grifart\Enum\Internal;
use Grifart\Enum\Enum;
/**
* Keeps track of all enum instances organized by enum root classes.
*/
final class InstanceRegister
{
/** @var \Grifart\Enum\Internal\Meta[] */
/** @var Meta<Enum>[] */
private static $instances = [];
/**
* @template TEnum of Enum
* @param class-string<TEnum> $enumClass
* @param callable():Meta<TEnum> $registrar
* @return Meta<TEnum>
*/
public static function get(string $enumClass, callable $registrar): Meta
{
if (!isset(self::$instances[$enumClass])) {
self::register($enumClass, $registrar());
}
return self::$instances[$enumClass];
/** @var Meta<TEnum> $meta */
$meta = self::$instances[$enumClass];
return $meta;
}
/**
* @template TEnum of \Grifart\Enum\Enum
* @param class-string<TEnum> $className
* @param Meta<TEnum> $meta
* @return void
*/
public static function register(string $className, Meta $meta): void
{
\assert($meta->getClass() === $className, 'Provided Meta object is for different enum class that was originally registered.');
// check consistency of enum when assertions are enabled (typically non-production code)
// @phpstan-ignore-next-line as "Call to function assert() with true will always evaluate to true." is intentional
assert(
(function () use ($meta): bool {
ConsistencyChecker::checkAnnotations($meta);
......
......@@ -7,21 +7,26 @@ use Grifart\Enum\MissingValueDeclarationException;
use Grifart\Enum\ReflectionFailedException;
use Grifart\Enum\UsageException;
/**
* @template TEnum of \Grifart\Enum\Enum
* @phpstan-type TScalarValue int|string
* @phpstan-type TConstantName string
*/
final class Meta
{
/** @var string */
/** @var class-string<TEnum> */
private $class;
/** @var array<string,int|string> */
/** @var array<TConstantName,TScalarValue> */
private $constantToScalar;
/** @var array<int|string,Enum> */
/** @var array<TScalarValue,TEnum> */
private $scalarToValue;
/**
* @param string $class
* @param array<string,string|int> $constantToScalar
* @param Enum[] $values
* @param class-string<TEnum> $class
* @param array<TConstantName,TScalarValue> $constantToScalar
* @param TEnum[] $values
*/
private function __construct(string $class, array $constantToScalar, array $values)
{
......@@ -32,7 +37,8 @@ final class Meta
/**
* @param Enum[] $values
* @return array<string|int,Enum>
* @phpstan-param TEnum[] $values
* @return array<TScalarValue,TEnum>
*/
private function buildScalarToValueMapping(array $values): array {
$scalarToValues = [];
......@@ -52,11 +58,7 @@ final class Meta
foreach($values as $value) {
$scalar = $value->toScalar();
if ($scalar === NULL) {
throw new UsageException(
"Parent constructor has not been called while constructing one of {$this->getClass()} enum values."
);
}
if (isset($scalarToValues[$scalar])) {
throw new UsageException('You have provided duplicated scalar values.');
......@@ -71,21 +73,27 @@ final class Meta
}
/**
* @param string $class
* @param array<string,string|int> $constantToScalar
* @param Enum[] $values
* @return self
* @param class-string<TEnum> $class
* @param array<TConstantName,TScalarValue> $constantToScalar
* @param TEnum[] $values
* @return self<TEnum>
*/
public static function from(string $class, array $constantToScalar, array $values): self
{
return new self($class, $constantToScalar, $values);
}
/**
* @return class-string<TEnum>
*/
public function getClass(): string
{
return $this->class;
}
/**
* @return \ReflectionClass<TEnum>
*/
public function getClassReflection(): \ReflectionClass
{
try {
......@@ -96,7 +104,7 @@ final class Meta
}
/**
* @return string[]
* @return TConstantName[]
*/
public function getConstantNames(): array
{
......@@ -104,7 +112,7 @@ final class Meta
}
/**
* @return string[]|int[]
* @return array<int, TScalarValue>
*/
public function getScalarValues(): array
{
......@@ -112,7 +120,7 @@ final class Meta
}
/**
* @return Enum[]
* @return TEnum[]
*/
public function getValues(): array
{
......@@ -120,7 +128,8 @@ final class Meta
}
/**
* @param string $constantName
* @param TConstantName $constantName
* @return ?TEnum
* @throws MissingValueDeclarationException
*/
public function getValueForConstantName($constantName): ?Enum
......@@ -133,7 +142,7 @@ final class Meta
}
/**
* @param string|int $scalarValue
* @param TScalarValue $scalarValue
*/
public function hasValueForScalar($scalarValue): bool
{
......@@ -141,7 +150,7 @@ final class Meta
}
/**
* @param string|int $scalarValue
* @param TScalarValue $scalarValue
*/
public function getConstantNameForScalar($scalarValue): string
{
......@@ -153,7 +162,7 @@ final class Meta
}
/**
* @return int|string
* @return TScalarValue
*/
public function getScalarForValue(Enum $enum)
{
......@@ -165,7 +174,8 @@ final class Meta
}
/**
* @param int|string $scalar
* @param TScalarValue $scalar
* @return TEnum
* @throws MissingValueDeclarationException if there is no value for given scalar
*/
public function getValueForScalar($scalar): Enum
......@@ -177,7 +187,7 @@ final class Meta
}
/**
* @param string|int $scalar
* @param TScalarValue $scalar
*/
private function hasConstantForScalar($scalar): bool
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment