Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
245
src/Framework/Tokenizer/ValueObjects/TokenCollection.php
Normal file
245
src/Framework/Tokenizer/ValueObjects/TokenCollection.php
Normal file
@@ -0,0 +1,245 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Tokenizer\ValueObjects;
|
||||
|
||||
use ArrayIterator;
|
||||
use Countable;
|
||||
use IteratorAggregate;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* Collection of tokens with utility methods
|
||||
*/
|
||||
final readonly class TokenCollection implements IteratorAggregate, Countable
|
||||
{
|
||||
/**
|
||||
* @param array<Token> $tokens
|
||||
*/
|
||||
public function __construct(
|
||||
private array $tokens = []
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get iterator for the collection
|
||||
*/
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
return new ArrayIterator($this->tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count tokens in collection
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
return count($this->tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all tokens as array
|
||||
* @return array<Token>
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get token at index
|
||||
*/
|
||||
public function get(int $index): ?Token
|
||||
{
|
||||
return $this->tokens[$index] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter tokens by predicate
|
||||
*/
|
||||
public function filter(callable $predicate): self
|
||||
{
|
||||
return new self(array_values(array_filter($this->tokens, $predicate)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by token type
|
||||
*/
|
||||
public function filterByType(TokenType ...$types): self
|
||||
{
|
||||
return $this->filter(fn (Token $token) => in_array($token->type, $types, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by PHP token ID
|
||||
*/
|
||||
public function filterById(int ...$ids): self
|
||||
{
|
||||
return $this->filter(fn (Token $token) => in_array($token->id, $ids, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get only structural tokens
|
||||
*/
|
||||
public function getStructural(): self
|
||||
{
|
||||
return $this->filter(fn (Token $token) => $token->isStructural());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get only identifiers
|
||||
*/
|
||||
public function getIdentifiers(): self
|
||||
{
|
||||
return $this->filter(fn (Token $token) => $token->isIdentifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tokens in line range
|
||||
*/
|
||||
public function getInLineRange(int $startLine, int $endLine): self
|
||||
{
|
||||
return $this->filter(
|
||||
fn (Token $token) =>
|
||||
$token->line >= $startLine && $token->line <= $endLine
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tokens at specific line
|
||||
*/
|
||||
public function getAtLine(int $line): self
|
||||
{
|
||||
return $this->filter(fn (Token $token) => $token->line === $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find first token matching predicate
|
||||
*/
|
||||
public function findFirst(callable $predicate): ?Token
|
||||
{
|
||||
foreach ($this->tokens as $token) {
|
||||
if ($predicate($token)) {
|
||||
return $token;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find first token of type
|
||||
*/
|
||||
public function findFirstOfType(TokenType $type): ?Token
|
||||
{
|
||||
return $this->findFirst(fn (Token $token) => $token->type === $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map tokens to another form
|
||||
*/
|
||||
public function map(callable $mapper): array
|
||||
{
|
||||
return array_map($mapper, $this->tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract all values
|
||||
*/
|
||||
public function getValues(): array
|
||||
{
|
||||
return $this->map(fn (Token $token) => $token->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract all clean values
|
||||
*/
|
||||
public function getCleanValues(): array
|
||||
{
|
||||
return $this->map(fn (Token $token) => $token->getCleanValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tokens grouped by type
|
||||
* @return array<string, array<Token>>
|
||||
*/
|
||||
public function groupByType(): array
|
||||
{
|
||||
$groups = [];
|
||||
foreach ($this->tokens as $token) {
|
||||
$type = $token->type->value;
|
||||
if (! isset($groups[$type])) {
|
||||
$groups[$type] = [];
|
||||
}
|
||||
$groups[$type][] = $token;
|
||||
}
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tokens grouped by line
|
||||
* @return array<int, array<Token>>
|
||||
*/
|
||||
public function groupByLine(): array
|
||||
{
|
||||
$groups = [];
|
||||
foreach ($this->tokens as $token) {
|
||||
if (! isset($groups[$token->line])) {
|
||||
$groups[$token->line] = [];
|
||||
}
|
||||
$groups[$token->line][] = $token;
|
||||
}
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if collection is empty
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get first token
|
||||
*/
|
||||
public function first(): ?Token
|
||||
{
|
||||
return $this->tokens[0] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last token
|
||||
*/
|
||||
public function last(): ?Token
|
||||
{
|
||||
return empty($this->tokens) ? null : $this->tokens[count($this->tokens) - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Slice collection
|
||||
*/
|
||||
public function slice(int $offset, ?int $length = null): self
|
||||
{
|
||||
return new self(array_slice($this->tokens, $offset, $length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge with another collection
|
||||
*/
|
||||
public function merge(self $other): self
|
||||
{
|
||||
return new self(array_merge($this->tokens, $other->tokens));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to string (concatenate all values)
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return implode('', $this->getValues());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user