Skip to content

Commit a4dec81

Browse files
committed
Remove location from Token
Update phpstan-baseline.neon
1 parent be4b3a4 commit a4dec81

File tree

6 files changed

+48
-42
lines changed

6 files changed

+48
-42
lines changed

phpstan-baseline.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ parameters:
2828
message: '#^Parameter \$column of class Vojtechdobes\\GrammarProcessing\\Location constructor expects int\<0, max\>, int given\.$#'
2929
identifier: argument.type
3030
count: 1
31-
path: src/GrammarProcessing/LexicalGrammar.php
31+
path: src/GrammarProcessing/LocationGetter.php

src/GrammarProcessing/LexicalGrammar.php

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,7 @@ public function parseSource(string $source): TokenStream
4242
throw new UnexpectedTokenException("Can't parse source: " . preg_last_error_msg(), null);
4343
}
4444

45-
$getLocation = function (int $offset) use ($source): Location {
46-
$precedingText = substr($source, 0, $offset);
47-
48-
return new Location(
49-
line: substr_count($precedingText, "\n") + 1,
50-
column: $offset - strrpos("\n" . $precedingText, "\n") + 1,
51-
);
52-
};
45+
$locationGetter = new LocationGetter($source);
5346

5447
$expectedOffset = 0;
5548
$endOffset = strlen($source);
@@ -58,7 +51,7 @@ public function parseSource(string $source): TokenStream
5851
if ($expectedOffset !== $match[0][1]) {
5952
$this->throwUnexpectedTokenException(
6053
$match[0][0],
61-
$getLocation($match[0][1]),
54+
$locationGetter->getLocation($match[0][1]),
6255
);
6356
}
6457

@@ -68,12 +61,12 @@ public function parseSource(string $source): TokenStream
6861
if ($expectedOffset !== strlen($source)) {
6962
$this->throwUnexpectedTokenException(
7063
substr($source, $expectedOffset),
71-
$getLocation($expectedOffset),
64+
$locationGetter->getLocation($expectedOffset),
7265
);
7366
}
7467

7568
if ($matches === []) {
76-
return new TokenStream([]);
69+
return new TokenStream([], $locationGetter);
7770
}
7871

7972
if ($this->ignoredTokenSymbols !== []) {
@@ -100,15 +93,15 @@ public function parseSource(string $source): TokenStream
10093
}
10194

10295
if ($matches === []) {
103-
return new TokenStream([]);
96+
return new TokenStream([], $locationGetter);
10497
}
10598

10699
$iMin = 1 + count($this->ignoredTokenSymbols);
107100
$iMax = count($this->syntaxTokenSymbols) + $iMin;
108101

109102
return new TokenStream(
110103
array_map(
111-
function (array $match) use ($getLocation, $iMax, $iMin): Token {
104+
function (array $match) use ($iMax, $iMin): Token {
112105
$type = NULL;
113106

114107
for ($i = $iMin; $i < $iMax; $i++) {
@@ -121,11 +114,11 @@ function (array $match) use ($getLocation, $iMax, $iMin): Token {
121114
$type,
122115
$match[0][0],
123116
$match[0][1],
124-
$getLocation,
125117
);
126118
},
127119
$matches,
128120
),
121+
$locationGetter,
129122
);
130123
}
131124

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Vojtechdobes\GrammarProcessing;
4+
5+
6+
final class LocationGetter
7+
{
8+
9+
public function __construct(
10+
private readonly string $source,
11+
) {}
12+
13+
14+
15+
public function getLocation(int $offset): Location
16+
{
17+
$precedingText = substr($this->source, 0, $offset);
18+
19+
return new Location(
20+
line: substr_count($precedingText, "\n") + 1,
21+
column: $offset - strrpos("\n" . $precedingText, "\n") + 1,
22+
);
23+
}
24+
25+
}

src/GrammarProcessing/Token.php

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,10 @@
66
final class Token
77
{
88

9-
/** @var callable(int): Location $getLocation */
10-
private $getLocation;
11-
12-
public Location $location {
13-
14-
get {
15-
return ($this->getLocation)($this->tokenOffset);
16-
}
17-
18-
}
19-
20-
21-
22-
/**
23-
* @param callable(int): Location $getLocation
24-
*/
259
public function __construct(
2610
public readonly string $type,
2711
public readonly string $value,
28-
private readonly int $tokenOffset,
29-
callable $getLocation,
30-
)
31-
{
32-
$this->getLocation = $getLocation;
33-
}
12+
public readonly int $offset,
13+
) {}
3414

3515
}

src/GrammarProcessing/TokenStream.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ final class TokenStream
1616
*/
1717
public function __construct(
1818
public readonly array $tokens,
19+
private readonly LocationGetter $locationGetter,
1920
) {}
2021

2122

@@ -65,7 +66,7 @@ public function consumeEndOfStream(): void
6566
throw new CannotConsumeTokenException(
6667
"Unexpected token '{$token->value}'",
6768
$this->currentToken,
68-
$token->location,
69+
$this->locationGetter->getLocation($token->offset),
6970
);
7071
}
7172

@@ -88,9 +89,9 @@ public function consumeTokenWithType(string $type): Token
8889

8990
if ($token->type !== $type) {
9091
throw new CannotConsumeTokenException(
91-
"Expected token with type '{$type}', got '{$token->type}' instead",
92+
"Expected token with type '{$type}', got '{$token->type}' ({$token->value}) instead",
9293
$this->currentToken,
93-
$token->location,
94+
$this->locationGetter->getLocation($token->offset),
9495
);
9596
}
9697

@@ -117,7 +118,7 @@ public function consumeTokenWithValue(string $value): Token
117118
throw new CannotConsumeTokenException(
118119
"Expected token '{$value}', got '{$token->value}' instead",
119120
$this->currentToken,
120-
$token->location,
121+
$this->locationGetter->getLocation($token->offset),
121122
);
122123
}
123124

tests/cases/LexicalGrammar.Test.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
$expectedTokens,
1717
] = $case;
1818

19+
$locationGetter = new Vojtechdobes\GrammarProcessing\LocationGetter($source);
20+
21+
function formatLocation(Vojtechdobes\GrammarProcessing\Location $location): string
22+
{
23+
return "{$location->line},{$location->column}";
24+
}
25+
1926
$lexicalGrammar = new Vojtechdobes\GrammarProcessing\LexicalGrammar(
2027
ignoredTokenSymbols: $ignoredTokenSymbols,
2128
syntaxTokenSymbols: $syntaxTokenSymbols,
@@ -31,7 +38,7 @@
3138
static fn ($token) => [
3239
$token->type,
3340
$token->value,
34-
"{$token->location->line},{$token->location->column}",
41+
formatLocation($locationGetter->getLocation($token->offset)),
3542
],
3643
$tokenStream->tokens,
3744
),

0 commit comments

Comments
 (0)