Skip to content

Commit 9d4796d

Browse files
Merge pull request #591 from kamil-tekiela/Micro-optimizations
Micro optimizations and refactorings
2 parents 0ff9969 + dbee88a commit 9d4796d

37 files changed

+123
-283
lines changed

psalm-baseline.xml

-51
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,6 @@
135135
<InvalidPropertyAssignmentValue>
136136
<code><![CDATA[[]]]></code>
137137
</InvalidPropertyAssignmentValue>
138-
<InvalidPropertyFetch>
139-
<code><![CDATA[$context::$keywords]]></code>
140-
</InvalidPropertyFetch>
141138
<MixedAssignment>
142139
<code><![CDATA[self::$keywords]]></code>
143140
</MixedAssignment>
@@ -155,49 +152,6 @@
155152
<MixedOperand>
156153
<code><![CDATA[$this->str[$this->last]]]></code>
157154
</MixedOperand>
158-
<PossiblyNullArgument>
159-
<code><![CDATA[$this->str[$this->last + 1]]]></code>
160-
<code><![CDATA[$this->str[$this->last]]]></code>
161-
<code><![CDATA[$this->str[$this->last]]]></code>
162-
<code><![CDATA[$this->str[$this->last]]]></code>
163-
<code><![CDATA[$this->str[$this->last]]]></code>
164-
<code><![CDATA[$this->str[$this->last]]]></code>
165-
<code><![CDATA[$this->str[$this->last]]]></code>
166-
<code><![CDATA[$this->str[$this->last]]]></code>
167-
<code><![CDATA[$this->str[$this->last]]]></code>
168-
<code><![CDATA[$this->str[$this->last]]]></code>
169-
<code><![CDATA[$token]]></code>
170-
<code><![CDATA[$token]]></code>
171-
<code><![CDATA[$token]]></code>
172-
<code><![CDATA[$token]]></code>
173-
<code><![CDATA[$token]]></code>
174-
</PossiblyNullArgument>
175-
<PossiblyNullOperand>
176-
<code><![CDATA[$this->str[$this->last++]]]></code>
177-
<code><![CDATA[$this->str[$this->last++]]]></code>
178-
<code><![CDATA[$this->str[$this->last]]]></code>
179-
<code><![CDATA[$this->str[$this->last]]]></code>
180-
<code><![CDATA[$this->str[$this->last]]]></code>
181-
<code><![CDATA[$this->str[$this->last]]]></code>
182-
<code><![CDATA[$this->str[$this->last]]]></code>
183-
<code><![CDATA[$this->str[$this->last]]]></code>
184-
<code><![CDATA[$this->str[$this->last]]]></code>
185-
<code><![CDATA[$this->str[$this->last]]]></code>
186-
<code><![CDATA[$this->str[$this->last]]]></code>
187-
<code><![CDATA[$this->str[$this->last]]]></code>
188-
<code><![CDATA[$this->str[$this->last]]]></code>
189-
<code><![CDATA[$this->str[$this->last]]]></code>
190-
<code><![CDATA[$this->str[$this->last]]]></code>
191-
<code><![CDATA[$this->str[$this->last]]]></code>
192-
<code><![CDATA[$this->str[$this->last]]]></code>
193-
<code><![CDATA[$this->str[$this->last]]]></code>
194-
<code><![CDATA[$this->str[$this->last]]]></code>
195-
<code><![CDATA[$this->str[++$this->last]]]></code>
196-
<code><![CDATA[$this->str[++$this->last]]]></code>
197-
<code><![CDATA[$this->str[++$this->last]]]></code>
198-
<code><![CDATA[$this->str[++$this->last]]]></code>
199-
<code><![CDATA[$this->str[++$this->last]]]></code>
200-
</PossiblyNullOperand>
201155
<PossiblyNullPropertyFetch>
202156
<code><![CDATA[$next->type]]></code>
203157
<code><![CDATA[$next->value]]></code>
@@ -210,11 +164,6 @@
210164
<RiskyTruthyFalsyComparison>
211165
<code><![CDATA[! $flags]]></code>
212166
<code><![CDATA[! $flags]]></code>
213-
<code><![CDATA[! $flags]]></code>
214-
<code><![CDATA[! $flags]]></code>
215-
<code><![CDATA[Context::isComment($token)]]></code>
216-
<code><![CDATA[Context::isComment($token)]]></code>
217-
<code><![CDATA[Context::isComment($token, $end)]]></code>
218167
<code><![CDATA[empty($delimiter)]]></code>
219168
</RiskyTruthyFalsyComparison>
220169
</file>

src/Context.php

+48-91
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use PhpMyAdmin\SqlParser\Contexts\ContextMySql50700;
88

9+
use function array_map;
910
use function class_exists;
1011
use function explode;
1112
use function in_array;
@@ -26,7 +27,7 @@
2627
*
2728
* Holds the configuration of the context that is currently used.
2829
*/
29-
abstract class Context
30+
final class Context
3031
{
3132
/**
3233
* The maximum length of a keyword.
@@ -54,7 +55,7 @@ abstract class Context
5455
* The prefix concatenated to the context name when an incomplete class name
5556
* is specified.
5657
*/
57-
public static string $contextPrefix = 'PhpMyAdmin\\SqlParser\\Contexts\\Context';
58+
private const CONTEXT_PREFIX = 'PhpMyAdmin\\SqlParser\\Contexts\\Context';
5859

5960
/**
6061
* List of keywords.
@@ -78,10 +79,8 @@ abstract class Context
7879

7980
/**
8081
* List of operators and their flags.
81-
*
82-
* @var array<string, int>
8382
*/
84-
public static array $operators = [
83+
private const OPERATORS = [
8584
// Some operators (*, =) may have ambiguous flags, because they depend on
8685
// the context they are being used in.
8786
// For example: 1. SELECT * FROM table; # SQL specific (wildcard)
@@ -366,15 +365,18 @@ public static function isKeyword(string $string, bool $isReserved = false): int|
366365
*/
367366
public static function isOperator(string $string): int|null
368367
{
369-
return static::$operators[$string] ?? null;
368+
return self::OPERATORS[$string] ?? null;
370369
}
371370

372371
/**
373372
* Checks if the given character is a whitespace.
374373
*/
375-
public static function isWhitespace(string $string): bool
374+
public static function isWhitespace(string $character): bool
376375
{
377-
return $string === ' ' || $string === "\r" || $string === "\n" || $string === "\t";
376+
return match ($character) {
377+
' ', "\r", "\n", "\t" => true,
378+
default => false,
379+
};
378380
}
379381

380382
/**
@@ -384,39 +386,20 @@ public static function isWhitespace(string $string): bool
384386
*/
385387
public static function isComment(string $string, bool $end = false): int|null
386388
{
387-
if ($string === '') {
388-
return null;
389-
}
390-
391-
// If comment is Bash style (#):
392-
if (str_starts_with($string, '#')) {
393-
return Token::FLAG_COMMENT_BASH;
394-
}
395-
396-
// If comment is a MySQL command
397-
if (str_starts_with($string, '/*!')) {
398-
return Token::FLAG_COMMENT_MYSQL_CMD;
399-
}
400-
401-
// If comment is opening C style (/*) or is closing C style (*/), warning, it could conflict
402-
// with wildcard and a real opening C style.
403-
// It would look like the following valid SQL statement: "SELECT */* comment */ FROM...".
404-
if (str_starts_with($string, '/*') || str_starts_with($string, '*/')) {
405-
return Token::FLAG_COMMENT_C;
406-
}
407-
408-
// If comment is SQL style (--\s?):
409-
if (
389+
return match (true) {
390+
str_starts_with($string, '#') => Token::FLAG_COMMENT_BASH,
391+
str_starts_with($string, '/*!') => Token::FLAG_COMMENT_MYSQL_CMD,
392+
// If comment is opening C style (/*) or is closing C style (*/), warning, it could conflict
393+
// with wildcard and a real opening C style.
394+
// It would look like the following valid SQL statement: "SELECT */* comment */ FROM...".
395+
str_starts_with($string, '/*') || str_starts_with($string, '*/') => Token::FLAG_COMMENT_C,
410396
str_starts_with($string, '-- ')
411-
|| str_starts_with($string, "--\r")
412-
|| str_starts_with($string, "--\n")
413-
|| str_starts_with($string, "--\t")
414-
|| ($string === '--' && $end)
415-
) {
416-
return Token::FLAG_COMMENT_SQL;
417-
}
418-
419-
return null;
397+
|| str_starts_with($string, "--\r")
398+
|| str_starts_with($string, "--\n")
399+
|| str_starts_with($string, "--\t")
400+
|| ($string === '--' && $end) => Token::FLAG_COMMENT_SQL,
401+
default => null,
402+
};
420403
}
421404

422405
/**
@@ -445,49 +428,30 @@ public static function isNumber(string $string): bool
445428
*
446429
* @return int|null the appropriate flag for the symbol type
447430
*/
448-
public static function isSymbol(string $string): int|null
431+
public static function isSymbol(string $character): int|null
449432
{
450-
if ($string === '') {
451-
return null;
452-
}
453-
454-
if (str_starts_with($string, '@')) {
455-
return Token::FLAG_SYMBOL_VARIABLE;
456-
}
457-
458-
if (str_starts_with($string, '`')) {
459-
return Token::FLAG_SYMBOL_BACKTICK;
460-
}
461-
462-
if (str_starts_with($string, ':') || str_starts_with($string, '?')) {
463-
return Token::FLAG_SYMBOL_PARAMETER;
464-
}
465-
466-
return null;
433+
return match ($character) {
434+
'@' => Token::FLAG_SYMBOL_VARIABLE,
435+
'`' => Token::FLAG_SYMBOL_BACKTICK,
436+
':', '?' => Token::FLAG_SYMBOL_PARAMETER,
437+
default => null,
438+
};
467439
}
468440

469441
/**
470442
* Checks if the given character is the beginning of a string.
471443
*
472-
* @param string $string string to be checked
444+
* @param string $character a character to be checked
473445
*
474446
* @return int|null the appropriate flag for the string type
475447
*/
476-
public static function isString(string $string): int|null
448+
public static function isString(string $character): int|null
477449
{
478-
if ($string === '') {
479-
return null;
480-
}
481-
482-
if (str_starts_with($string, '\'')) {
483-
return Token::FLAG_STRING_SINGLE_QUOTES;
484-
}
485-
486-
if (str_starts_with($string, '"')) {
487-
return Token::FLAG_STRING_DOUBLE_QUOTES;
488-
}
489-
490-
return null;
450+
return match ($character) {
451+
'\'' => Token::FLAG_STRING_SINGLE_QUOTES,
452+
'"' => Token::FLAG_STRING_DOUBLE_QUOTES,
453+
default => null,
454+
};
491455
}
492456

493457
/**
@@ -522,22 +486,19 @@ public static function load(string $context = ''): bool
522486
$context = ContextMySql50700::class;
523487
}
524488

525-
if (! class_exists($context)) {
526-
if (! class_exists(self::$contextPrefix . $context)) {
527-
return false;
528-
}
529-
530-
// Could be the fully qualified class name was given, like `ContextDBMS::class`.
531-
if (class_exists('\\' . $context)) {
532-
$context = '\\' . $context;
533-
} else {
534-
// Short context name (must be formatted into class name).
535-
$context = self::$contextPrefix . $context;
489+
$contextClass = $context;
490+
if (! class_exists($contextClass)) {
491+
$contextClass = self::CONTEXT_PREFIX . $context;
492+
if (! class_exists($contextClass)) {
493+
$contextClass = '\\' . $context;
494+
if (! class_exists($contextClass)) {
495+
return false;
496+
}
536497
}
537498
}
538499

539-
self::$loadedContext = $context;
540-
self::$keywords = $context::$keywords;
500+
self::$loadedContext = $contextClass;
501+
self::$keywords = $contextClass::KEYWORDS;
541502

542503
return true;
543504
}
@@ -688,11 +649,7 @@ public static function escape(string $str, string $quote = '`'): string
688649
*/
689650
public static function escapeAll(array $strings): array
690651
{
691-
foreach ($strings as $key => $value) {
692-
$strings[$key] = static::escape($value);
693-
}
694-
695-
return $strings;
652+
return array_map(static::escape(...), $strings);
696653
}
697654

698655
/**

src/Contexts/ContextMariaDb100000.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace PhpMyAdmin\SqlParser\Contexts;
66

7-
use PhpMyAdmin\SqlParser\Context;
87
use PhpMyAdmin\SqlParser\Token;
98

109
/**
@@ -15,7 +14,7 @@
1514
*
1615
* @see https://mariadb.com/kb/en/reserved-words/
1716
*/
18-
class ContextMariaDb100000 extends Context
17+
final class ContextMariaDb100000
1918
{
2019
/**
2120
* List of keywords.
@@ -24,11 +23,10 @@ class ContextMariaDb100000 extends Context
2423
*
2524
* @see Token
2625
*
27-
* @var array<string,int>
2826
* @psalm-var non-empty-array<string,Token::FLAG_KEYWORD_*|int>
2927
* @phpstan-var non-empty-array<non-empty-string,Token::FLAG_KEYWORD_*|int>
3028
*/
31-
public static array $keywords = [
29+
public const KEYWORDS = [
3230
'ACTION' => Token::FLAG_KEYWORD,
3331
'AFTER' => Token::FLAG_KEYWORD,
3432
'AGGREGATE' => Token::FLAG_KEYWORD,

src/Contexts/ContextMariaDb100100.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace PhpMyAdmin\SqlParser\Contexts;
66

7-
use PhpMyAdmin\SqlParser\Context;
87
use PhpMyAdmin\SqlParser\Token;
98

109
/**
@@ -15,7 +14,7 @@
1514
*
1615
* @see https://mariadb.com/kb/en/reserved-words/
1716
*/
18-
class ContextMariaDb100100 extends Context
17+
final class ContextMariaDb100100
1918
{
2019
/**
2120
* List of keywords.
@@ -24,11 +23,10 @@ class ContextMariaDb100100 extends Context
2423
*
2524
* @see Token
2625
*
27-
* @var array<string,int>
2826
* @psalm-var non-empty-array<string,Token::FLAG_KEYWORD_*|int>
2927
* @phpstan-var non-empty-array<non-empty-string,Token::FLAG_KEYWORD_*|int>
3028
*/
31-
public static array $keywords = [
29+
public const KEYWORDS = [
3230
'ACCOUNT' => Token::FLAG_KEYWORD,
3331
'ACTION' => Token::FLAG_KEYWORD,
3432
'AFTER' => Token::FLAG_KEYWORD,

src/Contexts/ContextMariaDb100200.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace PhpMyAdmin\SqlParser\Contexts;
66

7-
use PhpMyAdmin\SqlParser\Context;
87
use PhpMyAdmin\SqlParser\Token;
98

109
/**
@@ -15,7 +14,7 @@
1514
*
1615
* @see https://mariadb.com/kb/en/reserved-words/
1716
*/
18-
class ContextMariaDb100200 extends Context
17+
final class ContextMariaDb100200
1918
{
2019
/**
2120
* List of keywords.
@@ -24,11 +23,10 @@ class ContextMariaDb100200 extends Context
2423
*
2524
* @see Token
2625
*
27-
* @var array<string,int>
2826
* @psalm-var non-empty-array<string,Token::FLAG_KEYWORD_*|int>
2927
* @phpstan-var non-empty-array<non-empty-string,Token::FLAG_KEYWORD_*|int>
3028
*/
31-
public static array $keywords = [
29+
public const KEYWORDS = [
3230
'ACCOUNT' => Token::FLAG_KEYWORD,
3331
'ACTION' => Token::FLAG_KEYWORD,
3432
'AFTER' => Token::FLAG_KEYWORD,

0 commit comments

Comments
 (0)