diff --git a/.gitattributes b/.gitattributes index 606a7cb9..d7c1c1e7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -16,3 +16,5 @@ # Configure diff output for .php and .phar files. *.php diff=php *.phar -diff + +/vendor-bin/**/composer.lock binary diff --git a/README.ja.md b/README.ja.md index 232b33ee..d2444f14 100644 --- a/README.ja.md +++ b/README.ja.md @@ -155,6 +155,23 @@ $bind = (new Bind)->bind(RealBillingService::class, [$pointcut]); $billing = (new Weaver($bind, $tmpDir))->newInstance(RealBillingService::class, [$arg1, $arg2]); ``` +マッチャーはdoctrineアノテーション、またはPHP8アトリビュートの読み込みをサポートします。 + +```php + public function matchesClass(\ReflectionClass $class, array $arguments) : bool + { + assert($class instanceof \Ray\Aop\ReflectionClass); + $classAnnotation = $class->getAnnotation(Foo::class); // @Foo or #[Foo] + // ... + } + + public function matchesMethod(\ReflectionMethod $method, array $arguments) : bool + { + assert($method instanceof \Ray\Aop\ReflectionMethod); + $methodAnnotation = $method->getAnnotation(Bar::class); + } +``` + ## パフォーマンス `Weaver`オブジェクトはキャッシュ可能です。コンパイル、束縛、アノテーション読み込みコストを削減します。 @@ -242,11 +259,6 @@ $class = $invocation->getMethod()->getDeclaringClass(); このメソッドインターセプターのAPIは[AOPアライアンス](http://aopalliance.sourceforge.net/doc/org/aopalliance/intercept/MethodInterceptor.html)の部分実装です。 -## 要件 - -* PHP 5.6+ -* hhvm - ## インストール Ray.Aopの推奨インストール方法は、[Composer](https://github.com/composer/composer)でのインストールです。 @@ -256,18 +268,24 @@ Ray.Aopの推奨インストール方法は、[Composer](https://github.com/comp $ composer require ray/aop ~2.0 ``` -## Ray.Aopのテスト +## パフォーマンス + +AOPクラスのコンパイルにより、Ray.Aopは高速に動作します。アノテーションの読み込みは初回コンパイル時のみなので、ランタイムのパフォーマンスに影響を与えません。開発段階や最初の実行時にも、ファイルのタイムスタンプを利用してPHPファイルがキャッシュされ、通常はアノテーション生成のコストを気にする必要はありませんが、アプリケーションのブートストラップでアノテーションリーダーの設定を行うことで、初回コンパイル時のパフォーマンスが向上します。特に大規模なアプリケーションでこの設定は役立ちます。 -Ray.Aopをソースからインストールし、ユニットテストとデモを実行するには次のようにします。 +### APCu -```bash -git clone https://github.com/ray-di/Ray.Aop.git -cd Ray.Aop -composer install -vendor/bin/phpunit -php demo/run.php +```php +SevericeLocator::setReader(new PsrCachedReader(new Reader(), $apcuCache)); ``` +### アトリビュートのみ使用(推奨) + +```php +SevericeLocator::setReader(new AttributeReader);` +``` + +## DI Framework + DIとAOPを統合したDIフレームワーク[Ray.Di](https://github.com/ray-di/Ray.Di)もご覧ください。 * この文書の大部分は [Guice/AOP](https://github.com/google/guice/wiki/AOP) から借用しています。 diff --git a/README.md b/README.md index 2acf6bdd..cfebf780 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,23 @@ $bind = (new Bind())->bind(RealBillingService::class, [$pointcut]); $billing = (new Weaver($bind, $tmpDir))->newInstance(RealBillingService::class, [$arg1, $arg2]); ``` +The matcher supports reading doctrine annotations or PHP8 attributes. + +```php + public function matchesClass(\ReflectionClass $class, array $arguments) : bool + { + assert($class instanceof \Ray\Aop\ReflectionClass); + $classAnnotation = $class->getAnnotation(Foo::class); // @Foo or #[Foo] + // ... + } + + public function matchesMethod(\ReflectionMethod $method, array $arguments) : bool + { + assert($method instanceof \Ray\Aop\ReflectionMethod); + $methodAnnotation = $method->getAnnotation(Bar::class); + } +``` + ## Performance boost Cached `Weaver` object can save the compiling, binding, annotation reading costs. @@ -245,16 +262,20 @@ The recommended way to install Ray.Aop is through [Composer](https://github.com/ $ composer require ray/aop ^2.0 ``` -## Testing Ray.Aop +## Performance -Here's how to install Ray.Aop from source and run the unit tests and demos. +Compilation of the AOP class allows Ray.Aop to run faster. Annotations are only loaded at first compile time, so they do not affect runtime performance. During the development phase and even at first runtime, PHP files are cached using the file timestamps, so normally you do not need to worry about the cost of annotation generation, but by setting up an annotation reader in the application bootstrap, first-time compile time performance. This setting is especially useful for large applications. -```bash -git clone https://github.com/ray-di/Ray.Aop.git -cd Ray.Aop -composer install -composer test -php demo/run.php +### APCu + +```php +SevericeLocator::setReader(new PsrCachedReader(new Reader(), $apcuCache)); +``` + +### PHP8 attributes only (recommended) + +```php +SevericeLocator::setReader(new AttributeReader);` ``` ## Integrated DI framework diff --git a/annotation_loader.php b/annotation_loader.php index 455624b9..9f890289 100644 --- a/annotation_loader.php +++ b/annotation_loader.php @@ -4,4 +4,6 @@ use Doctrine\Common\Annotations\AnnotationRegistry; -AnnotationRegistry::registerLoader('class_exists'); +if (method_exists(AnnotationRegistry::class, 'registerLoader')) { + AnnotationRegistry::registerLoader('class_exists'); +} diff --git a/composer.json b/composer.json index c5d7697d..87c49b4c 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ ], "require": { "php": "^7.2 || ^8.0", - "doctrine/annotations": "^1.12", + "doctrine/annotations": "^1.12 || ^2.0", "koriym/attributes": "^1.0.3", "nikic/php-parser": "^4.16" }, @@ -42,19 +42,16 @@ "ray/di": "A dependency injection framework" }, "scripts" :{ - "bin": "echo 'bin not installed'", - "post-install-cmd": ["@composer bin all install --ansi"], - "post-update-cmd": ["@composer bin all update --ansi"], - "test": ["./vendor/bin/phpunit"], + "test": ["phpunit"], "tests": ["@cs", "@test", "@sa"], - "coverage": ["php -dzend_extension=xdebug.so -dxdebug.mode=coverage ./vendor/bin/phpunit --coverage-text --coverage-html=build/coverage"], - "pcov": ["php -dextension=pcov.so -d pcov.enabled=1 ./vendor/bin/phpunit --coverage-text --coverage-html=build/coverage --coverage-clover=coverage.xml"], - "cs": ["phpcs --standard=./phpcs.xml src tests"], - "cs-fix": ["./vendor/bin/phpcbf src tests"], - "clean": ["./vendor/bin/phpstan clear-result-cache", "./vendor/bin/psalm --clear-cache", "rm -rf tests/tmp/*.php"], - "sa": ["./vendor/bin/psalm --show-info=true", "./vendor/bin/phpstan analyse -c phpstan.neon"], - "metrics": ["./vendor/bin/phpmetrics --report-html=build/metrics --exclude=Exception src"], - "phpmd": ["./vendor/bin/phpmd src text ./phpmd.xml"], + "coverage": ["php -dzend_extension=xdebug.so -dxdebug.mode=coverage phpunit --coverage-text --coverage-html=build/coverage"], + "pcov": ["php -dextension=pcov.so -d pcov.enabled=1 phpunit --coverage-text --coverage-html=build/coverage --coverage-clover=coverage.xml"], + "cs": ["phpcs --standard=./phpcs.xml sl-src src tests"], + "cs-fix": ["phpcbf sl-src src tests"], + "clean": ["phpstan clear-result-cache", "psalm --clear-cache", "rm -rf tests/tmp/*.php"], + "sa": ["psalm --monochrome --show-info=true", "phpstan --memory-limit=-1 analyse -c phpstan.neon"], + "metrics": ["phpmetrics --report-html=build/metrics --exclude=Exception src"], + "phpmd": ["phpmd src text ./phpmd.xml"], "build": ["@cs", "@sa", "@pcov", "@metrics"] }, "extra": { @@ -62,6 +59,5 @@ "forward-command": true, "bin-links": true } - }, - "minimum-stability": "alpha" + } } diff --git a/phpcs.xml b/phpcs.xml index 8bdf94bd..15d1f034 100755 --- a/phpcs.xml +++ b/phpcs.xml @@ -41,6 +41,7 @@ com + diff --git a/phpstan.neon b/phpstan.neon index 2e552471..e05600cf 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,6 +1,7 @@ parameters: level: max paths: + - sl-src - src - tests excludePaths: diff --git a/psalm.xml b/psalm.xml index e1c8ce11..59c3c010 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,12 +1,14 @@ + diff --git a/sl-src/Cache.php b/sl-src/Cache.php new file mode 100644 index 00000000..0aebcb76 --- /dev/null +++ b/sl-src/Cache.php @@ -0,0 +1,101 @@ +tmpDir = $tmpDir; + } + + /** + * @psalm-param callable():array $callback + * + * @return array + * + * @psalm-suppress MixedInferredReturnType + */ + public function get(string $key, callable $callback): array + { + $filename = $this->getFilename($key); + if (! file_exists($filename)) { + $value = $callback(); + $this->writeFile($this->getFilename($key), serialize($value)); + + return $value; + } + + /** @psalm-suppress MixedAssignment, MixedArgument, MixedReturnStatement */ + return unserialize(require $filename); // @phpstan-ignore-line + } + + private function getFilename(string $id): string + { + $hash = hash('crc32', $id); + + $dir = $this->tmpDir + . DIRECTORY_SEPARATOR + . substr($hash, 0, 2); + if (! is_writable($dir)) { + mkdir($dir, 0777, true); + } + + return $dir + . DIRECTORY_SEPARATOR + . $hash + . '.php'; + } + + private function writeFile(string $filename, string $value): void + { + $filepath = pathinfo($filename, PATHINFO_DIRNAME); + if (! is_writable($filepath)) { + // @codeCoverageIgnoreStart + throw new DirectoryNotWritableException($filepath); + // @codeCoverageIgnoreEnd + } + + $tmpFile = (string) tempnam($filepath, 'swap'); + $valueWithSingileQuote = "'{$value}'"; + + $content = '> */ + private $loadedAnnotations = []; + + /** @var int[] */ + private $loadedFilemtimes = []; + + public function __construct(Reader $reader, Cache $cache) + { + $this->delegate = $reader; + $this->cache = $cache; + } + + /** + * {@inheritDoc} + */ + public function getClassAnnotations(ReflectionClass $class) // @phpstan-ignore-line + { + $cacheKey = $class->getName(); + + if (isset($this->loadedAnnotations[$cacheKey])) { + return $this->loadedAnnotations[$cacheKey]; + } + + $annots = $this->fetchFromCache($cacheKey, $class, __FUNCTION__, $class); + + return $this->loadedAnnotations[$cacheKey] = $annots; + } + + /** + * {@inheritDoc} + */ + public function getClassAnnotation(ReflectionClass $class, $annotationName) // @phpstan-ignore-line + { + foreach ($this->getClassAnnotations($class) as $annot) { + if ($annot instanceof $annotationName) { + return $annot; + } + } + + return null; + } + + /** + * {@inheritDoc} + */ + public function getPropertyAnnotations(ReflectionProperty $property) + { + throw new LogicException(__FUNCTION__ . ' Not Supported'); + } + + /** + * {@inheritDoc} + */ + public function getPropertyAnnotation(ReflectionProperty $property, $annotationName) + { + throw new LogicException(__FUNCTION__ . ' Not Supported'); + } + + /** + * {@inheritDoc} + */ + public function getMethodAnnotations(ReflectionMethod $method) + { + $class = $method->getDeclaringClass(); + $cacheKey = $class->getName() . '#' . $method->getName(); + + if (isset($this->loadedAnnotations[$cacheKey])) { + return $this->loadedAnnotations[$cacheKey]; + } + + $annots = $this->fetchFromCache($cacheKey, $class, __FUNCTION__, $method); + + return $this->loadedAnnotations[$cacheKey] = $annots; + } + + /** + * {@inheritDoc} + */ + public function getMethodAnnotation(ReflectionMethod $method, $annotationName) + { + foreach ($this->getMethodAnnotations($method) as $annot) { + if ($annot instanceof $annotationName) { + return $annot; + } + } + + return null; + } + + /** + * @return array + * + * @psalm-suppress MixedInferredReturnType + */ + private function fetchFromCache( // @phpstan-ignore-line + string $cacheKey, + ReflectionClass $class, + string $method, + Reflector $reflector + ): array { + $cacheKey = rawurlencode($cacheKey) . $this->getLastModification($class); + + return $this->cache->get( + $cacheKey, + /** @return array */ + function () use ($method, $reflector): array { + /** @psalm-suppress MixedReturnStatement */ + return $this->delegate->{$method}($reflector); + } + ); + } + + /** + * Returns the time the class was last modified, testing traits and parents + */ + private function getLastModification(ReflectionClass $class): int // @phpstan-ignore-line + { + $filename = $class->getFileName(); + + if (isset($this->loadedFilemtimes[$filename])) { + return $this->loadedFilemtimes[$filename]; + } + + $parent = $class->getParentClass(); + + $lastModification = max(array_merge( + [$filename ? filemtime($filename) : 0], + array_map(function (ReflectionClass $reflectionTrait): int { + return $this->getTraitLastModificationTime($reflectionTrait); + }, $class->getTraits()), + array_map(function (ReflectionClass $class): int { + return $this->getLastModification($class); + }, $class->getInterfaces()), + $parent ? [$this->getLastModification($parent)] : [] + )); + + assert($lastModification !== false); + + return $this->loadedFilemtimes[$filename] = $lastModification; + } + + private function getTraitLastModificationTime(ReflectionClass $reflectionTrait): int // @phpstan-ignore-line + { + $fileName = $reflectionTrait->getFileName(); + + if (isset($this->loadedFilemtimes[$fileName])) { + return $this->loadedFilemtimes[$fileName]; + } + + $lastModificationTime = max(array_merge( + [$fileName ? filemtime($fileName) : 0], + array_map(function (ReflectionClass $reflectionTrait): int { + return $this->getTraitLastModificationTime($reflectionTrait); + }, $reflectionTrait->getTraits()) + )); + + assert($lastModificationTime !== false); + + return $this->loadedFilemtimes[$fileName] = $lastModificationTime; + } +} diff --git a/sl-src/Exception/DirectoryNotWritableException.php b/sl-src/Exception/DirectoryNotWritableException.php new file mode 100644 index 00000000..b9808b92 --- /dev/null +++ b/sl-src/Exception/DirectoryNotWritableException.php @@ -0,0 +1,11 @@ + $arguments - */ + /** @param array $arguments */ public function __construct(string $matcherName, array $arguments) { parent::__construct($matcherName, $arguments); + $this->annotation = $arguments[0]; } } diff --git a/src/AopClass.php b/src/AopClass.php index 14935d05..5845084d 100644 --- a/src/AopClass.php +++ b/src/AopClass.php @@ -42,7 +42,7 @@ public function __construct( } /** - * {@inheritdoc} + * {@inheritDoc} * * @param ReflectionClass $sourceClass */ diff --git a/src/AopClassName.php b/src/AopClassName.php index 3d227a1d..00892bdb 100644 --- a/src/AopClassName.php +++ b/src/AopClassName.php @@ -18,9 +18,7 @@ public function __construct(string $classDir) $this->classDir = $classDir; } - /** - * @param class-string $class - */ + /** @param class-string $class */ public function __invoke(string $class, string $bindings): string { $fileTime = filemtime((string) (new ReflectionClass($class))->getFileName()); diff --git a/src/Bind.php b/src/Bind.php index 1fd244c0..756ab063 100644 --- a/src/Bind.php +++ b/src/Bind.php @@ -5,7 +5,6 @@ namespace Ray\Aop; use Doctrine\Common\Annotations\AnnotationException; -use ReflectionClass; use function array_key_exists; use function array_merge; @@ -19,39 +18,36 @@ final class Bind implements BindInterface /** @var MethodMatch */ private $methodMatch; - /** - * @throws AnnotationException - */ + /** @throws AnnotationException */ public function __construct() { $this->methodMatch = new MethodMatch($this); } - /** - * @return list - */ + /** @return list */ public function __sleep(): array { return ['bindings']; } /** - * {@inheritdoc} + * {@inheritDoc} */ public function bind(string $class, array $pointcuts): BindInterface { $pointcuts = $this->getAnnotationPointcuts($pointcuts); - $class = new ReflectionClass($class); - $methods = $class->getMethods(ReflectionMethod::IS_PUBLIC); + $reflectionClass = new ReflectionClass($class); + $methods = $reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC); foreach ($methods as $method) { - ($this->methodMatch)($class, $method, $pointcuts); + $rayMethod = new ReflectionMethod($reflectionClass->getName(), $method->getName()); + ($this->methodMatch)($reflectionClass, $rayMethod, $pointcuts); } return $this; } /** - * {@inheritdoc} + * {@inheritDoc} */ public function bindInterceptors(string $method, array $interceptors): BindInterface { @@ -64,7 +60,7 @@ public function bindInterceptors(string $method, array $interceptors): BindInter } /** - * {@inheritdoc} + * {@inheritDoc} */ public function getBindings(): array { @@ -72,7 +68,7 @@ public function getBindings(): array } /** - * {@inheritdoc} + * {@inheritDoc} */ public function __toString(): string { diff --git a/src/BuiltinMatcher.php b/src/BuiltinMatcher.php index 1580447c..6a922d46 100644 --- a/src/BuiltinMatcher.php +++ b/src/BuiltinMatcher.php @@ -5,7 +5,6 @@ namespace Ray\Aop; use Ray\Aop\Exception\InvalidMatcherException; -use ReflectionClass; use ReflectionMethod; use function assert; @@ -20,12 +19,11 @@ class BuiltinMatcher extends AbstractMatcher /** @var AbstractMatcher */ private $matcher; - /** - * @param mixed[] $arguments - */ + /** @param mixed[] $arguments */ public function __construct(string $matcherName, array $arguments) { parent::__construct(); + $this->matcherName = $matcherName; $this->arguments = $arguments; $matcherClass = 'Ray\Aop\Matcher\\' . ucwords($this->matcherName) . 'Matcher'; @@ -39,15 +37,15 @@ public function __construct(string $matcherName, array $arguments) } /** - * {@inheritdoc} + * {@inheritDoc} */ - public function matchesClass(ReflectionClass $class, array $arguments): bool + public function matchesClass(\ReflectionClass $class, array $arguments): bool { return $this->matcher->matchesClass($class, $arguments); } /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesMethod(ReflectionMethod $method, array $arguments): bool { diff --git a/src/CallIntercept.php b/src/CallIntercept.php index 4ada7403..10019c41 100644 --- a/src/CallIntercept.php +++ b/src/CallIntercept.php @@ -37,9 +37,7 @@ public function __construct(BuilderFactory $factory) $this->return = new Return_($methodCall); } - /** - * @return list|list - */ + /** @return list|list */ public function getStmts(?NodeAbstract $returnType): array { $isVoid = $returnType instanceof Identifier && ($returnType->name === 'void' || $returnType->name === 'never'); diff --git a/src/CodeGen.php b/src/CodeGen.php index b887eaba..688fd0ac 100644 --- a/src/CodeGen.php +++ b/src/CodeGen.php @@ -32,7 +32,7 @@ public function __construct( } /** - * {@inheritdoc} + * {@inheritDoc} * * @param ReflectionClass $sourceClass */ @@ -49,9 +49,7 @@ public function generate(ReflectionClass $sourceClass, BindInterface $bind): Cod return new Code(array_merge($visitor->declare, [$stmt])); } - /** - * @return string|null - */ + /** @return string|null */ private function getNamespace(CodeVisitor $source) { $parts = isset($source->namespace->name) ? $source->namespace->name->getParts() : []; diff --git a/src/CodeGenInterface.php b/src/CodeGenInterface.php index e3b1a954..349fbf81 100644 --- a/src/CodeGenInterface.php +++ b/src/CodeGenInterface.php @@ -8,8 +8,6 @@ interface CodeGenInterface { - /** - * @param ReflectionClass $sourceClass - */ + /** @param ReflectionClass $sourceClass */ public function generate(ReflectionClass $sourceClass, BindInterface $bind): Code; } diff --git a/src/CodeVisitor.php b/src/CodeVisitor.php index c9662660..25a70f9d 100644 --- a/src/CodeVisitor.php +++ b/src/CodeVisitor.php @@ -32,9 +32,7 @@ final class CodeVisitor extends NodeVisitorAbstract /** @var ClassMethod[] */ public $classMethod = []; - /** - * @return null - */ + /** @return null */ public function enterNode(Node $node) { if ($node instanceof Declare_) { @@ -68,9 +66,7 @@ private function validateClass(Class_ $class): void } } - /** - * @return null - */ + /** @return null */ private function enterNodeClass(Node $node) { if ($node instanceof Class_ && $node->name !== null) { diff --git a/src/Compiler.php b/src/Compiler.php index 0f75ba89..c0ada691 100644 --- a/src/Compiler.php +++ b/src/Compiler.php @@ -22,15 +22,13 @@ final class Compiler implements CompilerInterface /** @var string */ public $classDir; - /** @var CodeGenInterface */ + /** @var CodeGen */ private $codeGen; /** @var AopClassName */ private $aopClassName; - /** - * @throws AnnotationException - */ + /** @throws AnnotationException */ public function __construct(string $classDir) { if (! is_writable($classDir)) { @@ -39,30 +37,19 @@ public function __construct(string $classDir) $this->classDir = $classDir; $this->aopClassName = new AopClassName($classDir); - $parser = (new ParserFactory())->newInstance(); - $factory = new BuilderFactory(); - $aopClassName = new AopClassName($classDir); - $this->codeGen = new CodeGen( - $factory, - new VisitorFactory($parser), - new AopClass($parser, $factory, $aopClassName) - ); + $this->codeGen = $this->createCodeGen(); } - /** - * @return list - */ + /** @return list */ public function __sleep() { - return ['classDir']; + return ['classDir', 'aopClassName']; } - /** - * @throws AnnotationException - */ + /** @throws AnnotationException */ public function __wakeup() { - $this->__construct($this->classDir); + $this->codeGen = $this->createCodeGen(); } /** @@ -85,7 +72,7 @@ public function newInstance(string $class, array $args, BindInterface $bind) } /** - * {@inheritdoc} + * {@inheritDoc} */ public function compile(string $class, BindInterface $bind): string { @@ -104,9 +91,7 @@ public function compile(string $class, BindInterface $bind): string return $aopClass; } - /** - * @param class-string $class - */ + /** @param class-string $class */ private function hasNoBinding(string $class, BindInterface $bind): bool { $hasMethod = $this->hasBoundMethod($class, $bind); @@ -114,9 +99,7 @@ private function hasNoBinding(string $class, BindInterface $bind): bool return ! $bind->getBindings() && ! $hasMethod; } - /** - * @param class-string $class - */ + /** @param class-string $class */ private function hasBoundMethod(string $class, BindInterface $bind): bool { $bindingMethods = array_keys($bind->getBindings()); @@ -144,7 +127,7 @@ private function requireFile(string $aopClassName, \ReflectionClass $sourceClass } require_once $file; - class_exists($aopClassName); // ensue class is created + class_exists($aopClassName); // ensure class is created } private function getFileName(string $aopClassName): string @@ -153,4 +136,16 @@ private function getFileName(string $aopClassName): string return sprintf('%s/%s.php', $this->classDir, $flatName); } + + private function createCodeGen(): CodeGen + { + $parser = (new ParserFactory())->newInstance(); + $factory = new BuilderFactory(); + + return new CodeGen( + $factory, + new VisitorFactory($parser), + new AopClass($parser, $factory, $this->aopClassName) + ); + } } diff --git a/src/CompilerInterface.php b/src/CompilerInterface.php index 8dedfaa9..f1ff7b7a 100644 --- a/src/CompilerInterface.php +++ b/src/CompilerInterface.php @@ -16,8 +16,8 @@ public function compile(string $class, BindInterface $bind): string; /** * Return new instance weaved interceptor(s) * - * @param class-string $class - * @param array $args + * @param class-string $class + * @param list $args * * @return T * diff --git a/src/Invocation.php b/src/Invocation.php index 5e060bc0..217dc935 100644 --- a/src/Invocation.php +++ b/src/Invocation.php @@ -25,7 +25,7 @@ public function getArguments(): ArrayObject; /** * Get the named arguments as an array object. * - * @return ArrayObject the argument of the invocation [`paramName1'=>'arg1', `paramName2'=>'arg2'] + * @return ArrayObject the argument of the invocation [`paramName1'=>'arg1', `paramName2'=>'arg2'] */ public function getNamedArguments(): ArrayObject; } diff --git a/src/Matcher.php b/src/Matcher.php index 84b56e5e..dfee1b04 100644 --- a/src/Matcher.php +++ b/src/Matcher.php @@ -12,7 +12,7 @@ class Matcher implements MatcherInterface { /** - * {@inheritdoc} + * {@inheritDoc} */ public function any() { @@ -20,7 +20,7 @@ public function any() } /** - * {@inheritdoc} + * {@inheritDoc} */ public function annotatedWith($annotationName): AbstractMatcher { @@ -32,7 +32,7 @@ public function annotatedWith($annotationName): AbstractMatcher } /** - * {@inheritdoc} + * {@inheritDoc} */ public function subclassesOf($superClass): AbstractMatcher { @@ -44,7 +44,7 @@ public function subclassesOf($superClass): AbstractMatcher } /** - * {@inheritdoc} + * {@inheritDoc} */ public function startsWith($prefix): AbstractMatcher { @@ -72,7 +72,7 @@ public function logicalAnd(AbstractMatcher $matcherA, AbstractMatcher $matcherB) // @codingStandardsIgnoreEnd /** - * {@inheritdoc} + * {@inheritDoc} */ public function logicalNot(AbstractMatcher $matcher): AbstractMatcher { diff --git a/src/Matcher/AnnotatedWithMatcher.php b/src/Matcher/AnnotatedWithMatcher.php index dacba5f0..67835570 100644 --- a/src/Matcher/AnnotatedWithMatcher.php +++ b/src/Matcher/AnnotatedWithMatcher.php @@ -5,32 +5,37 @@ namespace Ray\Aop\Matcher; use Ray\Aop\AbstractMatcher; -use Ray\ServiceLocator\ServiceLocator; use ReflectionClass; use ReflectionMethod; +use function assert; + final class AnnotatedWithMatcher extends AbstractMatcher { /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesClass(ReflectionClass $class, array $arguments): bool { + assert($class instanceof \Ray\Aop\ReflectionClass); /** @var array $arguments */ [$annotation] = $arguments; - $annotation = ServiceLocator::getReader()->getClassAnnotation($class, $annotation); + /** @psalm-suppress MixedAssignment $annotation */ + $annotation = $class->getAnnotation($annotation); return (bool) $annotation; } /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesMethod(ReflectionMethod $method, array $arguments): bool { + assert($method instanceof \Ray\Aop\ReflectionMethod); /** @var array $arguments */ [$annotation] = $arguments; - $annotation = ServiceLocator::getReader()->getMethodAnnotation($method, $annotation); + + $annotation = $method->getAnnotation($annotation); return (bool) $annotation; } diff --git a/src/Matcher/AnyMatcher.php b/src/Matcher/AnyMatcher.php index 254a6b23..ada1e8f2 100644 --- a/src/Matcher/AnyMatcher.php +++ b/src/Matcher/AnyMatcher.php @@ -20,13 +20,14 @@ final class AnyMatcher extends AbstractMatcher public function __construct() { parent::__construct(); + if (self::$builtinMethods === []) { $this->setBuildInMethods(); } } /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesClass(ReflectionClass $class, array $arguments): bool { @@ -36,7 +37,7 @@ public function matchesClass(ReflectionClass $class, array $arguments): bool } /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesMethod(ReflectionMethod $method, array $arguments): bool { diff --git a/src/Matcher/LogicalAndMatcher.php b/src/Matcher/LogicalAndMatcher.php index 8199bdf0..a4dfcc25 100644 --- a/src/Matcher/LogicalAndMatcher.php +++ b/src/Matcher/LogicalAndMatcher.php @@ -13,7 +13,7 @@ final class LogicalAndMatcher extends AbstractMatcher { /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesClass(ReflectionClass $class, array $arguments): bool { @@ -27,7 +27,7 @@ public function matchesClass(ReflectionClass $class, array $arguments): bool } /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesMethod(ReflectionMethod $method, array $arguments): bool { diff --git a/src/Matcher/LogicalNotMatcher.php b/src/Matcher/LogicalNotMatcher.php index 9315b2a8..34e6e9d5 100644 --- a/src/Matcher/LogicalNotMatcher.php +++ b/src/Matcher/LogicalNotMatcher.php @@ -13,7 +13,7 @@ final class LogicalNotMatcher extends AbstractMatcher { /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesClass(ReflectionClass $class, array $arguments): bool { @@ -24,7 +24,7 @@ public function matchesClass(ReflectionClass $class, array $arguments): bool } /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesMethod(ReflectionMethod $method, array $arguments): bool { diff --git a/src/Matcher/LogicalOrMatcher.php b/src/Matcher/LogicalOrMatcher.php index 1ce845a8..ca00175e 100644 --- a/src/Matcher/LogicalOrMatcher.php +++ b/src/Matcher/LogicalOrMatcher.php @@ -13,7 +13,7 @@ final class LogicalOrMatcher extends AbstractMatcher { /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesClass(ReflectionClass $class, array $arguments): bool { @@ -29,7 +29,7 @@ public function matchesClass(ReflectionClass $class, array $arguments): bool } /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesMethod(ReflectionMethod $method, array $arguments): bool { diff --git a/src/Matcher/StartsWithMatcher.php b/src/Matcher/StartsWithMatcher.php index 595f11c1..88eb4b2a 100644 --- a/src/Matcher/StartsWithMatcher.php +++ b/src/Matcher/StartsWithMatcher.php @@ -13,7 +13,7 @@ final class StartsWithMatcher extends AbstractMatcher { /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesClass(ReflectionClass $class, array $arguments): bool { @@ -24,7 +24,7 @@ public function matchesClass(ReflectionClass $class, array $arguments): bool } /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesMethod(ReflectionMethod $method, array $arguments): bool { diff --git a/src/Matcher/SubclassesOfMatcher.php b/src/Matcher/SubclassesOfMatcher.php index 68cb0645..ebd6f54d 100644 --- a/src/Matcher/SubclassesOfMatcher.php +++ b/src/Matcher/SubclassesOfMatcher.php @@ -12,7 +12,7 @@ final class SubclassesOfMatcher extends AbstractMatcher { /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesClass(ReflectionClass $class, array $arguments): bool { @@ -23,7 +23,7 @@ public function matchesClass(ReflectionClass $class, array $arguments): bool } /** - * {@inheritdoc} + * {@inheritDoc} */ public function matchesMethod(ReflectionMethod $method, array $arguments): bool { diff --git a/src/MethodMatch.php b/src/MethodMatch.php index 78ca1a7f..4929cb81 100644 --- a/src/MethodMatch.php +++ b/src/MethodMatch.php @@ -4,8 +4,6 @@ namespace Ray\Aop; -use Doctrine\Common\Annotations\Reader; -use Ray\ServiceLocator\ServiceLocator; use ReflectionClass; use ReflectionMethod; @@ -14,26 +12,22 @@ final class MethodMatch { - /** @var Reader */ - private $reader; - /** @var BindInterface */ private $bind; public function __construct(BindInterface $bind) { $this->bind = $bind; - $this->reader = ServiceLocator::getReader(); } /** * @param ReflectionClass $class * @param Pointcut[] $pointcuts */ - public function __invoke(ReflectionClass $class, ReflectionMethod $method, array $pointcuts): void + public function __invoke(ReflectionClass $class, \Ray\Aop\ReflectionMethod $method, array $pointcuts): void { /** @var array $annotations */ - $annotations = $this->reader->getMethodAnnotations($method); + $annotations = $method->getAnnotations(); // priority bind foreach ($pointcuts as $key => $pointcut) { if ($pointcut instanceof PriorityPointcut) { @@ -50,9 +44,7 @@ public function __invoke(ReflectionClass $class, ReflectionMethod $method, array } } - /** - * @param ReflectionClass $class - */ + /** @param ReflectionClass $class */ private function annotatedMethodMatchBind(ReflectionClass $class, ReflectionMethod $method, Pointcut $pointCut): void { $isMethodMatch = $pointCut->methodMatcher->matchesMethod($method, $pointCut->methodMatcher->getArguments()); diff --git a/src/NullInterceptor.php b/src/NullInterceptor.php index a4de0aa4..43dfc6c1 100644 --- a/src/NullInterceptor.php +++ b/src/NullInterceptor.php @@ -6,9 +6,7 @@ class NullInterceptor implements MethodInterceptor { - /** - * @return mixed - */ + /** @return mixed */ public function invoke(MethodInvocation $invocation) { return $invocation->proceed(); diff --git a/src/Pointcut.php b/src/Pointcut.php index c0ab7d67..f4aca3da 100644 --- a/src/Pointcut.php +++ b/src/Pointcut.php @@ -15,9 +15,7 @@ class Pointcut /** @var array> */ public $interceptors = []; - /** - * @param array> $interceptors - */ + /** @param array> $interceptors */ public function __construct(AbstractMatcher $classMatcher, AbstractMatcher $methodMatcher, array $interceptors) { $this->classMatcher = $classMatcher; diff --git a/src/ReflectionClass.php b/src/ReflectionClass.php index 2c9f6162..6f1c7115 100644 --- a/src/ReflectionClass.php +++ b/src/ReflectionClass.php @@ -6,13 +6,16 @@ use Ray\ServiceLocator\ServiceLocator; +use function get_class_methods; + /** - * @extends \ReflectionClass + * @template T of object + * @template-extends \ReflectionClass */ class ReflectionClass extends \ReflectionClass implements Reader { /** - * {@inheritdoc} + * {@inheritDoc} * * @psalm-suppress NoInterfaceProperties */ @@ -25,7 +28,7 @@ public function getAnnotations(): array } /** - * {@inheritdoc} + * {@inheritDoc} */ public function getAnnotation(string $annotationName) { @@ -38,4 +41,37 @@ public function getAnnotation(string $annotationName) return null; } + + /** + * @param int|null $filter + * + * @return list + * + * @psalm-external-mutation-free + */ + public function getMethods($filter = null): array + { + unset($filter); + $methods = []; + $methodNames = get_class_methods($this->name); + foreach ($methodNames as $methodName) { + $methods[] = new ReflectionMethod($this->name, $methodName); + } + + return $methods; + } + + /** + * @psalm-suppress MethodSignatureMismatch + * @psalm-external-mutation-free + */ + public function getConstructor(): ?ReflectionMethod + { + $parent = parent::getConstructor(); + if ($parent === null) { + return null; + } + + return new ReflectionMethod($parent->class, $parent->name); + } } diff --git a/src/ReflectionMethod.php b/src/ReflectionMethod.php index a5e8c1a7..38e078c4 100644 --- a/src/ReflectionMethod.php +++ b/src/ReflectionMethod.php @@ -9,7 +9,6 @@ use function assert; use function class_exists; use function is_object; -use function is_string; final class ReflectionMethod extends \ReflectionMethod implements Reader { @@ -24,31 +23,33 @@ public function setObject(WeavedInterface $object): void $this->object = $object; } + /** + * @return ReflectionClass + * + * @psalm-external-mutation-free + * @psalm-suppress MethodSignatureMismatch + */ public function getDeclaringClass(): ReflectionClass { if (! is_object($this->object)) { - assert(class_exists($this->class)); - return new ReflectionClass($this->class); } $parencClass = (new \ReflectionClass($this->object))->getParentClass(); assert($parencClass instanceof \ReflectionClass); $originalClass = $parencClass->name; - assert(class_exists($originalClass)); return new ReflectionClass($originalClass); } /** - * {@inheritdoc} + * {@inheritDoc} * * @psalm-suppress NoInterfaceProperties */ public function getAnnotations(): array { assert(class_exists($this->class)); - assert(is_string($this->name)); /** @var list $annotations */ $annotations = ServiceLocator::getReader()->getMethodAnnotations(new \ReflectionMethod($this->class, $this->name)); diff --git a/src/ReflectiveMethodInvocation.php b/src/ReflectiveMethodInvocation.php index d3ff359e..63168bf8 100644 --- a/src/ReflectiveMethodInvocation.php +++ b/src/ReflectiveMethodInvocation.php @@ -52,7 +52,7 @@ public function __construct( } /** - * {@inheritdoc} + * {@inheritDoc} */ public function getMethod(): ReflectionMethod { @@ -70,7 +70,7 @@ public function getMethod(): ReflectionMethod } /** - * {@inheritdoc} + * {@inheritDoc} */ public function getArguments(): ArrayObject { @@ -78,7 +78,7 @@ public function getArguments(): ArrayObject } /** - * {@inheritdoc} + * {@inheritDoc} */ public function getNamedArguments(): ArrayObject { @@ -88,16 +88,17 @@ public function getNamedArguments(): ArrayObject foreach ($params as $param) { $pos = $param->getPosition(); if (array_key_exists($pos, (array) $args)) { + $name = $param->getName(); /** @psalm-suppress MixedAssignment */ - $namedParams[$param->getName()] = $args[$pos]; + $namedParams[$name] = $args[$pos]; } } - return new ArrayObject($namedParams); + return new ArrayObject($namedParams); // @phpstan-ignore-line } /** - * {@inheritdoc} + * {@inheritDoc} */ public function proceed() { @@ -110,7 +111,7 @@ public function proceed() } /** - * {@inheritdoc} + * {@inheritDoc} */ public function getThis() { diff --git a/src/VisitorFactory.php b/src/VisitorFactory.php index becdd88b..b29ed534 100644 --- a/src/VisitorFactory.php +++ b/src/VisitorFactory.php @@ -26,9 +26,7 @@ public function __construct(Parser $parser) $this->parser = $parser; } - /** - * @param ReflectionClass $class - */ + /** @param ReflectionClass $class */ public function __invoke(ReflectionClass $class): CodeVisitor { $traverser = new NodeTraverser(); diff --git a/src/Weaver.php b/src/Weaver.php index d9bbf84a..0306f1fa 100644 --- a/src/Weaver.php +++ b/src/Weaver.php @@ -37,8 +37,8 @@ public function __construct(BindInterface $bind, string $classDir) } /** - * @param class-string $class - * @param array $args + * @param class-string $class + * @param list $args * * @return T * diff --git a/tests/BindTest.php b/tests/BindTest.php index 5b131d40..5d47919d 100644 --- a/tests/BindTest.php +++ b/tests/BindTest.php @@ -20,6 +20,7 @@ class BindTest extends TestCase protected function setUp(): void { parent::setUp(); + $this->bind = new Bind(); } diff --git a/tests/CodeGenPhp71Test.php b/tests/CodeGenPhp71Test.php index 6a82f5c0..55a1e696 100644 --- a/tests/CodeGenPhp71Test.php +++ b/tests/CodeGenPhp71Test.php @@ -54,9 +54,7 @@ public function testReturnTypeNullable(): Code return $code; } - /** - * @depends testReturnTypeNullable - */ + /** @depends testReturnTypeNullable */ public function testContainsStatement(Code $code): void { $this->assertStringContainsString("declare (strict_types=1);\n", $code->code); diff --git a/tests/CompilerTest.php b/tests/CompilerTest.php index 2dbb2f8f..a6f6b196 100644 --- a/tests/CompilerTest.php +++ b/tests/CompilerTest.php @@ -37,6 +37,7 @@ class CompilerTest extends TestCase protected function setUp(): void { parent::setUp(); + $this->compiler = new Compiler(__DIR__ . '/tmp'); $matcher = new Matcher(); $pointcut = new Pointcut($matcher->any(), $matcher->startsWith('return'), [new FakeDoubleInterceptor()]); @@ -64,9 +65,7 @@ public function testNewInstanceTwice(): void $this->assertSame($class1File, $class2File); } - /** - * @depends testNewInstance - */ + /** @depends testNewInstance */ public function testParentClassName(object $class): void { $parent = (new ReflectionClass($class))->getParentClass(); @@ -77,9 +76,7 @@ public function testParentClassName(object $class): void $this->assertSame(FakeMock::class, $parent->getName()); } - /** - * @depends testNewInstance - */ + /** @depends testNewInstance */ public function testBuildClassWeaved(FakeMock $weaved): void { assert(isset($weaved->bindings)); @@ -99,9 +96,7 @@ public function testParenteClass(): FakeMock return $weaved; } - /** - * @depends testNewInstance - */ + /** @depends testNewInstance */ public function testWeavedInterceptorWorks(FakeMock $weaved): void { $result = $weaved->returnSame(1); @@ -110,9 +105,7 @@ public function testWeavedInterceptorWorks(FakeMock $weaved): void $this->assertSame(2, $result); } - /** - * @depends testNewInstance - */ + /** @depends testNewInstance */ public function testMethodReturnValue(FakeMock $weaved): void { $num = new FakeNum(); @@ -283,9 +276,7 @@ public function testMethodAnnotationReader(): void $this->assertInstanceOf(FakeMarker3::class, $annotation); } - /** - * @depends testMethodAnnotationReader - */ + /** @depends testMethodAnnotationReader */ public function testClassAnnotationReader(): void { $classAnnotation = FakeMethodAnnotationReaderInterceptor::$classAnnotation; diff --git a/tests/Fake/FakeClassTartget.php b/tests/Fake/FakeClassTartget.php new file mode 100644 index 00000000..48b88e12 --- /dev/null +++ b/tests/Fake/FakeClassTartget.php @@ -0,0 +1,32 @@ +assertInstanceOf(BuiltinMatcher::class, (new Matcher())->any()); @@ -28,9 +26,7 @@ public function testReturnBuildInMatcher(): void $this->assertInstanceOf(BuiltinMatcher::class, (new Matcher())->subclassesOf(FakeClass::class)); } - /** - * @throws ReflectionException - */ + /** @throws ReflectionException */ public function testValidationForAnnotatedWith(): void { $this->expectException(InvalidAnnotationException::class); @@ -38,9 +34,7 @@ public function testValidationForAnnotatedWith(): void (new Matcher())->annotatedWith('__invalid_class'); } - /** - * @throws ReflectionException - */ + /** @throws ReflectionException */ public function testValidationForSubclassesOf(): void { $this->expectException(InvalidArgumentException::class); diff --git a/tests/ReflectionClassTest.php b/tests/ReflectionClassTest.php new file mode 100644 index 00000000..0ca7b15d --- /dev/null +++ b/tests/ReflectionClassTest.php @@ -0,0 +1,58 @@ + */ + private $class; + + public function setUp(): void + { + $this->class = new ReflectionClass(FakeClassTartget::class); + } + + public function testGetAnnottaions(): void + { + $annotations = $this->class->getAnnotations(); + $this->assertSame(2, count($annotations)); + } + + public function testGetAnnottaion(): void + { + $annotation = $this->class->getAnnotation(FakeResource::class); + $this->assertInstanceOf(FakeResource::class, $annotation); + } + + public function testGetMethods(): void + { + $methods = $this->class->getMethods(); + $this->assertAllInstanceOfMethod($methods); + } + + public function testConstructor(): void + { + $constructor = $this->class->getConstructor(); + $this->assertInstanceOf(ReflectionMethod::class, $constructor); + } + + public function testConstructorNull(): void + { + $constructor = (new ReflectionClass(FakeAnnotateClass::class))->getConstructor(); + $this->assertNull($constructor); + } + + /** @param array $array */ + private function assertAllInstanceOfMethod(array $array): void + { + foreach ($array as $item) { + $this->assertInstanceOf(ReflectionMethod::class, $item); + } + } +} diff --git a/tests/ReflectiveMethodInvocationTest.php b/tests/ReflectiveMethodInvocationTest.php index 22a9e58b..6567589d 100644 --- a/tests/ReflectiveMethodInvocationTest.php +++ b/tests/ReflectiveMethodInvocationTest.php @@ -20,6 +20,7 @@ class ReflectiveMethodInvocationTest extends TestCase protected function setUp(): void { parent::setUp(); + $this->fake = new FakeClass(); $this->invocation = new ReflectiveMethodInvocation($this->fake, 'add', [1]); } diff --git a/tests/WeaverTest.php b/tests/WeaverTest.php index 15feb4c7..a322ae94 100644 --- a/tests/WeaverTest.php +++ b/tests/WeaverTest.php @@ -25,9 +25,7 @@ public function testConstruct(): Weaver return $weaver; } - /** - * @depends testConstruct - */ + /** @depends testConstruct */ public function testWeave(Weaver $weaver): void { $className = $weaver->weave(FakeWeaverMock::class); @@ -50,9 +48,7 @@ public function testWeaveLoad(): void $this->assertTrue(class_exists($className, false)); } - /** - * @depends testConstruct - */ + /** @depends testConstruct */ public function testNewInstance(Weaver $weaver): void { $weaved = $weaver->newInstance(FakeWeaverMock::class, []); @@ -61,9 +57,7 @@ public function testNewInstance(Weaver $weaver): void $this->assertSame(2, $result); } - /** - * @depends testConstruct - */ + /** @depends testConstruct */ public function testCachedWeaver(Weaver $weaver): void { $weaver = unserialize(serialize($weaver)); diff --git a/tests/script/method_stmts_gen.php b/tests/script/method_stmts_gen.php index 8fe671c0..961eb733 100644 --- a/tests/script/method_stmts_gen.php +++ b/tests/script/method_stmts_gen.php @@ -3,6 +3,8 @@ declare(strict_types=1); use PhpParser\BuilderFactory; +use PhpParser\Node\Stmt\Return_; +use PhpParser\PrettyPrinter\Standard; require dirname(__DIR__, 2) . '/vendor/autoload.php'; @@ -13,7 +15,7 @@ [$factory->funcCall('func_get_args'), $factory->constFetch('__FUNCTION__')] ); -$returnCall = new PhpParser\Node\Stmt\Return_( +$returnCall = new Return_( $factory->methodCall( $factory->var('this'), '_intercept', @@ -24,7 +26,7 @@ $nodeVoid = $factory->namespace('a')->addStmt($voidCall)->getNode(); $nodeReturn = $factory->namespace('a')->addStmt($returnCall)->getNode(); -$prettyPrinter = new PhpParser\PrettyPrinter\Standard(); +$prettyPrinter = new Standard(); echo $prettyPrinter->prettyPrintFile([$nodeVoid]); echo $prettyPrinter->prettyPrintFile([$nodeReturn]); diff --git a/vendor-bin/tools/composer.json b/vendor-bin/tools/composer.json index 32bc13df..fc698e35 100644 --- a/vendor-bin/tools/composer.json +++ b/vendor-bin/tools/composer.json @@ -1,11 +1,11 @@ { "require-dev": { - "doctrine/coding-standard": "^9.0", + "doctrine/coding-standard": "^12.0", "phpmd/phpmd": "^2.9", "phpmetrics/phpmetrics": "^2.7", "phpstan/phpstan": "^1.4", "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.2" + "vimeo/psalm": "^5.15" }, "config": { "allow-plugins": { diff --git a/vendor-bin/tools/composer.lock b/vendor-bin/tools/composer.lock index 0c8b2ca2..da7f6cec 100644 --- a/vendor-bin/tools/composer.lock +++ b/vendor-bin/tools/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e2465b8186889cdd77f0cb711dbbb20e", + "content-hash": "ebb08c4ce71f54fa42f6bde8754f54f1", "packages": [], "packages-dev": [ { @@ -173,79 +173,6 @@ ], "time": "2021-03-30T17:13:30+00:00" }, - { - "name": "composer/package-versions-deprecated", - "version": "1.11.99.5", - "source": { - "type": "git", - "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1.0 || ^2.0", - "php": "^7 || ^8" - }, - "replace": { - "ocramius/package-versions": "1.11.99" - }, - "require-dev": { - "composer/composer": "^1.9.3 || ^2.0@dev", - "ext-zip": "^1.13", - "phpunit/phpunit": "^6.5 || ^7" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "support": { - "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-01-17T14:14:24+00:00" - }, { "name": "composer/pcre", "version": "3.1.0", @@ -319,16 +246,16 @@ }, { "name": "composer/semver", - "version": "3.3.2", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", "shasum": "" }, "require": { @@ -378,9 +305,9 @@ "versioning" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.3.2" + "source": "https://github.com/composer/semver/tree/3.4.0" }, "funding": [ { @@ -396,7 +323,7 @@ "type": "tidelift" } ], - "time": "2022-04-01T19:23:25+00:00" + "time": "2023-08-31T09:50:34+00:00" }, { "name": "composer/xdebug-handler", @@ -466,35 +393,38 @@ }, { "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.2", + "version": "v1.0.0", "source": { "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" + "url": "https://github.com/PHPCSStandards/composer-installer.git", + "reference": "4be43904336affa5c2f70744a348312336afd0da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", + "reference": "4be43904336affa5c2f70744a348312336afd0da", "shasum": "" }, "require": { "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3", + "php": ">=5.4", "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" }, "require-dev": { "composer/composer": "*", + "ext-json": "*", + "ext-zip": "*", "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0" + "phpcompatibility/php-compatibility": "^9.0", + "yoast/phpunit-polyfills": "^1.0" }, "type": "composer-plugin", "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" }, "autoload": { "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -510,7 +440,7 @@ }, { "name": "Contributors", - "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" + "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" } ], "description": "PHP_CodeSniffer Standards Composer Installer Plugin", @@ -534,10 +464,10 @@ "tests" ], "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" + "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "source": "https://github.com/PHPCSStandards/composer-installer" }, - "time": "2022-02-04T12:51:07+00:00" + "time": "2023-01-05T11:28:13+00:00" }, { "name": "dnoegel/php-xdg-base-dir", @@ -578,23 +508,23 @@ }, { "name": "doctrine/coding-standard", - "version": "9.0.2", + "version": "12.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/coding-standard.git", - "reference": "35a2452c6025cb739c3244b3348bcd1604df07d1" + "reference": "1b2b7dc58c68833af481fb9325c25abd40681c79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/coding-standard/zipball/35a2452c6025cb739c3244b3348bcd1604df07d1", - "reference": "35a2452c6025cb739c3244b3348bcd1604df07d1", + "url": "https://api.github.com/repos/doctrine/coding-standard/zipball/1b2b7dc58c68833af481fb9325c25abd40681c79", + "reference": "1b2b7dc58c68833af481fb9325c25abd40681c79", "shasum": "" }, "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", - "php": "^7.1 || ^8.0", - "slevomat/coding-standard": "^7.0.0", - "squizlabs/php_codesniffer": "^3.6.0" + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0.0", + "php": "^7.2 || ^8.0", + "slevomat/coding-standard": "^8.11", + "squizlabs/php_codesniffer": "^3.7" }, "type": "phpcodesniffer-standard", "notification-url": "https://packagist.org/downloads/", @@ -618,6 +548,7 @@ "code", "coding", "cs", + "dev", "doctrine", "rules", "sniffer", @@ -627,9 +558,9 @@ ], "support": { "issues": "https://github.com/doctrine/coding-standard/issues", - "source": "https://github.com/doctrine/coding-standard/tree/9.0.2" + "source": "https://github.com/doctrine/coding-standard/tree/12.0.0" }, - "time": "2021-04-12T15:11:14+00:00" + "time": "2023-04-24T17:43:28+00:00" }, { "name": "doctrine/deprecations", @@ -779,6 +710,67 @@ }, "time": "2022-03-02T22:36:06+00:00" }, + { + "name": "fidry/cpu-core-counter", + "version": "0.5.1", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "b58e5a3933e541dc286cc91fc4f3898bbc6f1623" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/b58e5a3933e541dc286cc91fc4f3898bbc6f1623", + "reference": "b58e5a3933e541dc286cc91fc4f3898bbc6f1623", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^9.5.26 || ^8.5.31", + "theofidry/php-cs-fixer-config": "^1.0", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/0.5.1" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2022-12-24T12:35:10+00:00" + }, { "name": "netresearch/jsonmapper", "version": "v4.2.0", @@ -832,16 +824,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.16.0", + "version": "v4.17.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "19526a33fb561ef417e822e85f08a00db4059c17" + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/19526a33fb561ef417e822e85f08a00db4059c17", - "reference": "19526a33fb561ef417e822e85f08a00db4059c17", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", "shasum": "" }, "require": { @@ -882,62 +874,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.16.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" }, - "time": "2023-06-25T14:52:30+00:00" - }, - { - "name": "openlss/lib-array2xml", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/nullivex/lib-array2xml.git", - "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nullivex/lib-array2xml/zipball/a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", - "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "autoload": { - "psr-0": { - "LSS": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Bryan Tong", - "email": "bryan@nullivex.com", - "homepage": "https://www.nullivex.com" - }, - { - "name": "Tony Butler", - "email": "spudz76@gmail.com", - "homepage": "https://www.nullivex.com" - } - ], - "description": "Array2XML conversion library credit to lalit.org", - "homepage": "https://www.nullivex.com", - "keywords": [ - "array", - "array conversion", - "xml", - "xml conversion" - ], - "support": { - "issues": "https://github.com/nullivex/lib-array2xml/issues", - "source": "https://github.com/nullivex/lib-array2xml/tree/master" - }, - "time": "2019-03-29T20:06:56+00:00" + "time": "2023-08-13T19:53:39+00:00" }, { "name": "pdepend/pdepend", @@ -1114,16 +1053,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.7.2", + "version": "1.7.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "b2fe4d22a5426f38e014855322200b97b5362c0d" + "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b2fe4d22a5426f38e014855322200b97b5362c0d", - "reference": "b2fe4d22a5426f38e014855322200b97b5362c0d", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", + "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", "shasum": "" }, "require": { @@ -1166,9 +1105,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.2" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.3" }, - "time": "2023-05-30T18:13:47+00:00" + "time": "2023-08-12T11:01:26+00:00" }, { "name": "phpmd/phpmd", @@ -1323,16 +1262,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.23.1", + "version": "1.24.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "846ae76eef31c6d7790fac9bc399ecee45160b26" + "reference": "3510b0a6274cc42f7219367cb3abfc123ffa09d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/846ae76eef31c6d7790fac9bc399ecee45160b26", - "reference": "846ae76eef31c6d7790fac9bc399ecee45160b26", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/3510b0a6274cc42f7219367cb3abfc123ffa09d6", + "reference": "3510b0a6274cc42f7219367cb3abfc123ffa09d6", "shasum": "" }, "require": { @@ -1364,22 +1303,22 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.23.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.0" }, - "time": "2023-08-03T16:32:59+00:00" + "time": "2023-09-07T20:46:32+00:00" }, { "name": "phpstan/phpstan", - "version": "1.10.28", + "version": "1.10.33", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "e4545b55904ebef470423d3ddddb74fa7325497a" + "reference": "03b1cf9f814ba0863c4e9affea49a4d1ed9a2ed1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e4545b55904ebef470423d3ddddb74fa7325497a", - "reference": "e4545b55904ebef470423d3ddddb74fa7325497a", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/03b1cf9f814ba0863c4e9affea49a4d1ed9a2ed1", + "reference": "03b1cf9f814ba0863c4e9affea49a4d1ed9a2ed1", "shasum": "" }, "require": { @@ -1428,7 +1367,7 @@ "type": "tidelift" } ], - "time": "2023-08-08T12:33:42+00:00" + "time": "2023-09-04T12:20:53+00:00" }, { "name": "psr/container", @@ -1535,29 +1474,29 @@ }, { "name": "sebastian/diff", - "version": "4.0.5", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", - "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3", + "phpunit/phpunit": "^10.0", "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1589,7 +1528,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3" }, "funding": [ { @@ -1597,46 +1537,46 @@ "type": "github" } ], - "time": "2023-05-07T05:35:17+00:00" + "time": "2023-05-01T07:48:21+00:00" }, { "name": "slevomat/coding-standard", - "version": "7.2.1", + "version": "8.13.4", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90" + "reference": "4b2af2fb17773656d02fbfb5d18024ebd19fe322" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/4b2af2fb17773656d02fbfb5d18024ebd19fe322", + "reference": "4b2af2fb17773656d02fbfb5d18024ebd19fe322", "shasum": "" }, "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": "^1.5.1", - "squizlabs/php_codesniffer": "^3.6.2" + "phpstan/phpdoc-parser": "^1.23.0", + "squizlabs/php_codesniffer": "^3.7.1" }, "require-dev": { - "phing/phing": "2.17.3", + "phing/phing": "2.17.4", "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.4.10|1.7.1", - "phpstan/phpstan-deprecation-rules": "1.0.0", - "phpstan/phpstan-phpunit": "1.0.0|1.1.1", - "phpstan/phpstan-strict-rules": "1.2.3", - "phpunit/phpunit": "7.5.20|8.5.21|9.5.20" + "phpstan/phpstan": "1.10.26", + "phpstan/phpstan-deprecation-rules": "1.1.3", + "phpstan/phpstan-phpunit": "1.3.13", + "phpstan/phpstan-strict-rules": "1.5.1", + "phpunit/phpunit": "7.5.20|8.5.21|9.6.8|10.2.6" }, "type": "phpcodesniffer-standard", "extra": { "branch-alias": { - "dev-master": "7.x-dev" + "dev-master": "8.x-dev" } }, "autoload": { "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard" + "SlevomatCodingStandard\\": "SlevomatCodingStandard/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1644,9 +1584,13 @@ "MIT" ], "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "keywords": [ + "dev", + "phpcs" + ], "support": { "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/7.2.1" + "source": "https://github.com/slevomat/coding-standard/tree/8.13.4" }, "funding": [ { @@ -1658,7 +1602,70 @@ "type": "tidelift" } ], - "time": "2022-05-25T10:58:12+00:00" + "time": "2023-07-25T10:28:55+00:00" + }, + { + "name": "spatie/array-to-xml", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/array-to-xml.git", + "reference": "f9ab39c808500c347d5a8b6b13310bd5221e39e7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/f9ab39c808500c347d5a8b6b13310bd5221e39e7", + "reference": "f9ab39c808500c347d5a8b6b13310bd5221e39e7", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": "^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.2", + "pestphp/pest": "^1.21", + "spatie/pest-plugin-snapshots": "^1.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\ArrayToXml\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://freek.dev", + "role": "Developer" + } + ], + "description": "Convert an array to xml", + "homepage": "https://github.com/spatie/array-to-xml", + "keywords": [ + "array", + "convert", + "xml" + ], + "support": { + "source": "https://github.com/spatie/array-to-xml/tree/3.2.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2023-07-19T18:30:26+00:00" }, { "name": "squizlabs/php_codesniffer", @@ -1794,16 +1801,16 @@ }, { "name": "symfony/console", - "version": "v6.3.2", + "version": "v6.3.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "aa5d64ad3f63f2e48964fc81ee45cb318a723898" + "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/aa5d64ad3f63f2e48964fc81ee45cb318a723898", - "reference": "aa5d64ad3f63f2e48964fc81ee45cb318a723898", + "url": "https://api.github.com/repos/symfony/console/zipball/eca495f2ee845130855ddf1cf18460c38966c8b6", + "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6", "shasum": "" }, "require": { @@ -1864,7 +1871,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.3.2" + "source": "https://github.com/symfony/console/tree/v6.3.4" }, "funding": [ { @@ -1880,20 +1887,20 @@ "type": "tidelift" } ], - "time": "2023-07-19T20:17:28+00:00" + "time": "2023-08-16T10:10:12+00:00" }, { "name": "symfony/dependency-injection", - "version": "v6.3.2", + "version": "v6.3.4", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "474cfbc46aba85a1ca11a27db684480d0db64ba7" + "reference": "68a5a9570806a087982f383f6109c5e925892a49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/474cfbc46aba85a1ca11a27db684480d0db64ba7", - "reference": "474cfbc46aba85a1ca11a27db684480d0db64ba7", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/68a5a9570806a087982f383f6109c5e925892a49", + "reference": "68a5a9570806a087982f383f6109c5e925892a49", "shasum": "" }, "require": { @@ -1945,7 +1952,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.3.2" + "source": "https://github.com/symfony/dependency-injection/tree/v6.3.4" }, "funding": [ { @@ -1961,7 +1968,7 @@ "type": "tidelift" } ], - "time": "2023-07-19T20:17:28+00:00" + "time": "2023-08-16T17:55:17+00:00" }, { "name": "symfony/deprecation-contracts", @@ -2095,16 +2102,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", "shasum": "" }, "require": { @@ -2119,7 +2126,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2157,7 +2164,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" }, "funding": [ { @@ -2173,20 +2180,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354" + "reference": "875e90aeea2777b6f135677f618529449334a612" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", "shasum": "" }, "require": { @@ -2198,7 +2205,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2238,7 +2245,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" }, "funding": [ { @@ -2254,20 +2261,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", "shasum": "" }, "require": { @@ -2279,7 +2286,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2322,7 +2329,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" }, "funding": [ { @@ -2338,20 +2345,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + "reference": "42292d99c55abe617799667f454222c54c60e229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", "shasum": "" }, "require": { @@ -2366,7 +2373,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2405,90 +2412,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" }, "funding": [ { @@ -2504,7 +2428,7 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-07-28T09:04:16+00:00" }, { "name": "symfony/service-contracts", @@ -2676,16 +2600,16 @@ }, { "name": "symfony/var-exporter", - "version": "v6.3.2", + "version": "v6.3.4", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "3400949782c0cb5b3e73aa64cfd71dde000beccc" + "reference": "df1f8aac5751871b83d30bf3e2c355770f8f0691" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/3400949782c0cb5b3e73aa64cfd71dde000beccc", - "reference": "3400949782c0cb5b3e73aa64cfd71dde000beccc", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/df1f8aac5751871b83d30bf3e2c355770f8f0691", + "reference": "df1f8aac5751871b83d30bf3e2c355770f8f0691", "shasum": "" }, "require": { @@ -2730,7 +2654,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.3.2" + "source": "https://github.com/symfony/var-exporter/tree/v6.3.4" }, "funding": [ { @@ -2746,28 +2670,28 @@ "type": "tidelift" } ], - "time": "2023-07-26T17:39:03+00:00" + "time": "2023-08-16T18:14:47+00:00" }, { "name": "vimeo/psalm", - "version": "4.30.0", + "version": "5.15.0", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", - "reference": "d0bc6e25d89f649e4f36a534f330f8bb4643dd69" + "reference": "5c774aca4746caf3d239d9c8cadb9f882ca29352" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/d0bc6e25d89f649e4f36a534f330f8bb4643dd69", - "reference": "d0bc6e25d89f649e4f36a534f330f8bb4643dd69", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/5c774aca4746caf3d239d9c8cadb9f882ca29352", + "reference": "5c774aca4746caf3d239d9c8cadb9f882ca29352", "shasum": "" }, "require": { "amphp/amp": "^2.4.2", "amphp/byte-stream": "^1.5", - "composer/package-versions-deprecated": "^1.8.0", + "composer-runtime-api": "^2", "composer/semver": "^1.4 || ^2.0 || ^3.0", - "composer/xdebug-handler": "^1.1 || ^2.0 || ^3.0", + "composer/xdebug-handler": "^2.0 || ^3.0", "dnoegel/php-xdg-base-dir": "^0.1.1", "ext-ctype": "*", "ext-dom": "*", @@ -2776,35 +2700,38 @@ "ext-mbstring": "*", "ext-simplexml": "*", "ext-tokenizer": "*", - "felixfbecker/advanced-json-rpc": "^3.0.3", - "felixfbecker/language-server-protocol": "^1.5", + "felixfbecker/advanced-json-rpc": "^3.1", + "felixfbecker/language-server-protocol": "^1.5.2", + "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1", "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "nikic/php-parser": "^4.13", - "openlss/lib-array2xml": "^1.0", - "php": "^7.1|^8", - "sebastian/diff": "^3.0 || ^4.0", - "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0 || ^6.0", - "symfony/polyfill-php80": "^1.25", - "webmozart/path-util": "^2.3" + "nikic/php-parser": "^4.16", + "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", + "sebastian/diff": "^4.0 || ^5.0", + "spatie/array-to-xml": "^2.17.0 || ^3.0", + "symfony/console": "^4.1.6 || ^5.0 || ^6.0", + "symfony/filesystem": "^5.4 || ^6.0" + }, + "conflict": { + "nikic/php-parser": "4.17.0" }, "provide": { "psalm/psalm": "self.version" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.2", - "brianium/paratest": "^4.0||^6.0", + "amphp/phpunit-util": "^2.0", + "bamarni/composer-bin-plugin": "^1.4", + "brianium/paratest": "^6.9", "ext-curl": "*", + "mockery/mockery": "^1.5", + "nunomaduro/mock-final-classes": "^1.1", "php-parallel-lint/php-parallel-lint": "^1.2", - "phpdocumentor/reflection-docblock": "^5", - "phpmyadmin/sql-parser": "5.1.0||dev-master", - "phpspec/prophecy": ">=1.9.0", - "phpstan/phpdoc-parser": "1.2.* || 1.6.4", - "phpunit/phpunit": "^9.0", - "psalm/plugin-phpunit": "^0.16", - "slevomat/coding-standard": "^7.0", - "squizlabs/php_codesniffer": "^3.5", - "symfony/process": "^4.3 || ^5.0 || ^6.0", - "weirdan/prophecy-shim": "^1.0 || ^2.0" + "phpstan/phpdoc-parser": "^1.6", + "phpunit/phpunit": "^9.6", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.6", + "symfony/process": "^4.4 || ^5.0 || ^6.0" }, "suggest": { "ext-curl": "In order to send data to shepherd", @@ -2820,17 +2747,14 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev", + "dev-master": "5.x-dev", + "dev-4.x": "4.x-dev", "dev-3.x": "3.x-dev", "dev-2.x": "2.x-dev", "dev-1.x": "1.x-dev" } }, "autoload": { - "files": [ - "src/functions.php", - "src/spl_object_id.php" - ], "psr-4": { "Psalm\\": "src/Psalm/" } @@ -2848,13 +2772,14 @@ "keywords": [ "code", "inspection", - "php" + "php", + "static analysis" ], "support": { "issues": "https://github.com/vimeo/psalm/issues", - "source": "https://github.com/vimeo/psalm/tree/4.30.0" + "source": "https://github.com/vimeo/psalm/tree/5.15.0" }, - "time": "2022-11-06T20:37:08+00:00" + "time": "2023-08-20T23:07:30+00:00" }, { "name": "webmozart/assert", @@ -2913,57 +2838,6 @@ "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, "time": "2022-06-03T18:03:27+00:00" - }, - { - "name": "webmozart/path-util", - "version": "2.3.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/path-util.git", - "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", - "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "webmozart/assert": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\PathUtil\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", - "support": { - "issues": "https://github.com/webmozart/path-util/issues", - "source": "https://github.com/webmozart/path-util/tree/2.3.0" - }, - "abandoned": "symfony/filesystem", - "time": "2015-12-17T08:42:14+00:00" } ], "aliases": [],