Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ jobs:
strategy:
matrix:
php-version:
- "8.1"
- "8.2"
- "8.3"
- "8.4"
- "8.5"
Expand Down Expand Up @@ -50,7 +48,7 @@ jobs:
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
php-version: 8.3
coverage: pcov

- name: Install Dependencies
Expand All @@ -74,7 +72,7 @@ jobs:
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
php-version: 8.3
coverage: none

- name: Install dependencies
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ using [Composer](http://getcomposer.org).
composer require respect/stringifier
```

This library requires PHP >= 8.1.
This library requires PHP >= 8.3.

## Usage

Expand Down Expand Up @@ -190,4 +190,4 @@ echo $stringify->value(new class {
}
});
// Hello, world!
```
```
15 changes: 7 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,16 @@
}
],
"require": {
"php": "^8.1"
"php": "^8.3"
},
"require-dev": {
"malukenho/docheader": "^0.1.7",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan-deprecation-rules": "^1.1",
"phpstan/phpstan-phpunit": "^1.3",
"phpstan/phpstan-strict-rules": "^1.5",
"phpunit/phpunit": "^10.0",
"respect/coding-standard": "^4.0",
"squizlabs/php_codesniffer": "^3.7"
"phpstan/phpstan": "^2.1",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^12.5",
"respect/coding-standard": "^5.0"
},
"autoload": {
"psr-4": {
Expand Down
15 changes: 15 additions & 0 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,19 @@
<rule ref="PSR1.Classes.ClassDeclaration.MissingNamespace">
<exclude-pattern>tests/fixtures/</exclude-pattern>
</rule>
<rule ref="Squiz.Arrays.ArrayDeclaration.ValueNoNewline">
<exclude-pattern>tests/unit/Stringifiers/CallableStringifierTest.php</exclude-pattern>
</rule>
<rule ref="Squiz.Functions.GlobalFunction">
<exclude-pattern>tests/integration/lib/helpers.php</exclude-pattern>
</rule>
<rule ref="Generic.Files.InlineHTML.Found">
<exclude-pattern>tests/integration/</exclude-pattern>
</rule>
<rule ref="PSR12.Files.FileHeader.HeaderPosition">
<exclude-pattern>tests/integration/</exclude-pattern>
</rule>
<rule ref="Generic.PHP.CharacterBeforePHPOpeningTag.Found">
<exclude-pattern>tests/integration/</exclude-pattern>
</rule>
</ruleset>
2 changes: 1 addition & 1 deletion src/Helpers/ObjectHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

trait ObjectHelper
{
private function format(object $object, ?string ...$pieces): string
private function format(object $object, string|null ...$pieces): string
{
$filteredPieces = array_filter($pieces);
if (count($filteredPieces) === 0) {
Expand Down
6 changes: 3 additions & 3 deletions src/Quoters/StandardQuoter.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@

final class StandardQuoter implements Quoter
{
private const OBJECT_PLACEHOLDER = ' ... }';
private const ARRAY_PLACEHOLDER = ' ... ]';
private const GENERIC_PLACEHOLDER = ' ...';
private const string OBJECT_PLACEHOLDER = ' ... }';
private const string ARRAY_PLACEHOLDER = ' ... ]';
private const string GENERIC_PLACEHOLDER = ' ...';

public function __construct(private readonly int $maximumLength)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Stringifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@

interface Stringifier
{
public function stringify(mixed $raw, int $depth): ?string;
public function stringify(mixed $raw, int $depth): string|null;
}
6 changes: 3 additions & 3 deletions src/Stringifiers/ArrayObjectStringifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ final class ArrayObjectStringifier implements Stringifier

public function __construct(
private readonly Stringifier $stringifier,
private readonly Quoter $quoter
private readonly Quoter $quoter,
) {
}

public function stringify(mixed $raw, int $depth): ?string
public function stringify(mixed $raw, int $depth): string|null
{
if (!$raw instanceof ArrayObject) {
return null;
}

return $this->quoter->quote(
$this->format($raw, 'getArrayCopy() =>', $this->stringifier->stringify($raw->getArrayCopy(), $depth + 1)),
$depth
$depth,
);
}
}
12 changes: 5 additions & 7 deletions src/Stringifiers/ArrayStringifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@

final class ArrayStringifier implements Stringifier
{
private const LIMIT_EXCEEDED_PLACEHOLDER = '...';
private const string LIMIT_EXCEEDED_PLACEHOLDER = '...';

public function __construct(
private readonly Stringifier $stringifier,
private readonly Quoter $quoter,
private readonly int $maximumDepth,
private readonly int $maximumNumberOfItems
private readonly int $maximumNumberOfItems,
) {
}

public function stringify(mixed $raw, int $depth): ?string
public function stringify(mixed $raw, int $depth): string|null
{
if (!is_array($raw)) {
return null;
Expand Down Expand Up @@ -66,7 +66,7 @@ public function stringify(mixed $raw, int $depth): ?string
return $this->quoter->quote(sprintf('[%s]', implode(', ', $items)), $depth);
}

private function stringifyKeyValue(mixed $value, int $depth): ?string
private function stringifyKeyValue(mixed $value, int $depth): string|null
{
if (is_array($value)) {
return $this->stringify($value, $depth);
Expand All @@ -75,9 +75,7 @@ private function stringifyKeyValue(mixed $value, int $depth): ?string
return $this->stringifier->stringify($value, $depth);
}

/**
* @param mixed[] $array
*/
/** @param mixed[] $array */
private function isSequential(array $array): bool
{
return array_keys($array) === range(0, count($array) - 1);
Expand Down
4 changes: 2 additions & 2 deletions src/Stringifiers/BoolStringifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
final class BoolStringifier implements Stringifier
{
public function __construct(
private readonly Quoter $quoter
private readonly Quoter $quoter,
) {
}

public function stringify(mixed $raw, int $depth): ?string
public function stringify(mixed $raw, int $depth): string|null
{
if (!is_bool($raw)) {
return null;
Expand Down
44 changes: 27 additions & 17 deletions src/Stringifiers/CallableStringifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public function __construct(
) {
}

public function stringify(mixed $raw, int $depth): ?string
public function stringify(mixed $raw, int $depth): string|null
{
if (!is_callable($raw)) {
return null;
Expand All @@ -61,27 +61,30 @@ public function stringify(mixed $raw, int $depth): ?string
return $this->buildMethod(new ReflectionMethod($raw, '__invoke'), $raw, $depth);
}

if (is_array($raw) && is_object($raw[0])) {
if (is_array($raw) && is_object($raw[0]) && is_string($raw[1])) {
return $this->buildMethod(new ReflectionMethod($raw[0], $raw[1]), $raw[0], $depth);
}

if (is_array($raw) && is_string($raw[0])) {
if (is_array($raw) && is_string($raw[0]) && is_string($raw[1])) {
return $this->buildStaticMethod(new ReflectionMethod($raw[0], $raw[1]), $depth);
}

/** @var callable-string $raw */
if (str_contains($raw, ':')) {
if (is_string($raw) && str_contains($raw, ':')) {
/** @var class-string $class */
$class = (string) strstr($raw, ':', true);
$method = substr((string) strrchr($raw, ':'), 1);

return $this->buildStaticMethod(new ReflectionMethod($class, $method), $depth);
}

if (!is_string($raw)) {
return null;
}

return $this->buildFunction(new ReflectionFunction($raw), $depth);
}

public function buildFunction(ReflectionFunction $raw, int $depth): ?string
public function buildFunction(ReflectionFunction $raw, int $depth): string
{
return $this->quoter->quote($this->buildSignature($raw, $depth), $depth);
}
Expand All @@ -90,15 +93,15 @@ private function buildMethod(ReflectionMethod $reflection, object $object, int $
{
return $this->quoter->quote(
sprintf('%s->%s', $this->getName($object), $this->buildSignature($reflection, $depth)),
$depth
$depth,
);
}

private function buildStaticMethod(ReflectionMethod $reflection, int $depth): string
{
return $this->quoter->quote(
sprintf('%s::%s', $reflection->class, $this->buildSignature($reflection, $depth)),
$depth
$depth,
);
}

Expand All @@ -112,10 +115,10 @@ private function buildSignature(ReflectionFunctionAbstract $function, int $depth
array_map(
fn(ReflectionParameter $parameter): string => $this->buildParameter(
$parameter,
$depth + 1
$depth + 1,
),
$function->getParameters()
)
$function->getParameters(),
),
),
);

Expand All @@ -125,7 +128,7 @@ private function buildSignature(ReflectionFunctionAbstract $function, int $depth
' use ($%s)',
implode(
', $',
array_keys($closureUsedVariables)
array_keys($closureUsedVariables),
),
);
}
Expand Down Expand Up @@ -160,7 +163,7 @@ private function buildParameter(ReflectionParameter $reflectionParameter, int $d
return $parameter;
}

private function buildValue(ReflectionParameter $reflectionParameter, int $depth): ?string
private function buildValue(ReflectionParameter $reflectionParameter, int $depth): string|null
{
if (!$reflectionParameter->isDefaultValueAvailable()) {
return $this->stringifier->stringify(null, $depth);
Expand All @@ -178,19 +181,26 @@ private function buildType(ReflectionType $raw, int $depth): string
if ($raw instanceof ReflectionUnionType) {
return implode(
'|',
array_map(fn(ReflectionType $type) => $this->buildType($type, $depth), $raw->getTypes())
array_map(fn(ReflectionType $type) => $this->buildType($type, $depth), $raw->getTypes()),
);
}

if ($raw instanceof ReflectionIntersectionType) {
return implode(
'&',
array_map(fn(ReflectionType $type) => $this->buildType($type, $depth), $raw->getTypes())
array_map(fn(ReflectionType $type) => $this->buildType($type, $depth), $raw->getTypes()),
);
}

/** @var ReflectionNamedType $raw */
if ($raw instanceof ReflectionNamedType) {
$type = $raw->getName();
if ($raw->allowsNull()) {
$type = sprintf('?%s', $type);
}

return $type;
}

return ($raw->allowsNull() ? '?' : '') . $raw->getName();
return '';
}
}
20 changes: 9 additions & 11 deletions src/Stringifiers/CompositeStringifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@

final class CompositeStringifier implements Stringifier
{
private const MAXIMUM_DEPTH = 3;
private const MAXIMUM_NUMBER_OF_ITEMS = 5;
private const MAXIMUM_NUMBER_OF_PROPERTIES = self::MAXIMUM_NUMBER_OF_ITEMS;
private const MAXIMUM_LENGTH = 120;
private const int MAXIMUM_DEPTH = 3;
private const int MAXIMUM_NUMBER_OF_ITEMS = 5;
private const int MAXIMUM_NUMBER_OF_PROPERTIES = self::MAXIMUM_NUMBER_OF_ITEMS;
private const int MAXIMUM_LENGTH = 120;

/**
* @var Stringifier[]
*/
/** @var Stringifier[] */
private array $stringifiers = [];

public function __construct(Stringifier ...$stringifiers)
Expand All @@ -52,15 +50,15 @@ public static function createDefault(): self
$quoter,
self::MAXIMUM_DEPTH,
self::MAXIMUM_NUMBER_OF_ITEMS,
)
),
);
$stringifier->prependStringifier(
new ObjectStringifier(
$stringifier,
$quoter,
self::MAXIMUM_DEPTH,
self::MAXIMUM_NUMBER_OF_PROPERTIES
)
self::MAXIMUM_NUMBER_OF_PROPERTIES,
),
);
$stringifier->prependStringifier($callableStringifier = new CallableStringifier($stringifier, $quoter));
$stringifier->prependStringifier(new FiberObjectStringifier($callableStringifier, $quoter));
Expand All @@ -81,7 +79,7 @@ public function prependStringifier(Stringifier $stringifier): void
array_unshift($this->stringifiers, $stringifier);
}

public function stringify(mixed $raw, int $depth): ?string
public function stringify(mixed $raw, int $depth): string|null
{
foreach ($this->stringifiers as $stringifier) {
$string = $stringifier->stringify($raw, $depth);
Expand Down
4 changes: 2 additions & 2 deletions src/Stringifiers/DateTimeStringifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ final class DateTimeStringifier implements Stringifier

public function __construct(
private readonly Quoter $quoter,
private readonly string $format
private readonly string $format,
) {
}

public function stringify(mixed $raw, int $depth): ?string
public function stringify(mixed $raw, int $depth): string|null
{
if (!$raw instanceof DateTimeInterface) {
return null;
Expand Down
4 changes: 2 additions & 2 deletions src/Stringifiers/DeclaredStringifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
final class DeclaredStringifier implements Stringifier
{
public function __construct(
private readonly Quoter $quoter
private readonly Quoter $quoter,
) {
}

public function stringify(mixed $raw, int $depth): ?string
public function stringify(mixed $raw, int $depth): string|null
{
if (!is_string($raw) || $this->isNotDeclared($raw)) {
return null;
Expand Down
Loading