CHANGELOG.md000064400000071552144760113020006365 0ustar00# Changelog All notable changes to this project will be documented in this file, in reverse chronological order by release. ## 4.2.2 - 2021-05-07 ----- ### Release Notes for [4.2.2](https://github.com/laminas/laminas-code/milestone/14) 4.2.x bugfix release (patch) ### 4.2.2 - Total issues resolved: **1** - Total pull requests resolved: **1** - Total contributors: **1** #### Bug - [81: Fix `DocBlockGenerator` formatting issue when docblock long description is not available](https://github.com/laminas/laminas-code/pull/81) thanks to @martin-helmich ## 4.2.1 - 2021-04-23 ----- ### Release Notes for [4.2.1](https://github.com/laminas/laminas-code/milestone/12) 4.2.x bugfix release (patch) ### 4.2.1 - Total issues resolved: **1** - Total pull requests resolved: **1** - Total contributors: **1** #### Bug - [77: Consider missing indices in PropertyGenerator](https://github.com/laminas/laminas-code/pull/77) thanks to @rieschl ## 4.2.0 - 2021-04-14 ----- ### Release Notes for [4.2.0](https://github.com/laminas/laminas-code/milestone/11) Feature release (minor) ### 4.2.0 - Total issues resolved: **1** - Total pull requests resolved: **1** - Total contributors: **2** #### Enhancement - [72: Make sure variadic parameter does not have default value](https://github.com/laminas/laminas-code/pull/72) thanks to @mchekin #### Bug,Enhancement,Help Wanted - [35: `ParameterGenerator` always fails with variadic parameters](https://github.com/laminas/laminas-code/issues/35) thanks to @michalbundyra ## 4.1.0 - 2021-03-27 ----- ### Release Notes for [4.1.0](https://github.com/laminas/laminas-code/milestone/8) Feature release (minor) ### 4.1.0 - Total issues resolved: **0** - Total pull requests resolved: **3** - Total contributors: **3** #### Enhancement - [70: Improve `TraitGenerator` test code coverage](https://github.com/laminas/laminas-code/pull/70) thanks to @mchekin - [68: [Feature] Add/update type information for source files](https://github.com/laminas/laminas-code/pull/68) thanks to @lisachenko #### Documentation - [65: Correction of Laminas\Code\Generator\DocBlock\Tag\ParamTag example](https://github.com/laminas/laminas-code/pull/65) thanks to @mdthh ## 4.0.0 - 2020-12-30 ### Added - [laminas/laminas-code#57](https://github.com/laminas/laminas-code/pull/57) support for following PHP 8 types have been added: * union types * `false` * `mixed` * `null` * `static` ### Changed - [laminas/laminas-code#57](https://github.com/laminas/laminas-code/pull/57) due to internal refactoring requiring better internal types, the minimum supported PHP version is now `7.4` - BC BREAK [laminas/laminas-code#38](https://github.com/laminas/laminas-code/pull/38) changed generated class output to no longer contain excessive whitespace around contents. The structure of the generated output will still be the same, but spacing changed, which will likely lead o breakages if you are asserting/depending upon the strings produced by `Laminas\Code\Generator\ClassGenerator#generate()` - BC BREAK [laminas/laminas-code#42](https://github.com/laminas/laminas-code/pull/42) `declare()` statements will now be generated above `namespace` declarations: this is to be better compliant with PSR-2, but it may break downstream applications if these rely on the stability of code produced by `Laminas\Code\Generator\FileGenerator#generate()` ### Removed - BC BREAK [zendframwork/zend-code#153](https://github.com/zendframework/zend-code/pull/153) Removed the annotation API from the library - BC BREAK [laminas/laminas-code#39](https://github.com/laminas/laminas-code/pull/39) the `laminas/laminas-zendframework-bridge` has been removed, and is instead to be installed optionally by consumers of the library. If you are still migrating from `zendframework/zend-code`, you will need to add it to your `composer.json` yourself, or directly use to `Laminas\Code` symbols. - BC BREAK [laminas/laminas-code#58](https://github.com/laminas/laminas-code/pull/58) the `Scanner` and `Annotation` components have been removed, and with it all API that interacted with it: * `Laminas\Code\Generator\FileGeneratorRegistry` has been deleted * `Laminas\Code\Generator\FileGenerator::fromReflectedFileName()` was removed * `Laminas\Code\Generator\FileGenerator::fromReflection()` was removed * `Laminas\Code\NameInformation` has been deleted * `Laminas\Code\Reflection\ReflectionInterface` was marked `@internal` * `Laminas\Code\Reflection\FileReflection` has been deleted * `Laminas\Code\Generic\Prototype\PrototypeInterface` was marked `@internal` * `Laminas\Code\Generic\Prototype\PrototypeClassFactory` was marked `@internal` * `Laminas\Code\Generic\Prototype\PrototypeGenericInterface` was marked `@internal` * `Laminas\Code\Annotation\AnnotationInterface` has been deleted * `Laminas\Code\Annotation\Parser\GenericAnnotationParser` has been deleted * `Laminas\Code\Annotation\Parser\ParserInterface` has been deleted * `Laminas\Code\Annotation\Parser\DoctrineAnnotationParser` has been deleted * `Laminas\Code\Annotation\AnnotationManager` has been deleted * `Laminas\Code\Annotation\AnnotationCollection` has been deleted * `Laminas\Code\Scanner\ValueScanner` has been deleted * `Laminas\Code\Scanner\DirectoryScanner` has been deleted * `Laminas\Code\Scanner\DocBlockScanner#$nameInformation` was removed * `Laminas\Code\Scanner\DocBlockScanner#$annotationManager` was removed * `Laminas\Code\Scanner\DocBlockScanner#$annotations` was removed * `Laminas\Code\Scanner\DocBlockScanner#getAnnotations()` was removed * `Laminas\Code\Scanner\DocBlockScanner` was marked `@internal` * `Laminas\Code\Scanner\ConstantScanner` has been deleted * `Laminas\Code\Scanner\FunctionScanner` has been deleted * `Laminas\Code\Scanner\AnnotationScanner` has been deleted * `Laminas\Code\Scanner\DerivedClassScanner` has been deleted * `Laminas\Code\Scanner\ClassScanner` has been deleted * `Laminas\Code\Scanner\AggregateDirectoryScanner` has been deleted * `Laminas\Code\Scanner\TokenArrayScanner` has been deleted * `Laminas\Code\Scanner\ParameterScanner` has been deleted * `Laminas\Code\Scanner\FileScanner` has been deleted * `Laminas\Code\Scanner\PropertyScanner` has been deleted * `Laminas\Code\Scanner\CachingFileScanner` has been deleted * `Laminas\Code\Scanner\ScannerInterface` has been deleted * `Laminas\Code\Scanner\MethodScanner` has been deleted * `Laminas\Code\Scanner\Util` has been deleted ----- ### Release Notes for [4.0.0](https://github.com/laminas/laminas-code/milestone/1) next backward compatibility break release (major) ### 4.0.0 - Total issues resolved: **21** - Total pull requests resolved: **13** - Total contributors: **9** #### Enhancement - [64: Verify `4.0.x` branch against real-world applications before releasing](https://github.com/laminas/laminas-code/issues/64) thanks to @Ocramius - [63: Feature - #62 upgrade coding standard and lock dependencies](https://github.com/laminas/laminas-code/pull/63) thanks to @Ocramius - [61: fix #45 : Psalm integration](https://github.com/laminas/laminas-code/pull/61) thanks to @fezfez and @boesing - [60: Remove travi-ci and move to github action](https://github.com/laminas/laminas-code/pull/60) thanks to @fezfez and @weierophinney - [59: Merge release 3.5.1 into 4.0.x](https://github.com/laminas/laminas-code/pull/59) thanks to @github-actions[bot] - [57: #53 support php-8.0 type system additions](https://github.com/laminas/laminas-code/pull/57) thanks to @Ocramius and @weierophinney - [56: #48 merge release `3.5.0` into development branch for `4.0.x`](https://github.com/laminas/laminas-code/pull/56) thanks to @Ocramius - [10: Additional blank lines make generated class not PSR2 compliant](https://github.com/laminas/laminas-code/issues/10) thanks to @weierophinney #### BC Break,Enhancement - [58: BC BREAK: removed `Scanner` component, removed `FileReflection`, removed `NameInformation` and made `DocBlockScanner` `@internal`](https://github.com/laminas/laminas-code/pull/58) thanks to @Ocramius - [39: Suggest "laminas/laminas-zendframework-bridge"](https://github.com/laminas/laminas-code/pull/39) thanks to @olvlvl - [12: Remove code scanners to improve library maintainability](https://github.com/laminas/laminas-code/issues/12) thanks to @weierophinney #### Duplicate,Enhancement - [54: #53 added support for generating parameters with union types in their definitions](https://github.com/laminas/laminas-code/pull/54) thanks to @fezfez and @weierophinney - [48: Merge release 3.5.0 into 4.0.x](https://github.com/laminas/laminas-code/pull/48) thanks to @github-actions[bot] #### Bug - [50: Some constants are not rendered properly depending on environment values](https://github.com/laminas/laminas-code/pull/50) thanks to @drupol #### Bug,Unit Test Needed - [42: Moved declare statements above namespace](https://github.com/laminas/laminas-code/pull/42) thanks to @jguittard #### Awaiting Author Updates,BC Break - [38: Generating class in a better format.](https://github.com/laminas/laminas-code/pull/38) thanks to @tiagosampaio #### Bug,Duplicate,Won't Fix - [28: DirectoryScanner->getClasses() returns no classes](https://github.com/laminas/laminas-code/issues/28) thanks to @weierophinney #### Bug,Won't Fix - [27: Zend\Code\Scanner\MethodScanner does not account for scalar type declarations](https://github.com/laminas/laminas-code/issues/27) thanks to @weierophinney - [26: v3 only: Unknown Notices from ClassScanner](https://github.com/laminas/laminas-code/issues/26) thanks to @weierophinney - [22: Update AnnotationScanner.php](https://github.com/laminas/laminas-code/issues/22) thanks to @weierophinney - [18: Notice when using array as default value for parameter](https://github.com/laminas/laminas-code/issues/18) thanks to @weierophinney - [15: E_NOTICE with trait method aliases](https://github.com/laminas/laminas-code/issues/15) thanks to @weierophinney - [9: Zend\Code\Reflection\FileReflection getBody()](https://github.com/laminas/laminas-code/issues/9) thanks to @weierophinney - [8: Zend\Code\Reflection\FileReflection crashes on Zend's module.config.php](https://github.com/laminas/laminas-code/issues/8) thanks to @weierophinney - [3: Not using return value of array_map in ClassGenerator->setImplementedInterfaces](https://github.com/laminas/laminas-code/issues/3) thanks to @weierophinney #### Question,Won't Fix - [25: Use Reflection\FileReflection without including file? ](https://github.com/laminas/laminas-code/issues/25) thanks to @weierophinney #### Enhancement,Won't Fix - [19: Support nullable types](https://github.com/laminas/laminas-code/issues/19) thanks to @weierophinney - [1: perfect FunctionScanner class ](https://github.com/laminas/laminas-code/issues/1) thanks to @weierophinney #### BC Break,Enhancement,Question - [17: Deprecate scanner functionality (4.0), drop it (5.0) in favor of ](https://github.com/laminas/laminas-code/issues/17) thanks to @weierophinney ## 3.5.1 - 2020-11-30 ### Added ### Release Notes for [3.5.1](https://github.com/laminas/laminas-code/milestone/4) 3.5.x bugfix release (patch) ### 3.5.1 - Total issues resolved: **0** - Total pull requests resolved: **1** - Total contributors: **1** #### Enhancement - [55: Use `8.0` instead of `nightly` in travis-ci builds](https://github.com/laminas/laminas-code/pull/55) thanks to @fezfez ## 3.5.0 - 2020-11-11 ### Added - [#47](https://github.com/laminas/laminas-code/pull/47) adds support for PHP 8. NOTE: this simply means the code runs on PHP 8, not that it can generate code specific to PHP 8. ----- ### Release Notes for [3.5.0](https://github.com/laminas/laminas-code/milestone/3) next feature release (minor) ### 3.5.0 - Total issues resolved: **0** - Total pull requests resolved: **3** - Total contributors: **3** #### Enhancement,hacktoberfest-accepted - [47: Start PHP 8.0 support](https://github.com/laminas/laminas-code/pull/47) thanks to @Slamdunk - [43: QA fix for phpstan](https://github.com/laminas/laminas-code/pull/43) thanks to @janvernieuwe #### Documentation - [31: Modify the examples to make them compatible with PSR-12](https://github.com/laminas/laminas-code/pull/31) thanks to @simivar ## 3.4.1 - 2019-12-10 ### Added - [zendframwork/zend-code#180](https://github.com/zendframework/zend-code/pull/180) adds support for PHP 7.4. ### Changed - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#179](https://github.com/zendframework/zend-code/pull/179) fixes exception message when invalid value provided in `Laminas\Code\Generator\ValueGenerator`. - [zendframwork/zend-code#180](https://github.com/zendframework/zend-code/pull/180) fixes PHP 7.4 compatibility. ## 3.4.0 - 2019-10-06 ### Added - [zendframwork/zend-code#170](https://github.com/zendframework/zend-code/pull/170) adds class constant visibility modifiers support. - [zendframwork/zend-code#169](https://github.com/zendframework/zend-code/pull/169) adds the ability to define declare statements. - [zendframwork/zend-code#167](https://github.com/zendframework/zend-code/pull/167) adds the ability to remove doc block of a member. ### Changed - [zendframwork/zend-code#166](https://github.com/zendframework/zend-code/pull/166) changes omitting default property value if it is null. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#172](https://github.com/zendframework/zend-code/pull/172) fixes PHP 7.4 compatibility. ## 3.3.2 - 2019-08-31 ### Added - [zendframwork/zend-code#162](https://github.com/zendframework/zend-code/pull/162) adds support for PHP 7.3. ### Changed - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#171](https://github.com/zendframework/zend-code/pull/171) changes curly braces in array and string offset access to square brackets in order to prevent issues under the upcoming PHP 7.4 release. - [zendframwork/zend-code#164](https://github.com/zendframework/zend-code/pull/164) fixes indentation in multi-level arrays generated by `ValueGenerator`. ## 3.3.1 - 2018-08-13 ### Added - Nothing. ### Changed - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#158](https://github.com/zendframework/zend-code/pull/158) updates several `switch` cases to use `break` instead of `continue` in order to prevent issues under the upcoming PHP 7.3 release. - [zendframwork/zend-code#147](https://github.com/zendframework/zend-code/pull/147) fixes the regular expression used for `@var` annotations to allow omission of the variable name. - [zendframwork/zend-code#146](https://github.com/zendframework/zend-code/pull/146) updates all `@return` annotations to reflect the correct types returned by each method. - [zendframwork/zend-code#144](https://github.com/zendframework/zend-code/pull/144) fixes the class generator such that it now resolves `setExtendedClass()` arguments to aliases provided to the generator. - [zendframwork/zend-code#140](https://github.com/zendframework/zend-code/pull/140) fixes `MethodScanner::setVisibility()` such that it no longer casts the provided visibility token to lower case; this fix is necessary, as the method is supposed to expect only the appropriate `T_(PUBLIC|PROTECTED|PRIVATE)` token values, which are integers. - [zendframwork/zend-code#140](https://github.com/zendframework/zend-code/pull/140) updates the `MethodScanner::setVisibility()` method to raise a package-specific `InvalidArgumentException` instead of the non-existent package `Exception` class when an invalid visibility is provided. ## 3.3.0 - 2017-10-20 ### Added - [zendframwork/zend-code#131](https://github.com/zendframework/zend-code/pull/131) added the ability to omit a parameter type declaration - [zendframwork/zend-code#132](https://github.com/zendframework/zend-code/pull/132) added a lightweight `MethodGenerator::copyMethodSignature()` constructor that only copies the method declaration with no body nor docblock. - [zendframwork/zend-code#134](https://github.com/zendframework/zend-code/pull/134) short array notation is now used by default for generated array values - [zendframwork/zend-code#136](https://github.com/zendframework/zend-code/pull/136) added the ability to specify an `omitdefaultvalue` key when using `ParameterGenerator::fromArray()` ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#130](https://github.com/zendframework/zend-code/pull/130) Updated links to the documentation - [zendframwork/zend-code#133](https://github.com/zendframework/zend-code/pull/133) The default value of a `ParameterGenerator` is always a `ValueGenerator` ## 3.2.0 - 2017-07-23 ### Added - [zendframework/zend-code#112](https://github.com/zendframework/zend-code/pull/112) [zendframework/zend-code#110](https://github.com/zendframework/zend-code/pull/110) Introduced support for the PHP `7.2` `object` type-hint - [zendframwork/zend-code#41](https://github.com/zendframework/zend-code/pull/41) Added `VarTag` support to the docblock generators and reflectors: allows generating and parsing `@var` tags. - [zendframwork/zend-code#113](https://github.com/zendframework/zend-code/pull/113) Added PHP `7.2` to the build matrix - [zendframwork/zend-code#114](https://github.com/zendframework/zend-code/pull/114) Increased minimum supported PHP version to `^7.1.0` - [zendframwork/zend-code#114](https://github.com/zendframework/zend-code/pull/114) Upgraded PHPUnit dependency to `^6.2.2` - [zendframwork/zend-code#121](https://github.com/zendframework/zend-code/pull/121) Imported global functions via `use` statements (experimenting with OpCache OPCODE inlining optimisations) ### Deprecated - Nothing. ### Removed - [zendframwork/zend-code#113](https://github.com/zendframework/zend-code/pull/113) [zendframwork/zend-code#118](https://github.com/zendframework/zend-code/pull/118) Removed HHVM support - [zendframwork/zend-code#122](https://github.com/zendframework/zend-code/pull/122) Removed IRC notifications for pushes/build statuses ### Fixed - [zendframwork/zend-code#101](https://github.com/zendframework/zend-code/pull/101) avoid calling `isInternalPhpType` twice in the `TypeGenerator` - [zendframwork/zend-code#115](https://github.com/zendframework/zend-code/pull/115) Replaced assertions in the test suite with their static counterparts where applicable - [zendframwork/zend-code#120](https://github.com/zendframework/zend-code/pull/120) [zendframwork/zend-code#109](https://github.com/zendframework/zend-code/pull/109) [zendframwork/zend-code#100](https://github.com/zendframework/zend-code/pull/100) Applied Laminas coding standard to the library code - [zendframwork/zend-code#119](https://github.com/zendframework/zend-code/pull/119) Corrected test suite errors caused by mismatching parameter order - [zendframwork/zend-code#106](https://github.com/zendframework/zend-code/pull/106) - [zendframwork/zend-code#107](https://github.com/zendframework/zend-code/pull/107) Minor typing error corrections in documentation and error messages ## 3.1.0 - 2016-10-24 ### Added - [zendframwork/zend-code#87](https://github.com/zendframework/zend-code/pull/87) support for PHP 7.1's `void` return type declaration. - [zendframwork/zend-code#87](https://github.com/zendframework/zend-code/pull/87) support for PHP 7.1's nullable type declarations. - [zendframwork/zend-code#87](https://github.com/zendframework/zend-code/pull/87) support for PHP 7.1's `iterable` type declaration. - [zendframwork/zend-code#62](https://github.com/zendframework/zend-code/pull/62) added `Laminas\Code\Generator\MethodGenerator#getReturnType()` accessor. - [zendframwork/zend-code#68](https://github.com/zendframework/zend-code/pull/68) [zendframwork/zend-code#26](https://github.com/zendframework/zend-code/pull/26) added mutators to allow removing/checking for existence of methods, properties, constants, parameters and type declarations across all the code generator API. - [zendframwork/zend-code#65](https://github.com/zendframework/zend-code/pull/65) continuous integration testing now checks locked, newest and oldest dependency sets. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - Nothing. ## 3.0.5 - 2016-10-24 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#92](https://github.com/zendframework/zend-code/pull/92) corrected `Laminas\Code\Scanner\ClassScanner` to detect multiple interface inheritance. - [zendframwork/zend-code#95](https://github.com/zendframework/zend-code/pull/95) corrected `Laminas\Code\Generator\ParameterGenerator` to allow copying parameter signatures for non-optional parameters that are still nullable via a default `= null` value. - [zendframwork/zend-code#94](https://github.com/zendframework/zend-code/pull/94) corrected `Laminas\Code\Generator\ValueGenerator` so that class constants can now be generated with arrays as default value (supported since PHP 5.6). ## 3.0.4 - 2016-06-30 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#59](https://github.com/zendframework/zend-code/pull/59) fixes an issue with detection of multiple trait `use` statements. - [zendframwork/zend-code#75](https://github.com/zendframework/zend-code/pull/75) provides a patch to ensure that `extends` statements qualify the parent class based on the current namespace and/or import statements. ## 3.0.3 - 2016-06-27 ### Added - [zendframwork/zend-code#66](https://github.com/zendframework/zend-code/pull/66) publishes the documentation to https://docs.laminas.dev/laminas-code/. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#61](https://github.com/zendframework/zend-code/pull/61) fixes an issue with how parameter typehints were generated; previously, fully-qualified class names were not being generated with the leading backslash, causing them to attempt to resolve as if they were relative to the current namespace. - [zendframwork/zend-code#69](https://github.com/zendframework/zend-code/pull/69) fixes an issue with how class names under the same namespace are generated when generating typehints, extends, and implements values; they now strip the common namespace from the class name. - [zendframwork/zend-code#72](https://github.com/zendframework/zend-code/pull/72) fixes an issue within the `TokenArrayScanner` when scanning closures. ## 3.0.2 - 2016-04-20 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#52](https://github.com/zendframework/zend-code/pull/52) updates several dependency constraints: - laminas-stdlib now allows either the 2.7 or 3.0 series, as the APIs consumed by laminas-code are compatible across versions. - PHP now excludes the 7.0.5 release, as it has known issues in its tokenizer implementation that make the laminas-code token scanner unusable. - [zendframwork/zend-code#46](https://github.com/zendframework/zend-code/pull/46) updates all generators to use `\n` for line endings in generated code, vs `PHP_EOL`, ensuring cross-platform consistency. ## 3.0.1 - 2016-01-26 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#34](https://github.com/zendframework/zend-code/pull/34) method name cannot be optional when adding a method to a class generator. - [zendframwork/zend-code#38](https://github.com/zendframework/zend-code/pull/38) PHP_CodeSniffer was moved to dev dependencies ## 3.0.0 - 2016-01-13 ### Changed - [zendframwork/zend-code#140](https://github.com/zendframework/zend-code/pull/140) updates the `MethodScanner::setVisibility()` method to raise a package-specific `InvalidArgumentException` instead of the non-existent package `Exception` class when an invalid visibility is provided. This section refers to breaking changes: please refer to [docs/book/migration.md](docs/book/migration.md) for migration instructions. - Types `string`, `int`, `float`, `bool` passed to `Laminas\Code\Generator\ParameterGenerator#setType()` are no longer ignored in generated code [zendframwork/zend-code#30](https://github.com/zendframework/zend-code/pull/30) - Types declared in DocBlocks are now ignored when creating a `Laminas\Code\Generator\ParameterGenerator` via `Laminas\Code\Generator\ParameterGenerator::fromReflection()`. [zendframwork/zend-code#30](https://github.com/zendframework/zend-code/pull/30) - Type strings are now validated: passing an invalid type to any method in the generator API may lead to a `Laminas\Code\Generator\InvalidArgumentException` being thrown. [zendframwork/zend-code#30](https://github.com/zendframework/zend-code/pull/30) - `Laminas\Code\Generator\ParameterGenerator::$simple` was removed. [zendframwork/zend-code#30](https://github.com/zendframework/zend-code/pull/30) - `Laminas\Code\Generator\ParameterGenerator#$type` is now a `null|Laminas\Code\Generator\TypeGenerator`: was a `string` before. [zendframwork/zend-code#30](https://github.com/zendframework/zend-code/pull/30) - `Laminas\Code\Generator` type-hints are now always prefixed with the namespace separator `\`. [zendframwork/zend-code#30](https://github.com/zendframework/zend-code/pull/30) - `Laminas\Code\Reflection\ParameterReflection#getType()` was renamed to `Laminas\Code\Reflection\ParameterReflection#detectType()` in order to not override the inherited `ReflectionParameter#getType()`, introduced in PHP 7. [zendframwork/zend-code#30](https://github.com/zendframework/zend-code/pull/30) ### Added - PHP 7 return type hints generation support via `Laminas\Code\Generator\MethodGenerator#setReturnType()`. [zendframwork/zend-code#30](https://github.com/zendframework/zend-code/pull/30) - PHP 7 scalar type hints generation support via `Laminas\Code\Generator\ParameterGenerator#setType()` and `Laminas\Code\Generator\ParameterGenerator#getType()`. [zendframwork/zend-code#30](https://github.com/zendframework/zend-code/pull/30) - PHP 5.6 variadic arguments support via `Laminas\Code\Generator\ParameterGenerator#setVariadic()` and `Laminas\Code\Generator\ParameterGenerator#getVariadic()`. [zendframwork/zend-code#30](https://github.com/zendframework/zend-code/pull/30) - Generation of methods returning by reference is supported via `Laminas\Code\Generator\ParameterGenerator#setReturnsReference()`. [zendframwork/zend-code#30](https://github.com/zendframework/zend-code/pull/30) ### Deprecated - Nothing. ### Removed - `Laminas\Code\ParameterGenerator::$simple` was removed. [zendframwork/zend-code#30](https://github.com/zendframework/zend-code/pull/30) ### Fixed - Nothing. ## 2.6.2 - 2015-01-05 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#31](https://github.com/zendframework/zend-code/pull/31) updated license year. ## 2.6.2 - 2015-01-05 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#31](https://github.com/zendframework/zend-code/pull/31) updated license year. ## 2.6.1 - 2015-11-24 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#25](https://github.com/zendframework/zend-code/pull/25) changes the `doctrine/common` suggestion/dev-dependency to the more specific `doctrine/annotations` package (which is what is actually consumed). ## 2.6.0 - 2015-11-18 ### Added - [zendframwork/zend-code#12](https://github.com/zendframework/zend-code/pull/12) adds the ability to generate arrays using either long/standard syntax (`array(...)`) or short syntax (`[...]`). This can be accomplished by setting the value type to `ValueGenerator::TYPE_ARRAY_SHORT` instead of using `TYPE_ARRAY`. Additionally, you can use `TYPE_ARRAY_LONG` instead of `TYPE_ARRAY`; the two constants are synonyms. - [zendframwork/zend-code#11](https://github.com/zendframework/zend-code/pull/11) adds the ability to generate interfaces via the new class `Laminas\Code\Generator\InterfaceGenerator`. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [zendframwork/zend-code#20](https://github.com/zendframework/zend-code/pull/20) updates the laminas-eventmanager dependency to `^2.6|^3.0`, and changes its internal usage to use the `triggerEventUntil()` signature. ## 2.5.3 - 2015-11-18 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - [zendframwork/zend-code#10](https://github.com/zendframework/zend-code/pull/10) removes a development dependency on zendframework/zend-version. - [zendframwork/zend-code#23](https://github.com/zendframework/zend-code/pull/23) removes a requirement on laminas/laminas-stdlib. This results in a slight change in `Laminas\Code\Generator\ValueGenerator`: `setConstants()` and `getConstants()` can now receive/emit *either* an SPL `ArrayObject` or `Laminas\Stdlib\ArrayObject`. Since these are functionally equivalent, however, you will experience no change in behavior. ### Fixed - Nothing. COPYRIGHT.md000064400000000133144760113020006431 0ustar00Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/) LICENSE.md000064400000002732144760113020006152 0ustar00Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Laminas Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. README.md000064400000001612144760113020006021 0ustar00# laminas-code [![Build Status](https://travis-ci.com/laminas/laminas-code.svg?branch=master)](https://travis-ci.com/laminas/laminas-code) [![Coverage Status](https://coveralls.io/repos/github/laminas/laminas-code/badge.svg?branch=master)](https://coveralls.io/github/laminas/laminas-code?branch=master) `Laminas\Code\Generator` provides facilities to generate arbitrary code using an object-oriented interface, both to create new code as well as to update existing code. While the current implementation is limited to generating PHP code, you can easily extend the base class in order to provide code generation for other tasks: JavaScript, configuration files, apache vhosts, etc. - File issues at https://github.com/laminas/laminas-code/issues - Documentation is at https://docs.laminas.dev/laminas-code/ - Migration documentation from v2 to v3 is at https://docs.laminas.dev/laminas-code/migration/ composer.json000064400000004014144760113020007263 0ustar00{ "name": "laminas/laminas-code", "description": "Extensions to the PHP Reflection API, static code scanning, and code generation", "license": "BSD-3-Clause", "keywords": [ "laminas", "laminasframework", "code" ], "homepage": "https://laminas.dev", "support": { "docs": "https://docs.laminas.dev/laminas-code/", "issues": "https://github.com/laminas/laminas-code/issues", "source": "https://github.com/laminas/laminas-code", "rss": "https://github.com/laminas/laminas-code/releases.atom", "chat": "https://laminas.dev/chat", "forum": "https://discourse.laminas.dev" }, "config": { "sort-packages": true }, "require": { "php": "^7.4 || ~8.0.0", "laminas/laminas-eventmanager": "^3.3" }, "require-dev": { "ext-phar": "*", "doctrine/annotations": "^1.10.4", "laminas/laminas-coding-standard": "^2.1.4", "laminas/laminas-stdlib": "^3.3.0", "phpunit/phpunit": "^9.4.2", "psalm/plugin-phpunit": "^0.14.0", "vimeo/psalm": "^4.3.1" }, "conflict": { "phpspec/prophecy": "<1.9.0" }, "suggest": { "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", "laminas/laminas-stdlib": "Laminas\\Stdlib component", "laminas/laminas-zendframework-bridge": "A bridge with Zend Framework" }, "autoload": { "psr-4": { "Laminas\\Code\\": "src/" } }, "autoload-dev": { "psr-4": { "LaminasTest\\Code\\": "test/" } }, "scripts": { "check": [ "@cs-check", "@test" ], "cs-check": "phpcs", "cs-fix": "phpcbf", "test": "phpunit --colors=always", "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", "static-analysis": "psalm --shepherd --stats" }, "replace": { "zendframework/zend-code": "self.version" } } composer.lock000064400000467650144760113020007265 0ustar00{ "_readme": [ "This file locks the dependencies of your project to a known state", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], "content-hash": "2fb9c06f414decb3542601521e351397", "packages": [ { "name": "laminas/laminas-eventmanager", "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-eventmanager.git", "reference": "1940ccf30e058b2fd66f5a9d696f1b5e0027b082" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/laminas/laminas-eventmanager/zipball/1940ccf30e058b2fd66f5a9d696f1b5e0027b082", "reference": "1940ccf30e058b2fd66f5a9d696f1b5e0027b082", "shasum": "" }, "require": { "laminas/laminas-zendframework-bridge": "^1.0", "php": "^7.3 || ^8.0" }, "replace": { "zendframework/zend-eventmanager": "^3.2.1" }, "require-dev": { "container-interop/container-interop": "^1.1", "laminas/laminas-coding-standard": "~1.0.0", "laminas/laminas-stdlib": "^2.7.3 || ^3.0", "phpbench/phpbench": "^0.17.1", "phpunit/phpunit": "^8.5.8" }, "suggest": { "container-interop/container-interop": "^1.1, to use the lazy listeners feature", "laminas/laminas-stdlib": "^2.7.3 || ^3.0, to use the FilterChain feature" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.3.x-dev", "dev-develop": "3.4.x-dev" } }, "autoload": { "psr-4": { "Laminas\\EventManager\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "description": "Trigger and listen to events within a PHP application", "homepage": "https://laminas.dev", "keywords": [ "event", "eventmanager", "events", "laminas" ], "support": { "chat": "https://laminas.dev/chat", "docs": "https://docs.laminas.dev/laminas-eventmanager/", "forum": "https://discourse.laminas.dev", "issues": "https://github.com/laminas/laminas-eventmanager/issues", "rss": "https://github.com/laminas/laminas-eventmanager/releases.atom", "source": "https://github.com/laminas/laminas-eventmanager" }, "funding": [ { "url": "https://funding.communitybridge.org/projects/laminas-project", "type": "community_bridge" } ], "time": "2020-08-25T11:10:44+00:00" }, { "name": "laminas/laminas-zendframework-bridge", "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/laminas/laminas-zendframework-bridge.git", "reference": "6ede70583e101030bcace4dcddd648f760ddf642" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6ede70583e101030bcace4dcddd648f760ddf642", "reference": "6ede70583e101030bcace4dcddd648f760ddf642", "shasum": "" }, "require": { "php": "^5.6 || ^7.0 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3", "squizlabs/php_codesniffer": "^3.5" }, "type": "library", "extra": { "laminas": { "module": "Laminas\\ZendFrameworkBridge" } }, "autoload": { "files": [ "src/autoload.php" ], "psr-4": { "Laminas\\ZendFrameworkBridge\\": "src//" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "description": "Alias legacy ZF class names to Laminas Project equivalents.", "keywords": [ "ZendFramework", "autoloading", "laminas", "zf" ], "support": { "forum": "https://discourse.laminas.dev/", "issues": "https://github.com/laminas/laminas-zendframework-bridge/issues", "rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom", "source": "https://github.com/laminas/laminas-zendframework-bridge" }, "funding": [ { "url": "https://funding.communitybridge.org/projects/laminas-project", "type": "community_bridge" } ], "time": "2020-09-14T14:23:00+00:00" } ], "packages-dev": [ { "name": "amphp/amp", "version": "v2.5.1", "source": { "type": "git", "url": "https://github.com/amphp/amp.git", "reference": "ecdc3c476b3ccff02f8e5d5bcc04f7ccfd18751c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/amphp/amp/zipball/ecdc3c476b3ccff02f8e5d5bcc04f7ccfd18751c", "reference": "ecdc3c476b3ccff02f8e5d5bcc04f7ccfd18751c", "shasum": "" }, "require": { "php": ">=7" }, "require-dev": { "amphp/php-cs-fixer-config": "dev-master", "amphp/phpunit-util": "^1", "ext-json": "*", "jetbrains/phpstorm-stubs": "^2019.3", "phpunit/phpunit": "^6.0.9 | ^7", "psalm/phar": "^3.11@dev", "react/promise": "^2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.x-dev" } }, "autoload": { "psr-4": { "Amp\\": "lib" }, "files": [ "lib/functions.php", "lib/Internal/functions.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Daniel Lowrey", "email": "rdlowrey@php.net" }, { "name": "Aaron Piotrowski", "email": "aaron@trowski.com" }, { "name": "Bob Weinand", "email": "bobwei9@hotmail.com" }, { "name": "Niklas Keller", "email": "me@kelunik.com" } ], "description": "A non-blocking concurrency framework for PHP applications.", "homepage": "http://amphp.org/amp", "keywords": [ "async", "asynchronous", "awaitable", "concurrency", "event", "event-loop", "future", "non-blocking", "promise" ], "support": { "irc": "irc://irc.freenode.org/amphp", "issues": "https://github.com/amphp/amp/issues", "source": "https://github.com/amphp/amp/tree/v2.5.1" }, "funding": [ { "url": "https://github.com/amphp", "type": "github" } ], "time": "2020-11-03T16:23:45+00:00" }, { "name": "amphp/byte-stream", "version": "v1.8.0", "source": { "type": "git", "url": "https://github.com/amphp/byte-stream.git", "reference": "f0c20cf598a958ba2aa8c6e5a71c697d652c7088" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/amphp/byte-stream/zipball/f0c20cf598a958ba2aa8c6e5a71c697d652c7088", "reference": "f0c20cf598a958ba2aa8c6e5a71c697d652c7088", "shasum": "" }, "require": { "amphp/amp": "^2", "php": ">=7.1" }, "require-dev": { "amphp/php-cs-fixer-config": "dev-master", "amphp/phpunit-util": "^1.4", "friendsofphp/php-cs-fixer": "^2.3", "jetbrains/phpstorm-stubs": "^2019.3", "phpunit/phpunit": "^6 || ^7 || ^8", "psalm/phar": "^3.11.4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { "Amp\\ByteStream\\": "lib" }, "files": [ "lib/functions.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Aaron Piotrowski", "email": "aaron@trowski.com" }, { "name": "Niklas Keller", "email": "me@kelunik.com" } ], "description": "A stream abstraction to make working with non-blocking I/O simple.", "homepage": "http://amphp.org/byte-stream", "keywords": [ "amp", "amphp", "async", "io", "non-blocking", "stream" ], "support": { "irc": "irc://irc.freenode.org/amphp", "issues": "https://github.com/amphp/byte-stream/issues", "source": "https://github.com/amphp/byte-stream/tree/master" }, "time": "2020-06-29T18:35:05+00:00" }, { "name": "composer/package-versions-deprecated", "version": "1.11.99.1", "source": { "type": "git", "url": "https://github.com/composer/package-versions-deprecated.git", "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/7413f0b55a051e89485c5cb9f765fe24bb02a7b6", "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6", "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.1" }, "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": "2020-11-11T10:22:58+00:00" }, { "name": "composer/semver", "version": "3.2.4", "source": { "type": "git", "url": "https://github.com/composer/semver.git", "reference": "a02fdf930a3c1c3ed3a49b5f63859c0c20e10464" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/composer/semver/zipball/a02fdf930a3c1c3ed3a49b5f63859c0c20e10464", "reference": "a02fdf930a3c1c3ed3a49b5f63859c0c20e10464", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { "phpstan/phpstan": "^0.12.54", "symfony/phpunit-bridge": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { "dev-main": "3.x-dev" } }, "autoload": { "psr-4": { "Composer\\Semver\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nils Adermann", "email": "naderman@naderman.de", "homepage": "http://www.naderman.de" }, { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", "homepage": "http://seld.be" }, { "name": "Rob Bast", "email": "rob.bast@gmail.com", "homepage": "http://robbast.nl" } ], "description": "Semver library that offers utilities, version constraint parsing and validation.", "keywords": [ "semantic", "semver", "validation", "versioning" ], "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/semver/issues", "source": "https://github.com/composer/semver/tree/3.2.4" }, "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": "2020-11-13T08:59:24+00:00" }, { "name": "composer/xdebug-handler", "version": "1.4.5", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", "reference": "f28d44c286812c714741478d968104c5e604a1d4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f28d44c286812c714741478d968104c5e604a1d4", "reference": "f28d44c286812c714741478d968104c5e604a1d4", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0", "psr/log": "^1.0" }, "require-dev": { "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" }, "type": "library", "autoload": { "psr-4": { "Composer\\XdebugHandler\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "John Stevenson", "email": "john-stevenson@blueyonder.co.uk" } ], "description": "Restarts a process without Xdebug.", "keywords": [ "Xdebug", "performance" ], "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/xdebug-handler/issues", "source": "https://github.com/composer/xdebug-handler/tree/1.4.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": "2020-11-13T08:04:11+00:00" }, { "name": "dealerdirect/phpcodesniffer-composer-installer", "version": "v0.7.1", "source": { "type": "git", "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", "reference": "fe390591e0241955f22eb9ba327d137e501c771c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/fe390591e0241955f22eb9ba327d137e501c771c", "reference": "fe390591e0241955f22eb9ba327d137e501c771c", "shasum": "" }, "require": { "composer-plugin-api": "^1.0 || ^2.0", "php": ">=5.3", "squizlabs/php_codesniffer": "^2.0 || ^3.0 || ^4.0" }, "require-dev": { "composer/composer": "*", "phpcompatibility/php-compatibility": "^9.0", "sensiolabs/security-checker": "^4.1.0" }, "type": "composer-plugin", "extra": { "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" }, "autoload": { "psr-4": { "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Franck Nijhof", "email": "franck.nijhof@dealerdirect.com", "homepage": "http://www.frenck.nl", "role": "Developer / IT Manager" } ], "description": "PHP_CodeSniffer Standards Composer Installer Plugin", "homepage": "http://www.dealerdirect.com", "keywords": [ "PHPCodeSniffer", "PHP_CodeSniffer", "code quality", "codesniffer", "composer", "installer", "phpcs", "plugin", "qa", "quality", "standard", "standards", "style guide", "stylecheck", "tests" ], "support": { "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" }, "time": "2020-12-07T18:04:37+00:00" }, { "name": "dnoegel/php-xdg-base-dir", "version": "v0.1.1", "source": { "type": "git", "url": "https://github.com/dnoegel/php-xdg-base-dir.git", "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", "shasum": "" }, "require": { "php": ">=5.3.2" }, "require-dev": { "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" }, "type": "library", "autoload": { "psr-4": { "XdgBaseDir\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "implementation of xdg base directory specification for php", "support": { "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" }, "time": "2019-12-04T15:06:13+00:00" }, { "name": "doctrine/annotations", "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", "reference": "ce77a7ba1770462cd705a91a151b6c3746f9c6ad" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/annotations/zipball/ce77a7ba1770462cd705a91a151b6c3746f9c6ad", "reference": "ce77a7ba1770462cd705a91a151b6c3746f9c6ad", "shasum": "" }, "require": { "doctrine/lexer": "1.*", "ext-tokenizer": "*", "php": "^7.1 || ^8.0" }, "require-dev": { "doctrine/cache": "1.*", "doctrine/coding-standard": "^6.0 || ^8.1", "phpstan/phpstan": "^0.12.20", "phpunit/phpunit": "^7.5 || ^9.1.5" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.11.x-dev" } }, "autoload": { "psr-4": { "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, { "name": "Roman Borschel", "email": "roman@code-factory.org" }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" } ], "description": "Docblock Annotations Parser", "homepage": "https://www.doctrine-project.org/projects/annotations.html", "keywords": [ "annotations", "docblock", "parser" ], "support": { "issues": "https://github.com/doctrine/annotations/issues", "source": "https://github.com/doctrine/annotations/tree/1.11.1" }, "time": "2020-10-26T10:28:16+00:00" }, { "name": "doctrine/instantiator", "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^8.0", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", "phpstan/phpstan": "^0.12", "phpstan/phpstan-phpunit": "^0.12", "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", "source": "https://github.com/doctrine/instantiator/tree/1.4.0" }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { "url": "https://www.patreon.com/phpdoctrine", "type": "patreon" }, { "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", "type": "tidelift" } ], "time": "2020-11-10T18:47:58+00:00" }, { "name": "doctrine/lexer", "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^6.0", "phpstan/phpstan": "^0.11.8", "phpunit/phpunit": "^8.2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.2.x-dev" } }, "autoload": { "psr-4": { "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, { "name": "Roman Borschel", "email": "roman@code-factory.org" }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" } ], "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", "homepage": "https://www.doctrine-project.org/projects/lexer.html", "keywords": [ "annotations", "docblock", "lexer", "parser", "php" ], "support": { "issues": "https://github.com/doctrine/lexer/issues", "source": "https://github.com/doctrine/lexer/tree/1.2.1" }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { "url": "https://www.patreon.com/phpdoctrine", "type": "patreon" }, { "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", "type": "tidelift" } ], "time": "2020-05-25T17:44:05+00:00" }, { "name": "felixfbecker/advanced-json-rpc", "version": "v3.1.1", "source": { "type": "git", "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", "reference": "0ed363f8de17d284d479ec813c9ad3f6834b5c40" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/0ed363f8de17d284d479ec813c9ad3f6834b5c40", "reference": "0ed363f8de17d284d479ec813c9ad3f6834b5c40", "shasum": "" }, "require": { "netresearch/jsonmapper": "^1.0 || ^2.0", "php": ">=7.0", "phpdocumentor/reflection-docblock": "^4.0.0 || ^5.0.0" }, "require-dev": { "phpunit/phpunit": "^6.0.0" }, "type": "library", "autoload": { "psr-4": { "AdvancedJsonRpc\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "ISC" ], "authors": [ { "name": "Felix Becker", "email": "felix.b@outlook.com" } ], "description": "A more advanced JSONRPC implementation", "support": { "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/master" }, "time": "2020-03-11T15:21:41+00:00" }, { "name": "felixfbecker/language-server-protocol", "version": "v1.5.0", "source": { "type": "git", "url": "https://github.com/felixfbecker/php-language-server-protocol.git", "reference": "85e83cacd2ed573238678c6875f8f0d7ec699541" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/85e83cacd2ed573238678c6875f8f0d7ec699541", "reference": "85e83cacd2ed573238678c6875f8f0d7ec699541", "shasum": "" }, "require": { "php": ">=7.1" }, "require-dev": { "phpstan/phpstan": "*", "squizlabs/php_codesniffer": "^3.1", "vimeo/psalm": "^4.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { "LanguageServerProtocol\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "ISC" ], "authors": [ { "name": "Felix Becker", "email": "felix.b@outlook.com" } ], "description": "PHP classes for the Language Server Protocol", "keywords": [ "language", "microsoft", "php", "server" ], "support": { "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.0" }, "time": "2020-10-23T13:55:30+00:00" }, { "name": "laminas/laminas-coding-standard", "version": "2.1.4", "source": { "type": "git", "url": "https://github.com/laminas/laminas-coding-standard.git", "reference": "d75f1acf615232e108da2d2cf5a7df3e527b8f38" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/d75f1acf615232e108da2d2cf5a7df3e527b8f38", "reference": "d75f1acf615232e108da2d2cf5a7df3e527b8f38", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", "laminas/laminas-zendframework-bridge": "^1.0", "php": "^7.3 || ~8.0.0", "slevomat/coding-standard": "^6.4.1", "squizlabs/php_codesniffer": "^3.5.8", "webimpress/coding-standard": "^1.1.6" }, "type": "phpcodesniffer-standard", "autoload": { "psr-4": { "LaminasCodingStandard\\": "src/LaminasCodingStandard/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "description": "Laminas Coding Standard", "homepage": "https://laminas.dev", "keywords": [ "Coding Standard", "laminas" ], "support": { "chat": "https://laminas.dev/chat", "docs": "https://docs.laminas.dev/laminas-coding-standard/", "forum": "https://discourse.laminas.dev", "issues": "https://github.com/laminas/laminas-coding-standard/issues", "rss": "https://github.com/laminas/laminas-coding-standard/releases.atom", "source": "https://github.com/laminas/laminas-coding-standard" }, "funding": [ { "url": "https://funding.communitybridge.org/projects/laminas-project", "type": "community_bridge" } ], "time": "2020-10-26T07:33:05+00:00" }, { "name": "laminas/laminas-stdlib", "version": "3.3.1", "source": { "type": "git", "url": "https://github.com/laminas/laminas-stdlib.git", "reference": "d81c7ffe602ed0e6ecb18691019111c0f4bf1efe" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/d81c7ffe602ed0e6ecb18691019111c0f4bf1efe", "reference": "d81c7ffe602ed0e6ecb18691019111c0f4bf1efe", "shasum": "" }, "require": { "laminas/laminas-zendframework-bridge": "^1.0", "php": "^7.3 || ^8.0" }, "replace": { "zendframework/zend-stdlib": "^3.2.1" }, "require-dev": { "laminas/laminas-coding-standard": "~1.0.0", "phpbench/phpbench": "^0.17.1", "phpunit/phpunit": "~9.3.7" }, "type": "library", "autoload": { "psr-4": { "Laminas\\Stdlib\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "description": "SPL extensions, array utilities, error handlers, and more", "homepage": "https://laminas.dev", "keywords": [ "laminas", "stdlib" ], "support": { "chat": "https://laminas.dev/chat", "docs": "https://docs.laminas.dev/laminas-stdlib/", "forum": "https://discourse.laminas.dev", "issues": "https://github.com/laminas/laminas-stdlib/issues", "rss": "https://github.com/laminas/laminas-stdlib/releases.atom", "source": "https://github.com/laminas/laminas-stdlib" }, "funding": [ { "url": "https://funding.communitybridge.org/projects/laminas-project", "type": "community_bridge" } ], "time": "2020-11-19T20:18:59+00:00" }, { "name": "myclabs/deep-copy", "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "replace": { "myclabs/deep-copy": "self.version" }, "require-dev": { "doctrine/collections": "^1.0", "doctrine/common": "^2.6", "phpunit/phpunit": "^7.1" }, "type": "library", "autoload": { "psr-4": { "DeepCopy\\": "src/DeepCopy/" }, "files": [ "src/DeepCopy/deep_copy.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "Create deep copies (clones) of your objects", "keywords": [ "clone", "copy", "duplicate", "object", "object graph" ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", "type": "tidelift" } ], "time": "2020-11-13T09:40:50+00:00" }, { "name": "netresearch/jsonmapper", "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/cweiske/jsonmapper.git", "reference": "e0f1e33a71587aca81be5cffbb9746510e1fe04e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/e0f1e33a71587aca81be5cffbb9746510e1fe04e", "reference": "e0f1e33a71587aca81be5cffbb9746510e1fe04e", "shasum": "" }, "require": { "ext-json": "*", "ext-pcre": "*", "ext-reflection": "*", "ext-spl": "*", "php": ">=5.6" }, "require-dev": { "phpunit/phpunit": "~4.8.35 || ~5.7 || ~6.4 || ~7.0", "squizlabs/php_codesniffer": "~3.5" }, "type": "library", "autoload": { "psr-0": { "JsonMapper": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "OSL-3.0" ], "authors": [ { "name": "Christian Weiske", "email": "cweiske@cweiske.de", "homepage": "http://github.com/cweiske/jsonmapper/", "role": "Developer" } ], "description": "Map nested JSON structures onto PHP classes", "support": { "email": "cweiske@cweiske.de", "issues": "https://github.com/cweiske/jsonmapper/issues", "source": "https://github.com/cweiske/jsonmapper/tree/master" }, "time": "2020-04-16T18:48:43+00:00" }, { "name": "nikic/php-parser", "version": "v4.10.3", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", "reference": "dbe56d23de8fcb157bbc0cfb3ad7c7de0cfb0984" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dbe56d23de8fcb157bbc0cfb3ad7c7de0cfb0984", "reference": "dbe56d23de8fcb157bbc0cfb3ad7c7de0cfb0984", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": ">=7.0" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" ], "type": "library", "extra": { "branch-alias": { "dev-master": "4.9-dev" } }, "autoload": { "psr-4": { "PhpParser\\": "lib/PhpParser" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Nikita Popov" } ], "description": "A PHP parser written in PHP", "keywords": [ "parser", "php" ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.3" }, "time": "2020-12-03T17:45:45+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" }, { "name": "phar-io/manifest", "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", "ext-xmlwriter": "*", "phar-io/version": "^3.0.1", "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" }, { "name": "Sebastian Heuer", "email": "sebastian@phpeople.de", "role": "Developer" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "Developer" } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", "source": "https://github.com/phar-io/manifest/tree/master" }, "time": "2020-06-27T14:33:11+00:00" }, { "name": "phar-io/version", "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", "reference": "726c026815142e4f8677b7cb7f2249c9ffb7ecae" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phar-io/version/zipball/726c026815142e4f8677b7cb7f2249c9ffb7ecae", "reference": "726c026815142e4f8677b7cb7f2249c9ffb7ecae", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" }, { "name": "Sebastian Heuer", "email": "sebastian@phpeople.de", "role": "Developer" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "Developer" } ], "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", "source": "https://github.com/phar-io/version/tree/3.0.3" }, "time": "2020-11-30T09:21:21+00:00" }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { "dev-2.x": "2.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Jaap van Otterdijk", "email": "opensource@ijaap.nl" } ], "description": "Common reflection classes used by phpdocumentor to reflect the code structure", "homepage": "http://www.phpdoc.org", "keywords": [ "FQSEN", "phpDocumentor", "phpdoc", "reflection", "static analysis" ], "support": { "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" }, "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", "version": "5.2.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", "shasum": "" }, "require": { "ext-filter": "*", "php": "^7.2 || ^8.0", "phpdocumentor/reflection-common": "^2.2", "phpdocumentor/type-resolver": "^1.3", "webmozart/assert": "^1.9.1" }, "require-dev": { "mockery/mockery": "~1.3.2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "5.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Mike van Riel", "email": "me@mikevanriel.com" }, { "name": "Jaap van Otterdijk", "email": "account@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" }, "time": "2020-09-03T19:13:55+00:00" }, { "name": "phpdocumentor/type-resolver", "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { "ext-tokenizer": "*" }, "type": "library", "extra": { "branch-alias": { "dev-1.x": "1.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Mike van Riel", "email": "me@mikevanriel.com" } ], "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.4.0" }, "time": "2020-09-17T18:55:26+00:00" }, { "name": "phpspec/prophecy", "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d", "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", "php": "^7.2 || ~8.0, <8.1", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { "phpspec/phpspec": "^6.0", "phpunit/phpunit": "^8.0 || ^9.0 <9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.11.x-dev" } }, "autoload": { "psr-4": { "Prophecy\\": "src/Prophecy" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Konstantin Kudryashov", "email": "ever.zet@gmail.com", "homepage": "http://everzet.com" }, { "name": "Marcello Duarte", "email": "marcello.duarte@gmail.com" } ], "description": "Highly opinionated mocking framework for PHP 5.3+", "homepage": "https://github.com/phpspec/prophecy", "keywords": [ "Double", "Dummy", "fake", "mock", "spy", "stub" ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", "source": "https://github.com/phpspec/prophecy/tree/1.12.1" }, "time": "2020-09-29T09:10:42+00:00" }, { "name": "phpstan/phpdoc-parser", "version": "0.4.9", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", "reference": "98a088b17966bdf6ee25c8a4b634df313d8aa531" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/98a088b17966bdf6ee25c8a4b634df313d8aa531", "reference": "98a088b17966bdf6ee25c8a4b634df313d8aa531", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { "consistence/coding-standard": "^3.5", "ergebnis/composer-normalize": "^2.0.2", "jakub-onderka/php-parallel-lint": "^0.9.2", "phing/phing": "^2.16.0", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^0.12.26", "phpstan/phpstan-strict-rules": "^0.12", "phpunit/phpunit": "^6.3", "slevomat/coding-standard": "^4.7.2", "symfony/process": "^4.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "0.4-dev" } }, "autoload": { "psr-4": { "PHPStan\\PhpDocParser\\": [ "src/" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "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/master" }, "time": "2020-08-03T20:32:43+00:00" }, { "name": "phpunit/php-code-coverage", "version": "9.2.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f3e026641cc91909d421802dd3ac7827ebfd97e1", "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", "nikic/php-parser": "^4.10.2", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", "sebastian/code-unit-reverse-lookup": "^2.0.2", "sebastian/complexity": "^2.0", "sebastian/environment": "^5.1.2", "sebastian/lines-of-code": "^1.0.3", "sebastian/version": "^3.0.1", "theseer/tokenizer": "^1.2.0" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "suggest": { "ext-pcov": "*", "ext-xdebug": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "9.2-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", "homepage": "https://github.com/sebastianbergmann/php-code-coverage", "keywords": [ "coverage", "testing", "xunit" ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.5" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-28T06:44:49+00:00" }, { "name": "phpunit/php-file-iterator", "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "FilterIterator implementation that filters files based on a list of suffixes.", "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", "keywords": [ "filesystem", "iterator" ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T05:57:25+00:00" }, { "name": "phpunit/php-invoker", "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "ext-pcntl": "*", "phpunit/phpunit": "^9.3" }, "suggest": { "ext-pcntl": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Invoke callables with a timeout", "homepage": "https://github.com/sebastianbergmann/php-invoker/", "keywords": [ "process" ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T05:58:55+00:00" }, { "name": "phpunit/php-text-template", "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Simple template engine.", "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ "template" ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T05:33:50+00:00" }, { "name": "phpunit/php-timer", "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "5.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Utility class for timing", "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ "timer" ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T13:16:10+00:00" }, { "name": "phpunit/phpunit", "version": "9.5.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", "reference": "8e16c225d57c3d6808014df6b1dd7598d0a5bbbe" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8e16c225d57c3d6808014df6b1dd7598d0a5bbbe", "reference": "8e16c225d57c3d6808014df6b1dd7598d0a5bbbe", "shasum": "" }, "require": { "doctrine/instantiator": "^1.3.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", "myclabs/deep-copy": "^1.10.1", "phar-io/manifest": "^2.0.1", "phar-io/version": "^3.0.2", "php": ">=7.3", "phpspec/prophecy": "^1.12.1", "phpunit/php-code-coverage": "^9.2.3", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", "phpunit/php-timer": "^5.0.2", "sebastian/cli-parser": "^1.0.1", "sebastian/code-unit": "^1.0.6", "sebastian/comparator": "^4.0.5", "sebastian/diff": "^4.0.3", "sebastian/environment": "^5.1.3", "sebastian/exporter": "^4.0.3", "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", "sebastian/type": "^2.3", "sebastian/version": "^3.0.2" }, "require-dev": { "ext-pdo": "*", "phpspec/prophecy-phpunit": "^2.0.1" }, "suggest": { "ext-soap": "*", "ext-xdebug": "*" }, "bin": [ "phpunit" ], "type": "library", "extra": { "branch-alias": { "dev-master": "9.5-dev" } }, "autoload": { "classmap": [ "src/" ], "files": [ "src/Framework/Assert/Functions.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "The PHP Unit Testing framework.", "homepage": "https://phpunit.de/", "keywords": [ "phpunit", "testing", "xunit" ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.0" }, "funding": [ { "url": "https://phpunit.de/donate.html", "type": "custom" }, { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-12-04T05:05:53+00:00" }, { "name": "psalm/plugin-phpunit", "version": "0.14.0", "source": { "type": "git", "url": "https://github.com/psalm/psalm-plugin-phpunit.git", "reference": "f5147be764449ff5a11bded483b622e1e868f8ab" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/psalm/psalm-plugin-phpunit/zipball/f5147be764449ff5a11bded483b622e1e868f8ab", "reference": "f5147be764449ff5a11bded483b622e1e868f8ab", "shasum": "" }, "require": { "composer/package-versions-deprecated": "^1.10", "composer/semver": "^1.4 || ^2.0 || ^3.0", "ext-simplexml": "*", "php": "^7.1 || ^8.0", "vimeo/psalm": "dev-master || dev-4.x || ^4.0" }, "conflict": { "phpunit/phpunit": "<7.5" }, "require-dev": { "codeception/codeception": "^4.0.3", "php": "^7.3 || ^8.0", "phpunit/phpunit": "^7.5 || ^8.0 || ^9.0", "squizlabs/php_codesniffer": "^3.3.1", "weirdan/codeception-psalm-module": "^0.11.0", "weirdan/prophecy-shim": "^1.0 || ^2.0" }, "type": "psalm-plugin", "extra": { "psalm": { "pluginClass": "Psalm\\PhpUnitPlugin\\Plugin" } }, "autoload": { "psr-4": { "Psalm\\PhpUnitPlugin\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Matt Brown", "email": "github@muglug.com" } ], "description": "Psalm plugin for PHPUnit", "support": { "issues": "https://github.com/psalm/psalm-plugin-phpunit/issues", "source": "https://github.com/psalm/psalm-plugin-phpunit/tree/0.14.0" }, "time": "2020-12-08T22:25:25+00:00" }, { "name": "psr/container", "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", "shasum": "" }, "require": { "php": ">=5.3.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "http://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", "homepage": "https://github.com/php-fig/container", "keywords": [ "PSR-11", "container", "container-interface", "container-interop", "psr" ], "support": { "issues": "https://github.com/php-fig/container/issues", "source": "https://github.com/php-fig/container/tree/master" }, "time": "2017-02-14T16:28:37+00:00" }, { "name": "psr/log", "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", "shasum": "" }, "require": { "php": ">=5.3.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.1.x-dev" } }, "autoload": { "psr-4": { "Psr\\Log\\": "Psr/Log/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "http://www.php-fig.org/" } ], "description": "Common interface for logging libraries", "homepage": "https://github.com/php-fig/log", "keywords": [ "log", "psr", "psr-3" ], "support": { "source": "https://github.com/php-fig/log/tree/1.1.3" }, "time": "2020-03-23T09:12:05+00:00" }, { "name": "sebastian/cli-parser", "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library for parsing CLI options", "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T06:08:49+00:00" }, { "name": "sebastian/code-unit", "version": "1.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Collection of value objects that represent the PHP code units", "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T13:08:54+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T05:30:19+00:00" }, { "name": "sebastian/comparator", "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", "reference": "55f4261989e546dc112258c7a75935a81a7ce382" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", "reference": "55f4261989e546dc112258c7a75935a81a7ce382", "shasum": "" }, "require": { "php": ">=7.3", "sebastian/diff": "^4.0", "sebastian/exporter": "^4.0" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" } ], "description": "Provides the functionality to compare PHP values for equality", "homepage": "https://github.com/sebastianbergmann/comparator", "keywords": [ "comparator", "compare", "equality" ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T15:49:45+00:00" }, { "name": "sebastian/complexity", "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", "shasum": "" }, "require": { "nikic/php-parser": "^4.7", "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library for calculating the complexity of PHP code units", "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T15:52:27+00:00" }, { "name": "sebastian/diff", "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3", "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Kore Nordmann", "email": "mail@kore-nordmann.de" } ], "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ "diff", "udiff", "unidiff", "unified diff" ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T13:10:38+00:00" }, { "name": "sebastian/environment", "version": "5.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", "reference": "388b6ced16caa751030f6a69e588299fa09200ac" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", "reference": "388b6ced16caa751030f6a69e588299fa09200ac", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "suggest": { "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "5.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides functionality to handle HHVM/PHP environments", "homepage": "http://www.github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", "hhvm" ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T05:52:38+00:00" }, { "name": "sebastian/exporter", "version": "4.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", "shasum": "" }, "require": { "php": ">=7.3", "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-mbstring": "*", "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Adam Harvey", "email": "aharvey@php.net" }, { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", "homepage": "http://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T05:24:23+00:00" }, { "name": "sebastian/global-state", "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", "reference": "a90ccbddffa067b51f574dea6eb25d5680839455" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a90ccbddffa067b51f574dea6eb25d5680839455", "reference": "a90ccbddffa067b51f574dea6eb25d5680839455", "shasum": "" }, "require": { "php": ">=7.3", "sebastian/object-reflector": "^2.0", "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-dom": "*", "phpunit/phpunit": "^9.3" }, "suggest": { "ext-uopz": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "5.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Snapshotting of global state", "homepage": "http://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.2" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T15:55:19+00:00" }, { "name": "sebastian/lines-of-code", "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", "shasum": "" }, "require": { "nikic/php-parser": "^4.6", "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library for counting the lines of code in PHP source code", "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-28T06:42:11+00:00" }, { "name": "sebastian/object-enumerator", "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", "shasum": "" }, "require": { "php": ">=7.3", "sebastian/object-reflector": "^2.0", "sebastian/recursion-context": "^4.0" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T13:12:34+00:00" }, { "name": "sebastian/object-reflector", "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T13:14:26+00:00" }, { "name": "sebastian/recursion-context", "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Adam Harvey", "email": "aharvey@php.net" } ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T13:17:30+00:00" }, { "name": "sebastian/resource-operations", "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { "issues": "https://github.com/sebastianbergmann/resource-operations/issues", "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T06:45:17+00:00" }, { "name": "sebastian/type", "version": "2.3.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/81cd61ab7bbf2de744aba0ea61fae32f721df3d2", "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.3-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Collection of value objects that represent the types of the PHP type system", "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", "source": "https://github.com/sebastianbergmann/type/tree/2.3.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-10-26T13:18:59+00:00" }, { "name": "sebastian/version", "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", "reference": "c6c1022351a901512170118436c764e473f6de8c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", "reference": "c6c1022351a901512170118436c764e473f6de8c", "shasum": "" }, "require": { "php": ">=7.3" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-09-28T06:39:44+00:00" }, { "name": "slevomat/coding-standard", "version": "6.4.1", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", "reference": "696dcca217d0c9da2c40d02731526c1e25b65346" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/696dcca217d0c9da2c40d02731526c1e25b65346", "reference": "696dcca217d0c9da2c40d02731526c1e25b65346", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", "php": "^7.1 || ^8.0", "phpstan/phpdoc-parser": "0.4.5 - 0.4.9", "squizlabs/php_codesniffer": "^3.5.6" }, "require-dev": { "phing/phing": "2.16.3", "php-parallel-lint/php-parallel-lint": "1.2.0", "phpstan/phpstan": "0.12.48", "phpstan/phpstan-deprecation-rules": "0.12.5", "phpstan/phpstan-phpunit": "0.12.16", "phpstan/phpstan-strict-rules": "0.12.5", "phpunit/phpunit": "7.5.20|8.5.5|9.4.0" }, "type": "phpcodesniffer-standard", "extra": { "branch-alias": { "dev-master": "6.x-dev" } }, "autoload": { "psr-4": { "SlevomatCodingStandard\\": "SlevomatCodingStandard" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", "support": { "issues": "https://github.com/slevomat/coding-standard/issues", "source": "https://github.com/slevomat/coding-standard/tree/6.4.1" }, "funding": [ { "url": "https://github.com/kukulich", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", "type": "tidelift" } ], "time": "2020-10-05T12:39:37+00:00" }, { "name": "squizlabs/php_codesniffer", "version": "3.5.8", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", "reference": "9d583721a7157ee997f235f327de038e7ea6dac4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9d583721a7157ee997f235f327de038e7ea6dac4", "reference": "9d583721a7157ee997f235f327de038e7ea6dac4", "shasum": "" }, "require": { "ext-simplexml": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", "php": ">=5.4.0" }, "require-dev": { "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "bin": [ "bin/phpcs", "bin/phpcbf" ], "type": "library", "extra": { "branch-alias": { "dev-master": "3.x-dev" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Greg Sherwood", "role": "lead" } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", "keywords": [ "phpcs", "standards" ], "support": { "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", "source": "https://github.com/squizlabs/PHP_CodeSniffer", "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" }, "time": "2020-10-23T02:01:07+00:00" }, { "name": "symfony/console", "version": "v5.2.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", "reference": "3e0564fb08d44a98bd5f1960204c958e57bd586b" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/console/zipball/3e0564fb08d44a98bd5f1960204c958e57bd586b", "reference": "3e0564fb08d44a98bd5f1960204c958e57bd586b", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", "symfony/polyfill-php80": "^1.15", "symfony/service-contracts": "^1.1|^2", "symfony/string": "^5.1" }, "conflict": { "symfony/dependency-injection": "<4.4", "symfony/dotenv": "<5.1", "symfony/event-dispatcher": "<4.4", "symfony/lock": "<4.4", "symfony/process": "<4.4" }, "provide": { "psr/log-implementation": "1.0" }, "require-dev": { "psr/log": "~1.0", "symfony/config": "^4.4|^5.0", "symfony/dependency-injection": "^4.4|^5.0", "symfony/event-dispatcher": "^4.4|^5.0", "symfony/lock": "^4.4|^5.0", "symfony/process": "^4.4|^5.0", "symfony/var-dumper": "^4.4|^5.0" }, "suggest": { "psr/log": "For using the console logger", "symfony/event-dispatcher": "", "symfony/lock": "", "symfony/process": "" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Console Component", "homepage": "https://symfony.com", "keywords": [ "cli", "command line", "console", "terminal" ], "support": { "source": "https://github.com/symfony/console/tree/v5.2.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": "2020-11-28T11:24:18+00:00" }, { "name": "symfony/polyfill-ctype", "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", "shasum": "" }, "require": { "php": ">=7.1" }, "suggest": { "ext-ctype": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" }, "files": [ "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Gert de Pagter", "email": "BackEndTea@gmail.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for ctype functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "ctype", "polyfill", "portable" ], "support": { "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.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": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/polyfill-intl-grapheme", "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", "reference": "c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c", "reference": "c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c", "shasum": "" }, "require": { "php": ">=7.1" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Intl\\Grapheme\\": "" }, "files": [ "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for intl's grapheme_* functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "grapheme", "intl", "polyfill", "portable", "shim" ], "support": { "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.20.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": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/polyfill-intl-normalizer", "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", "reference": "727d1096295d807c309fb01a851577302394c897" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/727d1096295d807c309fb01a851577302394c897", "reference": "727d1096295d807c309fb01a851577302394c897", "shasum": "" }, "require": { "php": ">=7.1" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, "files": [ "bootstrap.php" ], "classmap": [ "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for intl's Normalizer class and related functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "intl", "normalizer", "polyfill", "portable", "shim" ], "support": { "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.20.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": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/polyfill-mbstring", "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", "shasum": "" }, "require": { "php": ">=7.1" }, "suggest": { "ext-mbstring": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" }, "files": [ "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for the Mbstring extension", "homepage": "https://symfony.com", "keywords": [ "compatibility", "mbstring", "polyfill", "portable", "shim" ], "support": { "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.20.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": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/polyfill-php73", "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/8ff431c517be11c78c48a39a66d37431e26a6bed", "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed", "shasum": "" }, "require": { "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Php73\\": "" }, "files": [ "bootstrap.php" ], "classmap": [ "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "polyfill", "portable", "shim" ], "support": { "source": "https://github.com/symfony/polyfill-php73/tree/v1.20.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": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/polyfill-php80", "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de", "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de", "shasum": "" }, "require": { "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Php80\\": "" }, "files": [ "bootstrap.php" ], "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.20.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": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/service-contracts", "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", "shasum": "" }, "require": { "php": ">=7.2.5", "psr/container": "^1.0" }, "suggest": { "symfony/service-implementation": "" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.2-dev" }, "thanks": { "name": "symfony/contracts", "url": "https://github.com/symfony/contracts" } }, "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Generic abstractions related to writing services", "homepage": "https://symfony.com", "keywords": [ "abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards" ], "support": { "source": "https://github.com/symfony/service-contracts/tree/master" }, "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": "2020-09-07T11:33:47+00:00" }, { "name": "symfony/string", "version": "v5.2.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", "reference": "40e975edadd4e32cd16f3753b3bad65d9ac48242" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/string/zipball/40e975edadd4e32cd16f3753b3bad65d9ac48242", "reference": "40e975edadd4e32cd16f3753b3bad65d9ac48242", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php80": "~1.15" }, "require-dev": { "symfony/error-handler": "^4.4|^5.0", "symfony/http-client": "^4.4|^5.0", "symfony/translation-contracts": "^1.1|^2", "symfony/var-exporter": "^4.4|^5.0" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\String\\": "" }, "files": [ "Resources/functions.php" ], "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony String component", "homepage": "https://symfony.com", "keywords": [ "grapheme", "i18n", "string", "unicode", "utf-8", "utf8" ], "support": { "source": "https://github.com/symfony/string/tree/v5.2.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": "2020-10-24T12:08:07+00:00" }, { "name": "theseer/tokenizer", "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", "reference": "75a63c33a8577608444246075ea0af0d052e452a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", "reference": "75a63c33a8577608444246075ea0af0d052e452a", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", "source": "https://github.com/theseer/tokenizer/tree/master" }, "funding": [ { "url": "https://github.com/theseer", "type": "github" } ], "time": "2020-07-12T23:59:07+00:00" }, { "name": "vimeo/psalm", "version": "4.3.1", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", "reference": "2feba22a005a18bf31d4c7b9bdb9252c73897476" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/vimeo/psalm/zipball/2feba22a005a18bf31d4c7b9bdb9252c73897476", "reference": "2feba22a005a18bf31d4c7b9bdb9252c73897476", "shasum": "" }, "require": { "amphp/amp": "^2.1", "amphp/byte-stream": "^1.5", "composer/package-versions-deprecated": "^1.8.0", "composer/semver": "^1.4 || ^2.0 || ^3.0", "composer/xdebug-handler": "^1.1", "dnoegel/php-xdg-base-dir": "^0.1.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-simplexml": "*", "ext-tokenizer": "*", "felixfbecker/advanced-json-rpc": "^3.0.3", "felixfbecker/language-server-protocol": "^1.4", "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0", "nikic/php-parser": "^4.10.1", "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", "webmozart/path-util": "^2.3" }, "provide": { "psalm/psalm": "self.version" }, "require-dev": { "amphp/amp": "^2.4.2", "bamarni/composer-bin-plugin": "^1.2", "brianium/paratest": "^4.0.0", "ext-curl": "*", "php": "^7.3|^8", "phpdocumentor/reflection-docblock": "^5", "phpmyadmin/sql-parser": "5.1.0", "phpspec/prophecy": ">=1.9.0", "phpunit/phpunit": "^9.0", "psalm/plugin-phpunit": "^0.13", "slevomat/coding-standard": "^5.0", "squizlabs/php_codesniffer": "^3.5", "symfony/process": "^4.3", "weirdan/prophecy-shim": "^1.0 || ^2.0" }, "suggest": { "ext-igbinary": "^2.0.5" }, "bin": [ "psalm", "psalm-language-server", "psalm-plugin", "psalm-refactor", "psalter" ], "type": "library", "extra": { "branch-alias": { "dev-master": "4.x-dev", "dev-3.x": "3.x-dev", "dev-2.x": "2.x-dev", "dev-1.x": "1.x-dev" } }, "autoload": { "psr-4": { "Psalm\\": "src/Psalm/" }, "files": [ "src/functions.php", "src/spl_object_id.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Matthew Brown" } ], "description": "A static analysis tool for finding errors in PHP applications", "keywords": [ "code", "inspection", "php" ], "support": { "issues": "https://github.com/vimeo/psalm/issues", "source": "https://github.com/vimeo/psalm/tree/4.3.1" }, "time": "2020-12-03T16:44:10+00:00" }, { "name": "webimpress/coding-standard", "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/webimpress/coding-standard.git", "reference": "579818b431e2a2c8f24b60776598499782727897" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/webimpress/coding-standard/zipball/579818b431e2a2c8f24b60776598499782727897", "reference": "579818b431e2a2c8f24b60776598499782727897", "shasum": "" }, "require": { "php": "^7.3 || ^8.0", "squizlabs/php_codesniffer": "^3.5.8" }, "require-dev": { "phpunit/phpunit": "^9.4.3" }, "type": "phpcodesniffer-standard", "extra": { "dev-master": "1.2.x-dev", "dev-develop": "1.3.x-dev" }, "autoload": { "psr-4": { "WebimpressCodingStandard\\": "src/WebimpressCodingStandard/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-2-Clause" ], "description": "Webimpress Coding Standard", "keywords": [ "Coding Standard", "PSR-2", "phpcs", "psr-12", "webimpress" ], "support": { "issues": "https://github.com/webimpress/coding-standard/issues", "source": "https://github.com/webimpress/coding-standard/tree/1.2.0" }, "funding": [ { "url": "https://github.com/michalbundyra", "type": "github" } ], "time": "2020-11-27T20:16:01+00:00" }, { "name": "webmozart/assert", "version": "1.9.1", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", "shasum": "" }, "require": { "php": "^5.3.3 || ^7.0 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "phpstan/phpstan": "<0.12.20", "vimeo/psalm": "<3.9.1" }, "require-dev": { "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" } ], "description": "Assertions to validate method input/output with nice error messages.", "keywords": [ "assert", "check", "validate" ], "support": { "issues": "https://github.com/webmozart/assert/issues", "source": "https://github.com/webmozart/assert/tree/master" }, "time": "2020-07-08T17:02:28+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" }, "time": "2015-12-17T08:42:14+00:00" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { "php": "^7.4 || ~8.0.0" }, "platform-dev": { "ext-phar": "*" }, "plugin-api-version": "2.0.0" } src/DeclareStatement.php000064400000004737144760113020011301 0ustar00 'integer', self::STRICT_TYPES => 'integer', self::ENCODING => 'string', ]; protected string $directive; /** @var int|string */ protected $value; /** @param int|string $value */ private function __construct(string $directive, $value) { $this->directive = $directive; $this->value = $value; } public function getDirective(): string { return $this->directive; } /** * @return int|string */ public function getValue() { return $this->value; } public static function ticks(int $value): self { return new self(self::TICKS, $value); } public static function strictTypes(int $value): self { return new self(self::STRICT_TYPES, $value); } public static function encoding(string $value): self { return new self(self::ENCODING, $value); } public static function fromArray(array $config): self { $directive = key($config); $value = $config[$directive]; if (! isset(self::ALLOWED[$directive])) { throw new InvalidArgumentException( sprintf( 'Declare directive must be one of: %s.', implode(', ', array_keys(self::ALLOWED)) ) ); } if (gettype($value) !== self::ALLOWED[$directive]) { throw new InvalidArgumentException( sprintf( 'Declare value invalid. Expected %s, got %s.', self::ALLOWED[$directive], gettype($value) ) ); } $method = str_replace('_', '', lcfirst(ucwords($directive, '_'))); return self::{$method}($value); } public function getStatement(): string { $value = is_string($this->value) ? '\'' . $this->value . '\'' : $this->value; return sprintf('declare(%s=%s);', $this->directive, $value); } } src/Exception/BadMethodCallException.php000064400000000634144760113020014305 0ustar00setOptions($options); } } /** * @param bool $isSourceDirty * @return AbstractGenerator */ public function setSourceDirty($isSourceDirty = true) { $this->isSourceDirty = (bool) $isSourceDirty; return $this; } /** * @return bool */ public function isSourceDirty() { return $this->isSourceDirty; } /** * @param string $indentation * @return AbstractGenerator */ public function setIndentation($indentation) { $this->indentation = (string) $indentation; return $this; } /** * @return string */ public function getIndentation() { return $this->indentation; } /** * @param ?string $sourceContent * @return AbstractGenerator */ public function setSourceContent($sourceContent) { $this->sourceContent = (string) $sourceContent; return $this; } /** * @return ?string */ public function getSourceContent() { return $this->sourceContent; } /** * @param array|Traversable $options * @throws Exception\InvalidArgumentException * @return AbstractGenerator */ public function setOptions($options) { if (! is_array($options) && ! $options instanceof Traversable) { throw new Exception\InvalidArgumentException(sprintf( '%s expects an array or Traversable object; received "%s"', __METHOD__, is_object($options) ? get_class($options) : gettype($options) )); } foreach ($options as $optionName => $optionValue) { $methodName = 'set' . $optionName; if (method_exists($this, $methodName)) { $this->{$methodName}($optionValue); } } return $this; } } src/Generator/AbstractMemberGenerator.php000064400000013422144760113020014534 0ustar00flags = $flags; return $this; } /** * @param int $flag * @return AbstractMemberGenerator */ public function addFlag($flag) { $this->setFlags($this->flags | $flag); return $this; } /** * @param int $flag * @return AbstractMemberGenerator */ public function removeFlag($flag) { $this->setFlags($this->flags & ~$flag); return $this; } /** * @param bool $isAbstract * @return AbstractMemberGenerator */ public function setAbstract($isAbstract) { return $isAbstract ? $this->addFlag(self::FLAG_ABSTRACT) : $this->removeFlag(self::FLAG_ABSTRACT); } /** * @return bool */ public function isAbstract() { return (bool) ($this->flags & self::FLAG_ABSTRACT); } /** * @param bool $isInterface * @return AbstractMemberGenerator */ public function setInterface($isInterface) { return $isInterface ? $this->addFlag(self::FLAG_INTERFACE) : $this->removeFlag(self::FLAG_INTERFACE); } /** * @return bool */ public function isInterface() { return (bool) ($this->flags & self::FLAG_INTERFACE); } /** * @param bool $isFinal * @return AbstractMemberGenerator */ public function setFinal($isFinal) { return $isFinal ? $this->addFlag(self::FLAG_FINAL) : $this->removeFlag(self::FLAG_FINAL); } /** * @return bool */ public function isFinal() { return (bool) ($this->flags & self::FLAG_FINAL); } /** * @param bool $isStatic * @return AbstractMemberGenerator */ public function setStatic($isStatic) { return $isStatic ? $this->addFlag(self::FLAG_STATIC) : $this->removeFlag(self::FLAG_STATIC); } /** * @return bool */ public function isStatic() { return (bool) ($this->flags & self::FLAG_STATIC); // is FLAG_STATIC in flags } /** * @param string $visibility * @return AbstractMemberGenerator */ public function setVisibility($visibility) { switch ($visibility) { case self::VISIBILITY_PUBLIC: $this->removeFlag(self::FLAG_PRIVATE | self::FLAG_PROTECTED); // remove both $this->addFlag(self::FLAG_PUBLIC); break; case self::VISIBILITY_PROTECTED: $this->removeFlag(self::FLAG_PUBLIC | self::FLAG_PRIVATE); // remove both $this->addFlag(self::FLAG_PROTECTED); break; case self::VISIBILITY_PRIVATE: $this->removeFlag(self::FLAG_PUBLIC | self::FLAG_PROTECTED); // remove both $this->addFlag(self::FLAG_PRIVATE); break; } return $this; } /** * @return string */ public function getVisibility() { switch (true) { case $this->flags & self::FLAG_PROTECTED: return self::VISIBILITY_PROTECTED; case $this->flags & self::FLAG_PRIVATE: return self::VISIBILITY_PRIVATE; default: return self::VISIBILITY_PUBLIC; } } /** * @param string $name * @return AbstractMemberGenerator */ public function setName($name) { $this->name = (string) $name; return $this; } /** * @return string */ public function getName() { return $this->name; } /** * @param DocBlockGenerator|string $docBlock * @throws Exception\InvalidArgumentException * @return AbstractMemberGenerator */ public function setDocBlock($docBlock) { if (is_string($docBlock)) { $docBlock = new DocBlockGenerator($docBlock); } elseif (! $docBlock instanceof DocBlockGenerator) { throw new Exception\InvalidArgumentException(sprintf( '%s is expecting either a string, array or an instance of %s\DocBlockGenerator', __METHOD__, __NAMESPACE__ )); } $this->docBlock = $docBlock; return $this; } public function removeDocBlock(): void { $this->docBlock = null; } /** * @return DocBlockGenerator|null */ public function getDocBlock() { return $this->docBlock; } } src/Generator/BodyGenerator.php000064400000001474144760113020012542 0ustar00content = (string) $content; return $this; } /** * @return string */ public function getContent() { return $this->content; } /** * @return string */ public function generate() { return $this->getContent(); } } src/Generator/ClassGenerator.php000064400000073522144760113020012715 0ustar00 */ protected array $implementedInterfaces = []; /** @var PropertyGenerator[] */ protected array $properties = []; /** @var PropertyGenerator[] */ protected array $constants = []; /** @var MethodGenerator[] */ protected array $methods = []; /** @var TraitUsageGenerator Object to encapsulate trait usage logic */ protected TraitUsageGenerator $traitUsageGenerator; /** * Build a Code Generation Php Object from a Class Reflection * * @return static */ public static function fromReflection(ClassReflection $classReflection) { $cg = new static($classReflection->getName()); $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $cg->setDocBlock(DocBlockGenerator::fromReflection($classReflection->getDocBlock())); } $cg->setAbstract($classReflection->isAbstract()); // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } $parentClass = $classReflection->getParentClass(); $interfaces = $classReflection->getInterfaces(); if ($parentClass) { $cg->setExtendedClass($parentClass->getName()); $interfaces = array_diff($interfaces, $parentClass->getInterfaces()); } $interfaceNames = []; foreach ($interfaces as $interface) { $interfaceNames[] = $interface->getName(); } $cg->setImplementedInterfaces($interfaceNames); $properties = []; foreach ($classReflection->getProperties() as $reflectionProperty) { if ($reflectionProperty->getDeclaringClass()->getName() == $classReflection->getName()) { $properties[] = PropertyGenerator::fromReflection($reflectionProperty); } } $cg->addProperties($properties); $constants = []; foreach ($classReflection->getConstants() as $name => $value) { $constants[] = [ 'name' => $name, 'value' => $value, ]; } $cg->addConstants($constants); $methods = []; foreach ($classReflection->getMethods() as $reflectionMethod) { $className = $cg->getName(); $namespaceName = $cg->getNamespaceName(); if ($namespaceName !== null) { $className = $namespaceName . '\\' . $className; } if ($reflectionMethod->getDeclaringClass()->getName() == $className) { $methods[] = MethodGenerator::fromReflection($reflectionMethod); } } $cg->addMethods($methods); return $cg; } /** * Generate from array * * @configkey name string [required] Class Name * @configkey filegenerator FileGenerator File generator that holds this class * @configkey namespacename string The namespace for this class * @configkey docblock string The docblock information * @configkey flags int Flags, one of ClassGenerator::FLAG_ABSTRACT ClassGenerator::FLAG_FINAL * @configkey extendedclass string Class which this class is extending * @configkey implementedinterfaces * @configkey properties * @configkey methods * @throws Exception\InvalidArgumentException * @param array $array * @return self */ public static function fromArray(array $array) { if (! isset($array['name'])) { throw new Exception\InvalidArgumentException( 'Class generator requires that a name is provided for this object' ); } $cg = new static($array['name']); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'containingfile': $cg->setContainingFileGenerator($value); break; case 'namespacename': $cg->setNamespaceName($value); break; case 'docblock': $docBlock = $value instanceof DocBlockGenerator ? $value : DocBlockGenerator::fromArray($value); $cg->setDocBlock($docBlock); break; case 'flags': $cg->setFlags($value); break; case 'extendedclass': $cg->setExtendedClass($value); break; case 'implementedinterfaces': $cg->setImplementedInterfaces($value); break; case 'properties': $cg->addProperties($value); break; case 'methods': $cg->addMethods($value); break; } } return $cg; } /** * @param string $name * @param string $namespaceName * @param int|int[]|null $flags * @param class-string|null $extends * @param string[] $interfaces * @psalm-param array $interfaces * @param PropertyGenerator[]|string[]|array[] $properties * @param MethodGenerator[]|string[]|array[] $methods * @param DocBlockGenerator $docBlock */ public function __construct( $name = null, $namespaceName = null, $flags = null, $extends = null, array $interfaces = [], array $properties = [], array $methods = [], $docBlock = null ) { $this->traitUsageGenerator = new TraitUsageGenerator($this); if ($name !== null) { $this->setName($name); } if ($namespaceName !== null) { $this->setNamespaceName($namespaceName); } if ($flags !== null) { $this->setFlags($flags); } if ($properties !== []) { $this->addProperties($properties); } if ($extends !== null) { $this->setExtendedClass($extends); } if ($interfaces !== []) { $this->setImplementedInterfaces($interfaces); } if ($methods !== []) { $this->addMethods($methods); } if ($docBlock !== null) { $this->setDocBlock($docBlock); } } /** * @param string $name * @return self */ public function setName($name) { if (false !== strpos($name, '\\')) { $namespace = substr($name, 0, strrpos($name, '\\')); $name = substr($name, strrpos($name, '\\') + 1); $this->setNamespaceName($namespace); } $this->name = $name; return $this; } /** * @return string */ public function getName() { return $this->name; } /** * @param ?string $namespaceName * @return self */ public function setNamespaceName($namespaceName) { $this->namespaceName = $namespaceName; return $this; } /** * @return ?string */ public function getNamespaceName() { return $this->namespaceName; } /** * @return self */ public function setContainingFileGenerator(FileGenerator $fileGenerator) { $this->containingFileGenerator = $fileGenerator; return $this; } /** * @return ?FileGenerator */ public function getContainingFileGenerator() { return $this->containingFileGenerator; } /** * @return self */ public function setDocBlock(DocBlockGenerator $docBlock) { $this->docBlock = $docBlock; return $this; } /** * @return ?DocBlockGenerator */ public function getDocBlock() { return $this->docBlock; } /** * @param int[]|int $flags * @return self */ public function setFlags($flags) { if (is_array($flags)) { $flagsArray = $flags; $flags = 0x00; foreach ($flagsArray as $flag) { $flags |= $flag; } } // check that visibility is one of three $this->flags = $flags; return $this; } /** * @param int $flag * @return self */ public function addFlag($flag) { $this->setFlags($this->flags | $flag); return $this; } /** * @param int $flag * @return self */ public function removeFlag($flag) { $this->setFlags($this->flags & ~$flag); return $this; } /** * @param bool $isAbstract * @return self */ public function setAbstract($isAbstract) { return $isAbstract ? $this->addFlag(self::FLAG_ABSTRACT) : $this->removeFlag(self::FLAG_ABSTRACT); } /** * @return bool */ public function isAbstract() { return (bool) ($this->flags & self::FLAG_ABSTRACT); } /** * @param bool $isFinal * @return self */ public function setFinal($isFinal) { return $isFinal ? $this->addFlag(self::FLAG_FINAL) : $this->removeFlag(self::FLAG_FINAL); } /** * @return bool */ public function isFinal() { return (bool) ($this->flags & self::FLAG_FINAL); } /** * @param ?string $extendedClass * @psalm-param ?class-string $extendedClass * @return self */ public function setExtendedClass($extendedClass) { $this->extendedClass = $extendedClass; return $this; } /** * @return ?string * @psalm-return ?class-string */ public function getExtendedClass() { return $this->extendedClass; } /** * @return bool */ public function hasExtentedClass() { return ! empty($this->extendedClass); } /** * @return self */ public function removeExtentedClass() { $this->setExtendedClass(null); return $this; } /** * @param string[] $implementedInterfaces * @psalm-param array $implementedInterfaces * @return self */ public function setImplementedInterfaces(array $implementedInterfaces) { array_map(function ($implementedInterface) { // This loop is just validating that the given `$implementedInterfaces` contains valid syntax/symbols return TypeGenerator::fromTypeString($implementedInterface); }, $implementedInterfaces); $this->implementedInterfaces = $implementedInterfaces; return $this; } /** * @return string[] * @psalm-return array */ public function getImplementedInterfaces() { return $this->implementedInterfaces; } /** * @param string $implementedInterface * @psalm-param class-string $implementedInterface * @return bool */ public function hasImplementedInterface($implementedInterface) { $interfaceType = TypeGenerator::fromTypeString($implementedInterface); return (bool) array_filter( array_map([TypeGenerator::class, 'fromTypeString'], $this->implementedInterfaces), static fn (TypeGenerator $interface): bool => $interfaceType->equals($interface) ); } /** * @param string $implementedInterface * @psalm-param class-string $implementedInterface * @return self */ public function removeImplementedInterface($implementedInterface) { $interfaceType = TypeGenerator::fromTypeString($implementedInterface); $this->implementedInterfaces = array_filter( $this->implementedInterfaces, static fn (string $interface): bool => ! TypeGenerator::fromTypeString($interface)->equals($interfaceType) ); return $this; } /** * @param string $constantName * @return PropertyGenerator|false */ public function getConstant($constantName) { if (isset($this->constants[$constantName])) { return $this->constants[$constantName]; } return false; } /** * @return PropertyGenerator[] indexed by constant name */ public function getConstants() { return $this->constants; } /** * @param string $constantName * @return self */ public function removeConstant($constantName) { unset($this->constants[$constantName]); return $this; } /** * @param string $constantName * @return bool */ public function hasConstant($constantName) { return isset($this->constants[$constantName]); } /** * Add constant from PropertyGenerator * * @throws Exception\InvalidArgumentException * @return self */ public function addConstantFromGenerator(PropertyGenerator $constant) { $constantName = $constant->getName(); if (isset($this->constants[$constantName])) { throw new Exception\InvalidArgumentException(sprintf( 'A constant by name %s already exists in this class.', $constantName )); } if (! $constant->isConst()) { throw new Exception\InvalidArgumentException(sprintf( 'The value %s is not defined as a constant.', $constantName )); } $this->constants[$constantName] = $constant; return $this; } /** * Add Constant * * @param string $name Non-empty string * @param string|int|null|float|array $value Scalar * @throws Exception\InvalidArgumentException * @return self */ public function addConstant($name, $value) { if (empty($name) || ! is_string($name)) { throw new Exception\InvalidArgumentException(sprintf( '%s expects string for name', __METHOD__ )); } $this->validateConstantValue($value); return $this->addConstantFromGenerator( new PropertyGenerator($name, new PropertyValueGenerator($value), PropertyGenerator::FLAG_CONSTANT) ); } /** * @param PropertyGenerator[]|array[] $constants * @return self */ public function addConstants(array $constants) { foreach ($constants as $constant) { if ($constant instanceof PropertyGenerator) { $this->addPropertyFromGenerator($constant); } else { if (is_array($constant)) { $this->addConstant(...array_values($constant)); } } } return $this; } /** * @param PropertyGenerator[]|string[]|array[] $properties * @return self */ public function addProperties(array $properties) { foreach ($properties as $property) { if ($property instanceof PropertyGenerator) { $this->addPropertyFromGenerator($property); } elseif (is_string($property)) { $this->addProperty($property); } else { $this->addProperty(...array_values($property)); } } return $this; } /** * Add Property from scalars * * @param string $name * @param string|array $defaultValue * @param int $flags * @throws Exception\InvalidArgumentException * @return self */ public function addProperty($name, $defaultValue = null, $flags = PropertyGenerator::FLAG_PUBLIC) { if (! is_string($name)) { throw new Exception\InvalidArgumentException(sprintf( '%s::%s expects string for name', static::class, __FUNCTION__ )); } // backwards compatibility // @todo remove this on next major version if ($flags === PropertyGenerator::FLAG_CONSTANT) { return $this->addConstant($name, $defaultValue); } return $this->addPropertyFromGenerator(new PropertyGenerator($name, $defaultValue, $flags)); } /** * Add property from PropertyGenerator * * @throws Exception\InvalidArgumentException * @return self */ public function addPropertyFromGenerator(PropertyGenerator $property) { $propertyName = $property->getName(); if (isset($this->properties[$propertyName])) { throw new Exception\InvalidArgumentException(sprintf( 'A property by name %s already exists in this class.', $propertyName )); } // backwards compatibility // @todo remove this on next major version if ($property->isConst()) { return $this->addConstantFromGenerator($property); } $this->properties[$propertyName] = $property; return $this; } /** * @return PropertyGenerator[] */ public function getProperties() { return $this->properties; } /** * @param string $propertyName * @return PropertyGenerator|false */ public function getProperty($propertyName) { foreach ($this->getProperties() as $property) { if ($property->getName() == $propertyName) { return $property; } } return false; } /** * Add a class to "use" classes * * @param string $use * @param string|null $useAlias * @return self */ public function addUse($use, $useAlias = null) { $this->traitUsageGenerator->addUse($use, $useAlias); return $this; } /** * @param string $use * @return bool */ public function hasUse($use) { return $this->traitUsageGenerator->hasUse($use); } /** * @param string $use * @return self */ public function removeUse($use) { $this->traitUsageGenerator->removeUse($use); return $this; } /** * @param string $use * @return bool */ public function hasUseAlias($use) { return $this->traitUsageGenerator->hasUseAlias($use); } /** * @param string $use * @return self */ public function removeUseAlias($use) { $this->traitUsageGenerator->removeUseAlias($use); return $this; } /** * Returns the "use" classes * * @return array */ public function getUses() { return $this->traitUsageGenerator->getUses(); } /** * @param string $propertyName * @return self */ public function removeProperty($propertyName) { unset($this->properties[$propertyName]); return $this; } /** * @param string $propertyName * @return bool */ public function hasProperty($propertyName) { return isset($this->properties[$propertyName]); } /** * @param MethodGenerator[]|string[]|array[] $methods * @return self */ public function addMethods(array $methods) { foreach ($methods as $method) { if ($method instanceof MethodGenerator) { $this->addMethodFromGenerator($method); } elseif (is_string($method)) { $this->addMethod($method); } else { $this->addMethod(...array_values($method)); } } return $this; } /** * Add Method from scalars * * @param string $name * @param ParameterGenerator[]|array[]|string[] $parameters * @param int $flags * @param string $body * @param string $docBlock * @throws Exception\InvalidArgumentException * @return self */ public function addMethod( $name, array $parameters = [], $flags = MethodGenerator::FLAG_PUBLIC, $body = null, $docBlock = null ) { if (! is_string($name)) { throw new Exception\InvalidArgumentException(sprintf( '%s::%s expects string for name', static::class, __FUNCTION__ )); } return $this->addMethodFromGenerator(new MethodGenerator($name, $parameters, $flags, $body, $docBlock)); } /** * Add Method from MethodGenerator * * @throws Exception\InvalidArgumentException * @return self */ public function addMethodFromGenerator(MethodGenerator $method) { $methodName = $method->getName(); if ($this->hasMethod($methodName)) { throw new Exception\InvalidArgumentException(sprintf( 'A method by name %s already exists in this class.', $methodName )); } $this->methods[strtolower($methodName)] = $method; return $this; } /** * @return MethodGenerator[] */ public function getMethods() { return $this->methods; } /** * @param string $methodName * @return MethodGenerator|false */ public function getMethod($methodName) { return $this->hasMethod($methodName) ? $this->methods[strtolower($methodName)] : false; } /** * @param string $methodName * @return self */ public function removeMethod($methodName) { unset($this->methods[strtolower($methodName)]); return $this; } /** * @param string $methodName * @return bool */ public function hasMethod($methodName) { return isset($this->methods[strtolower($methodName)]); } /** * @inheritDoc */ public function addTrait($trait) { $this->traitUsageGenerator->addTrait($trait); return $this; } /** * @inheritDoc */ public function addTraits(array $traits) { $this->traitUsageGenerator->addTraits($traits); return $this; } /** * @inheritDoc */ public function hasTrait($traitName) { return $this->traitUsageGenerator->hasTrait($traitName); } /** * @inheritDoc */ public function getTraits() { return $this->traitUsageGenerator->getTraits(); } /** * @inheritDoc */ public function removeTrait($traitName) { return $this->traitUsageGenerator->removeTrait($traitName); } /** * @inheritDoc */ public function addTraitAlias($method, $alias, $visibility = null) { $this->traitUsageGenerator->addTraitAlias($method, $alias, $visibility); return $this; } /** * @inheritDoc */ public function getTraitAliases() { return $this->traitUsageGenerator->getTraitAliases(); } /** * @inheritDoc */ public function addTraitOverride($method, $traitsToReplace) { $this->traitUsageGenerator->addTraitOverride($method, $traitsToReplace); return $this; } /** * @inheritDoc */ public function removeTraitOverride($method, $overridesToRemove = null) { $this->traitUsageGenerator->removeTraitOverride($method, $overridesToRemove); return $this; } /** * @inheritDoc */ public function getTraitOverrides() { return $this->traitUsageGenerator->getTraitOverrides(); } /** * @return bool */ public function isSourceDirty() { if (($docBlock = $this->getDocBlock()) && $docBlock->isSourceDirty()) { return true; } foreach ($this->getProperties() as $property) { if ($property->isSourceDirty()) { return true; } } foreach ($this->getMethods() as $method) { if ($method->isSourceDirty()) { return true; } } return parent::isSourceDirty(); } /** * @inheritDoc */ public function generate() { if (! $this->isSourceDirty()) { $output = $this->getSourceContent(); if (! empty($output)) { return $output; } } $indent = $this->getIndentation(); $output = ''; if (null !== ($namespace = $this->getNamespaceName())) { $output .= 'namespace ' . $namespace . ';' . self::LINE_FEED . self::LINE_FEED; } $uses = $this->getUses(); if (! empty($uses)) { foreach ($uses as $use) { $output .= 'use ' . $use . ';' . self::LINE_FEED; } $output .= self::LINE_FEED; } if (null !== ($docBlock = $this->getDocBlock())) { $docBlock->setIndentation(''); $output .= $docBlock->generate(); } if ($this->isAbstract()) { $output .= 'abstract '; } elseif ($this->isFinal()) { $output .= 'final '; } $output .= static::OBJECT_TYPE . ' ' . $this->getName(); if (! empty($this->extendedClass)) { $output .= ' extends ' . $this->generateShortOrCompleteClassname($this->extendedClass); } $implemented = $this->getImplementedInterfaces(); if (! empty($implemented)) { $implemented = array_map([$this, 'generateShortOrCompleteClassname'], $implemented); $output .= ' ' . static::IMPLEMENTS_KEYWORD . ' ' . implode(', ', $implemented); } $output .= self::LINE_FEED . '{' . self::LINE_FEED; $traitUseOutput = rtrim($this->traitUsageGenerator->generate(), self::LINE_FEED); $constants = []; $properties = []; $methods = []; foreach ($this->getConstants() as $constant) { $constants[] = $constant->generate(); } foreach ($this->getProperties() as $property) { $properties[] = $property->generate(); } foreach ($this->getMethods() as $method) { $methods[] = $method->generate(); } $contents = rtrim( implode( self::LINE_FEED . self::LINE_FEED, array_filter([ $traitUseOutput, implode(self::LINE_FEED . self::LINE_FEED, $constants), implode(self::LINE_FEED . self::LINE_FEED, $properties), implode(self::LINE_FEED, $methods), ]) ), self::LINE_FEED ); return $output . $contents . ($contents === '' ? '' : self::LINE_FEED) . '}' . self::LINE_FEED; } /** * @param mixed $value * @return void * @throws Exception\InvalidArgumentException */ private function validateConstantValue($value) { if (null === $value || is_scalar($value)) { return; } if (is_array($value)) { array_walk($value, [$this, 'validateConstantValue']); return; } throw new Exception\InvalidArgumentException(sprintf( 'Expected value for constant, value must be a "scalar" or "null", "%s" found', gettype($value) )); } /** * @param string $fqnClassName * @return string */ private function generateShortOrCompleteClassname($fqnClassName) { $fqnClassName = ltrim($fqnClassName, '\\'); $parts = explode('\\', $fqnClassName); $className = array_pop($parts); $classNamespace = implode('\\', $parts); $currentNamespace = (string) $this->getNamespaceName(); if ($this->hasUseAlias($fqnClassName)) { return $this->traitUsageGenerator->getUseAlias($fqnClassName); } if ($this->hasUseAlias($classNamespace)) { $namespaceAlias = $this->traitUsageGenerator->getUseAlias($classNamespace); return $namespaceAlias . '\\' . $className; } if ($this->traitUsageGenerator->isUseAlias($fqnClassName)) { return $fqnClassName; } if ($this->traitUsageGenerator->isUseAlias($classNamespace)) { return $fqnClassName; } if ($classNamespace === $currentNamespace || in_array($fqnClassName, $this->getUses())) { return $className; } return '\\' . $fqnClassName; } } src/Generator/DocBlock/Tag.php000064400000002570144760113020012167 0ustar00initializeDefaultTags(); return $tagManager->createTagFromReflection($reflectionTag); } /** * @deprecated Deprecated in 2.3. Use GenericTag::setContent() instead * * @param string $description * @return Tag */ public function setDescription($description) { return $this->setContent($description); } /** * @deprecated Deprecated in 2.3. Use GenericTag::getContent() instead * * @return string */ public function getDescription() { return $this->getContent(); } } src/Generator/DocBlock/Tag/AbstractTypeableTag.php000064400000004165144760113020016056 0ustar00setTypes($types); } if (! empty($description)) { $this->setDescription($description); } } /** * @param string $description * @return AbstractTypeableTag */ public function setDescription($description) { $this->description = $description; return $this; } /** * @return string */ public function getDescription() { return $this->description; } /** * Array of types or string with types delimited by pipe (|) * e.g. array('int', 'null') or "int|null" * * @param array|string $types * @return AbstractTypeableTag */ public function setTypes($types) { if (is_string($types)) { $types = explode('|', $types); } $this->types = $types; return $this; } /** * @return array */ public function getTypes() { return $this->types; } /** * @param string $delimiter * @return string */ public function getTypesAsString($delimiter = '|') { return implode($delimiter, $this->types); } } src/Generator/DocBlock/Tag/AuthorTag.php000064400000004600144760113020014061 0ustar00setAuthorName($authorName); } if (! empty($authorEmail)) { $this->setAuthorEmail($authorEmail); } } /** * @deprecated Deprecated in 2.3. Use TagManager::createTagFromReflection() instead * * @return AuthorTag */ public static function fromReflection(ReflectionTagInterface $reflectionTag) { $tagManager = new TagManager(); $tagManager->initializeDefaultTags(); return $tagManager->createTagFromReflection($reflectionTag); } /** * @return string */ public function getName() { return 'author'; } /** * @param string $authorEmail * @return AuthorTag */ public function setAuthorEmail($authorEmail) { $this->authorEmail = $authorEmail; return $this; } /** * @return string */ public function getAuthorEmail() { return $this->authorEmail; } /** * @param string $authorName * @return AuthorTag */ public function setAuthorName($authorName) { $this->authorName = $authorName; return $this; } /** * @return string */ public function getAuthorName() { return $this->authorName; } /** * @return string */ public function generate() { return '@author' . (! empty($this->authorName) ? ' ' . $this->authorName : '') . (! empty($this->authorEmail) ? ' <' . $this->authorEmail . '>' : ''); } } src/Generator/DocBlock/Tag/GenericTag.php000064400000003277144760113020014204 0ustar00setName($name); } if (! empty($content)) { $this->setContent($content); } } /** * @param string $name * @return GenericTag */ public function setName($name) { $this->name = ltrim($name, '@'); return $this; } /** * @return string */ public function getName() { return $this->name; } /** * @param string $content * @return GenericTag */ public function setContent($content) { $this->content = $content; return $this; } /** * @return string */ public function getContent() { return $this->content; } /** * @return string */ public function generate() { return '@' . $this->name . (! empty($this->content) ? ' ' . $this->content : ''); } } src/Generator/DocBlock/Tag/LicenseTag.php000064400000004401144760113020014200 0ustar00setUrl($url); } if (! empty($licenseName)) { $this->setLicenseName($licenseName); } } /** * @deprecated Deprecated in 2.3. Use TagManager::createTagFromReflection() instead * * @return ReturnTag */ public static function fromReflection(ReflectionTagInterface $reflectionTag) { $tagManager = new TagManager(); $tagManager->initializeDefaultTags(); return $tagManager->createTagFromReflection($reflectionTag); } /** * @return string */ public function getName() { return 'license'; } /** * @param string $url * @return LicenseTag */ public function setUrl($url) { $this->url = $url; return $this; } /** * @return string */ public function getUrl() { return $this->url; } /** * @param string $name * @return LicenseTag */ public function setLicenseName($name) { $this->licenseName = $name; return $this; } /** * @return string */ public function getLicenseName() { return $this->licenseName; } /** * @return string */ public function generate() { return '@license' . (! empty($this->url) ? ' ' . $this->url : '') . (! empty($this->licenseName) ? ' ' . $this->licenseName : ''); } } src/Generator/DocBlock/Tag/MethodTag.php000064400000004062144760113020014041 0ustar00setMethodName($methodName); } $this->setIsStatic((bool) $isStatic); parent::__construct($types, $description); } /** * @return string */ public function getName() { return 'method'; } /** * @param bool $isStatic * @return MethodTag */ public function setIsStatic($isStatic) { $this->isStatic = $isStatic; return $this; } /** * @return bool */ public function isStatic() { return $this->isStatic; } /** * @param string $methodName * @return MethodTag */ public function setMethodName($methodName) { $this->methodName = rtrim($methodName, ')('); return $this; } /** * @return string */ public function getMethodName() { return $this->methodName; } /** * @return string */ public function generate() { return '@method' . ($this->isStatic ? ' static' : '') . (! empty($this->types) ? ' ' . $this->getTypesAsString() : '') . (! empty($this->methodName) ? ' ' . $this->methodName . '()' : '') . (! empty($this->description) ? ' ' . $this->description : ''); } } src/Generator/DocBlock/Tag/ParamTag.php000064400000005751144760113020013667 0ustar00setVariableName($variableName); } parent::__construct($types, $description); } /** * @deprecated Deprecated in 2.3. Use TagManager::createTagFromReflection() instead * * @return ParamTag */ public static function fromReflection(ReflectionTagInterface $reflectionTag) { $tagManager = new TagManager(); $tagManager->initializeDefaultTags(); return $tagManager->createTagFromReflection($reflectionTag); } /** * @return string */ public function getName() { return 'param'; } /** * @param string $variableName * @return ParamTag */ public function setVariableName($variableName) { $this->variableName = ltrim($variableName, '$'); return $this; } /** * @return string */ public function getVariableName() { return $this->variableName; } /** * @deprecated Deprecated in 2.3. Use setTypes() instead * * @param string $datatype * @return ParamTag */ public function setDatatype($datatype) { return $this->setTypes($datatype); } /** * @deprecated Deprecated in 2.3. Use getTypes() or getTypesAsString() instead * * @return string */ public function getDatatype() { return $this->getTypesAsString(); } /** * @deprecated Deprecated in 2.3. Use setVariableName() instead * * @param string $paramName * @return ParamTag */ public function setParamName($paramName) { return $this->setVariableName($paramName); } /** * @deprecated Deprecated in 2.3. Use getVariableName() instead * * @return string */ public function getParamName() { return $this->getVariableName(); } /** * @return string */ public function generate() { return '@param' . (! empty($this->types) ? ' ' . $this->getTypesAsString() : '') . (! empty($this->variableName) ? ' $' . $this->variableName : '') . (! empty($this->description) ? ' ' . $this->description : ''); } } src/Generator/DocBlock/Tag/PropertyTag.php000064400000003132144760113020014442 0ustar00setPropertyName($propertyName); } parent::__construct($types, $description); } /** * @return string */ public function getName() { return 'property'; } /** * @param string $propertyName * @return self */ public function setPropertyName($propertyName) { $this->propertyName = ltrim($propertyName, '$'); return $this; } /** * @return string */ public function getPropertyName() { return $this->propertyName; } /** * @return string */ public function generate() { return '@property' . (! empty($this->types) ? ' ' . $this->getTypesAsString() : '') . (! empty($this->propertyName) ? ' $' . $this->propertyName : '') . (! empty($this->description) ? ' ' . $this->description : ''); } } src/Generator/DocBlock/Tag/ReturnTag.php000064400000003233144760113020014077 0ustar00initializeDefaultTags(); return $tagManager->createTagFromReflection($reflectionTag); } /** * @return string */ public function getName() { return 'return'; } /** * @deprecated Deprecated in 2.3. Use setTypes() instead * * @param string $datatype * @return ReturnTag */ public function setDatatype($datatype) { return $this->setTypes($datatype); } /** * @deprecated Deprecated in 2.3. Use getTypes() or getTypesAsString() instead * * @return string */ public function getDatatype() { return $this->getTypesAsString(); } /** * @return string */ public function generate() { return '@return ' . $this->getTypesAsString() . (! empty($this->description) ? ' ' . $this->description : ''); } } src/Generator/DocBlock/Tag/TagInterface.php000064400000000664144760113020014525 0ustar00types) ? ' ' . $this->getTypesAsString() : '') . (! empty($this->description) ? ' ' . $this->description : ''); } } src/Generator/DocBlock/Tag/VarTag.php000064400000003274144760113020013355 0ustar00variableName = ltrim($variableName, '$'); } parent::__construct($types, $description); } /** * {@inheritDoc} */ public function getName(): string { return 'var'; } /** * @internal this code is only public for compatibility with the * * @see \Laminas\Code\Generator\DocBlock\TagManager, which * uses setters */ public function setVariableName(?string $variableName): void { if (null !== $variableName) { $this->variableName = ltrim($variableName, '$'); } } public function getVariableName(): ?string { return $this->variableName; } /** * {@inheritDoc} */ public function generate(): string { return '@var' . (! empty($this->types) ? ' ' . $this->getTypesAsString() : '') . (null !== $this->variableName ? ' $' . $this->variableName : '') . (! empty($this->description) ? ' ' . $this->description : ''); } } src/Generator/DocBlock/TagManager.php000064400000005243144760113020013462 0ustar00addPrototype(new Tag\ParamTag()); $this->addPrototype(new Tag\ReturnTag()); $this->addPrototype(new Tag\MethodTag()); $this->addPrototype(new Tag\PropertyTag()); $this->addPrototype(new Tag\AuthorTag()); $this->addPrototype(new Tag\LicenseTag()); $this->addPrototype(new Tag\ThrowsTag()); $this->addPrototype(new Tag\VarTag()); $this->setGenericPrototype(new Tag\GenericTag()); } /** * @return TagInterface */ public function createTagFromReflection(ReflectionTagInterface $reflectionTag) { $tagName = $reflectionTag->getName(); /** @var TagInterface $newTag */ $newTag = $this->getClonedPrototype($tagName); // transport any properties via accessors and mutators from reflection to codegen object $reflectionClass = new ReflectionClass($reflectionTag); foreach ($reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { if (0 === strpos($method->getName(), 'get')) { $propertyName = substr($method->getName(), 3); if (method_exists($newTag, 'set' . $propertyName)) { $newTag->{'set' . $propertyName}($reflectionTag->{'get' . $propertyName}()); } } elseif (0 === strpos($method->getName(), 'is')) { $propertyName = ucfirst($method->getName()); if (method_exists($newTag, 'set' . $propertyName)) { $newTag->{'set' . $propertyName}($reflectionTag->{$method->getName()}()); } } } return $newTag; } } src/Generator/DocBlockGenerator.php000064400000015701144760113020013323 0ustar00setSourceContent($reflectionDocBlock->getContents()); $docBlock->setSourceDirty(false); $docBlock->setShortDescription($reflectionDocBlock->getShortDescription()); $docBlock->setLongDescription($reflectionDocBlock->getLongDescription()); foreach ($reflectionDocBlock->getTags() as $tag) { $docBlock->setTag(self::getTagManager()->createTagFromReflection($tag)); } return $docBlock; } /** * Generate from array * * @configkey shortdescription string The short description for this doc block * @configkey longdescription string The long description for this doc block * @configkey tags array * @throws Exception\InvalidArgumentException * @param array $array * @return DocBlockGenerator */ public static function fromArray(array $array) { $docBlock = new static(); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'shortdescription': $docBlock->setShortDescription($value); break; case 'longdescription': $docBlock->setLongDescription($value); break; case 'tags': $docBlock->setTags($value); break; } } return $docBlock; } /** * @return TagManager */ protected static function getTagManager() { if (! isset(static::$tagManager)) { static::$tagManager = new TagManager(); static::$tagManager->initializeDefaultTags(); } return static::$tagManager; } /** * @param ?string $shortDescription * @param ?string $longDescription * @param array[]|TagInterface[] $tags */ public function __construct($shortDescription = null, $longDescription = null, array $tags = []) { if ($shortDescription) { $this->setShortDescription($shortDescription); } if ($longDescription) { $this->setLongDescription($longDescription); } if ($tags) { $this->setTags($tags); } } /** * @param string $shortDescription * @return DocBlockGenerator */ public function setShortDescription($shortDescription) { $this->shortDescription = $shortDescription; return $this; } /** * @return string */ public function getShortDescription() { return $this->shortDescription; } /** * @param string $longDescription * @return DocBlockGenerator */ public function setLongDescription($longDescription) { $this->longDescription = $longDescription; return $this; } /** * @return string */ public function getLongDescription() { return $this->longDescription; } /** * @param array[]|TagInterface[] $tags * @return DocBlockGenerator */ public function setTags(array $tags) { foreach ($tags as $tag) { $this->setTag($tag); } return $this; } /** * @param array|TagInterface $tag * @throws Exception\InvalidArgumentException * @return DocBlockGenerator */ public function setTag($tag) { if (is_array($tag)) { // use deprecated Tag class for backward compatibility to old array-keys $genericTag = new Tag(); $genericTag->setOptions($tag); $tag = $genericTag; } elseif (! $tag instanceof TagInterface) { throw new Exception\InvalidArgumentException(sprintf( '%s expects either an array of method options or an instance of %s\DocBlock\Tag\TagInterface', __METHOD__, __NAMESPACE__ )); } $this->tags[] = $tag; return $this; } /** * @return TagInterface[] */ public function getTags() { return $this->tags; } /** * @param bool $value * @return DocBlockGenerator */ public function setWordWrap($value) { $this->wordwrap = (bool) $value; return $this; } /** * @return bool */ public function getWordWrap() { return $this->wordwrap; } /** * @return string */ public function generate() { if (! $this->isSourceDirty()) { return $this->docCommentize(trim($this->getSourceContent() ?? '')); } $output = ''; if ($sd = $this->getShortDescription()) { $output .= $sd . self::LINE_FEED . self::LINE_FEED; } if ($ld = $this->getLongDescription()) { $output .= $ld . self::LINE_FEED . self::LINE_FEED; } /** @var GeneratorInterface $tag */ foreach ($this->getTags() as $tag) { $output .= $tag->generate() . self::LINE_FEED; } return $this->docCommentize(trim($output)); } /** * @param string $content * @return string */ protected function docCommentize($content) { $indent = $this->getIndentation(); $output = $indent . '/**' . self::LINE_FEED; $content = $this->getWordWrap() == true ? wordwrap($content, 80, self::LINE_FEED) : $content; $lines = explode(self::LINE_FEED, $content); foreach ($lines as $line) { $output .= $indent . ' *'; if ($line) { $output .= ' ' . $line; } $output .= self::LINE_FEED; } $output .= $indent . ' */' . self::LINE_FEED; return $output; } } src/Generator/Exception/ClassNotFoundException.php000064400000000637144760113020016335 0ustar00 */ protected array $uses = []; /** * @var ClassGenerator[] * @psalm-var array */ protected array $classes = []; protected string $body = ''; /** * @var DeclareStatement[] * @psalm-var array */ protected array $declares = []; /** * Passes $options to {@link setOptions()}. * * @param array|Traversable|null $options */ public function __construct($options = null) { if (null !== $options) { $this->setOptions($options); } } /** * @param array $values * @return FileGenerator */ public static function fromArray(array $values) { $fileGenerator = new static(); foreach ($values as $name => $value) { switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'filename': $fileGenerator->setFilename($value); break; case 'class': $fileGenerator->setClass( $value instanceof ClassGenerator ? $value : ClassGenerator::fromArray($value) ); break; case 'requiredfiles': $fileGenerator->setRequiredFiles($value); break; case 'declares': $fileGenerator->setDeclares(array_map(static function ($directive, $value) { return DeclareStatement::fromArray([$directive => $value]); }, array_keys($value), $value)); break; default: if (property_exists($fileGenerator, $name)) { $fileGenerator->{$name} = $value; } elseif (method_exists($fileGenerator, 'set' . $name)) { $fileGenerator->{'set' . $name}($value); } } } return $fileGenerator; } /** * @param DocBlockGenerator|array|string $docBlock * @throws Exception\InvalidArgumentException * @return FileGenerator */ public function setDocBlock($docBlock) { if (is_string($docBlock)) { $docBlock = ['shortDescription' => $docBlock]; } if (is_array($docBlock)) { $docBlock = new DocBlockGenerator($docBlock); } elseif (! $docBlock instanceof DocBlockGenerator) { throw new Exception\InvalidArgumentException(sprintf( '%s is expecting either a string, array or an instance of %s\DocBlockGenerator', __METHOD__, __NAMESPACE__ )); } $this->docBlock = $docBlock; return $this; } /** * @return ?DocBlockGenerator */ public function getDocBlock() { return $this->docBlock; } /** * @param string[] $requiredFiles * @return FileGenerator */ public function setRequiredFiles(array $requiredFiles) { $this->requiredFiles = $requiredFiles; return $this; } /** * @return string[] */ public function getRequiredFiles() { return $this->requiredFiles; } /** * @return string */ public function getNamespace() { return $this->namespace; } /** * @param string $namespace * @return FileGenerator */ public function setNamespace($namespace) { $this->namespace = (string) $namespace; return $this; } /** * Returns an array with the first element the use statement, second is the as part. * If $withResolvedAs is set to true, there will be a third element that is the * "resolved" as statement, as the second part is not required in use statements * * @param bool $withResolvedAs * @return array * @psalm-return array */ public function getUses($withResolvedAs = false) { $uses = $this->uses; if ($withResolvedAs) { for ($useIndex = 0, $count = count($uses); $useIndex < $count; $useIndex++) { if ($uses[$useIndex][1] == '') { if (($lastSeparator = strrpos($uses[$useIndex][0], '\\')) !== false) { $uses[$useIndex][2] = substr($uses[$useIndex][0], $lastSeparator + 1); } else { $uses[$useIndex][2] = $uses[$useIndex][0]; } } else { $uses[$useIndex][2] = $uses[$useIndex][1]; } } } return $uses; } /** * @param array $uses * @return FileGenerator */ public function setUses(array $uses) { foreach ($uses as $use) { $use = (array) $use; if (array_key_exists('use', $use) && array_key_exists('as', $use)) { $import = $use['use']; $alias = $use['as']; } elseif (count($use) == 2) { [$import, $alias] = $use; } else { $import = current($use); $alias = null; } $this->setUse($import, $alias); } return $this; } /** * @param string $use * @param null|string $as * @return FileGenerator */ public function setUse($use, $as = null) { if (! in_array([$use, $as], $this->uses)) { $this->uses[] = [$use, $as]; } return $this; } /** * @param array[]|string[]|ClassGenerator[] $classes * @return FileGenerator */ public function setClasses(array $classes) { foreach ($classes as $class) { $this->setClass($class); } return $this; } /** * @param string|null $name * @return ClassGenerator * @throws ClassNotFoundException */ public function getClass($name = null) { if ($name === null) { reset($this->classes); $class = current($this->classes); if (false === $class) { throw new ClassNotFoundException('No class is set'); } return $class; } if (false === array_key_exists($name, $this->classes)) { throw new ClassNotFoundException(sprintf('Class %s is not set', $name)); } return $this->classes[$name]; } /** * @param array|string|ClassGenerator $class * @throws Exception\InvalidArgumentException * @return FileGenerator */ public function setClass($class) { if (is_array($class)) { $class = ClassGenerator::fromArray($class); } elseif (is_string($class)) { $class = new ClassGenerator($class); } elseif (! $class instanceof ClassGenerator) { throw new Exception\InvalidArgumentException(sprintf( '%s is expecting either a string, array or an instance of %s\ClassGenerator', __METHOD__, __NAMESPACE__ )); } // @todo check for dup here $className = $class->getName(); $this->classes[$className] = $class; return $this; } /** * @param string $filename * @return FileGenerator */ public function setFilename($filename) { $this->filename = (string) $filename; return $this; } /** * @return string */ public function getFilename() { return $this->filename; } /** * @return ClassGenerator[] */ public function getClasses() { return $this->classes; } /** * @param string $body * @return FileGenerator */ public function setBody($body) { $this->body = (string) $body; return $this; } /** * @return string */ public function getBody() { return $this->body; } /** * @param DeclareStatement[] $declares * @return static */ public function setDeclares(array $declares) { foreach ($declares as $declare) { /** @psalm-suppress DocblockTypeContradiction $declare should be always DeclareStatement */ if (! $declare instanceof DeclareStatement) { throw new InvalidArgumentException(sprintf( '%s is expecting an array of %s objects', __METHOD__, DeclareStatement::class )); } if (! array_key_exists($declare->getDirective(), $this->declares)) { $this->declares[$declare->getDirective()] = $declare; } } return $this; } /** * @return bool */ public function isSourceDirty() { $docBlock = $this->getDocBlock(); if ($docBlock && $docBlock->isSourceDirty()) { return true; } foreach ($this->classes as $class) { if ($class->isSourceDirty()) { return true; } } return parent::isSourceDirty(); } /** * @return string */ public function generate() { if ($this->isSourceDirty() === false) { return $this->sourceContent ?? ''; } $output = ''; // @note body gets populated when FileGenerator created // from a file. @see fromReflection and may also be set // via FileGenerator::setBody $body = $this->getBody(); // start with the body (if there), or open tag if (preg_match('#(?:\s*)<\?php#', $body) == false) { $output = 'getDocBlock())) { $docBlock->setIndentation(''); if (preg_match('#/\* Laminas_Code_Generator_FileGenerator-DocBlockMarker \*/#m', $output)) { // @codingStandardsIgnoreStart $output = preg_replace('#/\* Laminas_Code_Generator_FileGenerator-DocBlockMarker \*/#m', $docBlock->generate(), $output, 1); // @codingStandardsIgnoreEnd } else { $output .= $docBlock->generate() . self::LINE_FEED; } } // newline $output .= self::LINE_FEED; // declares, if any if ($this->declares) { $declareStatements = ''; foreach ($this->declares as $declare) { $declareStatements .= $declare->getStatement() . self::LINE_FEED; } if (preg_match('#/\* Laminas_Code_Generator_FileGenerator-DeclaresMarker \*/#m', $output)) { $output = preg_replace( '#/\* Laminas_Code_Generator_FileGenerator-DeclaresMarker \*/#m', $declareStatements, $output, 1 ); } else { $output .= $declareStatements; } $output .= self::LINE_FEED; } // namespace, if any $namespace = $this->getNamespace(); if ($namespace) { $namespace = sprintf('namespace %s;%s', $namespace, str_repeat(self::LINE_FEED, 2)); if (preg_match('#/\* Laminas_Code_Generator_FileGenerator-NamespaceMarker \*/#m', $output)) { $output = preg_replace( '#/\* Laminas_Code_Generator_FileGenerator-NamespaceMarker \*/#m', $namespace, $output, 1 ); } else { $output .= $namespace; } } // process required files // @todo marker replacement for required files $requiredFiles = $this->getRequiredFiles(); if (! empty($requiredFiles)) { foreach ($requiredFiles as $requiredFile) { $output .= 'require_once \'' . $requiredFile . '\';' . self::LINE_FEED; } $output .= self::LINE_FEED; } $classes = $this->getClasses(); $classUses = []; //build uses array foreach ($classes as $class) { //check for duplicate use statements $uses = $class->getUses(); if (! empty($uses) && is_array($uses)) { $classUses = array_merge($classUses, $uses); } } // process import statements $uses = $this->getUses(); if (! empty($uses)) { $useOutput = ''; foreach ($uses as $use) { [$import, $alias] = $use; if (null === $alias) { $tempOutput = sprintf('%s', $import); } else { $tempOutput = sprintf('%s as %s', $import, $alias); } //don't duplicate use statements if (! in_array($tempOutput, $classUses)) { $useOutput .= 'use ' . $tempOutput . ';'; $useOutput .= self::LINE_FEED; } } $useOutput .= self::LINE_FEED; if (preg_match('#/\* Laminas_Code_Generator_FileGenerator-UseMarker \*/#m', $output)) { $output = preg_replace( '#/\* Laminas_Code_Generator_FileGenerator-UseMarker \*/#m', $useOutput, $output, 1 ); } else { $output .= $useOutput; } } // process classes if (! empty($classes)) { foreach ($classes as $class) { // @codingStandardsIgnoreStart $regex = str_replace('&', $class->getName(), '/\* Laminas_Code_Generator_Php_File-ClassMarker: \{[A-Za-z0-9\\\]+?&\} \*/'); // @codingStandardsIgnoreEnd if (preg_match('#' . $regex . '#m', $output)) { $output = preg_replace('#' . $regex . '#', $class->generate(), $output, 1); } else { if ($namespace) { $class->setNamespaceName(null); } $output .= $class->generate() . self::LINE_FEED; } } } if (! empty($body)) { // add an extra space between classes and if (! empty($classes)) { $output .= self::LINE_FEED; } $output .= $body; } return $output; } /** * @return FileGenerator * @throws Exception\RuntimeException */ public function write() { if ($this->filename == '' || ! is_writable(dirname($this->filename))) { throw new Exception\RuntimeException('This code generator object is not writable.'); } file_put_contents($this->filename, $this->generate()); return $this; } } src/Generator/GeneratorInterface.php000064400000000624144760113020013541 0ustar00isInterface()) { throw new Exception\InvalidArgumentException(sprintf( 'Class %s is not a interface', $classReflection->getName() )); } // class generator $cg = new static($classReflection->getName()); $methods = []; $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $cg->setDocBlock(DocBlockGenerator::fromReflection($classReflection->getDocBlock())); } // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } foreach ($classReflection->getMethods() as $reflectionMethod) { $className = $cg->getName(); $namespaceName = $cg->getNamespaceName(); if ($namespaceName !== null) { $className = $namespaceName . '\\' . $className; } if ($reflectionMethod->getDeclaringClass()->getName() == $className) { $methods[] = MethodGenerator::fromReflection($reflectionMethod); } } foreach ($classReflection->getConstants() as $name => $value) { $cg->addConstant($name, $value); } $cg->addMethods($methods); return $cg; } /** * Generate from array * * @configkey name string [required] Class Name * @configkey filegenerator FileGenerator File generator that holds this class * @configkey namespacename string The namespace for this class * @configkey docblock string The docblock information * @configkey constants * @configkey methods * @throws Exception\InvalidArgumentException * @param array $array * @return InterfaceGenerator */ public static function fromArray(array $array) { if (! isset($array['name'])) { throw new Exception\InvalidArgumentException( 'Class generator requires that a name is provided for this object' ); } $cg = new static($array['name']); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'containingfile': $cg->setContainingFileGenerator($value); break; case 'namespacename': $cg->setNamespaceName($value); break; case 'docblock': $docBlock = $value instanceof DocBlockGenerator ? $value : DocBlockGenerator::fromArray($value); $cg->setDocBlock($docBlock); break; case 'methods': $cg->addMethods($value); break; case 'constants': $cg->addConstants($value); break; } } return $cg; } /** * {@inheritDoc} */ public function addPropertyFromGenerator(PropertyGenerator $property) { return $this; } /** * {@inheritDoc} */ public function addMethodFromGenerator(MethodGenerator $method) { $method->setInterface(true); return parent::addMethodFromGenerator($method); } /** * {@inheritDoc} */ public function setExtendedClass($extendedClass) { return $this; } /** * {@inheritDoc} */ public function setAbstract($isAbstract) { return $this; } } src/Generator/MethodGenerator.php000064400000025325144760113020013066 0ustar00setSourceContent($reflectionMethod->getContents(false)); $method->setSourceDirty(false); if ($reflectionMethod->getDocComment() != '') { $method->setDocBlock(DocBlockGenerator::fromReflection($reflectionMethod->getDocBlock())); } $method->setBody(static::clearBodyIndention($reflectionMethod->getBody())); return $method; } /** * Returns a MethodGenerator based on a MethodReflection with only the signature copied. * * This is similar to fromReflection() but without the method body and phpdoc as this is quite heavy to copy. * It's for example useful when creating proxies where you normally change the method body anyway. */ public static function copyMethodSignature(MethodReflection $reflectionMethod): MethodGenerator { $method = new static(); $declaringClass = $reflectionMethod->getDeclaringClass(); $method->returnType = TypeGenerator::fromReflectionType($reflectionMethod->getReturnType(), $declaringClass); $method->setFinal($reflectionMethod->isFinal()); if ($reflectionMethod->isPrivate()) { $method->setVisibility(self::VISIBILITY_PRIVATE); } elseif ($reflectionMethod->isProtected()) { $method->setVisibility(self::VISIBILITY_PROTECTED); } else { $method->setVisibility(self::VISIBILITY_PUBLIC); } $method->setInterface($declaringClass->isInterface()); $method->setStatic($reflectionMethod->isStatic()); $method->setReturnsReference($reflectionMethod->returnsReference()); $method->setName($reflectionMethod->getName()); foreach ($reflectionMethod->getParameters() as $reflectionParameter) { $method->setParameter(ParameterGenerator::fromReflection($reflectionParameter)); } return $method; } /** * Identify the space indention from the first line and remove this indention * from all lines * * @param string $body * @return string */ protected static function clearBodyIndention($body) { if (empty($body)) { return $body; } $lines = explode("\n", $body); $indention = str_replace(trim($lines[1]), '', $lines[1]); foreach ($lines as $key => $line) { if (substr($line, 0, strlen($indention)) == $indention) { $lines[$key] = substr($line, strlen($indention)); } } $body = implode("\n", $lines); return $body; } /** * Generate from array * * @configkey name string [required] Class Name * @configkey docblock string The docblock information * @configkey flags int Flags, one of MethodGenerator::FLAG_ABSTRACT MethodGenerator::FLAG_FINAL * @configkey parameters string Class which this class is extending * @configkey body string * @configkey abstract bool * @configkey final bool * @configkey static bool * @configkey visibility string * @throws Exception\InvalidArgumentException * @param array $array * @return MethodGenerator */ public static function fromArray(array $array) { if (! isset($array['name'])) { throw new Exception\InvalidArgumentException( 'Method generator requires that a name is provided for this object' ); } $method = new static($array['name']); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'docblock': $docBlock = $value instanceof DocBlockGenerator ? $value : DocBlockGenerator::fromArray($value); $method->setDocBlock($docBlock); break; case 'flags': $method->setFlags($value); break; case 'parameters': $method->setParameters($value); break; case 'body': $method->setBody($value); break; case 'abstract': $method->setAbstract($value); break; case 'final': $method->setFinal($value); break; case 'interface': $method->setInterface($value); break; case 'static': $method->setStatic($value); break; case 'visibility': $method->setVisibility($value); break; case 'returntype': $method->setReturnType($value); break; } } return $method; } /** * @param ?string $name * @param ParameterGenerator[]|array[]|string[] $parameters * @param int|int[] $flags * @param ?string $body * @param DocBlockGenerator|string|null $docBlock */ public function __construct( $name = null, array $parameters = [], $flags = self::FLAG_PUBLIC, $body = null, $docBlock = null ) { if ($name) { $this->setName($name); } if ($parameters) { $this->setParameters($parameters); } if ($flags !== self::FLAG_PUBLIC) { $this->setFlags($flags); } if ($body) { $this->setBody($body); } if ($docBlock) { $this->setDocBlock($docBlock); } } /** * @param ParameterGenerator[]|array[]|string[] $parameters * @return MethodGenerator */ public function setParameters(array $parameters) { foreach ($parameters as $parameter) { $this->setParameter($parameter); } return $this; } /** * @param ParameterGenerator|array|string $parameter * @throws Exception\InvalidArgumentException * @return MethodGenerator */ public function setParameter($parameter) { if (is_string($parameter)) { $parameter = new ParameterGenerator($parameter); } if (is_array($parameter)) { $parameter = ParameterGenerator::fromArray($parameter); } if (! $parameter instanceof ParameterGenerator) { throw new Exception\InvalidArgumentException(sprintf( '%s is expecting either a string, array or an instance of %s\ParameterGenerator', __METHOD__, __NAMESPACE__ )); } $this->parameters[$parameter->getName()] = $parameter; return $this; } /** * @return ParameterGenerator[] */ public function getParameters() { return $this->parameters; } /** * @param string $body * @return MethodGenerator */ public function setBody($body) { $this->body = $body; return $this; } /** * @return string */ public function getBody() { return $this->body; } /** * @param string|null $returnType * @return MethodGenerator */ public function setReturnType($returnType = null) { $this->returnType = null === $returnType ? null : TypeGenerator::fromTypeString($returnType); return $this; } /** * @return TypeGenerator|null */ public function getReturnType() { return $this->returnType; } /** * @param bool $returnsReference * @return MethodGenerator */ public function setReturnsReference($returnsReference) { $this->returnsReference = (bool) $returnsReference; return $this; } /** * @return string */ public function generate() { $output = ''; $indent = $this->getIndentation(); if (($docBlock = $this->getDocBlock()) !== null) { $docBlock->setIndentation($indent); $output .= $docBlock->generate(); } $output .= $indent; if ($this->isAbstract()) { $output .= 'abstract '; } else { $output .= $this->isFinal() ? 'final ' : ''; } $output .= $this->getVisibility() . ($this->isStatic() ? ' static' : '') . ' function ' . ($this->returnsReference ? '& ' : '') . $this->getName() . '('; $parameters = $this->getParameters(); if (! empty($parameters)) { foreach ($parameters as $parameter) { $parameterOutput[] = $parameter->generate(); } $output .= implode(', ', $parameterOutput); } $output .= ')'; if ($this->returnType) { $output .= ' : ' . $this->returnType->generate(); } if ($this->isAbstract()) { return $output . ';'; } if ($this->isInterface()) { return $output . ';'; } $output .= self::LINE_FEED . $indent . '{' . self::LINE_FEED; if ($this->body) { $output .= preg_replace('#^((?![a-zA-Z0-9_-]+;).+?)$#m', $indent . $indent . '$1', trim($this->body)) . self::LINE_FEED; } $output .= $indent . '}' . self::LINE_FEED; return $output; } /** @return string */ public function __toString() { return $this->generate(); } } src/Generator/ParameterGenerator.php000064400000020331144760113020013556 0ustar00setName($reflectionParameter->getName()); $param->type = TypeGenerator::fromReflectionType( $reflectionParameter->getType(), $reflectionParameter->getDeclaringClass() ); $param->setPosition($reflectionParameter->getPosition()); $variadic = $reflectionParameter->isVariadic(); $param->setVariadic($variadic); if (! $variadic && ($reflectionParameter->isOptional() || $reflectionParameter->isDefaultValueAvailable())) { try { $param->setDefaultValue($reflectionParameter->getDefaultValue()); } catch (ReflectionException $e) { $param->setDefaultValue(null); } } $param->setPassedByReference($reflectionParameter->isPassedByReference()); return $param; } /** * Generate from array * * @configkey name string [required] Class Name * @configkey type string * @configkey defaultvalue null|bool|string|int|float|array|ValueGenerator * @configkey passedbyreference bool * @configkey position int * @configkey sourcedirty bool * @configkey indentation string * @configkey sourcecontent string * @configkey omitdefaultvalue bool * @throws Exception\InvalidArgumentException * @param array $array * @return ParameterGenerator */ public static function fromArray(array $array) { if (! isset($array['name'])) { throw new Exception\InvalidArgumentException( 'Parameter generator requires that a name is provided for this object' ); } $param = new static($array['name']); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'type': $param->setType($value); break; case 'defaultvalue': $param->setDefaultValue($value); break; case 'passedbyreference': $param->setPassedByReference($value); break; case 'position': $param->setPosition($value); break; case 'sourcedirty': $param->setSourceDirty($value); break; case 'indentation': $param->setIndentation($value); break; case 'sourcecontent': $param->setSourceContent($value); break; case 'omitdefaultvalue': $param->omitDefaultValue($value); break; } } return $param; } /** * @param ?string $name * @param ?string $type * @param ?mixed $defaultValue * @param ?int $position * @param bool $passByReference */ public function __construct( $name = null, $type = null, $defaultValue = null, $position = null, $passByReference = false ) { if (null !== $name) { $this->setName($name); } if (null !== $type) { $this->setType($type); } if (null !== $defaultValue) { $this->setDefaultValue($defaultValue); } if (null !== $position) { $this->setPosition($position); } if (false !== $passByReference) { $this->setPassedByReference(true); } } /** * @param string $type * @return ParameterGenerator */ public function setType($type) { $this->type = TypeGenerator::fromTypeString($type); return $this; } /** * @return string */ public function getType() { return $this->type ? $this->type->__toString() : null; } /** * @param string $name * @return ParameterGenerator */ public function setName($name) { $this->name = (string) $name; return $this; } /** * @return string */ public function getName() { return $this->name; } /** * Set the default value of the parameter. * * Certain variables are difficult to express * * @param null|bool|string|int|float|array|ValueGenerator $defaultValue * @return ParameterGenerator */ public function setDefaultValue($defaultValue) { if ($this->variadic) { throw new Exception\InvalidArgumentException('Variadic parameter cannot have a default value'); } if (! $defaultValue instanceof ValueGenerator) { $defaultValue = new ValueGenerator($defaultValue); } $this->defaultValue = $defaultValue; return $this; } /** * @return ?ValueGenerator */ public function getDefaultValue() { return $this->defaultValue; } /** * @param int $position * @return ParameterGenerator */ public function setPosition($position) { $this->position = (int) $position; return $this; } /** * @return int */ public function getPosition() { return $this->position; } /** * @return bool */ public function getPassedByReference() { return $this->passedByReference; } /** * @param bool $passedByReference * @return ParameterGenerator */ public function setPassedByReference($passedByReference) { $this->passedByReference = (bool) $passedByReference; return $this; } /** * @param bool $variadic * @return ParameterGenerator */ public function setVariadic($variadic) { if (isset($this->defaultValue)) { throw new Exception\InvalidArgumentException('Variadic parameter cannot have a default value'); } $this->variadic = (bool) $variadic; return $this; } /** * @return bool */ public function getVariadic() { return $this->variadic; } /** * @return string */ public function generate() { $output = $this->generateTypeHint(); if (true === $this->passedByReference) { $output .= '&'; } if ($this->variadic) { $output .= '... '; } $output .= '$' . $this->name; if ($this->omitDefaultValue) { return $output; } if ($this->defaultValue instanceof ValueGenerator) { $output .= ' = '; $this->defaultValue->setOutputMode(ValueGenerator::OUTPUT_SINGLE_LINE); $output .= $this->defaultValue; } return $output; } /** * @return string */ private function generateTypeHint() { if (null === $this->type) { return ''; } return $this->type->generate() . ' '; } /** * @return ParameterGenerator */ public function omitDefaultValue(bool $omit = true) { $this->omitDefaultValue = $omit; return $this; } } src/Generator/PropertyGenerator.php000064400000016423144760113020013471 0ustar00setName($reflectionProperty->getName()); $allDefaultProperties = $reflectionProperty->getDeclaringClass()->getDefaultProperties(); $defaultValue = $allDefaultProperties[$reflectionProperty->getName()] ?? null; $property->setDefaultValue($defaultValue); if ($defaultValue === null) { $property->omitDefaultValue = true; } if ($reflectionProperty->getDocComment() != '') { $property->setDocBlock(DocBlockGenerator::fromReflection($reflectionProperty->getDocBlock())); } if ($reflectionProperty->isStatic()) { $property->setStatic(true); } if ($reflectionProperty->isPrivate()) { $property->setVisibility(self::VISIBILITY_PRIVATE); } elseif ($reflectionProperty->isProtected()) { $property->setVisibility(self::VISIBILITY_PROTECTED); } else { $property->setVisibility(self::VISIBILITY_PUBLIC); } $property->setSourceDirty(false); return $property; } /** * Generate from array * * @configkey name string [required] Class Name * @configkey const bool * @configkey defaultvalue null|bool|string|int|float|array|ValueGenerator * @configkey flags int * @configkey abstract bool * @configkey final bool * @configkey static bool * @configkey visibility string * @configkey omitdefaultvalue bool * @throws Exception\InvalidArgumentException * @param array $array * @return static */ public static function fromArray(array $array) { if (! isset($array['name'])) { throw new Exception\InvalidArgumentException( 'Property generator requires that a name is provided for this object' ); } $property = new static($array['name']); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'const': $property->setConst($value); break; case 'defaultvalue': $property->setDefaultValue($value); break; case 'docblock': $docBlock = $value instanceof DocBlockGenerator ? $value : DocBlockGenerator::fromArray($value); $property->setDocBlock($docBlock); break; case 'flags': $property->setFlags($value); break; case 'abstract': $property->setAbstract($value); break; case 'final': $property->setFinal($value); break; case 'static': $property->setStatic($value); break; case 'visibility': $property->setVisibility($value); break; case 'omitdefaultvalue': $property->omitDefaultValue($value); break; } } return $property; } /** * @param ?string $name * @param PropertyValueGenerator|string|array|null $defaultValue * @param int $flags */ public function __construct($name = null, $defaultValue = null, $flags = self::FLAG_PUBLIC) { if (null !== $name) { $this->setName($name); } if (null !== $defaultValue) { $this->setDefaultValue($defaultValue); } if ($flags !== self::FLAG_PUBLIC) { $this->setFlags($flags); } } /** * @param bool $const * @return PropertyGenerator */ public function setConst($const) { if ($const) { $this->setFlags(self::FLAG_CONSTANT); } else { $this->removeFlag(self::FLAG_CONSTANT); } return $this; } /** * @return bool */ public function isConst() { return (bool) ($this->flags & self::FLAG_CONSTANT); } /** * @param PropertyValueGenerator|mixed $defaultValue * @param string $defaultValueType * @param string $defaultValueOutputMode * @return $this */ public function setDefaultValue( $defaultValue, $defaultValueType = PropertyValueGenerator::TYPE_AUTO, $defaultValueOutputMode = PropertyValueGenerator::OUTPUT_MULTIPLE_LINE ) { if (! $defaultValue instanceof PropertyValueGenerator) { $defaultValue = new PropertyValueGenerator($defaultValue, $defaultValueType, $defaultValueOutputMode); } $this->defaultValue = $defaultValue; return $this; } /** * @return ?PropertyValueGenerator */ public function getDefaultValue() { return $this->defaultValue; } /** * @throws Exception\RuntimeException * @return string */ public function generate() { $name = $this->getName(); $defaultValue = $this->getDefaultValue(); $output = ''; if (($docBlock = $this->getDocBlock()) !== null) { $docBlock->setIndentation(' '); $output .= $docBlock->generate(); } if ($this->isConst()) { if ($defaultValue !== null && ! $defaultValue->isValidConstantType()) { throw new Exception\RuntimeException(sprintf( 'The property %s is said to be ' . 'constant but does not have a valid constant value.', $this->name )); } return $output . $this->indentation . $this->getVisibility() . ' const ' . $name . ' = ' . ($defaultValue !== null ? $defaultValue->generate() : 'null;'); } $output .= $this->indentation . $this->getVisibility() . ($this->isStatic() ? ' static' : '') . ' $' . $name; if ($this->omitDefaultValue) { return $output . ';'; } return $output . ' = ' . ($defaultValue !== null ? $defaultValue->generate() : 'null;'); } /** * @return PropertyGenerator */ public function omitDefaultValue(bool $omit = true) { $this->omitDefaultValue = $omit; return $this; } } src/Generator/PropertyValueGenerator.php000064400000001017144760113020014457 0ustar00getName()); $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $cg->setDocBlock(DocBlockGenerator::fromReflection($classReflection->getDocBlock())); } // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } $properties = []; foreach ($classReflection->getProperties() as $reflectionProperty) { if ($reflectionProperty->getDeclaringClass()->getName() == $classReflection->getName()) { $properties[] = PropertyGenerator::fromReflection($reflectionProperty); } } $cg->addProperties($properties); $methods = []; foreach ($classReflection->getMethods() as $reflectionMethod) { $className = $cg->getName(); $namespaceName = $cg->getNamespaceName(); if ($namespaceName !== null) { $className = $namespaceName . '\\' . $className; } if ($reflectionMethod->getDeclaringClass()->getName() == $className) { $methods[] = MethodGenerator::fromReflection($reflectionMethod); } } $cg->addMethods($methods); return $cg; } /** * Generate from array * * @configkey name string [required] Class Name * @configkey filegenerator FileGenerator File generator that holds this class * @configkey namespacename string The namespace for this class * @configkey docblock string The docblock information * @configkey properties * @configkey methods * @throws Exception\InvalidArgumentException * @param array $array * @return TraitGenerator */ public static function fromArray(array $array) { if (! isset($array['name'])) { throw new Exception\InvalidArgumentException( 'Class generator requires that a name is provided for this object' ); } $cg = new static($array['name']); foreach ($array as $name => $value) { // normalize key switch (strtolower(str_replace(['.', '-', '_'], '', $name))) { case 'containingfile': $cg->setContainingFileGenerator($value); break; case 'namespacename': $cg->setNamespaceName($value); break; case 'docblock': $docBlock = $value instanceof DocBlockGenerator ? $value : DocBlockGenerator::fromArray($value); $cg->setDocBlock($docBlock); break; case 'properties': $cg->addProperties($value); break; case 'methods': $cg->addMethods($value); break; } } return $cg; } /** * @inheritDoc * @param int[]|int $flags */ public function setFlags($flags) { return $this; } /** * @param int $flag * @return self */ public function addFlag($flag) { return $this; } /** * @param int $flag * @return self */ public function removeFlag($flag) { return $this; } /** * @inheritDoc */ public function setFinal($isFinal) { return $this; } /** * @param ?string $extendedClass * @return self */ public function setExtendedClass($extendedClass) { return $this; } /** * @inheritDoc */ public function setImplementedInterfaces(array $implementedInterfaces) { return $this; } /** * @inheritDoc */ public function setAbstract($isAbstract) { return $this; } } src/Generator/TraitUsageGenerator.php000064400000027743144760113020013724 0ustar00 Array of trait names */ protected array $traits = []; /** @var array Array of trait aliases */ protected array $traitAliases = []; /** @var array Array of trait overrides */ protected array $traitOverrides = []; /** @var array Array of string names */ protected array $uses = []; public function __construct(ClassGenerator $classGenerator) { $this->classGenerator = $classGenerator; } /** * @inheritDoc */ public function addUse($use, $useAlias = null) { $this->removeUse($use); if (! empty($useAlias)) { $use .= ' as ' . $useAlias; } $this->uses[$use] = $use; return $this; } /** * @inheritDoc */ public function getUses() { return array_values($this->uses); } /** * @param string $use * @return bool */ public function hasUse($use) { foreach ($this->uses as $key => $value) { $parts = explode(' ', $value); if ($parts[0] === $use) { return true; } } return false; } /** * @param string $use * @return bool */ public function hasUseAlias($use) { foreach ($this->uses as $key => $value) { $parts = explode(' as ', $value); if ($parts[0] === $use && count($parts) == 2) { return true; } } return false; } /** * Returns the alias of the provided FQCN */ public function getUseAlias(string $use): ?string { foreach ($this->uses as $key => $value) { $parts = explode(' as ', $key); if ($parts[0] === $use && count($parts) == 2) { return $parts[1]; } } return null; } /** * Returns true if the alias is defined in the use list */ public function isUseAlias(string $alias): bool { foreach ($this->uses as $key => $value) { $parts = explode(' as ', $key); if (count($parts) === 2 && $parts[1] === $alias) { return true; } } return false; } /** * @param string $use * @return TraitUsageGenerator */ public function removeUse($use) { foreach ($this->uses as $key => $value) { $parts = explode(' ', $value); if ($parts[0] === $use) { unset($this->uses[$value]); } } return $this; } /** * @param string $use * @return TraitUsageGenerator */ public function removeUseAlias($use) { foreach ($this->uses as $key => $value) { $parts = explode(' as ', $value); if ($parts[0] === $use && count($parts) == 2) { unset($this->uses[$value]); } } return $this; } /** * @inheritDoc */ public function addTrait($trait) { if (is_array($trait)) { if (! array_key_exists('traitName', $trait)) { throw new Exception\InvalidArgumentException('Missing required value for traitName'); } $traitName = $trait['traitName']; if (array_key_exists('aliases', $trait)) { foreach ($trait['aliases'] as $alias) { $this->addAlias($alias); } } if (array_key_exists('insteadof', $trait)) { foreach ($trait['insteadof'] as $insteadof) { $this->addTraitOverride($insteadof); } } } else { $traitName = $trait; } if (! $this->hasTrait($traitName)) { $this->traits[] = $traitName; } return $this; } /** * @inheritDoc */ public function addTraits(array $traits) { foreach ($traits as $trait) { $this->addTrait($trait); } return $this; } /** * @inheritDoc */ public function hasTrait($traitName) { return in_array($traitName, $this->traits); } /** * @inheritDoc */ public function getTraits() { return $this->traits; } /** * @inheritDoc */ public function removeTrait($traitName) { $key = array_search($traitName, $this->traits); if (false !== $key) { unset($this->traits[$key]); } return $this; } /** * @inheritDoc */ public function addTraitAlias($method, $alias, $visibility = null) { $traitAndMethod = $method; if (is_array($method)) { if (! array_key_exists('traitName', $method)) { throw new Exception\InvalidArgumentException('Missing required argument "traitName" for $method'); } if (! array_key_exists('method', $method)) { throw new Exception\InvalidArgumentException('Missing required argument "method" for $method'); } $traitAndMethod = $method['traitName'] . '::' . $method['method']; } // Validations if (false === strpos($traitAndMethod, '::')) { throw new Exception\InvalidArgumentException( 'Invalid Format: $method must be in the format of trait::method' ); } if (! is_string($alias)) { throw new Exception\InvalidArgumentException('Invalid Alias: $alias must be a string or array.'); } if ($this->classGenerator->hasMethod($alias)) { throw new Exception\InvalidArgumentException('Invalid Alias: Method name already exists on this class.'); } if ( null !== $visibility && $visibility !== ReflectionMethod::IS_PUBLIC && $visibility !== ReflectionMethod::IS_PRIVATE && $visibility !== ReflectionMethod::IS_PROTECTED ) { throw new Exception\InvalidArgumentException( 'Invalid Type: $visibility must of ReflectionMethod::IS_PUBLIC,' . ' ReflectionMethod::IS_PRIVATE or ReflectionMethod::IS_PROTECTED' ); } [$trait, $method] = explode('::', $traitAndMethod); if (! $this->hasTrait($trait)) { throw new Exception\InvalidArgumentException('Invalid trait: Trait does not exists on this class'); } $this->traitAliases[$traitAndMethod] = [ 'alias' => $alias, 'visibility' => $visibility, ]; return $this; } /** * @inheritDoc */ public function getTraitAliases() { return $this->traitAliases; } /** * @inheritDoc */ public function addTraitOverride($method, $traitsToReplace) { if (false === is_array($traitsToReplace)) { $traitsToReplace = [$traitsToReplace]; } $traitAndMethod = $method; if (is_array($method)) { if (! array_key_exists('traitName', $method)) { throw new Exception\InvalidArgumentException('Missing required argument "traitName" for $method'); } if (! array_key_exists('method', $method)) { throw new Exception\InvalidArgumentException('Missing required argument "method" for $method'); } $traitAndMethod = (string) $method['traitName'] . '::' . (string) $method['method']; } // Validations if (false === strpos($traitAndMethod, '::')) { throw new Exception\InvalidArgumentException( 'Invalid Format: $method must be in the format of trait::method' ); } [$trait, $method] = explode('::', $traitAndMethod); if (! $this->hasTrait($trait)) { throw new Exception\InvalidArgumentException('Invalid trait: Trait does not exists on this class'); } if (! array_key_exists($traitAndMethod, $this->traitOverrides)) { $this->traitOverrides[$traitAndMethod] = []; } foreach ($traitsToReplace as $traitToReplace) { if (! is_string($traitToReplace)) { throw new Exception\InvalidArgumentException( 'Invalid Argument: $traitToReplace must be a string or array of strings' ); } if (! in_array($traitToReplace, $this->traitOverrides[$traitAndMethod])) { $this->traitOverrides[$traitAndMethod][] = $traitToReplace; } } return $this; } /** * @inheritDoc */ public function removeTraitOverride($method, $overridesToRemove = null) { if (! array_key_exists($method, $this->traitOverrides)) { return $this; } if (null === $overridesToRemove) { unset($this->traitOverrides[$method]); return $this; } $overridesToRemove = ! is_array($overridesToRemove) ? [$overridesToRemove] : $overridesToRemove; foreach ($overridesToRemove as $traitToRemove) { $key = array_search($traitToRemove, $this->traitOverrides[$method]); if (false !== $key) { unset($this->traitOverrides[$method][$key]); } } return $this; } /** * @inheritDoc */ public function getTraitOverrides() { return $this->traitOverrides; } /** * @inheritDoc */ public function generate() { $output = ''; $indent = $this->getIndentation(); $traits = $this->getTraits(); if (empty($traits)) { return $output; } $output .= $indent . 'use ' . implode(', ', $traits); $aliases = $this->getTraitAliases(); $overrides = $this->getTraitOverrides(); if (empty($aliases) && empty($overrides)) { return $output . ';' . self::LINE_FEED . self::LINE_FEED; } $output .= ' {' . self::LINE_FEED; foreach ($aliases as $method => $alias) { $visibility = null !== $alias['visibility'] ? current(Reflection::getModifierNames($alias['visibility'])) . ' ' : ''; // validation check if ($this->classGenerator->hasMethod($alias['alias'])) { throw new Exception\RuntimeException(sprintf( 'Generation Error: Aliased method %s already exists on this class', $alias['alias'] )); } $output .= $indent . $indent . $method . ' as ' . $visibility . $alias['alias'] . ';' . self::LINE_FEED; } foreach ($overrides as $method => $insteadofTraits) { foreach ($insteadofTraits as $insteadofTrait) { $output .= $indent . $indent . $method . ' insteadof ' . $insteadofTrait . ';' . self::LINE_FEED; } } return $output . self::LINE_FEED . $indent . '}' . self::LINE_FEED . self::LINE_FEED; } } src/Generator/TraitUsageInterface.php000064400000011013144760113020013655 0ustar00 $traits * @return self */ public function addTraits(array $traits); /** * Check to see if the class has a trait defined * * @param string $traitName * @return bool */ public function hasTrait($traitName); /** * Get a list of trait names * * @return array */ public function getTraits(); /** * Remove a trait by its name * * @param string $traitName */ public function removeTrait($traitName); /** * Add a trait alias. This will be used to generate the AS portion of the use statement. * * $method: * This method provides 2 ways for defining the trait method. * Option 1: String * Option 2: Array * key: traitName value: name of trait * key: method value: trait method * * $alias: * Alias is a string representing the new method name. * * $visibilty: * ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PRIVATE | ReflectionMethod::IS_PROTECTED * * @param mixed $method String or Array * @param string $alias * @param null|int $visibility */ public function addTraitAlias($method, $alias, $visibility = null); /** * @return array */ public function getTraitAliases(); /** * Add a trait method override. This will be used to generate the INSTEADOF portion of the use * statement. * * $method: * This method provides 2 ways for defining the trait method. * Option 1: String Format: :: * Option 2: Array * key: traitName value: trait name * key: method value: method name * * $traitToReplace: * The name of the trait that you wish to supersede. * * This method provides 2 ways for defining the trait method. * Option 1: String of trait to replace * Option 2: Array of strings of traits to replace * @param mixed $method * @param mixed $traitsToReplace */ public function addTraitOverride($method, $traitsToReplace); /** * Remove an override for a given trait::method * * $method: * This method provides 2 ways for defining the trait method. * Option 1: String Format: :: * Option 2: Array * key: traitName value: trait name * key: method value: method name * * $overridesToRemove: * The name of the trait that you wish to remove. * * This method provides 2 ways for defining the trait method. * Option 1: String of trait to replace * Option 2: Array of strings of traits to replace * * @param mixed $method * @param mixed $overridesToRemove * @return self */ public function removeTraitOverride($method, $overridesToRemove = null); /** * Return trait overrides * * @return array */ public function getTraitOverrides(); } src/Generator/TypeGenerator.php000064400000013547144760113020012572 0ustar00 */ private array $types; private bool $nullable; /** * @internal * * @psalm-pure */ public static function fromReflectionType( ?ReflectionType $type, ?ReflectionClass $currentClass ): ?self { if (null === $type) { return null; } assert($type instanceof ReflectionNamedType || $type instanceof ReflectionUnionType); return self::fromTypeString(implode( '|', array_map( static fn(ReflectionNamedType $type): string => self::reflectionNamedTypeToString($type, $currentClass), $type instanceof ReflectionNamedType ? [$type] : $type->getTypes() ) )); } /** @psalm-pure */ private static function reflectionNamedTypeToString( ReflectionNamedType $type, ?ReflectionClass $currentClass ): string { $lowerCaseName = strtolower($type->getName()); if ('mixed' === $lowerCaseName || 'null' === $lowerCaseName) { // `mixed` and `null` are implicitly nullable, therefore we need to skip adding nullability markers to it return $lowerCaseName; } $nullabilityMarker = $type->allowsNull() ? '?' : ''; if ('self' === $lowerCaseName && $currentClass) { return $nullabilityMarker . $currentClass->getName(); } if ('parent' === $lowerCaseName && $currentClass && $parentClass = $currentClass->getParentClass()) { return $nullabilityMarker . $parentClass->getName(); } return $nullabilityMarker . $type->getName(); } /** * @throws InvalidArgumentException * @psalm-pure */ public static function fromTypeString(string $type): self { [$nullable, $trimmedNullable] = self::trimNullable($type); $types = array_map([AtomicType::class, 'fromString'], explode('|', $trimmedNullable)); usort( $types, static fn(AtomicType $left, AtomicType $right): int => [$left->sortIndex, $left->type] <=> [$right->sortIndex, $right->type] ); assert([] !== $types); if (1 === count($types)) { $types[0]->assertCanBeAStandaloneType(); if ($nullable) { $types[0]->assertCanBeStandaloneNullable(); } return new self($types, $nullable); } if ($nullable) { throw new InvalidArgumentException(sprintf( 'Type "%s" is a union type, and therefore cannot be also marked nullable with the "?" prefix', $type )); } foreach ($types as $index => $atomicType) { $otherTypes = array_diff_key($types, array_flip([$index])); assert([] !== $otherTypes, 'There are always 2 or more types in a union type'); $atomicType->assertCanUnionWith($otherTypes); } return new self($types, $nullable); } /** * @param AtomicType[] $types * @psalm-param non-empty-list $types */ private function __construct(array $types, bool $nullable) { $this->types = $types; $this->nullable = $nullable; } /** * {@inheritDoc} * * Generates the type string, including FQCN "\\" prefix, so that * it can directly be used within any code snippet, regardless of * imports. * * @psalm-return non-empty-string */ public function generate() { $typesAsStrings = array_map( fn(AtomicType $type): string => $type->fullyQualifiedName(), $this->types ); if ($this->nullable) { return '?' . implode('|', $typesAsStrings); } return implode('|', $typesAsStrings); } public function equals(TypeGenerator $otherType): bool { return $this->generate() === $otherType->generate(); } /** * @return string the cleaned type string. Please note that this value is not suitable for code generation, * since the returned value does not include any root namespace prefixes, when applicable, * and therefore the values cannot be used as FQCN in generated code. */ public function __toString() { return implode('|', array_map( fn(AtomicType $type): string => $type->type, $this->types )); } /** * @param string $type * @return bool[]|string[] ordered tuple, first key represents whether the type is nullable, second is the * trimmed string * @psalm-return array{bool, string} * @psalm-pure */ private static function trimNullable($type) { if (0 === strpos($type, '?')) { return [true, substr($type, 1)]; } return [false, $type]; } } src/Generator/TypeGenerator/AtomicType.php000064400000013620144760113020014640 0ustar00 */ private const BUILT_IN_TYPES_PRECEDENCE = [ 'bool' => 1, 'int' => 2, 'float' => 3, 'string' => 4, 'array' => 5, 'callable' => 6, 'iterable' => 7, 'object' => 8, 'static' => 9, 'mixed' => 10, 'void' => 11, 'false' => 12, 'null' => 13, ]; /** @psalm-var array */ private const NOT_NULLABLE_TYPES = [ 'null' => null, 'false' => null, 'void' => null, 'mixed' => null, ]; /** A regex pattern to match valid class/interface/trait names */ private const VALID_IDENTIFIER_MATCHER = '/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*' . '(\\\\[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)*$/'; /** @psalm-var value-of|0 */ public int $sortIndex; /** @psalm-var non-empty-string */ public string $type; /** * @psalm-param non-empty-string $type * @psalm-param value-of|0 $sortIndex */ private function __construct(string $type, int $sortIndex) { $this->type = $type; $this->sortIndex = $sortIndex; } /** * @psalm-pure * @throws InvalidArgumentException */ public static function fromString(string $type): self { $trimmedType = '\\' === ($type[0] ?? '') ? substr($type, 1) : $type; $lowerCaseType = strtolower($trimmedType); if (array_key_exists($lowerCaseType, self::BUILT_IN_TYPES_PRECEDENCE)) { if ($lowerCaseType !== strtolower($type)) { throw new InvalidArgumentException(sprintf( 'Provided type "%s" is a built-in type, and should not be prefixed with "\\"', $type )); } return new self($lowerCaseType, self::BUILT_IN_TYPES_PRECEDENCE[$lowerCaseType]); } if (1 !== preg_match(self::VALID_IDENTIFIER_MATCHER, $trimmedType)) { throw new InvalidArgumentException(sprintf( 'Provided type "%s" is not recognized as a valid expression: ' . 'it must match "%s" or be one of the built-in types (%s)', $type, self::VALID_IDENTIFIER_MATCHER, implode(', ', self::BUILT_IN_TYPES_PRECEDENCE) )); } assert('' !== $trimmedType); return new self($trimmedType, 0); } /** @psalm-pure */ public static function null(): self { return new self('null', self::BUILT_IN_TYPES_PRECEDENCE['null']); } /** @psalm-return non-empty-string */ public function fullyQualifiedName(): string { return array_key_exists($this->type, self::BUILT_IN_TYPES_PRECEDENCE) ? $this->type : '\\' . $this->type; } /** * @psalm-param non-empty-array $others * @throws InvalidArgumentException */ public function assertCanUnionWith(array $others): void { if ( 'mixed' === $this->type || 'void' === $this->type ) { throw new InvalidArgumentException(sprintf( 'Type "%s" cannot be composed in a union with any other types', $this->type )); } foreach ($others as $other) { if ($other->type === $this->type) { throw new InvalidArgumentException(sprintf( 'Type "%s" cannot be composed in a union with the same type "%s"', $this->type, $other->type )); } } if ( $this->requiresUnionWithStandaloneType() && [] === array_filter($others, static fn (self $type): bool => ! $type->requiresUnionWithStandaloneType()) ) { throw new InvalidArgumentException(sprintf( 'Type "%s" requires to be composed with non-standalone types', $this->type )); } } /** @throws InvalidArgumentException */ public function assertCanBeAStandaloneType(): void { if ($this->requiresUnionWithStandaloneType()) { throw new InvalidArgumentException(sprintf( 'Type "%s" cannot be used standalone, and must be part of a union type', $this->type )); } } /** @throws InvalidArgumentException */ public function assertCanBeStandaloneNullable(): void { if (array_key_exists($this->type, self::NOT_NULLABLE_TYPES)) { throw new InvalidArgumentException(sprintf( 'Type "%s" cannot be nullable', $this->type )); } } private function requiresUnionWithStandaloneType(): bool { return 'null' === $this->type || 'false' === $this->type; } } src/Generator/ValueGenerator.php000064400000031561144760113020012721 0ustar00setValue($value); } if ($type !== self::TYPE_AUTO) { $this->setType($type); } if ($outputMode !== self::OUTPUT_MULTIPLE_LINE) { $this->setOutputMode($outputMode); } if ($constants === null) { $constants = new SplArrayObject(); } elseif (! ($constants instanceof SplArrayObject || $constants instanceof StdlibArrayObject)) { throw new InvalidArgumentException( '$constants must be an instance of ArrayObject or Laminas\Stdlib\ArrayObject' ); } $this->constants = $constants; } /** * Init constant list by defined and magic constants */ public function initEnvironmentConstants() { $constants = [ '__DIR__', '__FILE__', '__LINE__', '__CLASS__', '__TRAIT__', '__METHOD__', '__FUNCTION__', '__NAMESPACE__', '::', ]; $constants = array_merge($constants, array_keys(get_defined_constants()), $this->constants->getArrayCopy()); $this->constants->exchangeArray($constants); } /** * Add constant to list * * @param string $constant * @return $this */ public function addConstant($constant) { $this->constants->append($constant); return $this; } /** * Delete constant from constant list * * @param string $constant * @return bool */ public function deleteConstant($constant) { if (($index = array_search($constant, $this->constants->getArrayCopy())) !== false) { $this->constants->offsetUnset($index); } return $index !== false; } /** * Return constant list * * @return SplArrayObject|StdlibArrayObject */ public function getConstants() { return $this->constants; } /** * @return bool */ public function isValidConstantType() { if ($this->type === self::TYPE_AUTO) { $type = $this->getAutoDeterminedType($this->value); } else { $type = $this->type; } $validConstantTypes = [ self::TYPE_ARRAY, self::TYPE_ARRAY_LONG, self::TYPE_ARRAY_SHORT, self::TYPE_BOOLEAN, self::TYPE_BOOL, self::TYPE_NUMBER, self::TYPE_INTEGER, self::TYPE_INT, self::TYPE_FLOAT, self::TYPE_DOUBLE, self::TYPE_STRING, self::TYPE_CONSTANT, self::TYPE_NULL, ]; return in_array($type, $validConstantTypes); } /** * @param mixed $value * @return ValueGenerator */ public function setValue($value) { $this->value = $value; return $this; } /** * @return mixed */ public function getValue() { return $this->value; } /** * @param string $type * @return ValueGenerator */ public function setType($type) { $this->type = (string) $type; return $this; } /** * @return string */ public function getType() { return $this->type; } /** * @param int $arrayDepth * @return ValueGenerator */ public function setArrayDepth($arrayDepth) { $this->arrayDepth = (int) $arrayDepth; return $this; } /** * @return int */ public function getArrayDepth() { return $this->arrayDepth; } /** * @param string $type * @return string */ protected function getValidatedType($type) { $types = [ self::TYPE_AUTO, self::TYPE_BOOLEAN, self::TYPE_BOOL, self::TYPE_NUMBER, self::TYPE_INTEGER, self::TYPE_INT, self::TYPE_FLOAT, self::TYPE_DOUBLE, self::TYPE_STRING, self::TYPE_ARRAY, self::TYPE_ARRAY_SHORT, self::TYPE_ARRAY_LONG, self::TYPE_CONSTANT, self::TYPE_NULL, self::TYPE_OBJECT, self::TYPE_OTHER, ]; if (in_array($type, $types)) { return $type; } return self::TYPE_AUTO; } /** * @param mixed $value * @return string */ public function getAutoDeterminedType($value) { switch (gettype($value)) { case 'boolean': return self::TYPE_BOOLEAN; case 'string': foreach ($this->constants as $constant) { if ($value === $constant) { return self::TYPE_CONSTANT; } if (strpos($value, $constant) !== false) { return self::TYPE_CONSTANT; } } return self::TYPE_STRING; case 'double': case 'float': case 'integer': return self::TYPE_NUMBER; case 'array': return self::TYPE_ARRAY; case 'NULL': return self::TYPE_NULL; case 'object': case 'resource': case 'unknown type': default: return self::TYPE_OTHER; } } /** * @throws Exception\RuntimeException * @return string */ public function generate() { $type = $this->type; if ($type !== self::TYPE_AUTO) { $type = $this->getValidatedType($type); } $value = $this->value; if ($type === self::TYPE_AUTO) { $type = $this->getAutoDeterminedType($value); } $isArrayType = in_array($type, [self::TYPE_ARRAY, self::TYPE_ARRAY_LONG, self::TYPE_ARRAY_SHORT]); if ($isArrayType) { foreach ($value as &$curValue) { if ($curValue instanceof self) { continue; } if (is_array($curValue)) { $newType = $type; } else { $newType = self::TYPE_AUTO; } $curValue = new self($curValue, $newType, self::OUTPUT_MULTIPLE_LINE, $this->getConstants()); $curValue->setIndentation($this->indentation); } } $output = ''; switch ($type) { case self::TYPE_BOOLEAN: case self::TYPE_BOOL: $output .= $value ? 'true' : 'false'; break; case self::TYPE_STRING: $output .= self::escape($value); break; case self::TYPE_NULL: $output .= 'null'; break; case self::TYPE_NUMBER: case self::TYPE_INTEGER: case self::TYPE_INT: case self::TYPE_FLOAT: case self::TYPE_DOUBLE: case self::TYPE_CONSTANT: $output .= $value; break; case self::TYPE_ARRAY: case self::TYPE_ARRAY_LONG: case self::TYPE_ARRAY_SHORT: if ($type === self::TYPE_ARRAY_LONG) { $startArray = 'array('; $endArray = ')'; } else { $startArray = '['; $endArray = ']'; } $output .= $startArray; if ($this->outputMode == self::OUTPUT_MULTIPLE_LINE) { $output .= self::LINE_FEED . str_repeat($this->indentation, $this->arrayDepth + 1); } $outputParts = []; $noKeyIndex = 0; foreach ($value as $n => $v) { /** @var ValueGenerator $v */ $v->setArrayDepth($this->arrayDepth + 1); $partV = $v->generate(); $short = false; if (is_int($n)) { if ($n === $noKeyIndex) { $short = true; $noKeyIndex++; } else { $noKeyIndex = max($n + 1, $noKeyIndex); } } if ($short) { $outputParts[] = $partV; } else { $outputParts[] = (is_int($n) ? $n : self::escape($n)) . ' => ' . $partV; } } $padding = $this->outputMode == self::OUTPUT_MULTIPLE_LINE ? self::LINE_FEED . str_repeat($this->indentation, $this->arrayDepth + 1) : ' '; $output .= implode(',' . $padding, $outputParts); if ($this->outputMode == self::OUTPUT_MULTIPLE_LINE) { if (count($outputParts) > 0) { $output .= ','; } $output .= self::LINE_FEED . str_repeat($this->indentation, $this->arrayDepth); } $output .= $endArray; break; case self::TYPE_OTHER: default: throw new Exception\RuntimeException(sprintf( 'Type "%s" is unknown or cannot be used as property default value.', is_object($value) ? get_class($value) : gettype($value) )); } return $output; } /** * Quotes value for PHP code. * * @param string $input Raw string. * @param bool $quote Whether add surrounding quotes or not. * @return string PHP-ready code. */ public static function escape($input, $quote = true) { $output = addcslashes($input, "\\'"); // adds quoting strings if ($quote) { $output = "'" . $output . "'"; } return $output; } /** * @param string $outputMode * @return ValueGenerator */ public function setOutputMode($outputMode) { $this->outputMode = (string) $outputMode; return $this; } /** * @return string */ public function getOutputMode() { return $this->outputMode; } /** @return string */ public function __toString() { return $this->generate(); } } src/Generic/Prototype/PrototypeClassFactory.php000064400000006500144760113020015747 0ustar00addPrototype($prototype); } if ($genericPrototype) { $this->setGenericPrototype($genericPrototype); } } /** * @throws Exception\InvalidArgumentException */ public function addPrototype(PrototypeInterface $prototype) { $prototypeName = $this->normalizeName($prototype->getName()); if (isset($this->prototypes[$prototypeName])) { throw new Exception\InvalidArgumentException('A prototype with this name already exists in this manager'); } $this->prototypes[$prototypeName] = $prototype; } /** * @throws Exception\InvalidArgumentException */ public function setGenericPrototype(PrototypeGenericInterface $prototype) { if (isset($this->genericPrototype)) { throw new Exception\InvalidArgumentException('A default prototype is already set'); } $this->genericPrototype = $prototype; } /** * @param string $name * @return string */ protected function normalizeName($name) { return str_replace(['-', '_'], '', $name); } /** * @param string $name * @return bool */ public function hasPrototype($name) { $name = $this->normalizeName($name); return isset($this->prototypes[$name]); } /** * @param string $prototypeName * @return PrototypeInterface * @throws Exception\RuntimeException */ public function getClonedPrototype($prototypeName) { $prototypeName = $this->normalizeName($prototypeName); if (! $this->hasPrototype($prototypeName) && ! isset($this->genericPrototype)) { throw new Exception\RuntimeException('This tag name is not supported by this tag manager'); } if (! $this->hasPrototype($prototypeName)) { $newPrototype = clone $this->genericPrototype; $newPrototype->setName($prototypeName); } else { $newPrototype = clone $this->prototypes[$prototypeName]; } return $newPrototype; } } src/Generic/Prototype/PrototypeGenericInterface.php000064400000001035144760113020016545 0ustar00docBlock)) { return $this->docBlock; } if ('' == $this->getDocComment()) { return false; } $this->docBlock = new DocBlockReflection($this); return $this->docBlock; } /** * Return the start line of the class * * @param bool $includeDocComment * @return int */ public function getStartLine($includeDocComment = false) { if ($includeDocComment && $this->getDocComment() != '') { return $this->getDocBlock()->getStartLine(); } return parent::getStartLine(); } /** * Return the contents of the class * * @param bool $includeDocBlock * @return string */ public function getContents($includeDocBlock = true) { $fileName = $this->getFileName(); if (false === $fileName || ! file_exists($fileName)) { return ''; } $filelines = file($fileName); $startnum = $this->getStartLine($includeDocBlock); $endnum = $this->getEndLine() - $this->getStartLine(); // Ensure we get between the open and close braces $lines = array_slice($filelines, $startnum, $endnum); array_unshift($lines, $filelines[$startnum - 1]); return strstr(implode('', $lines), '{'); } /** * Get all reflection objects of implemented interfaces * * @return ClassReflection[] */ public function getInterfaces() { $phpReflections = parent::getInterfaces(); $laminasReflections = []; while ($phpReflections && ($phpReflection = array_shift($phpReflections))) { $instance = new ClassReflection($phpReflection->getName()); $laminasReflections[] = $instance; unset($phpReflection); } unset($phpReflections); return $laminasReflections; } /** * Return method reflection by name * * @param string $name * @return MethodReflection */ public function getMethod($name) { return new MethodReflection($this->getName(), parent::getMethod($name)->getName()); } /** * Get reflection objects of all methods * * @param int $filter * @return MethodReflection[] */ public function getMethods($filter = -1) { $methods = []; foreach (parent::getMethods($filter) as $method) { $instance = new MethodReflection($this->getName(), $method->getName()); $methods[] = $instance; } return $methods; } /** * Returns an array of reflection classes of traits used by this class. * * @return null|array */ public function getTraits() { $vals = []; $traits = parent::getTraits(); if ($traits === null) { return; } foreach ($traits as $trait) { $vals[] = new ClassReflection($trait->getName()); } return $vals; } /** * Get parent reflection class of reflected class * * @return ClassReflection|bool */ public function getParentClass() { $phpReflection = parent::getParentClass(); if ($phpReflection) { $laminasReflection = new ClassReflection($phpReflection->getName()); unset($phpReflection); return $laminasReflection; } return false; } /** * Return reflection property of this class by name * * @param string $name * @return PropertyReflection */ public function getProperty($name) { $phpReflection = parent::getProperty($name); $laminasReflection = new PropertyReflection($this->getName(), $phpReflection->getName()); unset($phpReflection); return $laminasReflection; } /** * Return reflection properties of this class * * @param int $filter * @return PropertyReflection[] */ public function getProperties($filter = -1) { $phpReflections = parent::getProperties($filter); $laminasReflections = []; while ($phpReflections && ($phpReflection = array_shift($phpReflections))) { $instance = new PropertyReflection($this->getName(), $phpReflection->getName()); $laminasReflections[] = $instance; unset($phpReflection); } unset($phpReflections); return $laminasReflections; } /** * @return string */ public function toString() { return parent::__toString(); } /** * @return string */ public function __toString() { return parent::__toString(); } } src/Reflection/DocBlock/Tag/AuthorTag.php000064400000003024144760113020014224 0ustar00]*)\>)?(.*)$/u', $tagDocblockLine, $match)) { return; } if ($match[1] !== '') { $this->authorName = rtrim($match[1]); } if (isset($match[3]) && $match[3] !== '') { $this->authorEmail = $match[3]; } } /** * @return null|string */ public function getAuthorName() { return $this->authorName; } /** * @return null|string */ public function getAuthorEmail() { return $this->authorEmail; } /** * @return string * @psalm-return non-empty-string */ public function __toString() { return 'DocBlock Tag [ * @' . $this->getName() . ' ]' . "\n"; } } src/Reflection/DocBlock/Tag/GenericTag.php000064400000004164144760113020014344 0ustar00contentSplitCharacter = $contentSplitCharacter; } /** * @param string $tagDocBlockLine * @return void */ public function initialize($tagDocBlockLine) { $this->parse($tagDocBlockLine); } /** * Get annotation tag name * * @return string */ public function getName() { return $this->name; } /** * @param string $name */ public function setName($name) { $this->name = $name; } /** * @return string */ public function getContent() { return $this->content; } /** * @param int $position * @return string */ public function returnValue($position) { return $this->values[$position]; } /** * Serialize to string * * Required by Reflector * * @todo What should this do? * @return string * @psalm-return non-empty-string */ public function __toString() { return 'DocBlock Tag [ * @' . $this->name . ' ]' . "\n"; } /** * @param string $docBlockLine */ protected function parse($docBlockLine) { $this->content = trim($docBlockLine); $this->values = explode($this->contentSplitCharacter, $docBlockLine); } } src/Reflection/DocBlock/Tag/LicenseTag.php000064400000002760144760113020014352 0ustar00url = trim($match[1]); } if (isset($match[2]) && $match[2] !== '') { $this->licenseName = $match[2]; } } /** * @return null|string */ public function getUrl() { return $this->url; } /** * @return null|string */ public function getLicenseName() { return $this->licenseName; } /** * @return string * @psalm-return non-empty-string */ public function __toString() { return 'DocBlock Tag [ * @' . $this->getName() . ' ]' . "\n"; } } src/Reflection/DocBlock/Tag/MethodTag.php000064400000004603144760113020014206 0ustar00 */ protected $types = []; /** @var string */ protected $methodName; /** @var string */ protected $description; /** * Is static method * * @var bool */ protected $isStatic = false; /** * @return string */ public function getName() { return 'method'; } /** * Initializer * * @param string $tagDocblockLine */ public function initialize($tagDocblockLine) { $match = []; if (! preg_match('#^(static[\s]+)?(.+[\s]+)?(.+\(\))[\s]*(.*)$#m', $tagDocblockLine, $match)) { return; } if ($match[1] !== '') { $this->isStatic = true; } if ($match[2] !== '') { $this->types = explode('|', rtrim($match[2])); } $this->methodName = $match[3]; if ($match[4] !== '') { $this->description = $match[4]; } } /** * Get return value type * * @deprecated 2.0.4 use getTypes instead * * @return null|string */ public function getReturnType() { if (empty($this->types)) { return; } return $this->types[0]; } /** {@inheritDoc} */ public function getTypes() { return $this->types; } /** * @return string */ public function getMethodName() { return $this->methodName; } /** * @return null|string */ public function getDescription() { return $this->description; } /** * @return bool */ public function isStatic() { return $this->isStatic; } /** * @return string * @psalm-return non-empty-string */ public function __toString() { return 'DocBlock Tag [ * @' . $this->getName() . ' ]' . "\n"; } } src/Reflection/DocBlock/Tag/ParamTag.php000064400000003764144760113020014035 0ustar00 */ protected $types = []; /** @var string */ protected $variableName; /** @var string */ protected $description; /** * @return string */ public function getName() { return 'param'; } /** * Initializer * * @param string $tagDocBlockLine */ public function initialize($tagDocBlockLine) { $matches = []; if (! preg_match('#((?:[\w|\\\]+(?:\[\])*\|?)+)(?:\s+(\$\S+))?(?:\s+(.*))?#s', $tagDocBlockLine, $matches)) { return; } $this->types = explode('|', $matches[1]); if (isset($matches[2])) { $this->variableName = $matches[2]; } if (isset($matches[3])) { $this->description = trim(preg_replace('#\s+#', ' ', $matches[3])); } } /** * Get parameter variable type * * @deprecated 2.0.4 use getTypes instead * * @return string */ public function getType() { if (empty($this->types)) { return ''; } return $this->types[0]; } /** {@inheritDoc} */ public function getTypes() { return $this->types; } /** * Get parameter name * * @return string */ public function getVariableName() { return $this->variableName; } /** * @return string */ public function getDescription() { return $this->description; } } src/Reflection/DocBlock/Tag/PhpDocTypedTagInterface.php000064400000001026144760113020016766 0ustar00 */ public function getTypes(); } src/Reflection/DocBlock/Tag/PropertyTag.php000064400000004104144760113020014606 0ustar00 */ protected $types = []; /** @var string */ protected $propertyName; /** @var string */ protected $description; /** * @return string */ public function getName() { return 'property'; } /** * Initializer * * @param string $tagDocblockLine */ public function initialize($tagDocblockLine) { $match = []; if (! preg_match('#^(.+)?(\$[\S]+)[\s]*(.*)$#m', $tagDocblockLine, $match)) { return; } if ($match[1] !== '') { $this->types = explode('|', rtrim($match[1])); } if ($match[2] !== '') { $this->propertyName = $match[2]; } if ($match[3] !== '') { $this->description = $match[3]; } } /** * @deprecated 2.0.4 use getTypes instead * * @return null|string */ public function getType() { if (empty($this->types)) { return; } return $this->types[0]; } /** {@inheritDoc} */ public function getTypes() { return $this->types; } /** * @return null|string */ public function getPropertyName() { return $this->propertyName; } /** * @return null|string */ public function getDescription() { return $this->description; } /** * @return string * @psalm-return non-empty-string */ public function __toString() { return 'DocBlock Tag [ * @' . $this->getName() . ' ]' . "\n"; } } src/Reflection/DocBlock/Tag/ReturnTag.php000064400000003126144760113020014244 0ustar00types = explode('|', $matches[1]); if (isset($matches[2])) { $this->description = trim(preg_replace('#\s+#', ' ', $matches[2])); } } /** * @deprecated 2.0.4 use getTypes instead * * @return string */ public function getType() { if (empty($this->types)) { return ''; } return $this->types[0]; } /** {@inheritDoc} */ public function getTypes() { return $this->types; } /** * @return string */ public function getDescription() { return $this->description; } } src/Reflection/DocBlock/Tag/TagInterface.php000064400000001042144760113020014660 0ustar00 */ protected $types = []; /** @var string */ protected $description; /** * @return string */ public function getName() { return 'throws'; } /** * @param string $tagDocBlockLine * @return void */ public function initialize($tagDocBlockLine) { $matches = []; preg_match('#([\w|\\\]+)(?:\s+(.*))?#', $tagDocBlockLine, $matches); $this->types = explode('|', $matches[1]); if (isset($matches[2])) { $this->description = $matches[2]; } } /** * Get return variable type * * @deprecated 2.0.4 use getTypes instead * * @return string */ public function getType() { return implode('|', $this->getTypes()); } /** {@inheritDoc} */ public function getTypes() { return $this->types; } /** * @return string */ public function getDescription() { return $this->description; } } src/Reflection/DocBlock/Tag/VarTag.php000064400000003533144760113020013517 0ustar00 */ private $types = []; /** @var string|null */ private $variableName; /** @var string|null */ private $description; /** * {@inheritDoc} */ public function getName(): string { return 'var'; } /** * {@inheritDoc} */ public function initialize($tagDocblockLine): void { $match = []; if ( ! preg_match( '#^([^\$]\S+)?\s*(\$[\S]+)?\s*(.*)$#m', $tagDocblockLine, $match ) ) { return; } if ($match[1] !== '') { $this->types = explode('|', rtrim($match[1])); } if ($match[2] !== '') { $this->variableName = $match[2]; } if ($match[3] !== '') { $this->description = $match[3]; } } /** {@inheritDoc} */ public function getTypes(): array { return $this->types; } public function getVariableName(): ?string { return $this->variableName; } public function getDescription(): ?string { return $this->description; } /** * @psalm-return non-empty-string */ public function __toString(): string { return 'DocBlock Tag [ * @' . $this->getName() . ' ]' . PHP_EOL; } } src/Reflection/DocBlock/TagManager.php000064400000002602144760113020013622 0ustar00addPrototype(new Tag\ParamTag()); $this->addPrototype(new Tag\ReturnTag()); $this->addPrototype(new Tag\MethodTag()); $this->addPrototype(new Tag\PropertyTag()); $this->addPrototype(new Tag\AuthorTag()); $this->addPrototype(new Tag\LicenseTag()); $this->addPrototype(new Tag\ThrowsTag()); $this->addPrototype(new Tag\VarTag()); $this->setGenericPrototype(new Tag\GenericTag()); } /** * @param string $tagName * @param string $content * @return TagInterface */ public function createTag($tagName, $content = null) { /** @var TagInterface $newTag */ $newTag = $this->getClonedPrototype($tagName); if ($content) { $newTag->initialize($content); } return $newTag; } } src/Reflection/DocBlockReflection.php000064400000015217144760113020013635 0ustar00initializeDefaultTags(); } $this->tagManager = $tagManager; if ($commentOrReflector instanceof Reflector) { $this->reflector = $commentOrReflector; if (! method_exists($commentOrReflector, 'getDocComment')) { throw new Exception\InvalidArgumentException('Reflector must contain method "getDocComment"'); } $this->docComment = $commentOrReflector->getDocComment(); // determine line numbers $lineCount = substr_count($this->docComment, "\n"); $this->startLine = $this->reflector->getStartLine() - $lineCount - 1; $this->endLine = $this->reflector->getStartLine() - 1; } elseif (is_string($commentOrReflector)) { $this->docComment = $commentOrReflector; } else { throw new Exception\InvalidArgumentException(sprintf( '%s must have a (string) DocComment or a Reflector in the constructor', static::class )); } if ($this->docComment == '') { throw new Exception\InvalidArgumentException('DocComment cannot be empty'); } $this->reflect(); } /** * Retrieve contents of DocBlock * * @return string */ public function getContents() { $this->reflect(); return $this->cleanDocComment; } /** * Get start line (position) of DocBlock * * @return int */ public function getStartLine() { $this->reflect(); return $this->startLine; } /** * Get last line (position) of DocBlock * * @return int */ public function getEndLine() { $this->reflect(); return $this->endLine; } /** * Get DocBlock short description * * @return string */ public function getShortDescription() { $this->reflect(); return $this->shortDescription; } /** * Get DocBlock long description * * @return string */ public function getLongDescription() { $this->reflect(); return $this->longDescription; } /** * Does the DocBlock contain the given annotation tag? * * @param string $name * @return bool */ public function hasTag($name) { $this->reflect(); foreach ($this->tags as $tag) { if ($tag->getName() == $name) { return true; } } return false; } /** * Retrieve the given DocBlock tag * * @param string $name * @return DocBlockTagInterface|false */ public function getTag($name) { $this->reflect(); foreach ($this->tags as $tag) { if ($tag->getName() == $name) { return $tag; } } return false; } /** * Get all DocBlock annotation tags * * @param string $filter * @return DocBlockTagInterface[] */ public function getTags($filter = null) { $this->reflect(); if ($filter === null || ! is_string($filter)) { return $this->tags; } $returnTags = []; foreach ($this->tags as $tag) { if ($tag->getName() == $filter) { $returnTags[] = $tag; } } return $returnTags; } /** * Parse the DocBlock * * @return void */ protected function reflect() { if ($this->isReflected) { return; } $docComment = preg_replace('#[ ]{0,1}\*/$#', '', $this->docComment); // create a clean docComment $this->cleanDocComment = preg_replace("#[ \t]*(?:/\*\*|\*/|\*)[ ]{0,1}(.*)?#", '$1', $docComment); // @todo should be changed to remove first and last empty line $this->cleanDocComment = ltrim($this->cleanDocComment, "\r\n"); $scanner = new DocBlockScanner($docComment); $this->shortDescription = ltrim($scanner->getShortDescription()); $this->longDescription = ltrim($scanner->getLongDescription()); foreach ($scanner->getTags() as $tag) { $this->tags[] = $this->tagManager->createTag(ltrim($tag['name'], '@'), ltrim($tag['value'])); } $this->isReflected = true; } /** * @return string */ public function toString() { $str = 'DocBlock [ /* DocBlock */ ] {' . "\n\n"; $str .= ' - Tags [' . count($this->tags) . '] {' . "\n"; foreach ($this->tags as $tag) { $str .= ' ' . $tag; } $str .= ' }' . "\n"; $str .= '}' . "\n"; return $str; } /** * Serialize to string * * Required by the Reflector interface * * @return string */ public function __toString() { return $this->toString(); } } src/Reflection/Exception/BadMethodCallException.php000064400000000715144760113020016377 0ustar00getDocComment())) { throw new Exception\InvalidArgumentException(sprintf( '%s does not have a DocBlock', $this->getName() )); } return new DocBlockReflection($comment); } /** * Get start line (position) of function * * @param bool $includeDocComment * @return int */ public function getStartLine($includeDocComment = false) { if ($includeDocComment) { if ($this->getDocComment() != '') { return $this->getDocBlock()->getStartLine(); } } return parent::getStartLine(); } /** * Get contents of function * * @param bool $includeDocBlock * @return string */ public function getContents($includeDocBlock = true) { $fileName = $this->getFileName(); if (false === $fileName) { return ''; } $startLine = $this->getStartLine(); $endLine = $this->getEndLine(); // eval'd protect if (preg_match('#\((\d+)\) : eval\(\)\'d code$#', $fileName, $matches)) { $fileName = preg_replace('#\(\d+\) : eval\(\)\'d code$#', '', $fileName); $startLine = $endLine = $matches[1]; } $lines = array_slice( file($fileName, FILE_IGNORE_NEW_LINES), $startLine - 1, $endLine - ($startLine - 1), true ); $functionLine = implode("\n", $lines); $content = ''; if ($this->isClosure()) { preg_match('#function\s*\([^\)]*\)\s*(use\s*\([^\)]+\))?\s*\{(.*\;)?\s*\}#s', $functionLine, $matches); if (isset($matches[0])) { $content = $matches[0]; } } else { $name = substr($this->getName(), strrpos($this->getName(), '\\') + 1); preg_match( '#function\s+' . preg_quote($name) . '\s*\([^\)]*\)\s*{([^{}]+({[^}]+})*[^}]+)?}#', $functionLine, $matches ); if (isset($matches[0])) { $content = $matches[0]; } } $docComment = $this->getDocComment(); return $includeDocBlock && $docComment ? $docComment . "\n" . $content : $content; } /** * Get method prototype * * @param string $format * @return array|string */ public function getPrototype($format = self::PROTOTYPE_AS_ARRAY) { $returnType = 'mixed'; $docBlock = $this->getDocBlock(); if ($docBlock) { $return = $docBlock->getTag('return'); $returnTypes = $return->getTypes(); $returnType = count($returnTypes) > 1 ? implode('|', $returnTypes) : $returnTypes[0]; } $prototype = [ 'namespace' => $this->getNamespaceName(), 'name' => substr($this->getName(), strlen($this->getNamespaceName()) + 1), 'return' => $returnType, 'arguments' => [], ]; $parameters = $this->getParameters(); foreach ($parameters as $parameter) { $prototype['arguments'][$parameter->getName()] = [ 'type' => $parameter->detectType(), 'required' => ! $parameter->isOptional(), 'by_ref' => $parameter->isPassedByReference(), 'default' => $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null, ]; } if ($format == self::PROTOTYPE_AS_STRING) { $line = $prototype['return'] . ' ' . $prototype['name'] . '('; $args = []; foreach ($prototype['arguments'] as $name => $argument) { $argsLine = ($argument['type'] ? $argument['type'] . ' ' : '') . ($argument['by_ref'] ? '&' : '') . '$' . $name; if (! $argument['required']) { $argsLine .= ' = ' . var_export($argument['default'], true); } $args[] = $argsLine; } $line .= implode(', ', $args); $line .= ')'; return $line; } return $prototype; } /** * Get function parameters * * @return ParameterReflection[] */ public function getParameters() { $phpReflections = parent::getParameters(); $laminasReflections = []; while ($phpReflections && ($phpReflection = array_shift($phpReflections))) { $instance = new ParameterReflection($this->getName(), $phpReflection->getName()); $laminasReflections[] = $instance; unset($phpReflection); } unset($phpReflections); return $laminasReflections; } /** * Get return type tag * * @throws Exception\InvalidArgumentException * @return DocBlockReflection */ public function getReturn() { $docBlock = $this->getDocBlock(); if (! $docBlock->hasTag('return')) { throw new Exception\InvalidArgumentException( 'Function does not specify an @return annotation tag; cannot determine return type' ); } $tag = $docBlock->getTag('return'); return new DocBlockReflection('@return ' . $tag->getDescription()); } /** * Get method body * * @return string|false */ public function getBody() { $fileName = $this->getFileName(); if (false === $fileName) { throw new Exception\InvalidArgumentException( 'Cannot determine internals functions body' ); } $startLine = $this->getStartLine(); $endLine = $this->getEndLine(); // eval'd protect if (preg_match('#\((\d+)\) : eval\(\)\'d code$#', $fileName, $matches)) { $fileName = preg_replace('#\(\d+\) : eval\(\)\'d code$#', '', $fileName); $startLine = $endLine = $matches[1]; } $lines = array_slice( file($fileName, FILE_IGNORE_NEW_LINES), $startLine - 1, $endLine - ($startLine - 1), true ); $functionLine = implode("\n", $lines); $body = false; if ($this->isClosure()) { preg_match('#function\s*\([^\)]*\)\s*(use\s*\([^\)]+\))?\s*\{(.*\;)\s*\}#s', $functionLine, $matches); if (isset($matches[2])) { $body = $matches[2]; } } else { $name = substr($this->getName(), strrpos($this->getName(), '\\') + 1); preg_match('#function\s+' . $name . '\s*\([^\)]*\)\s*{([^{}]+({[^}]+})*[^}]+)}#', $functionLine, $matches); if (isset($matches[1])) { $body = $matches[1]; } } return $body; } /** * @return string */ public function toString() { return $this->__toString(); } /** * Required due to bug in php * * @return string */ public function __toString() { return parent::__toString(); } } src/Reflection/MethodReflection.php000064400000033035144760113020013373 0ustar00getDocComment()) { return false; } return new DocBlockReflection($this); } /** * Get start line (position) of method * * @param bool $includeDocComment * @return int */ public function getStartLine($includeDocComment = false) { if ($includeDocComment) { if ($this->getDocComment() != '') { return $this->getDocBlock()->getStartLine(); } } return parent::getStartLine(); } /** * Get reflection of declaring class * * @return ClassReflection */ public function getDeclaringClass() { $phpReflection = parent::getDeclaringClass(); $laminasReflection = new ClassReflection($phpReflection->getName()); unset($phpReflection); return $laminasReflection; } /** * Get method prototype * * @param string $format * @return array|string */ public function getPrototype($format = self::PROTOTYPE_AS_ARRAY) { $returnType = 'mixed'; $docBlock = $this->getDocBlock(); if ($docBlock) { $return = $docBlock->getTag('return'); $returnTypes = $return->getTypes(); $returnType = count($returnTypes) > 1 ? implode('|', $returnTypes) : $returnTypes[0]; } $declaringClass = $this->getDeclaringClass(); $prototype = [ 'namespace' => $declaringClass->getNamespaceName(), 'class' => substr($declaringClass->getName(), strlen($declaringClass->getNamespaceName()) + 1), 'name' => $this->getName(), 'visibility' => $this->isPublic() ? 'public' : ($this->isPrivate() ? 'private' : 'protected'), 'return' => $returnType, 'arguments' => [], ]; $parameters = $this->getParameters(); foreach ($parameters as $parameter) { $prototype['arguments'][$parameter->getName()] = [ 'type' => $parameter->detectType(), 'required' => ! $parameter->isOptional(), 'by_ref' => $parameter->isPassedByReference(), 'default' => $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null, ]; } if ($format == self::PROTOTYPE_AS_STRING) { $line = $prototype['visibility'] . ' ' . $prototype['return'] . ' ' . $prototype['name'] . '('; $args = []; foreach ($prototype['arguments'] as $name => $argument) { $argsLine = ($argument['type'] ? $argument['type'] . ' ' : '') . ($argument['by_ref'] ? '&' : '') . '$' . $name; if (! $argument['required']) { $argsLine .= ' = ' . var_export($argument['default'], true); } $args[] = $argsLine; } $line .= implode(', ', $args); $line .= ')'; return $line; } return $prototype; } /** * Get all method parameter reflection objects * * @return ParameterReflection[] */ public function getParameters() { $phpReflections = parent::getParameters(); $laminasReflections = []; while ($phpReflections && ($phpReflection = array_shift($phpReflections))) { $instance = new ParameterReflection( [$this->getDeclaringClass()->getName(), $this->getName()], $phpReflection->getName() ); $laminasReflections[] = $instance; unset($phpReflection); } unset($phpReflections); return $laminasReflections; } /** * Get method contents * * @param bool $includeDocBlock * @return string */ public function getContents($includeDocBlock = true) { $docComment = $this->getDocComment(); $content = $includeDocBlock && ! empty($docComment) ? $docComment . "\n" : ''; $content .= $this->extractMethodContents(); return $content; } /** * Get method body * * @return string */ public function getBody() { return $this->extractMethodContents(true); } /** * Tokenize method string and return concatenated body * * @param bool $bodyOnly * @return string */ protected function extractMethodContents($bodyOnly = false) { $fileName = $this->getFileName(); if ((class_exists($this->class) && false === $fileName) || ! file_exists($fileName)) { return ''; } $lines = array_slice( file($fileName, FILE_IGNORE_NEW_LINES), $this->getStartLine() - 1, $this->getEndLine() - ($this->getStartLine() - 1), true ); $functionLine = implode("\n", $lines); $tokens = token_get_all(' $token) { $tokenType = is_array($token) ? token_name($token[0]) : $token; $tokenValue = is_array($token) ? $token[1] : $token; switch ($tokenType) { case 'T_FINAL': case 'T_ABSTRACT': case 'T_PUBLIC': case 'T_PROTECTED': case 'T_PRIVATE': case 'T_STATIC': case 'T_FUNCTION': // check to see if we have a valid function // then check if we are inside function and have a closure if ($this->isValidFunction($tokens, $key, $this->getName())) { if ($bodyOnly === false) { //if first instance of tokenType grab prefixed whitespace //and append to body if ($capture === false) { $body .= $this->extractPrefixedWhitespace($tokens, $key); } $body .= $tokenValue; } $capture = true; } else { //closure test if ($firstBrace && $tokenType == 'T_FUNCTION') { $body .= $tokenValue; break; } $capture = false; break; } break; case '{': if ($capture === false) { break; } if ($firstBrace === false) { $firstBrace = true; if ($bodyOnly === true) { break; } } $body .= $tokenValue; break; case '}': if ($capture === false) { break; } //check to see if this is the last brace if ($this->isEndingBrace($tokens, $key)) { //capture the end brace if not bodyOnly if ($bodyOnly === false) { $body .= $tokenValue; } break 2; } $body .= $tokenValue; break; default: if ($capture === false) { break; } // if returning body only wait for first brace before capturing if ($bodyOnly === true && $firstBrace !== true) { break; } $body .= $tokenValue; break; } } //remove ending whitespace and return return rtrim($body); } /** * Take current position and find any whitespace * * @param array $haystack * @param int $position * @return string */ protected function extractPrefixedWhitespace($haystack, $position) { $content = ''; $count = count($haystack); if ($position + 1 == $count) { return $content; } for ($i = $position - 1; $i >= 0; $i--) { $tokenType = is_array($haystack[$i]) ? token_name($haystack[$i][0]) : $haystack[$i]; $tokenValue = is_array($haystack[$i]) ? $haystack[$i][1] : $haystack[$i]; //search only for whitespace if ($tokenType == 'T_WHITESPACE') { $content .= $tokenValue; } else { break; } } return $content; } /** * Test for ending brace * * @param array $haystack * @param int $position * @return bool */ protected function isEndingBrace($haystack, $position) { $count = count($haystack); //advance one position $position += 1; if ($position == $count) { return true; } for ($i = $position; $i < $count; $i++) { $tokenType = is_array($haystack[$i]) ? token_name($haystack[$i][0]) : $haystack[$i]; switch ($tokenType) { case 'T_FINAL': case 'T_ABSTRACT': case 'T_PUBLIC': case 'T_PROTECTED': case 'T_PRIVATE': case 'T_STATIC': return true; case 'T_FUNCTION': // If a function is encountered and that function is not a closure // then return true. otherwise the function is a closure, return false if ($this->isValidFunction($haystack, $i)) { return true; } return false; case '}': case ';': case 'T_BREAK': case 'T_CATCH': case 'T_DO': case 'T_ECHO': case 'T_ELSE': case 'T_ELSEIF': case 'T_EVAL': case 'T_EXIT': case 'T_FINALLY': case 'T_FOR': case 'T_FOREACH': case 'T_GOTO': case 'T_IF': case 'T_INCLUDE': case 'T_INCLUDE_ONCE': case 'T_PRINT': case 'T_STRING': case 'T_STRING_VARNAME': case 'T_THROW': case 'T_USE': case 'T_VARIABLE': case 'T_WHILE': case 'T_YIELD': return false; } } } /** * Test to see if current position is valid function or * closure. Returns true if it's a function and NOT a closure * * @param array $haystack * @param int $position * @param string $functionName * @return bool */ protected function isValidFunction($haystack, $position, $functionName = null) { $isValid = false; $count = count($haystack); for ($i = $position + 1; $i < $count; $i++) { $tokenType = is_array($haystack[$i]) ? token_name($haystack[$i][0]) : $haystack[$i]; $tokenValue = is_array($haystack[$i]) ? $haystack[$i][1] : $haystack[$i]; //check for occurrence of ( or if ($tokenType == 'T_STRING') { //check to see if function name is passed, if so validate against that if ($functionName !== null && $tokenValue != $functionName) { $isValid = false; break; } $isValid = true; break; } elseif ($tokenValue == '(') { break; } } return $isValid; } /** * @return string */ public function toString() { return parent::__toString(); } /** * @return string */ public function __toString() { return parent::__toString(); } } src/Reflection/ParameterReflection.php000064400000006021144760113020014066 0ustar00getName()); unset($phpReflection); return $laminasReflection; } /** * Get class reflection object * * @return null|ClassReflection */ public function getClass() { $phpReflectionType = parent::getType(); if ($phpReflectionType === null) { return null; } $laminasReflection = new ClassReflection($phpReflectionType->getName()); unset($phpReflectionType); return $laminasReflection; } /** * Get declaring function reflection object * * @return FunctionReflection|MethodReflection */ public function getDeclaringFunction() { $phpReflection = parent::getDeclaringFunction(); if ($phpReflection instanceof ReflectionMethod) { $laminasReflection = new MethodReflection($this->getDeclaringClass()->getName(), $phpReflection->getName()); } else { $laminasReflection = new FunctionReflection($phpReflection->getName()); } unset($phpReflection); return $laminasReflection; } /** * Get parameter type * * @return string|null */ public function detectType() { if ( method_exists($this, 'getType') && null !== ($type = $this->getType()) && $type->isBuiltin() ) { return $type->getName(); } if (null !== $type && $type->getName() === 'self') { return $this->getDeclaringClass()->getName(); } if (($class = $this->getClass()) instanceof ReflectionClass) { return $class->getName(); } $docBlock = $this->getDeclaringFunction()->getDocBlock(); if (! $docBlock instanceof DocBlockReflection) { return null; } $params = $docBlock->getTags('param'); if (isset($params[$this->getPosition()])) { return $params[$this->getPosition()]->getType(); } return null; } /** * @return string */ public function toString() { return parent::__toString(); } /** * @return string */ public function __toString() { return parent::__toString(); } } src/Reflection/PropertyReflection.php000064400000002610144760113020013772 0ustar00getName()); unset($phpReflection); return $laminasReflection; } /** * Get DocBlock comment * * @return string|false False if no DocBlock defined */ public function getDocComment() { return parent::getDocComment(); } /** * @return false|DocBlockReflection */ public function getDocBlock() { if (! ($docComment = $this->getDocComment())) { return false; } return new DocBlockReflection($docComment); } /** * @return string */ public function toString() { return $this->__toString(); } } src/Reflection/ReflectionInterface.php000064400000001016144760113020014045 0ustar00docComment = $docComment; } /** * @return string */ public function getShortDescription() { $this->scan(); return $this->shortDescription; } /** * @return string */ public function getLongDescription() { $this->scan(); return $this->longDescription; } /** * @return array */ public function getTags() { $this->scan(); return $this->tags; } /** * @return void */ protected function scan() { if ($this->isScanned) { return; } $mode = 1; $tokens = $this->tokenize(); $tagIndex = null; reset($tokens); SCANNER_TOP: $token = current($tokens); switch ($token[0]) { case 'DOCBLOCK_NEWLINE': if ($this->shortDescription != '' && $tagIndex === null) { $mode = 2; } else { $this->longDescription .= $token[1]; } goto SCANNER_CONTINUE; //goto no break needed case 'DOCBLOCK_WHITESPACE': case 'DOCBLOCK_TEXT': if ($tagIndex !== null) { $this->tags[$tagIndex]['value'] .= $this->tags[$tagIndex]['value'] == '' ? $token[1] : ' ' . $token[1]; goto SCANNER_CONTINUE; } elseif ($mode <= 2) { if ($mode == 1) { $this->shortDescription .= $token[1]; } else { $this->longDescription .= $token[1]; } goto SCANNER_CONTINUE; } //gotos no break needed case 'DOCBLOCK_TAG': array_push($this->tags, [ 'name' => $token[1], 'value' => '', ]); end($this->tags); $tagIndex = key($this->tags); $mode = 3; goto SCANNER_CONTINUE; //goto no break needed case 'DOCBLOCK_COMMENTEND': goto SCANNER_END; } SCANNER_CONTINUE: if (next($tokens) === false) { goto SCANNER_END; } goto SCANNER_TOP; SCANNER_END: $this->shortDescription = trim($this->shortDescription); $this->longDescription = trim($this->longDescription); $this->isScanned = true; } /** * @return array */ protected function tokenize() { static $CONTEXT_INSIDE_DOCBLOCK = 0x01; static $CONTEXT_INSIDE_ASTERISK = 0x02; $context = 0x00; $stream = $this->docComment; $streamIndex = null; $tokens = []; $tokenIndex = null; $currentChar = null; $currentWord = null; $currentLine = null; $MACRO_STREAM_ADVANCE_CHAR = function ($positionsForward = 1) use ( &$stream, &$streamIndex, &$currentChar, &$currentWord, &$currentLine ) { $positionsForward = $positionsForward > 0 ? $positionsForward : 1; $streamIndex = $streamIndex === null ? 0 : $streamIndex + $positionsForward; if (! isset($stream[$streamIndex])) { $currentChar = false; return false; } $currentChar = $stream[$streamIndex]; $matches = []; $currentLine = preg_match('#(.*?)\r?\n#', $stream, $matches, null, $streamIndex) === 1 ? $matches[1] : substr($stream, $streamIndex); if ($currentChar === ' ') { $currentWord = preg_match('#( +)#', $currentLine, $matches) === 1 ? $matches[1] : $currentLine; } else { $currentWord = ($matches = strpos($currentLine, ' ')) !== false ? substr($currentLine, 0, $matches) : $currentLine; } return $currentChar; }; $MACRO_STREAM_ADVANCE_WORD = function () use (&$currentWord, &$MACRO_STREAM_ADVANCE_CHAR) { return $MACRO_STREAM_ADVANCE_CHAR(strlen($currentWord)); }; $MACRO_STREAM_ADVANCE_LINE = function () use (&$currentLine, &$MACRO_STREAM_ADVANCE_CHAR) { return $MACRO_STREAM_ADVANCE_CHAR(strlen($currentLine)); }; $MACRO_TOKEN_ADVANCE = function () use (&$tokenIndex, &$tokens) { $tokenIndex = $tokenIndex === null ? 0 : $tokenIndex + 1; $tokens[$tokenIndex] = ['DOCBLOCK_UNKNOWN', '']; }; $MACRO_TOKEN_SET_TYPE = function ($type) use (&$tokenIndex, &$tokens) { $tokens[$tokenIndex][0] = $type; }; $MACRO_TOKEN_APPEND_CHAR = function () use (&$currentChar, &$tokens, &$tokenIndex) { $tokens[$tokenIndex][1] .= $currentChar; }; $MACRO_TOKEN_APPEND_WORD = function () use (&$currentWord, &$tokens, &$tokenIndex) { $tokens[$tokenIndex][1] .= $currentWord; }; $MACRO_TOKEN_APPEND_WORD_PARTIAL = function ($length) use (&$currentWord, &$tokens, &$tokenIndex) { $tokens[$tokenIndex][1] .= substr($currentWord, 0, $length); }; $MACRO_TOKEN_APPEND_LINE = function () use (&$currentLine, &$tokens, &$tokenIndex) { $tokens[$tokenIndex][1] .= $currentLine; }; $MACRO_STREAM_ADVANCE_CHAR(); $MACRO_TOKEN_ADVANCE(); TOKENIZER_TOP: if ($context === 0x00 && $currentChar === '/' && $currentWord === '/**') { $MACRO_TOKEN_SET_TYPE('DOCBLOCK_COMMENTSTART'); $MACRO_TOKEN_APPEND_WORD(); $MACRO_TOKEN_ADVANCE(); $context |= $CONTEXT_INSIDE_DOCBLOCK; $context |= $CONTEXT_INSIDE_ASTERISK; if ($MACRO_STREAM_ADVANCE_WORD() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; } if ($context & $CONTEXT_INSIDE_DOCBLOCK && $currentWord === '*/') { $MACRO_TOKEN_SET_TYPE('DOCBLOCK_COMMENTEND'); $MACRO_TOKEN_APPEND_WORD(); $MACRO_TOKEN_ADVANCE(); $context &= ~$CONTEXT_INSIDE_DOCBLOCK; if ($MACRO_STREAM_ADVANCE_WORD() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; } if ($currentChar === ' ' || $currentChar === "\t") { $MACRO_TOKEN_SET_TYPE( $context & $CONTEXT_INSIDE_ASTERISK ? 'DOCBLOCK_WHITESPACE' : 'DOCBLOCK_WHITESPACE_INDENT' ); $MACRO_TOKEN_APPEND_WORD(); $MACRO_TOKEN_ADVANCE(); if ($MACRO_STREAM_ADVANCE_WORD() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; } if ($currentChar === '*') { if (($context & $CONTEXT_INSIDE_DOCBLOCK) && ($context & $CONTEXT_INSIDE_ASTERISK)) { $MACRO_TOKEN_SET_TYPE('DOCBLOCK_TEXT'); } else { $MACRO_TOKEN_SET_TYPE('DOCBLOCK_ASTERISK'); $context |= $CONTEXT_INSIDE_ASTERISK; } $MACRO_TOKEN_APPEND_CHAR(); $MACRO_TOKEN_ADVANCE(); if ($MACRO_STREAM_ADVANCE_CHAR() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; } if ($currentChar === '@') { $MACRO_TOKEN_SET_TYPE('DOCBLOCK_TAG'); $MACRO_TOKEN_APPEND_WORD(); $MACRO_TOKEN_ADVANCE(); if ($MACRO_STREAM_ADVANCE_WORD() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; } if ($currentChar === "\n") { $MACRO_TOKEN_SET_TYPE('DOCBLOCK_NEWLINE'); $MACRO_TOKEN_APPEND_CHAR(); $MACRO_TOKEN_ADVANCE(); $context &= ~$CONTEXT_INSIDE_ASTERISK; if ($MACRO_STREAM_ADVANCE_CHAR() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; } $MACRO_TOKEN_SET_TYPE('DOCBLOCK_TEXT'); $MACRO_TOKEN_APPEND_LINE(); $MACRO_TOKEN_ADVANCE(); if ($MACRO_STREAM_ADVANCE_LINE() === false) { goto TOKENIZER_END; } goto TOKENIZER_TOP; TOKENIZER_END: array_pop($tokens); return $tokens; } }