Skip to content

Commit 54a3d40

Browse files
committed
TASK: Turn parsers into singletons where applicable
1 parent ae2ab3c commit 54a3d40

File tree

36 files changed

+298
-193
lines changed

36 files changed

+298
-193
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/**
4+
* PackageFactory.ComponentEngine - Universal View Components for PHP
5+
* Copyright (C) 2023 Contributors of PackageFactory.ComponentEngine
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
declare(strict_types=1);
22+
23+
namespace PackageFactory\ComponentEngine\Framework\PHP\Singleton;
24+
25+
trait Singleton
26+
{
27+
private static ?self $instance = null;
28+
29+
private function __construct()
30+
{
31+
}
32+
33+
final public static function singleton(): static
34+
{
35+
return static::$instance ??= new static();
36+
}
37+
38+
final public function __clone()
39+
{
40+
trigger_error('Cloning ' . __CLASS__ . ' is not allowed.', E_USER_ERROR);
41+
}
42+
43+
final public function __wakeup()
44+
{
45+
trigger_error('Unserializing ' . __CLASS__ . ' is not allowed.', E_USER_ERROR);
46+
}
47+
}

src/Language/Parser/BooleanLiteral/BooleanLiteralParser.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,16 @@
2222

2323
namespace PackageFactory\ComponentEngine\Language\Parser\BooleanLiteral;
2424

25+
use PackageFactory\ComponentEngine\Framework\PHP\Singleton\Singleton;
2526
use PackageFactory\ComponentEngine\Language\AST\Node\BooleanLiteral\BooleanLiteralNode;
2627
use PackageFactory\ComponentEngine\Parser\Tokenizer\Scanner;
2728
use PackageFactory\ComponentEngine\Parser\Tokenizer\Token;
2829
use PackageFactory\ComponentEngine\Parser\Tokenizer\TokenType;
2930

3031
final class BooleanLiteralParser
3132
{
33+
use Singleton;
34+
3235
/**
3336
* @param \Iterator<mixed,Token> $tokens
3437
* @return BooleanLiteralNode

src/Language/Parser/ComponentDeclaration/ComponentDeclarationParser.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
namespace PackageFactory\ComponentEngine\Language\Parser\ComponentDeclaration;
2424

2525
use PackageFactory\ComponentEngine\Domain\ComponentName\ComponentName;
26+
use PackageFactory\ComponentEngine\Framework\PHP\Singleton\Singleton;
2627
use PackageFactory\ComponentEngine\Language\AST\Node\ComponentDeclaration\ComponentDeclarationNode;
2728
use PackageFactory\ComponentEngine\Language\AST\Node\ComponentDeclaration\ComponentNameNode;
2829
use PackageFactory\ComponentEngine\Language\AST\Node\Expression\ExpressionNode;
@@ -36,13 +37,10 @@
3637

3738
final class ComponentDeclarationParser
3839
{
39-
private readonly PropertyDeclarationParser $propertyDeclarationParser;
40-
private ?ExpressionParser $returnParser = null;
40+
use Singleton;
4141

42-
public function __construct()
43-
{
44-
$this->propertyDeclarationParser = new PropertyDeclarationParser();
45-
}
42+
private ?PropertyDeclarationParser $propertyDeclarationParser = null;
43+
private ?ExpressionParser $returnParser = null;
4644

4745
/**
4846
* @param \Iterator<mixed,Token> $tokens
@@ -125,8 +123,11 @@ private function skipOpeningBracketToken(\Iterator &$tokens): void
125123
*/
126124
private function parseProps(\Iterator &$tokens): PropertyDeclarationNodes
127125
{
126+
$this->propertyDeclarationParser ??= PropertyDeclarationParser::singleton();
127+
128128
$items = [];
129129
while (Scanner::type($tokens) !== TokenType::KEYWORD_RETURN) {
130+
assert($this->propertyDeclarationParser !== null);
130131
$items[] = $this->propertyDeclarationParser->parse($tokens);
131132

132133
Scanner::skipSpaceAndComments($tokens);

src/Language/Parser/EnumDeclaration/EnumDeclarationParser.php

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,15 @@
2424

2525
use PackageFactory\ComponentEngine\Domain\EnumMemberName\EnumMemberName;
2626
use PackageFactory\ComponentEngine\Domain\EnumName\EnumName;
27+
use PackageFactory\ComponentEngine\Framework\PHP\Singleton\Singleton;
2728
use PackageFactory\ComponentEngine\Language\AST\Node\EnumDeclaration\EnumDeclarationNode;
2829
use PackageFactory\ComponentEngine\Language\AST\Node\EnumDeclaration\EnumMemberDeclarationNode;
2930
use PackageFactory\ComponentEngine\Language\AST\Node\EnumDeclaration\EnumMemberDeclarationNodes;
3031
use PackageFactory\ComponentEngine\Language\AST\Node\EnumDeclaration\EnumMemberNameNode;
3132
use PackageFactory\ComponentEngine\Language\AST\Node\EnumDeclaration\EnumMemberValueNode;
3233
use PackageFactory\ComponentEngine\Language\AST\Node\EnumDeclaration\EnumNameNode;
34+
use PackageFactory\ComponentEngine\Language\AST\Node\IntegerLiteral\IntegerLiteralNode;
35+
use PackageFactory\ComponentEngine\Language\AST\Node\StringLiteral\StringLiteralNode;
3336
use PackageFactory\ComponentEngine\Language\Parser\IntegerLiteral\IntegerLiteralParser;
3437
use PackageFactory\ComponentEngine\Language\Parser\StringLiteral\StringLiteralParser;
3538
use PackageFactory\ComponentEngine\Parser\Source\Range;
@@ -39,14 +42,10 @@
3942

4043
final class EnumDeclarationParser
4144
{
42-
private readonly StringLiteralParser $stringLiteralParser;
43-
private readonly IntegerLiteralParser $integerLiteralParser;
45+
use Singleton;
4446

45-
public function __construct()
46-
{
47-
$this->stringLiteralParser = new StringLiteralParser();
48-
$this->integerLiteralParser = new IntegerLiteralParser();
49-
}
47+
private ?StringLiteralParser $stringLiteralParser = null;
48+
private ?IntegerLiteralParser $integerLiteralParser = null;
5049

5150
/**
5251
* @param \Iterator<mixed,Token> $tokens
@@ -213,12 +212,12 @@ private function parseEnumMemberValue(\Iterator &$tokens): ?EnumMemberValueNode
213212
$valueToken = $tokens->current();
214213
$value = match ($valueToken->type) {
215214
TokenType::STRING_QUOTED =>
216-
$this->stringLiteralParser->parse($tokens),
215+
$this->parseStringLiteral($tokens),
217216
TokenType::NUMBER_BINARY,
218217
TokenType::NUMBER_OCTAL,
219218
TokenType::NUMBER_DECIMAL,
220219
TokenType::NUMBER_HEXADECIMAL =>
221-
$this->integerLiteralParser->parse($tokens),
220+
$this->parseIntegerLiteral($tokens),
222221
default => throw new \Exception('@TODO: Unexpected Token ' . Scanner::type($tokens)->value)
223222
};
224223

@@ -234,4 +233,24 @@ private function parseEnumMemberValue(\Iterator &$tokens): ?EnumMemberValueNode
234233
value: $value
235234
);
236235
}
236+
237+
/**
238+
* @param \Iterator $tokens
239+
* @return StringLiteralNode
240+
*/
241+
private function parseStringLiteral(\Iterator &$tokens): StringLiteralNode
242+
{
243+
$this->stringLiteralParser ??= StringLiteralParser::singleton();
244+
return $this->stringLiteralParser->parse($tokens);
245+
}
246+
247+
/**
248+
* @param \Iterator $tokens
249+
* @return IntegerLiteralNode
250+
*/
251+
private function parseIntegerLiteral(\Iterator &$tokens): IntegerLiteralNode
252+
{
253+
$this->integerLiteralParser ??= IntegerLiteralParser::singleton();
254+
return $this->integerLiteralParser->parse($tokens);
255+
}
237256
}

src/Language/Parser/Export/ExportParser.php

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
namespace PackageFactory\ComponentEngine\Language\Parser\Export;
2424

25+
use PackageFactory\ComponentEngine\Framework\PHP\Singleton\Singleton;
2526
use PackageFactory\ComponentEngine\Language\AST\Node\ComponentDeclaration\ComponentDeclarationNode;
2627
use PackageFactory\ComponentEngine\Language\AST\Node\EnumDeclaration\EnumDeclarationNode;
2728
use PackageFactory\ComponentEngine\Language\AST\Node\Export\ExportNode;
@@ -37,16 +38,11 @@
3738

3839
final class ExportParser
3940
{
40-
private readonly ComponentDeclarationParser $componentDeclarationParser;
41-
private readonly EnumDeclarationParser $enumDeclarationParser;
42-
private readonly StructDeclarationParser $structDeclarationParser;
41+
use Singleton;
4342

44-
public function __construct()
45-
{
46-
$this->componentDeclarationParser = new ComponentDeclarationParser();
47-
$this->enumDeclarationParser = new EnumDeclarationParser();
48-
$this->structDeclarationParser = new StructDeclarationParser();
49-
}
43+
private ?ComponentDeclarationParser $componentDeclarationParser = null;
44+
private ?EnumDeclarationParser $enumDeclarationParser = null;
45+
private ?StructDeclarationParser $structDeclarationParser = null;
5046

5147
/**
5248
* @param \Iterator<mixed,Token> $tokens
@@ -99,6 +95,7 @@ private function extractToken(\Iterator &$tokens, TokenType $tokenType): Token
9995
*/
10096
private function parseComponentDeclaration(\Iterator &$tokens): ComponentDeclarationNode
10197
{
98+
$this->componentDeclarationParser ??= ComponentDeclarationParser::singleton();
10299
return $this->componentDeclarationParser->parse($tokens);
103100
}
104101

@@ -108,6 +105,7 @@ private function parseComponentDeclaration(\Iterator &$tokens): ComponentDeclara
108105
*/
109106
private function parseEnumDeclaration(\Iterator &$tokens): EnumDeclarationNode
110107
{
108+
$this->enumDeclarationParser ??= EnumDeclarationParser::singleton();
111109
return $this->enumDeclarationParser->parse($tokens);
112110
}
113111

@@ -117,6 +115,7 @@ private function parseEnumDeclaration(\Iterator &$tokens): EnumDeclarationNode
117115
*/
118116
private function parseStructDeclaration(\Iterator &$tokens): StructDeclarationNode
119117
{
118+
$this->structDeclarationParser ??= StructDeclarationParser::singleton();
120119
return $this->structDeclarationParser->parse($tokens);
121120
}
122121
}

src/Language/Parser/Expression/ExpressionParser.php

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,27 +48,19 @@
4848

4949
final class ExpressionParser
5050
{
51-
private readonly BooleanLiteralParser $booleanLiteralParser;
52-
private readonly NullLiteralParser $nullLiteralParser;
53-
private readonly StringLiteralParser $stringLiteralParser;
54-
private readonly IntegerLiteralParser $integerLiteralParser;
55-
private readonly ValueReferenceParser $valueReferenceParser;
56-
private readonly TemplateLiteralParser $templateLiteralParser;
57-
private readonly TagParser $tagParser;
58-
private readonly MatchParser $matchParser;
51+
private ?BooleanLiteralParser $booleanLiteralParser = null;
52+
private ?IntegerLiteralParser $integerLiteralParser = null;
53+
private ?MatchParser $matchParser = null;
54+
private ?NullLiteralParser $nullLiteralParser = null;
55+
private ?StringLiteralParser $stringLiteralParser = null;
56+
private ?TagParser $tagParser = null;
57+
private ?TemplateLiteralParser $templateLiteralParser = null;
58+
private ?ValueReferenceParser $valueReferenceParser = null;
5959

6060
public function __construct(
6161
private ?TokenType $stopAt = null,
6262
private Precedence $precedence = Precedence::SEQUENCE
6363
) {
64-
$this->booleanLiteralParser = new BooleanLiteralParser();
65-
$this->nullLiteralParser = new NullLiteralParser();
66-
$this->stringLiteralParser = new StringLiteralParser();
67-
$this->integerLiteralParser = new IntegerLiteralParser();
68-
$this->valueReferenceParser = new ValueReferenceParser();
69-
$this->templateLiteralParser = new TemplateLiteralParser();
70-
$this->tagParser = new TagParser();
71-
$this->matchParser = new MatchParser();
7264
}
7365

7466
/**
@@ -267,6 +259,8 @@ private function shouldStop(\Iterator &$tokens): bool
267259
*/
268260
private function parseBooleanLiteral(\Iterator &$tokens): ExpressionNode
269261
{
262+
$this->booleanLiteralParser ??= BooleanLiteralParser::singleton();
263+
270264
$booleanLiteralNode = $this->booleanLiteralParser->parse($tokens);
271265

272266
return new ExpressionNode(
@@ -281,6 +275,9 @@ private function parseBooleanLiteral(\Iterator &$tokens): ExpressionNode
281275
*/
282276
private function parseNullLiteral(\Iterator &$tokens): ExpressionNode
283277
{
278+
279+
$this->nullLiteralParser ??= NullLiteralParser::singleton();
280+
284281
$nullLiteralNode = $this->nullLiteralParser->parse($tokens);
285282

286283
return new ExpressionNode(
@@ -295,6 +292,8 @@ private function parseNullLiteral(\Iterator &$tokens): ExpressionNode
295292
*/
296293
private function parseStringLiteral(\Iterator &$tokens): ExpressionNode
297294
{
295+
$this->stringLiteralParser ??= StringLiteralParser::singleton();
296+
298297
$stringLiteralNode = $this->stringLiteralParser->parse($tokens);
299298

300299
return new ExpressionNode(
@@ -309,6 +308,8 @@ private function parseStringLiteral(\Iterator &$tokens): ExpressionNode
309308
*/
310309
private function parseIntegerLiteral(\Iterator &$tokens): ExpressionNode
311310
{
311+
$this->integerLiteralParser ??= IntegerLiteralParser::singleton();
312+
312313
$integerLiteralNode = $this->integerLiteralParser->parse($tokens);
313314

314315
return new ExpressionNode(
@@ -323,6 +324,8 @@ private function parseIntegerLiteral(\Iterator &$tokens): ExpressionNode
323324
*/
324325
private function parseValueReference(\Iterator &$tokens): ExpressionNode
325326
{
327+
$this->valueReferenceParser ??= ValueReferenceParser::singleton();
328+
326329
$valueReferenceNode = $this->valueReferenceParser->parse($tokens);
327330

328331
return new ExpressionNode(
@@ -337,6 +340,8 @@ private function parseValueReference(\Iterator &$tokens): ExpressionNode
337340
*/
338341
private function parseTag(\Iterator &$tokens): ExpressionNode
339342
{
343+
$this->tagParser ??= TagParser::singleton();
344+
340345
$tagNode = $this->tagParser->parse($tokens);
341346

342347
return new ExpressionNode(
@@ -351,6 +356,8 @@ private function parseTag(\Iterator &$tokens): ExpressionNode
351356
*/
352357
private function parseTemplateLiteral(\Iterator &$tokens): ExpressionNode
353358
{
359+
$this->templateLiteralParser ??= TemplateLiteralParser::singleton();
360+
354361
$templateLiteralNode = $this->templateLiteralParser->parse($tokens);
355362

356363
return new ExpressionNode(
@@ -365,6 +372,8 @@ private function parseTemplateLiteral(\Iterator &$tokens): ExpressionNode
365372
*/
366373
private function parseMatch(\Iterator &$tokens): ExpressionNode
367374
{
375+
$this->matchParser ??= MatchParser::singleton();
376+
368377
$matchNode = $this->matchParser->parse($tokens);
369378

370379
return new ExpressionNode(

src/Language/Parser/Import/ImportParser.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
namespace PackageFactory\ComponentEngine\Language\Parser\Import;
2424

2525
use PackageFactory\ComponentEngine\Domain\VariableName\VariableName;
26+
use PackageFactory\ComponentEngine\Framework\PHP\Singleton\Singleton;
2627
use PackageFactory\ComponentEngine\Language\AST\Node\Import\ImportedNameNode;
2728
use PackageFactory\ComponentEngine\Language\AST\Node\Import\ImportedNameNodes;
2829
use PackageFactory\ComponentEngine\Language\AST\Node\Import\ImportNode;
@@ -36,12 +37,9 @@
3637

3738
final class ImportParser
3839
{
39-
private readonly StringLiteralParser $pathParser;
40+
use Singleton;
4041

41-
public function __construct()
42-
{
43-
$this->pathParser = new StringLiteralParser();
44-
}
42+
private ?StringLiteralParser $pathParser = null;
4543

4644
/**
4745
* @param \Iterator<mixed,Token> $tokens
@@ -108,6 +106,8 @@ private function skipToken(\Iterator &$tokens, TokenType $tokenType): void
108106
*/
109107
private function parsePath(\Iterator &$tokens): StringLiteralNode
110108
{
109+
$this->pathParser ??= StringLiteralParser::singleton();
110+
111111
$path = $this->pathParser->parse($tokens);
112112
Scanner::skipSpace($tokens);
113113

src/Language/Parser/IntegerLiteral/IntegerLiteralParser.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
namespace PackageFactory\ComponentEngine\Language\Parser\IntegerLiteral;
2424

25+
use PackageFactory\ComponentEngine\Framework\PHP\Singleton\Singleton;
2526
use PackageFactory\ComponentEngine\Language\AST\Node\IntegerLiteral\IntegerFormat;
2627
use PackageFactory\ComponentEngine\Language\AST\Node\IntegerLiteral\IntegerLiteralNode;
2728
use PackageFactory\ComponentEngine\Parser\Tokenizer\Scanner;
@@ -31,6 +32,8 @@
3132

3233
final class IntegerLiteralParser
3334
{
35+
use Singleton;
36+
3437
/**
3538
* @param \Iterator<mixed,Token> $tokens
3639
* @return IntegerLiteralNode

0 commit comments

Comments
 (0)