Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tr() and td() functions #102

Merged
merged 11 commits into from
May 28, 2024
Next Next commit
feat: add tr() function
roxblnfk committed May 24, 2024
commit 12d3d954f769012590843c3281415ef8936a4f4b
15 changes: 15 additions & 0 deletions src/Client/TrapHandle.php
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
use Buggregator\Trap\Client\TrapHandle\Counter;
use Buggregator\Trap\Client\TrapHandle\Dumper as VarDumper;
use Buggregator\Trap\Client\TrapHandle\StaticState;
use Buggregator\Trap\Support\Tick;
use Symfony\Component\VarDumper\Caster\TraceStub;

/**
@@ -35,6 +36,20 @@ public static function fromArray(array $array): self
return new self($array);
}

/**
* Create a new instance with a single value.
*
* @param int<0, max> $number The tick number.
* @param float $delta The time delta between the current and previous tick.
*/
public static function fromTicker(int $number, float $delta, int $memory): self
{
$self = new self([]);
$self->values[] = new Tick($number, $delta, $memory, $self->staticState->stackTrace[0]);

return $self;
}

/**
* Dump only if the condition is true.
* The check is performed immediately upon declaration.
Original file line number Diff line number Diff line change
@@ -2,11 +2,10 @@

declare(strict_types=1);

namespace Buggregator\Trap\Support;
namespace Buggregator\Trap\Support\Caster;

use Buggregator\Trap\Support\Caster\EnumValue;
use Google\Protobuf\Internal\Descriptor as InternalDescriptor;
use Google\Protobuf\Descriptor as PublicDescriptor;
use Google\Protobuf\Internal\Descriptor as InternalDescriptor;
use Google\Protobuf\Internal\DescriptorPool;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\MapField;
@@ -57,7 +56,7 @@
public static function cast(Message $c, array $a, Stub $stub, bool $isNested): array
{
/** @var PublicDescriptor|InternalDescriptor $descriptor */
$descriptor = DescriptorPool::getGeneratedPool()->getDescriptorByClassName($c::class);

Check failure on line 59 in src/Support/Caster/ProtobufCaster.php

GitHub Actions / static-analysis (ubuntu-latest, 8.2, locked)

MixedMethodCall

src/Support/Caster/ProtobufCaster.php:59:59: MixedMethodCall: Cannot determine the type of the object on the left hand side of this expression (see https://psalm.dev/015)

return self::castMessage($c, $descriptor);
}
@@ -121,7 +120,7 @@
for ($i = 0; $i < $pub->getFieldCount(); $i++) {
/** @var \Google\Protobuf\Internal\FieldDescriptor $fd */
$fd = $descriptor->getFieldByIndex($i);
$value = $message->{$fd->getGetter()}();

Check failure on line 123 in src/Support/Caster/ProtobufCaster.php

GitHub Actions / static-analysis (ubuntu-latest, 8.2, locked)

MixedAssignment

src/Support/Caster/ProtobufCaster.php:123:13: MixedAssignment: Unable to determine the type that $value is being assigned to (see https://psalm.dev/032)

// Skip defaults

@@ -141,11 +140,11 @@
continue;
}

if ($fd->isRepeated() && \count($value) === 0) {

Check failure on line 143 in src/Support/Caster/ProtobufCaster.php

GitHub Actions / static-analysis (ubuntu-latest, 8.2, locked)

MixedArgument

src/Support/Caster/ProtobufCaster.php:143:45: MixedArgument: Argument 1 of count cannot be mixed, expecting Countable|array<array-key, mixed> (see https://psalm.dev/030)
continue;
}

if ($fd->isMap() && \count($value) === 0) {

Check failure on line 147 in src/Support/Caster/ProtobufCaster.php

GitHub Actions / static-analysis (ubuntu-latest, 8.2, locked)

MixedArgument

src/Support/Caster/ProtobufCaster.php:147:40: MixedArgument: Argument 1 of count cannot be mixed, expecting Countable|array<array-key, mixed> (see https://psalm.dev/030)
continue;
}

@@ -156,8 +155,8 @@
/** @var \Google\Protobuf\Internal\EnumValueDescriptorProto $v */
$v = $ed->getValueByNumber($value);

$values[$fd->getName()] = new EnumValue(

Check failure on line 158 in src/Support/Caster/ProtobufCaster.php

GitHub Actions / static-analysis (ubuntu-latest, 8.2, locked)

MixedArrayOffset

src/Support/Caster/ProtobufCaster.php:158:17: MixedArrayOffset: Cannot access value on variable $values[mixed] using mixed offset (see https://psalm.dev/031)
class: $ed->getClass(),

Check failure on line 159 in src/Support/Caster/ProtobufCaster.php

GitHub Actions / static-analysis (ubuntu-latest, 8.2, locked)

MixedArgument

src/Support/Caster/ProtobufCaster.php:159:28: MixedArgument: Argument 1 of Buggregator\Trap\Support\Caster\EnumValue::__construct cannot be mixed, expecting string (see https://psalm.dev/030)
name: $v->getName(),
value: $v->getNumber(),
);
23 changes: 23 additions & 0 deletions src/Support/Caster/TickerCaster.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Buggregator\Trap\Support\Caster;

use Buggregator\Trap\Support\Tick;
use Symfony\Component\VarDumper\Cloner\Stub;

/**
* @internal
*/
final class TickerCaster
{
public static function cast(Tick $tick, array $a, Stub $stub, bool $isNested): mixed
{
$stub->type = $stub::TYPE_REF;
$stub->class = $tick->__toString();
$stub->attr = $tick->line;

return [];
}
}
62 changes: 62 additions & 0 deletions src/Support/Tick.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace Buggregator\Trap\Support;

/**
* Data object representing a tick.
*
* @see tr()
* @internal
*/
final class Tick
{
/**
* @param int<0, max> $number The tick number.
* @param float $delta The time delta between the current and previous tick.
* @param int $memory The memory usage.
* @param array{
* function?: string,
* line?: int,
* file?: string,
* class?: class-string,
* type?: string,
* args?: list<mixed>
* } $line The stack trace line.
*/
public function __construct(
public readonly int $number,
public readonly float $delta,
public readonly int $memory,
public readonly array $line,
) {
}

public function __toString(): string
{
// Format delta
$delta = $this->delta;
$deltaStr = match (true) {
$delta === 0.0 => '-.---',
$delta < 0.001 => \sprintf('+%.3fms', $delta * 1000),
$delta < 0.01 => \sprintf('+%.2fms', $delta * 1000),
$delta < 1 => \sprintf('+%.1fms', ($delta * 1000)),
$delta < 10 => \sprintf('+%.2fs', $delta),
$delta < 60 => \sprintf('+%.3fs', $delta),
default => \sprintf('+%dm %ds', (int) $delta % 60, (int) $delta % 60),
};

return \sprintf(
"Tick #%d %s %sM",
$this->number,
$deltaStr,
\number_format(
$this->memory / 1024 / 1024,
2,
'.',
'_',
),
);
}
}
44 changes: 43 additions & 1 deletion src/functions.php
Original file line number Diff line number Diff line change
@@ -4,7 +4,9 @@

use Buggregator\Trap\Client\TrapHandle;
use Buggregator\Trap\Support\Caster\EnumValue;
use Buggregator\Trap\Support\ProtobufCaster;
use Buggregator\Trap\Support\Caster\ProtobufCaster;
use Buggregator\Trap\Support\Caster\TickerCaster;
use Buggregator\Trap\Support\Tick;
use Google\Protobuf\Internal\MapField;
use Google\Protobuf\Internal\Message;
use Google\Protobuf\Internal\RepeatedField;
@@ -26,6 +28,44 @@ function trap(mixed ...$values): TrapHandle
// do nothing
}

try {
/**
* Send values into Buggregator and return the first value.
*
* When arguments are passed it equals to {@see trap()} with `->return()` method call.
* When no arguments passed, it calculates ticks, time between the last `tr()` call and memory usage.
*
* @param mixed ...$values
*/
function tr(mixed ...$values): mixed
{
static $counter = -1;
static $time = 0;

++$counter;

try {
if ($values === []) {
$previous = $time;
$mem = $time = \microtime(true);
return TrapHandle::fromTicker(
$counter,
$counter === 0 ? 0 : $mem - $previous,
memory_get_usage(),
)->return();
}

$mem = $time = \microtime(true);
/** @psalm-suppress InternalMethod */
return TrapHandle::fromArray($values)->return();
} finally {
$mem === $time and $time = \microtime(true);
}
}
} catch (\Throwable $e) {
// do nothing
}

/**
* Register the var-dump caster for protobuf messages
*/
@@ -38,4 +78,6 @@ function trap(mixed ...$values): TrapHandle
AbstractCloner::$defaultCasters[MapField::class] ??= [ProtobufCaster::class, 'castMap'];
/** @psalm-suppress MixedAssignment */
AbstractCloner::$defaultCasters[EnumValue::class] ??= [ProtobufCaster::class, 'castEnum'];
/** @psalm-suppress MixedAssignment */
AbstractCloner::$defaultCasters[Tick::class] ??= [TickerCaster::class, 'cast'];
}

Unchanged files with check annotations Beta

*/
public function setOnPayload(callable $callable): void
{
$this->onPayload = @\Closure::bind($callable(...), $this) ?? $callable(...);

Check failure on line 115 in src/Socket/Client.php

GitHub Actions / static-analysis (ubuntu-latest, 8.2, locked)

InvalidArgument

src/Socket/Client.php:115:28: InvalidArgument: Isset only works with variables and array elements (see https://psalm.dev/004)

Check failure on line 115 in src/Socket/Client.php

GitHub Actions / static-analysis (ubuntu-latest, 8.2, locked)

PossiblyNullPropertyAssignmentValue

src/Socket/Client.php:115:28: PossiblyNullPropertyAssignmentValue: $this->onPayload with non-nullable declared type 'Closure' cannot be assigned nullable type 'Closure|Closure(string):void|null' (see https://psalm.dev/148)
}
/**
*/
public function setOnClose(callable $callable): void
{
$this->onClose = @\Closure::bind($callable(...), $this) ?? $callable(...);

Check failure on line 124 in src/Socket/Client.php

GitHub Actions / static-analysis (ubuntu-latest, 8.2, locked)

InvalidArgument

src/Socket/Client.php:124:26: InvalidArgument: Isset only works with variables and array elements (see https://psalm.dev/004)

Check failure on line 124 in src/Socket/Client.php

GitHub Actions / static-analysis (ubuntu-latest, 8.2, locked)

PossiblyNullPropertyAssignmentValue

src/Socket/Client.php:124:26: PossiblyNullPropertyAssignmentValue: $this->onClose with non-nullable declared type 'Closure' cannot be assigned nullable type 'Closure|Closure():void|null' (see https://psalm.dev/148)
}
public function send(string $payload): void