fixing more psalm complaints

This commit is contained in:
Brett McBride 2025-07-16 17:02:47 +10:00
parent 7c9f012de4
commit 26b1143b4d
30 changed files with 119 additions and 54 deletions

View File

@ -1,4 +1,4 @@
FROM composer:2 AS composer FROM composer:2.8 AS composer
FROM debian:bullseye FROM debian:bullseye
WORKDIR /usr/src/myapp WORKDIR /usr/src/myapp
@ -38,7 +38,7 @@ RUN apt-get install -y \
COPY --from=composer /usr/bin/composer /usr/local/bin/composer COPY --from=composer /usr/bin/composer /usr/local/bin/composer
RUN echo ";grpc.enable_fork_support = 1" > $(php-config --ini-dir)/40-otel-dev.ini \ RUN echo "grpc.enable_fork_support = 1" > $(php-config --ini-dir)/40-otel-dev.ini \
&& echo "grpc.poll_strategy = epoll1" >> $(php-config --ini-dir)/40-otel-dev.ini \ && echo "grpc.poll_strategy = epoll1" >> $(php-config --ini-dir)/40-otel-dev.ini \
&& echo "zend.assertions = 1" >> $(php-config --ini-dir)/40-otel-dev.ini && echo "zend.assertions = 1" >> $(php-config --ini-dir)/40-otel-dev.ini

View File

@ -60,7 +60,7 @@ $otelHandler = new class(LogLevel::INFO) extends AbstractProcessingHandler {
{ {
return (new LogRecord($record['message'])) return (new LogRecord($record['message']))
->setSeverityText($record->level->toPsrLogLevel()) ->setSeverityText($record->level->toPsrLogLevel())
->setTimestamp((int) (microtime(true) * LogRecord::NANOS_PER_SECOND)) ->setTimestamp((int) (microtime(true) * (float) LogRecord::NANOS_PER_SECOND))
->setObservedTimestamp((int) $record->datetime->format('U') * LogRecord::NANOS_PER_SECOND) ->setObservedTimestamp((int) $record->datetime->format('U') * LogRecord::NANOS_PER_SECOND)
->setSeverityNumber(Severity::fromPsr3($record->level->toPsrLogLevel())) ->setSeverityNumber(Severity::fromPsr3($record->level->toPsrLogLevel()))
->setAttributes($record->context + $record->extra); ->setAttributes($record->context + $record->extra);

View File

@ -15,6 +15,9 @@ use OpenTelemetry\SDK\Trace\TracerProvider;
$filename = sys_get_temp_dir() . '/traces.jsonl'; $filename = sys_get_temp_dir() . '/traces.jsonl';
$file = fopen($filename, 'a'); $file = fopen($filename, 'a');
if ($file === false) {
throw new \RuntimeException('Failed to open file for writing: ' . $filename);
}
$transport = (new StreamTransportFactory())->create($file, ContentTypes::NDJSON); $transport = (new StreamTransportFactory())->create($file, ContentTypes::NDJSON);
$exporter = new SpanExporter($transport); $exporter = new SpanExporter($transport);

View File

@ -15,6 +15,7 @@
<directory name="./examples/traces/demo/"/> <directory name="./examples/traces/demo/"/>
<directory name="tests/Unit/Config/SDK/Configuration/ExampleSdk"/> <directory name="tests/Unit/Config/SDK/Configuration/ExampleSdk"/>
<directory name="tests/TraceContext/W3CTestService"/> <directory name="tests/TraceContext/W3CTestService"/>
<directory name="vendor"/>
</ignoreFiles> </ignoreFiles>
</projectFiles> </projectFiles>
<plugins> <plugins>
@ -27,11 +28,6 @@
<referencedClass name="GMP"/> <referencedClass name="GMP"/>
</errorLevel> </errorLevel>
</UndefinedClass> </UndefinedClass>
<UndefinedFunction>
<errorLevel type="suppress">
<referencedFunction name="OpenTelemetry\Instrumentation\hook"/>
</errorLevel>
</UndefinedFunction>
<UndefinedMethod> <UndefinedMethod>
<errorLevel type="suppress"> <errorLevel type="suppress">
<referencedMethod name="Google\Protobuf\Internal\RepeatedField::offsetGet"/> <referencedMethod name="Google\Protobuf\Internal\RepeatedField::offsetGet"/>
@ -43,11 +39,6 @@
<directory name="./examples"/> <directory name="./examples"/>
</errorLevel> </errorLevel>
</ArgumentTypeCoercion> </ArgumentTypeCoercion>
<InvalidArgument>
<errorLevel type="suppress">
<directory name="src/Config/SDK/Configuration/Internal"/>
</errorLevel>
</InvalidArgument>
<UndefinedInterfaceMethod> <UndefinedInterfaceMethod>
<errorLevel type="suppress"> <errorLevel type="suppress">
<directory name="src/Config/SDK/ComponentProvider"/> <directory name="src/Config/SDK/ComponentProvider"/>
@ -57,34 +48,56 @@
<PossiblyInvalidArgument> <PossiblyInvalidArgument>
<errorLevel type="suppress"> <errorLevel type="suppress">
<directory name="src/Config/SDK/Configuration"/> <directory name="src/Config/SDK/Configuration"/>
<directory name="tests/Integration/Config"/>
</errorLevel> </errorLevel>
</PossiblyInvalidArgument> </PossiblyInvalidArgument>
<PossiblyNullReference>
<errorLevel type="suppress">
<directory name="src/Config/SDK/ComponentProvider"/>
<directory name="tests/Integration/Config/ComponentProvider"/>
</errorLevel>
</PossiblyNullReference>
<MoreSpecificImplementedParamType> <MoreSpecificImplementedParamType>
<errorLevel type="suppress"> <errorLevel type="suppress">
<directory name="src/Config/SDK/ComponentProvider"/> <directory name="src/Config/SDK/ComponentProvider"/>
<directory name="tests/Integration/Config/ComponentProvider"/> <directory name="tests"/>
</errorLevel> </errorLevel>
</MoreSpecificImplementedParamType> </MoreSpecificImplementedParamType>
<InvalidDocblock> <UndefinedMagicMethod>
<errorLevel type="suppress"> <errorLevel type="suppress">
<directory name="src/Config/SDK/ComponentProvider"/> <referencedMethod name="Prophecy\Prophecy\ObjectProphecy::accepts"/>
<referencedMethod name="Prophecy\Prophecy\ObjectProphecy::fields"/>
</errorLevel> </errorLevel>
</InvalidDocblock> </UndefinedMagicMethod>
<NonInvariantDocblockPropertyType> <PossiblyFalseArgument>
<errorLevel type="suppress"> <errorLevel type="suppress">
<directory name="src/Config/SDK/Configuration/Internal"/> <directory name="tests"/>
</errorLevel> </errorLevel>
</NonInvariantDocblockPropertyType> </PossiblyFalseArgument>
<NonInvariantPropertyType> <PossiblyFalseOperand>
<errorLevel type="suppress"> <errorLevel type="suppress">
<directory name="src/Config/SDK/Configuration/Internal"/> <directory name="examples/baggage"/>
<file name="src/SDK/Metrics/MetricExporter/ConsoleMetricExporter.php"/>
</errorLevel> </errorLevel>
</NonInvariantPropertyType> </PossiblyFalseOperand>
<InvalidOperand>
<errorLevel type="suppress">
<directory name="tests"/>
</errorLevel>
</InvalidOperand>
<FalsableReturnStatement>
<errorLevel type="suppress">
<directory name="src/API/Trace"/>
</errorLevel>
</FalsableReturnStatement>
<PossiblyNullArgument>
<errorLevel type="suppress">
<file name="src/API/Instrumentation/CachedInstrumentation.php"/>
</errorLevel>
</PossiblyNullArgument>
<InvalidNullableReturnType>
<errorLevel type="suppress">
<file name="src/API/Instrumentation/CachedInstrumentation.php"/>
</errorLevel>
</InvalidNullableReturnType>
<NullableReturnStatement>
<errorLevel type="suppress">
<file name="src/API/Instrumentation/CachedInstrumentation.php"/>
</errorLevel>
</NullableReturnStatement>
</issueHandlers> </issueHandlers>
</psalm> </psalm>

View File

@ -48,6 +48,6 @@ final class SystemClock implements ClockInterface
*/ */
private static function calculateReferenceTime(float $wallClockMicroTime, int $upTime): int private static function calculateReferenceTime(float $wallClockMicroTime, int $upTime): int
{ {
return ((int) ($wallClockMicroTime * ClockInterface::NANOS_PER_SECOND)) - $upTime; return ((int) ($wallClockMicroTime * (float) ClockInterface::NANOS_PER_SECOND)) - $upTime;
} }
} }

View File

@ -62,6 +62,7 @@ final class CachedInstrumentation
return $this->meters[$meterProvider] ??= $meterProvider->getMeter($this->name, $this->version, $this->schemaUrl, $this->attributes); return $this->meters[$meterProvider] ??= $meterProvider->getMeter($this->name, $this->version, $this->schemaUrl, $this->attributes);
} }
public function logger(): LoggerInterface public function logger(): LoggerInterface
{ {
$loggerProvider = Globals::loggerProvider(); $loggerProvider = Globals::loggerProvider();

View File

@ -94,6 +94,9 @@ class TraceState implements TraceStateInterface
foreach ([128, 0] as $threshold) { foreach ([128, 0] as $threshold) {
// Then entries SHOULD be removed starting from the end of tracestate. // Then entries SHOULD be removed starting from the end of tracestate.
for ($value = end($traceState); $key = key($traceState);) { for ($value = end($traceState); $key = key($traceState);) {
if ($value === false) {
continue;
}
$entry = strlen($key) + 1 + strlen($value); $entry = strlen($key) + 1 + strlen($value);
$value = prev($traceState); $value = prev($traceState);
if ($entry <= $threshold) { if ($entry <= $threshold) {

View File

@ -27,6 +27,7 @@ use OpenTelemetry\Config\SDK\Configuration\Internal\ResourceCollection;
use OpenTelemetry\Config\SDK\Configuration\Internal\TrackingEnvReader; use OpenTelemetry\Config\SDK\Configuration\Internal\TrackingEnvReader;
use OpenTelemetry\Config\SDK\Configuration\Loader\YamlExtensionFileLoader; use OpenTelemetry\Config\SDK\Configuration\Loader\YamlExtensionFileLoader;
use OpenTelemetry\Config\SDK\Configuration\Loader\YamlSymfonyFileLoader; use OpenTelemetry\Config\SDK\Configuration\Loader\YamlSymfonyFileLoader;
use RuntimeException;
use function serialize; use function serialize;
use function sprintf; use function sprintf;
use Symfony\Component\Config\Definition\Builder\NodeBuilder; use Symfony\Component\Config\Definition\Builder\NodeBuilder;
@ -107,7 +108,11 @@ final class ConfigurationFactory
} }
$loader = new ConfigurationLoader($resources); $loader = new ConfigurationLoader($resources);
$locator = new FileLocator(getcwd()); $cwd = getcwd();
if ($cwd === false) {
throw new RuntimeException('Current working directory could not be determined.');
}
$locator = new FileLocator($cwd);
$fileLoader = new DelegatingLoader(new LoaderResolver([ $fileLoader = new DelegatingLoader(new LoaderResolver([
new YamlSymfonyFileLoader($loader, $locator), new YamlSymfonyFileLoader($loader, $locator),
new YamlExtensionFileLoader($loader, $locator), new YamlExtensionFileLoader($loader, $locator),

View File

@ -32,6 +32,9 @@ final class FiberBoundContextStorage implements ContextStorageInterface, Context
return $this->heads[Fiber::getCurrent() ?? $this] ?? null; return $this->heads[Fiber::getCurrent() ?? $this] ?? null;
} }
/**
* @psalm-suppress PossiblyNullPropertyFetch
*/
#[\Override] #[\Override]
public function scope(): ?ContextStorageScopeInterface public function scope(): ?ContextStorageScopeInterface
{ {
@ -62,6 +65,9 @@ final class FiberBoundContextStorage implements ContextStorageInterface, Context
return $head->node->context ?? Context::getRoot(); return $head->node->context ?? Context::getRoot();
} }
/**
* @psalm-suppress PossiblyNullArgument,PossiblyNullPropertyFetch
*/
#[\Override] #[\Override]
public function attach(ContextInterface $context): ContextStorageScopeInterface public function attach(ContextInterface $context): ContextStorageScopeInterface
{ {

View File

@ -43,6 +43,9 @@ final class SanitizeCombinedHeadersPropagationGetter implements ExtendedPropagat
); );
} }
/**
* @psalm-suppress PossiblyNullArgument
*/
#[\Override] #[\Override]
public function getAll($carrier, string $key): array public function getAll($carrier, string $key): array
{ {

View File

@ -33,6 +33,9 @@ final class ZendObserverFiber
: (bool) $enabled; : (bool) $enabled;
} }
/**
* @psalm-suppress PossiblyNullReference,UndefinedMethod
*/
public static function init(): bool public static function init(): bool
{ {
static $fibers; static $fibers;

View File

@ -84,7 +84,7 @@ final class GrpcTransportFactory implements TransportFactoryInterface
$opts, $opts,
$method, $method,
$headers, $headers,
(int) ($timeout * self::MILLIS_PER_SECOND), (int) ($timeout * (float) self::MILLIS_PER_SECOND),
); );
} }

View File

@ -214,6 +214,9 @@ final class MetricConverter
return $pHistogramDataPoint; return $pHistogramDataPoint;
} }
/**
* @psalm-suppress PossiblyFalseArgument
*/
private function convertExemplar(SDK\Metrics\Data\Exemplar $exemplar): Exemplar private function convertExemplar(SDK\Metrics\Data\Exemplar $exemplar): Exemplar
{ {
$pExemplar = new Exemplar(); $pExemplar = new Exemplar();

View File

@ -19,6 +19,7 @@ use function json_encode;
use const JSON_UNESCAPED_SLASHES; use const JSON_UNESCAPED_SLASHES;
use const JSON_UNESCAPED_UNICODE; use const JSON_UNESCAPED_UNICODE;
use function lcfirst; use function lcfirst;
use OpenTelemetry\API\Behavior\LogsMessagesTrait;
use OpenTelemetry\SDK\Common\Export\TransportInterface; use OpenTelemetry\SDK\Common\Export\TransportInterface;
use function property_exists; use function property_exists;
use function sprintf; use function sprintf;
@ -30,6 +31,7 @@ use function ucwords;
*/ */
final class ProtobufSerializer final class ProtobufSerializer
{ {
use LogsMessagesTrait;
private function __construct(private readonly string $contentType) private function __construct(private readonly string $contentType)
{ {
} }
@ -121,7 +123,14 @@ final class ProtobufSerializer
unset($payload); unset($payload);
self::traverseDescriptor($data, $desc); self::traverseDescriptor($data, $desc);
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); $encoded = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
if ($encoded === false) {
self::logWarning('Failed to encode protobuf to JSON: ' . json_last_error_msg());
return '';
}
return $encoded;
} }
private static function traverseDescriptor(object $data, Descriptor $desc): void private static function traverseDescriptor(object $data, Descriptor $desc): void

View File

@ -101,7 +101,7 @@ final class PsrTransport implements TransportInterface
$delay = PsrUtils::retryDelay($retries, $this->retryDelay, $response); $delay = PsrUtils::retryDelay($retries, $this->retryDelay, $response);
$sec = (int) $delay; $sec = (int) $delay;
$nsec = (int) (($delay - $sec) * 1e9); $nsec = (int) (($delay - (float) $sec) * 1e9);
/** @psalm-suppress ArgumentTypeCoercion */ /** @psalm-suppress ArgumentTypeCoercion */
if (time_nanosleep($sec, $nsec) !== true) { if (time_nanosleep($sec, $nsec) !== true) {

View File

@ -64,7 +64,7 @@ final class StreamTransport implements TransportInterface
} }
if ($bytesWritten !== strlen($payload)) { if ($bytesWritten !== strlen($payload)) {
return new ErrorFuture(new RuntimeException(sprintf('Write failure, wrote %d of %d bytes', $bytesWritten, strlen($payload)))); return new ErrorFuture(new RuntimeException(sprintf('Write failure, wrote %d of %d bytes', $bytesWritten ?: 0, strlen($payload))));
} }
return new CompletedFuture(null); return new CompletedFuture(null);

View File

@ -28,8 +28,8 @@ final class StreamTransportFactory implements TransportFactoryInterface
* *
* @psalm-template CONTENT_TYPE of string * @psalm-template CONTENT_TYPE of string
* @psalm-param CONTENT_TYPE $contentType * @psalm-param CONTENT_TYPE $contentType
* @psalm-return TransportInterface<CONTENT_TYPE>
* @throws ErrorException * @throws ErrorException
* @psalm-return TransportInterface<CONTENT_TYPE>
*/ */
#[\Override] #[\Override]
public function create( public function create(

View File

@ -51,6 +51,7 @@ final class Configurator
/** /**
* @return T * @return T
* @psalm-suppress PossiblyNullArgument
*/ */
public function resolve(InstrumentationScopeInterface $instrumentationScope): Config public function resolve(InstrumentationScopeInterface $instrumentationScope): Config
{ {

View File

@ -46,6 +46,7 @@ final class ShutdownHandler
* @param callable $shutdownFunction function to register * @param callable $shutdownFunction function to register
* *
* @see register_shutdown_function * @see register_shutdown_function
* @psalm-suppress PossiblyNullArgument,PossiblyNullPropertyFetch
*/ */
public static function register(callable $shutdownFunction): void public static function register(callable $shutdownFunction): void
{ {

View File

@ -47,7 +47,7 @@ function weaken(Closure $closure, ?object &$target = null): Closure
$ref = WeakReference::create($target); $ref = WeakReference::create($target);
/** /**
* @psalm-suppress all * @psalm-suppress PossiblyNullReference,PossiblyNullFunctionCall
*/ */
return $scope && $target::class === $scope->name && !$scope->isInternal() return $scope && $target::class === $scope->name && !$scope->isInternal()
? static fn (...$args) => ($obj = $ref->get()) ? $closure->call($obj, ...$args) : null ? static fn (...$args) => ($obj = $ref->get()) ? $closure->call($obj, ...$args) : null

View File

@ -4,9 +4,11 @@ declare(strict_types=1);
namespace OpenTelemetry\SDK\Logs\Exporter; namespace OpenTelemetry\SDK\Logs\Exporter;
use OpenTelemetry\API\Behavior\LogsMessagesTrait;
use OpenTelemetry\SDK\Common\Export\TransportInterface; use OpenTelemetry\SDK\Common\Export\TransportInterface;
use OpenTelemetry\SDK\Common\Future\CancellationInterface; use OpenTelemetry\SDK\Common\Future\CancellationInterface;
use OpenTelemetry\SDK\Common\Future\CompletedFuture; use OpenTelemetry\SDK\Common\Future\CompletedFuture;
use OpenTelemetry\SDK\Common\Future\ErrorFuture;
use OpenTelemetry\SDK\Common\Future\FutureInterface; use OpenTelemetry\SDK\Common\Future\FutureInterface;
use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface; use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
use OpenTelemetry\SDK\Logs\LogRecordExporterInterface; use OpenTelemetry\SDK\Logs\LogRecordExporterInterface;
@ -45,7 +47,13 @@ class ConsoleExporter implements LogRecordExporterInterface
'resource' => $resource, 'resource' => $resource,
'scopes' => array_values($scopes), 'scopes' => array_values($scopes),
]; ];
$this->transport->send(json_encode($output, JSON_PRETTY_PRINT)); $payload = json_encode($output, JSON_PRETTY_PRINT);
if ($payload === false) {
return new ErrorFuture(
new \RuntimeException('Failed to encode log records to JSON: ' . json_last_error_msg())
););
}
$this->transport->send($payload);
return new CompletedFuture(true); return new CompletedFuture(true);
} }

View File

@ -31,7 +31,7 @@ class ReadableLogRecord extends LogRecord
parent::__construct($logRecord->body); parent::__construct($logRecord->body);
$this->timestamp = $logRecord->timestamp; $this->timestamp = $logRecord->timestamp;
$this->observedTimestamp = $logRecord->observedTimestamp $this->observedTimestamp = $logRecord->observedTimestamp
?? (int) (microtime(true) * LogRecord::NANOS_PER_SECOND); ?? (int) (microtime(true) * (float) LogRecord::NANOS_PER_SECOND);
$this->context = $logRecord->context; $this->context = $logRecord->context;
$context = $this->context ?? Context::getCurrent(); $context = $this->context ?? Context::getCurrent();
$this->spanContext = Span::fromContext($context)->getContext(); $this->spanContext = Span::fromContext($context)->getContext();

View File

@ -62,7 +62,9 @@ final class ExplicitBucketHistogramAggregation implements AggregationInterface
public function merge($left, $right): ExplicitBucketHistogramSummary public function merge($left, $right): ExplicitBucketHistogramSummary
{ {
$count = $left->count + $right->count; $count = $left->count + $right->count;
$sum = $left->sum + $right->sum; $sum = (is_int($left->sum) && is_int($right->sum))
? ($left->sum + $right->sum)
: ((float) $left->sum + (float) $right->sum);
$min = self::min($left->min, $right->min); $min = self::min($left->min, $right->min);
$max = self::max($left->max, $right->max); $max = self::max($left->max, $right->max);
$buckets = $right->buckets; $buckets = $right->buckets;
@ -87,7 +89,9 @@ final class ExplicitBucketHistogramAggregation implements AggregationInterface
public function diff($left, $right): ExplicitBucketHistogramSummary public function diff($left, $right): ExplicitBucketHistogramSummary
{ {
$count = -$left->count + $right->count; $count = -$left->count + $right->count;
$sum = -$left->sum + $right->sum; $sum = (is_int($left->sum) && is_int($right->sum))
? (-$left->sum + $right->sum)
: (-(float) $left->sum + (float) $right->sum);
$min = $left->min > $right->min ? $right->min : NAN; $min = $left->min > $right->min ? $right->min : NAN;
$max = $left->max < $right->max ? $right->max : NAN; $max = $left->max < $right->max ? $right->max : NAN;
$buckets = $right->buckets; $buckets = $right->buckets;

View File

@ -40,11 +40,11 @@ final class SumAggregation implements AggregationInterface
#[\Override] #[\Override]
public function merge($left, $right): SumSummary public function merge($left, $right): SumSummary
{ {
$sum = $left->value + $right->value; $sum = (is_int($left->value) && is_int($right->value))
? ($left->value + $right->value)
: ((float) $left->value + (float) $right->value);
return new SumSummary( return new SumSummary($sum);
$sum,
);
} }
/** /**
@ -54,11 +54,11 @@ final class SumAggregation implements AggregationInterface
#[\Override] #[\Override]
public function diff($left, $right): SumSummary public function diff($left, $right): SumSummary
{ {
$sum = -$left->value + $right->value; $diff = (is_int($left->value) && is_int($right->value))
? (-$left->value + $right->value)
: (-(float) $left->value + (float) $right->value);
return new SumSummary( return new SumSummary($diff);
$sum,
);
} }
/** /**

View File

@ -42,9 +42,9 @@ interface AggregationInterface
/** /**
* @param array<AttributesInterface> $attributes * @param array<AttributesInterface> $attributes
* @psalm-param array<T> $summaries
* @param array<list<Exemplar>> $exemplars * @param array<list<Exemplar>> $exemplars
* @param string|Temporality $temporality * @param string|Temporality $temporality
* @psalm-param array<T> $summaries
*/ */
public function toData( public function toData(
array $attributes, array $attributes,

View File

@ -18,6 +18,7 @@ final class AsynchronousInstruments
/** /**
* @param ArrayAccess<object, ObservableCallbackDestructor> $destructors * @param ArrayAccess<object, ObservableCallbackDestructor> $destructors
* @param non-empty-list<Instrument> $instruments * @param non-empty-list<Instrument> $instruments
* @psalm-suppress PossiblyNullArgument,PossiblyNullPropertyAssignment,PossiblyNullPropertyFetch
*/ */
public static function observe( public static function observe(
MetricWriterInterface $writer, MetricWriterInterface $writer,

View File

@ -99,6 +99,7 @@ class TraceIdRatioBasedSampler implements SamplerInterface
assert($precision >= 1); assert($precision >= 1);
assert($wordSize >= 1 && ($wordSize & $wordSize - 1) === 0); assert($wordSize >= 1 && ($wordSize & $wordSize - 1) === 0);
/** @psalm-suppress PossiblyInvalidArrayAccess */
$b = unpack('J', pack('E', $probability))[1]; $b = unpack('J', pack('E', $probability))[1];
$e = $b >> 52 & (1 << 11) - 1; $e = $b >> 52 & (1 << 11) - 1;
$f = $b & (1 << 52) - 1 | ($e ? 1 << 52 : 0); $f = $b & (1 << 52) - 1 | ($e ? 1 << 52 : 0);

View File

@ -53,8 +53,8 @@ final class Span extends API\Span implements ReadWriteSpanInterface
* End users should use a {@see API\TracerInterface} in order to create spans. * End users should use a {@see API\TracerInterface} in order to create spans.
* *
* @param non-empty-string $name * @param non-empty-string $name
* @psalm-param API\SpanKind::KIND_* $kind
* @param list<LinkInterface> $links * @param list<LinkInterface> $links
* @psalm-param API\SpanKind::KIND_* $kind
* *
* @internal * @internal
* @psalm-internal OpenTelemetry * @psalm-internal OpenTelemetry

View File

@ -831,8 +831,8 @@ class SpanTest extends MockeryTestCase
} }
/** /**
* @psalm-param API\SpanKind::KIND_* $kind
* @param list<LinkInterface> $links * @param list<LinkInterface> $links
* @psalm-param API\SpanKind::KIND_* $kind
*/ */
private function createTestSpan( private function createTestSpan(
int $kind = API\SpanKind::KIND_INTERNAL, int $kind = API\SpanKind::KIND_INTERNAL,

View File

@ -1,7 +1,7 @@
{ {
"require-dev": { "require-dev": {
"vimeo/psalm": "^5.24", "vimeo/psalm": "^6",
"psalm/plugin-mockery": "^1", "psalm/plugin-mockery": "^1",
"psalm/plugin-phpunit": "^0.18.4" "psalm/plugin-phpunit": "^0.19"
} }
} }