diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index f4e814b53..b16d399b2 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -461,12 +461,12 @@ parameters: path: src/Statement.php - - message: "#^Offset 'class' does not exist on array\\{class\\?\\: class\\-string\\, field\\?\\: non\\-empty\\-string, options\\?\\: array\\\\}\\.$#" + message: "#^Offset 'class' does not exist on array\\{\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\Array2d', field\\: 'values'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\ArrayObj', field\\: 'partition'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\Condition', field\\: 'having'\\|'where'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\Expression', field\\: 'table', options\\: array\\{parseField\\: 'table'\\}\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\ExpressionArray', field\\: 'expr'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\ExpressionArray', field\\: 'fields'\\|'tables', options\\: array\\{parseField\\: 'table'\\}\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\ExpressionArray', field\\: 'from', options\\: array\\{field\\: 'table'\\}\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\FunctionCall', field\\: 'call'\\|'procedure'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\GroupKeyword', field\\: 'group'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\IndexHint', field\\: 'index_hints'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\IntoKeyword', field\\: 'into'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\JoinKeyword', field\\: 'join'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\Limit', field\\: 'limit'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\OptionsArray', field\\: 'endOptions'\\|'groupOptions'\\|'options'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\OrderKeyword', field\\: 'order'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\RenameOperation', field\\: 'renames'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\SetOperation', field\\: 'set'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\UnionKeyword', field\\: 'union'\\}\\.$#" count: 1 path: src/Statement.php - - message: "#^Offset 'field' does not exist on array\\{class\\?\\: class\\-string\\, field\\?\\: non\\-empty\\-string, options\\?\\: array\\\\}\\.$#" + message: "#^Offset 'field' does not exist on array\\{\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\Array2d', field\\: 'values'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\ArrayObj', field\\: 'partition'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\Condition', field\\: 'having'\\|'where'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\Expression', field\\: 'table', options\\: array\\{parseField\\: 'table'\\}\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\ExpressionArray', field\\: 'expr'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\ExpressionArray', field\\: 'fields'\\|'tables', options\\: array\\{parseField\\: 'table'\\}\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\ExpressionArray', field\\: 'from', options\\: array\\{field\\: 'table'\\}\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\FunctionCall', field\\: 'call'\\|'procedure'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\GroupKeyword', field\\: 'group'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\IndexHint', field\\: 'index_hints'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\IntoKeyword', field\\: 'into'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\JoinKeyword', field\\: 'join'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\Limit', field\\: 'limit'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\OptionsArray', field\\: 'endOptions'\\|'groupOptions'\\|'options'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\OrderKeyword', field\\: 'order'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\RenameOperation', field\\: 'renames'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\SetOperation', field\\: 'set'\\}\\|array\\{class\\: 'PhpMyAdmin\\\\\\\\SqlParser\\\\\\\\Components\\\\\\\\UnionKeyword', field\\: 'union'\\}\\.$#" count: 1 path: src/Statement.php diff --git a/psalm-baseline.xml b/psalm-baseline.xml index faa8f9085..c60c4c5a2 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,46 +1,6 @@ - - 1, - 'EVERY' => [ - 2, - 'expr', - ], - 'AT' => [ - 2, - 'expr', - ], - 'STARTS' => [ - 3, - 'expr', - ], - 'ENDS' => [ - 4, - 'expr', - ], - 'ON COMPLETION PRESERVE' => 5, - 'ON COMPLETION NOT PRESERVE' => 5, - 'RENAME' => 6, - 'TO' => [ - 7, - 'expr', - ['parseField' => 'table'], - ], - 'ENABLE' => 8, - 'DISABLE' => 8, - 'DISABLE ON SLAVE' => 8, - 'COMMENT' => [ - 9, - 'var', - ], - 'DO' => 10, - ]]]> - - - $arrayKey - $options @@ -104,7 +64,7 @@ - value]]]> + value]]]> $isOperator @@ -137,13 +97,9 @@ - keyword]]]> - keyword]]]> + keyword]]]> + keyword]]]> - - keyword]]]> - keyword]]]> - $field @@ -241,15 +197,11 @@ - keyword]]]> - keyword]]]> + keyword]]]> + keyword]]]> - - keyword]]]> - keyword]]]> - - type, static::$joins)]]> + type, self::JOINS)]]> ArrayObj::parse($parser, $list) @@ -712,13 +664,9 @@ list)]]> - keyword]]]> - keyword]]]> + keyword]]]> + keyword]]]> - - keyword]]]> - keyword]]]> - $msg @@ -733,7 +681,7 @@ tokens]]> - static::$statementParsers + self::STATEMENT_PARSERS idx]]> @@ -773,17 +721,13 @@ value]]]> value]]]> - value]]]> - Parser::$keywordParsers[$tokenValue] - keyword]]]> - value]]]> + value]]]> + Parser::KEYWORD_PARSERS[$tokenValue] + keyword]]]> + value]]]> value]]]> value]]]> - - Parser::$keywordParsers[$tokenValue] - keyword]]]> - $tokenValue @@ -794,10 +738,10 @@ $field->build()]]> - - - - + + + + bool @@ -1179,19 +1123,17 @@ - tokens[$list->idx - 2]->value]]]> - tokens[$list->idx - 4]->value]]]> - tokens[$list->idx - 6]->value]]]> - value]]]> - keyword]]]> - keyword]]]> + tokens[$list->idx - 2]->value]]]> + tokens[$list->idx - 4]->value]]]> + tokens[$list->idx - 6]->value]]]> + value]]]> + keyword]]]> + keyword]]]> self::$inlineClauses[$lastClause] self::$inlineClauses[$lastClause] self::$shortClauses[$lastClause] - keyword]]]> - keyword]]]> self::$inlineClauses[$lastClause] self::$inlineClauses[$lastClause] self::$shortClauses[$lastClause] diff --git a/src/Components/AlterOperation.php b/src/Components/AlterOperation.php index bc2d85fd2..e0d92e406 100644 --- a/src/Components/AlterOperation.php +++ b/src/Components/AlterOperation.php @@ -22,11 +22,8 @@ final class AlterOperation implements Component { /** * All database options. - * - * @var array> - * @psalm-var array [ 1, 'var', @@ -59,11 +56,8 @@ final class AlterOperation implements Component /** * All table options. - * - * @var array> - * @psalm-var array [ 1, 'var=', @@ -151,11 +145,8 @@ final class AlterOperation implements Component /** * All user options. - * - * @var array> - * @psalm-var array [ 1, 'var', @@ -202,19 +193,13 @@ final class AlterOperation implements Component /** * All view options. - * - * @var array> - * @psalm-var array 1]; + public const VIEW_OPTIONS = ['AS' => 1]; /** * All event options. - * - * @var array> - * @psalm-var array 1, 'EVERY' => [ 2, @@ -441,7 +426,7 @@ public static function parse(Parser $parser, TokensList $list, array $options = ); break; } - } elseif (! empty(Parser::$statementParsers[$arrayKey])) { + } elseif (! empty(Parser::STATEMENT_PARSERS[$arrayKey])) { // We have reached the end of ALTER operation and suddenly found // a start to new statement, but have not found a delimiter between them $parser->error( @@ -450,8 +435,8 @@ public static function parse(Parser $parser, TokensList $list, array $options = ); break; } elseif ( - (array_key_exists($arrayKey, self::$databaseOptions) - || array_key_exists($arrayKey, self::$tableOptions)) + (array_key_exists($arrayKey, self::DATABASE_OPTIONS) + || array_key_exists($arrayKey, self::TABLE_OPTIONS)) && ! self::checkIfColumnDefinitionKeyword($arrayKey) ) { // This alter operation has finished, which means a comma diff --git a/src/Components/Condition.php b/src/Components/Condition.php index 1b36a7ef4..1f6819478 100644 --- a/src/Components/Condition.php +++ b/src/Components/Condition.php @@ -20,10 +20,8 @@ final class Condition implements Component { /** * Logical operators that can be used to delimit expressions. - * - * @var string[] */ - public static $delimiters = [ + private const DELIMITERS = [ '&&', '||', 'AND', @@ -33,10 +31,8 @@ final class Condition implements Component /** * List of allowed reserved keywords in conditions. - * - * @var array */ - public static $allowedKeywords = [ + private const ALLOWED_KEYWORDS = [ 'ALL' => 1, 'AND' => 1, 'BETWEEN' => 1, @@ -143,7 +139,7 @@ public static function parse(Parser $parser, TokensList $list, array $options = } // Conditions are delimited by logical operators. - if (in_array($token->value, static::$delimiters, true)) { + if (in_array($token->value, self::DELIMITERS, true)) { if ($betweenBefore && ($token->value === 'AND')) { // The syntax of keyword `BETWEEN` is hard-coded. $betweenBefore = false; @@ -174,7 +170,7 @@ public static function parse(Parser $parser, TokensList $list, array $options = $betweenBefore = true; } - if (($brackets === 0) && empty(static::$allowedKeywords[$token->value])) { + if (($brackets === 0) && empty(self::ALLOWED_KEYWORDS[$token->value])) { break; } } diff --git a/src/Components/CreateDefinition.php b/src/Components/CreateDefinition.php index 4d00b9738..53350541f 100644 --- a/src/Components/CreateDefinition.php +++ b/src/Components/CreateDefinition.php @@ -22,15 +22,8 @@ final class CreateDefinition implements Component { /** * All field options. - * - * @var array>> - * @psalm-var array true, @@ -271,7 +264,7 @@ public static function parse(Parser $parser, TokensList $list, array $options = $expr->type = DataType::parse($parser, $list); $state = 3; } elseif ($state === 3) { - $expr->options = OptionsArray::parse($parser, $list, static::$fieldOptions); + $expr->options = OptionsArray::parse($parser, $list, self::FIELD_OPTIONS); $state = 4; } elseif ($state === 4) { if ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'REFERENCES') { diff --git a/src/Components/DataType.php b/src/Components/DataType.php index 31a5d3cc9..09f49cdd9 100644 --- a/src/Components/DataType.php +++ b/src/Components/DataType.php @@ -21,11 +21,8 @@ final class DataType implements Component { /** * All data type options. - * - * @var array> - * @psalm-var array 1, 'CHARACTER SET' => [ 2, @@ -137,7 +134,7 @@ public static function parse(Parser $parser, TokensList $list, array $options = $parameters->raw : $parameters->values; } - $ret->options = OptionsArray::parse($parser, $list, static::$dataTypeOptions); + $ret->options = OptionsArray::parse($parser, $list, self::DATA_TYPE_OPTIONS); ++$list->idx; break; } diff --git a/src/Components/Expression.php b/src/Components/Expression.php index 3dce60e3b..59d2c8ddb 100644 --- a/src/Components/Expression.php +++ b/src/Components/Expression.php @@ -25,10 +25,8 @@ final class Expression implements Component { /** * List of allowed reserved keywords in expressions. - * - * @var array */ - private static $allowedKeywords = [ + private const ALLOWED_KEYWORDS = [ 'AND' => 1, 'AS' => 1, 'BETWEEN' => 1, @@ -226,7 +224,7 @@ public static function parse(Parser $parser, TokensList $list, array $options = } if ($token->type === Token::TYPE_KEYWORD) { - if (($brackets > 0) && empty($ret->subquery) && ! empty(Parser::$statementParsers[$token->keyword])) { + if (($brackets > 0) && empty($ret->subquery) && ! empty(Parser::STATEMENT_PARSERS[$token->keyword])) { // A `(` was previously found and this keyword is the // beginning of a statement, so this is a subquery. $ret->subquery = $token->keyword; @@ -237,7 +235,7 @@ public static function parse(Parser $parser, TokensList $list, array $options = ) { $isExpr = true; } elseif (($token->flags & Token::FLAG_KEYWORD_RESERVED) && ($brackets === 0)) { - if (empty(self::$allowedKeywords[$token->keyword])) { + if (empty(self::ALLOWED_KEYWORDS[$token->keyword])) { // A reserved keyword that is not allowed in the // expression was found so the expression must have // ended and a new clause is starting. diff --git a/src/Components/IntoKeyword.php b/src/Components/IntoKeyword.php index bf1aadf48..756ae5d06 100644 --- a/src/Components/IntoKeyword.php +++ b/src/Components/IntoKeyword.php @@ -19,11 +19,8 @@ final class IntoKeyword implements Component { /** * FIELDS/COLUMNS Options for `SELECT...INTO` statements. - * - * @var array> - * @psalm-var array [ 1, 'expr', @@ -41,11 +38,8 @@ final class IntoKeyword implements Component /** * LINES Options for `SELECT...INTO` statements. - * - * @var array> - * @psalm-var array [ 1, 'expr', @@ -87,7 +81,7 @@ final class IntoKeyword implements Component /** * Options for FIELDS/COLUMNS keyword. * - * @see IntoKeyword::$statementFieldsOptions + * @see IntoKeyword::STATEMENT_FIELDS_OPTIONS * * @var OptionsArray|null */ @@ -103,7 +97,7 @@ final class IntoKeyword implements Component /** * Options for OPTIONS keyword. * - * @see IntoKeyword::$statementLinesOptions + * @see IntoKeyword::STATEMENT_LINES_OPTIONS * * @var OptionsArray|null */ @@ -247,12 +241,12 @@ public function parseFileOptions(Parser $parser, TokensList $list, $keyword = 'F if ($keyword === 'FIELDS' || $keyword === 'COLUMNS') { // parse field options - $this->fieldsOptions = OptionsArray::parse($parser, $list, static::$statementFieldsOptions); + $this->fieldsOptions = OptionsArray::parse($parser, $list, self::STATEMENT_FIELDS_OPTIONS); $this->fieldsKeyword = ($keyword === 'FIELDS'); } else { // parse line options - $this->linesOptions = OptionsArray::parse($parser, $list, static::$statementLinesOptions); + $this->linesOptions = OptionsArray::parse($parser, $list, self::STATEMENT_LINES_OPTIONS); } } diff --git a/src/Components/JoinKeyword.php b/src/Components/JoinKeyword.php index b820b8db9..19745f5d3 100644 --- a/src/Components/JoinKeyword.php +++ b/src/Components/JoinKeyword.php @@ -21,10 +21,8 @@ final class JoinKeyword implements Component { /** * Types of join. - * - * @var array */ - public static $joins = [ + public const JOINS = [ 'CROSS JOIN' => 'CROSS', 'FULL JOIN' => 'FULL', 'FULL OUTER JOIN' => 'FULL', @@ -45,7 +43,7 @@ final class JoinKeyword implements Component /** * Type of this join. * - * @see JoinKeyword::$joins + * @see JoinKeyword::JOINS * * @var string */ @@ -73,7 +71,7 @@ final class JoinKeyword implements Component public $using; /** - * @see JoinKeyword::$joins + * @see JoinKeyword::JOINS * * @param string $type Join type * @param Expression $expr join expression @@ -145,11 +143,11 @@ public static function parse(Parser $parser, TokensList $list, array $options = } if ($state === 0) { - if (($token->type !== Token::TYPE_KEYWORD) || empty(static::$joins[$token->keyword])) { + if (($token->type !== Token::TYPE_KEYWORD) || empty(self::JOINS[$token->keyword])) { break; } - $expr->type = static::$joins[$token->keyword]; + $expr->type = self::JOINS[$token->keyword]; $state = 1; } elseif ($state === 1) { $expr->expr = Expression::parse($parser, $list, ['field' => 'table']); @@ -164,14 +162,14 @@ public static function parse(Parser $parser, TokensList $list, array $options = $state = 4; break; default: - if (empty(static::$joins[$token->keyword])) { + if (empty(self::JOINS[$token->keyword])) { /* Next clause is starting */ break 2; } $ret[] = $expr; $expr = new static(); - $expr->type = static::$joins[$token->keyword]; + $expr->type = self::JOINS[$token->keyword]; $state = 1; break; @@ -211,7 +209,7 @@ public static function buildAll(array $component): string { $ret = []; foreach ($component as $c) { - $ret[] = array_search($c->type, static::$joins) . ' ' . $c->expr + $ret[] = array_search($c->type, self::JOINS) . ' ' . $c->expr . (! empty($c->on) ? ' ON ' . Condition::buildAll($c->on) : '') . (! empty($c->using) diff --git a/src/Components/Key.php b/src/Components/Key.php index aa356f440..20fd00020 100644 --- a/src/Components/Key.php +++ b/src/Components/Key.php @@ -22,11 +22,8 @@ final class Key implements Component { /** * All key options. - * - * @var array> - * @psalm-var array [ 1, 'var=', @@ -221,7 +218,7 @@ public static function parse(Parser $parser, TokensList $list, array $options = $lastColumn['length'] = $token->value; } } elseif ($state === 4) { - $ret->options = OptionsArray::parse($parser, $list, static::$keyOptions); + $ret->options = OptionsArray::parse($parser, $list, self::KEY_OPTIONS); ++$list->idx; break; } elseif ($state === 5) { diff --git a/src/Components/Reference.php b/src/Components/Reference.php index 17b37bda8..3d780ee86 100644 --- a/src/Components/Reference.php +++ b/src/Components/Reference.php @@ -20,11 +20,8 @@ final class Reference implements Component { /** * All references options. - * - * @var array> - * @psalm-var array [ 1, 'var', @@ -126,7 +123,7 @@ public static function parse(Parser $parser, TokensList $list, array $options = $ret->columns = ArrayObj::parse($parser, $list)->values; $state = 2; } elseif ($state === 2) { - $ret->options = OptionsArray::parse($parser, $list, static::$referencesOptions); + $ret->options = OptionsArray::parse($parser, $list, self::REFERENCES_OPTIONS); ++$list->idx; break; } diff --git a/src/Lexer.php b/src/Lexer.php index 483215257..f36f16e50 100644 --- a/src/Lexer.php +++ b/src/Lexer.php @@ -30,10 +30,8 @@ class Lexer extends Core { /** * A list of methods that are used in lexing the SQL query. - * - * @var string[] */ - public static $parserMethods = [ + private const PARSER_METHODS = [ // It is best to put the parsers in order of their complexity // (ascending) and their occurrence rate (descending). // @@ -70,14 +68,11 @@ class Lexer extends Core 'parseUnknown', ]; - /** * A list of keywords that indicate that the function keyword * is not used as a function - * - * @var string[] */ - public $keywordNameIndicators = [ + private const KEYWORD_NAME_INDICATORS = [ 'FROM', 'SET', 'WHERE', @@ -86,10 +81,8 @@ class Lexer extends Core /** * A list of operators that indicate that the function keyword * is not used as a function - * - * @var string[] */ - public $operatorNameIndicators = [ + private const OPERATOR_NAME_INDICATORS = [ ',', '.', ]; @@ -238,7 +231,7 @@ public function lex(): void */ $token = null; - foreach (static::$parserMethods as $method) { + foreach (self::PARSER_METHODS as $method) { $token = $this->$method(); if ($token) { @@ -413,10 +406,10 @@ private function solveAmbiguityOnFunctionKeywords(): void $next = $this->list->getNext(); if ( ($next->type !== Token::TYPE_KEYWORD - || ! in_array($next->value, $this->keywordNameIndicators, true) + || ! in_array($next->value, self::KEYWORD_NAME_INDICATORS, true) ) && ($next->type !== Token::TYPE_OPERATOR - || ! in_array($next->value, $this->operatorNameIndicators, true) + || ! in_array($next->value, self::OPERATOR_NAME_INDICATORS, true) ) && ($next->value !== null) ) { diff --git a/src/Parser.php b/src/Parser.php index b80ea1e4d..3920bf707 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -23,10 +23,9 @@ class Parser extends Core /** * Array of classes that are used in parsing the SQL statements. * - * @var array * @psalm-var array|''> */ - public static $statementParsers = [ + public const STATEMENT_PARSERS = [ // MySQL Utility Statements 'DESCRIBE' => Statements\ExplainStatement::class, 'DESC' => Statements\ExplainStatement::class, @@ -97,15 +96,8 @@ class Parser extends Core /** * Array of classes that are used in parsing SQL components. - * - * @var array>> - * @psalm-var array, - * field?: non-empty-string, - * options?: array - * }> */ - public static $keywordParsers = [ + public const KEYWORD_PARSERS = [ // This is not a proper keyword and was added here to help the // formatter. 'PARTITION BY' => [], @@ -494,9 +486,9 @@ public function parse(): void } $list->idx = $lastIdx; - } elseif (empty(static::$statementParsers[$token->keyword])) { + } elseif (empty(self::STATEMENT_PARSERS[$token->keyword])) { // Checking if it is a known statement that can be parsed. - if (! isset(static::$statementParsers[$token->keyword])) { + if (! isset(self::STATEMENT_PARSERS[$token->keyword])) { // A statement is considered recognized if the parser // is aware that it is a statement, but it does not have // a parser for it yet. @@ -514,7 +506,7 @@ public function parse(): void * * @var string */ - $class = static::$statementParsers[$statementName ?? $token->keyword]; + $class = self::STATEMENT_PARSERS[$statementName ?? $token->keyword]; /** * Processed statement. diff --git a/src/Statement.php b/src/Statement.php index 9f75c60e6..14b1d4cfb 100644 --- a/src/Statement.php +++ b/src/Statement.php @@ -61,20 +61,6 @@ abstract class Statement implements Stringable */ public static $clauses = []; - /** - * Options that can be given to GROUP BY component. - * - * @var array> - * @psalm-var array$field)) { @@ -318,7 +304,7 @@ public function parse(Parser $parser, TokensList $list): void $options = []; // Looking for duplicated clauses. - if (! empty(Parser::$keywordParsers[$token->value]) || ! empty(Parser::$statementParsers[$token->value])) { + if (! empty(Parser::KEYWORD_PARSERS[$token->value]) || ! empty(Parser::STATEMENT_PARSERS[$token->value])) { if (! empty($parsedClauses[$token->value])) { $parser->error('This type of clause was previously parsed.', $token); break; @@ -332,16 +318,16 @@ public function parse(Parser $parser, TokensList $list): void // but it might be the beginning of a statement of truncate, // so let the value use the keyword field for truncate type. $tokenValue = in_array($token->keyword, ['TRUNCATE']) ? $token->keyword : $token->value; - if (! empty(Parser::$keywordParsers[$tokenValue]) && $list->idx < $list->count) { - $class = Parser::$keywordParsers[$tokenValue]['class']; - $field = Parser::$keywordParsers[$tokenValue]['field']; - if (! empty(Parser::$keywordParsers[$tokenValue]['options'])) { - $options = Parser::$keywordParsers[$tokenValue]['options']; + if (! empty(Parser::KEYWORD_PARSERS[$tokenValue]) && $list->idx < $list->count) { + $class = Parser::KEYWORD_PARSERS[$tokenValue]['class']; + $field = Parser::KEYWORD_PARSERS[$tokenValue]['field']; + if (! empty(Parser::KEYWORD_PARSERS[$tokenValue]['options'])) { + $options = Parser::KEYWORD_PARSERS[$tokenValue]['options']; } } // Checking if this is the beginning of the statement. - if (! empty(Parser::$statementParsers[$token->keyword])) { + if (! empty(Parser::STATEMENT_PARSERS[$token->keyword])) { if ( ! empty(static::$clauses) // Undefined for some statements. && empty(static::$clauses[$token->value]) @@ -370,24 +356,33 @@ public function parse(Parser $parser, TokensList $list): void } elseif ($class === null) { if ($this instanceof Statements\SelectStatement && $token->value === 'WITH ROLLUP') { // Handle group options in Select statement - // See Statements\SelectStatement::$statementGroupOptions - $this->groupOptions = OptionsArray::parse($parser, $list, static::$statementGroupOptions); + $this->groupOptions = OptionsArray::parse( + $parser, + $list, + Statements\SelectStatement::STATEMENT_GROUP_OPTIONS + ); } elseif ( $this instanceof Statements\SelectStatement && ($token->value === 'FOR UPDATE' || $token->value === 'LOCK IN SHARE MODE') ) { // Handle special end options in Select statement - // See Statements\SelectStatement::$statementEndOptions - $this->endOptions = OptionsArray::parse($parser, $list, static::$statementEndOptions); + $this->endOptions = OptionsArray::parse( + $parser, + $list, + Statements\SelectStatement::STATEMENT_END_OPTIONS + ); } elseif ( $this instanceof Statements\SetStatement && ($token->value === 'COLLATE' || $token->value === 'DEFAULT') ) { // Handle special end options in SET statement - // See Statements\SetStatement::$statementEndOptions - $this->endOptions = OptionsArray::parse($parser, $list, static::$statementEndOptions); + $this->endOptions = OptionsArray::parse( + $parser, + $list, + Statements\SetStatement::STATEMENT_END_OPTIONS + ); } else { // There is no parser for this keyword and isn't the beginning // of a statement (so no options) either. diff --git a/src/Statements/AlterStatement.php b/src/Statements/AlterStatement.php index 1a9b6f07a..f03484465 100644 --- a/src/Statements/AlterStatement.php +++ b/src/Statements/AlterStatement.php @@ -120,15 +120,15 @@ public function parse(Parser $parser, TokensList $list): void if ($state === 0) { $options = []; if ($this->options->has('DATABASE')) { - $options = AlterOperation::$databaseOptions; + $options = AlterOperation::DATABASE_OPTIONS; } elseif ($this->options->has('TABLE')) { - $options = AlterOperation::$tableOptions; + $options = AlterOperation::TABLE_OPTIONS; } elseif ($this->options->has('VIEW')) { - $options = AlterOperation::$viewOptions; + $options = AlterOperation::VIEW_OPTIONS; } elseif ($this->options->has('USER')) { - $options = AlterOperation::$userOptions; + $options = AlterOperation::USER_OPTIONS; } elseif ($this->options->has('EVENT')) { - $options = AlterOperation::$eventOptions; + $options = AlterOperation::EVENT_OPTIONS; } $this->altered[] = AlterOperation::parse($parser, $list, $options); diff --git a/src/Statements/CreateStatement.php b/src/Statements/CreateStatement.php index 51cf1060e..24896bd7c 100644 --- a/src/Statements/CreateStatement.php +++ b/src/Statements/CreateStatement.php @@ -73,11 +73,8 @@ class CreateStatement extends Statement /** * All database options. - * - * @var array> - * @psalm-var array [ 1, 'var=', @@ -106,11 +103,8 @@ class CreateStatement extends Statement /** * All table options. - * - * @var array> - * @psalm-var array [ 1, 'var=', @@ -223,11 +217,8 @@ class CreateStatement extends Statement /** * All function options. - * - * @var array> - * @psalm-var array [ 2, 'var', @@ -263,11 +254,8 @@ class CreateStatement extends Statement /** * All trigger options. - * - * @var array> - * @psalm-var array 1, 'AFTER' => 1, 'INSERT' => 2, @@ -287,9 +275,9 @@ class CreateStatement extends Statement * * Used by `CREATE TABLE`, `CREATE FUNCTION` and `CREATE PROCEDURE`. * - * @see CreateStatement::$tableOptions - * @see CreateStatement::$functionOptions - * @see CreateStatement::$triggerOptions + * @see CreateStatement::TABLE_OPTIONS + * @see CreateStatement::FUNCTION_OPTIONS + * @see CreateStatement::TRIGGER_OPTIONS * * @var OptionsArray|null */ @@ -562,7 +550,7 @@ public function parse(Parser $parser, TokensList $list): void } if ($isDatabase) { - $this->entityOptions = OptionsArray::parse($parser, $list, static::$databaseOptions); + $this->entityOptions = OptionsArray::parse($parser, $list, self::DATABASE_OPTIONS); } elseif ($this->options->has('TABLE')) { if (($token->type === Token::TYPE_KEYWORD) && ($token->keyword === 'SELECT')) { /* CREATE TABLE ... SELECT */ @@ -606,7 +594,7 @@ public function parse(Parser $parser, TokensList $list): void ++$list->idx; - $this->entityOptions = OptionsArray::parse($parser, $list, static::$tableOptions); + $this->entityOptions = OptionsArray::parse($parser, $list, self::TABLE_OPTIONS); /** * The field that is being filled (`partitionBy` or @@ -714,7 +702,7 @@ public function parse(Parser $parser, TokensList $list): void ++$list->idx; - $this->entityOptions = OptionsArray::parse($parser, $list, static::$functionOptions); + $this->entityOptions = OptionsArray::parse($parser, $list, self::FUNCTION_OPTIONS); ++$list->idx; for (; $list->idx < $list->count; ++$list->idx) { @@ -764,7 +752,7 @@ public function parse(Parser $parser, TokensList $list): void } } elseif ($this->options->has('TRIGGER')) { // Parsing the time and the event. - $this->entityOptions = OptionsArray::parse($parser, $list, static::$triggerOptions); + $this->entityOptions = OptionsArray::parse($parser, $list, self::TRIGGER_OPTIONS); ++$list->idx; $list->getNextOfTypeAndValue(Token::TYPE_KEYWORD, 'ON'); diff --git a/src/Statements/ExplainStatement.php b/src/Statements/ExplainStatement.php index 27876af64..6fc283c6c 100644 --- a/src/Statements/ExplainStatement.php +++ b/src/Statements/ExplainStatement.php @@ -20,11 +20,8 @@ class ExplainStatement extends Statement { /** * Options for `EXPLAIN` statements. - * - * @var array> - * @psalm-var array 1, 'PARTITIONS' => 1, @@ -166,7 +163,7 @@ public function parse(Parser $parser, TokensList $list): void } } elseif ($state === 1) { // Parsing options. - $this->options = OptionsArray::parse($parser, $list, static::$OPTIONS); + $this->options = OptionsArray::parse($parser, $list, self::OPTIONS); $state = 2; } elseif ($state === 2) { $currIdx = $list->idx; diff --git a/src/Statements/LoadStatement.php b/src/Statements/LoadStatement.php index 88f37d933..241dd7b86 100644 --- a/src/Statements/LoadStatement.php +++ b/src/Statements/LoadStatement.php @@ -54,11 +54,8 @@ class LoadStatement extends Statement /** * FIELDS/COLUMNS Options for `LOAD DATA...INFILE` statements. - * - * @var array> - * @psalm-var array [ 1, 'expr', @@ -76,11 +73,8 @@ class LoadStatement extends Statement /** * LINES Options for `LOAD DATA...INFILE` statements. - * - * @var array> - * @psalm-var array [ 1, 'expr', @@ -122,7 +116,7 @@ class LoadStatement extends Statement /** * Options for FIELDS/COLUMNS keyword. * - * @see LoadStatement::$statementFieldsOptions + * @see LoadStatement::STATEMENT_FIELDS_OPTIONS * * @var OptionsArray|null */ @@ -138,7 +132,7 @@ class LoadStatement extends Statement /** * Options for OPTIONS keyword. * - * @see LoadStatement::$statementLinesOptions + * @see LoadStatement::STATEMENT_LINES_OPTIONS * * @var OptionsArray|null */ @@ -323,12 +317,12 @@ public function parseFileOptions(Parser $parser, TokensList $list, $keyword = 'F if ($keyword === 'FIELDS' || $keyword === 'COLUMNS') { // parse field options - $this->fieldsOptions = OptionsArray::parse($parser, $list, static::$statementFieldsOptions); + $this->fieldsOptions = OptionsArray::parse($parser, $list, self::STATEMENT_FIELDS_OPTIONS); $this->fieldsKeyword = $keyword; } else { // parse line options - $this->linesOptions = OptionsArray::parse($parser, $list, static::$statementLinesOptions); + $this->linesOptions = OptionsArray::parse($parser, $list, self::STATEMENT_LINES_OPTIONS); } } diff --git a/src/Statements/MaintenanceStatement.php b/src/Statements/MaintenanceStatement.php index 36c749d46..3748670ba 100644 --- a/src/Statements/MaintenanceStatement.php +++ b/src/Statements/MaintenanceStatement.php @@ -39,7 +39,7 @@ public function after(Parser $parser, TokensList $list, Token $token): void { // [some options] is going to be parsed first. // - // There is a parser specified in `Parser::$keywordParsers` + // There is a parser specified in `Parser::KEYWORD_PARSERS` // which parses the name of the tables. // // Finally, we parse here [some more options] and that's all. diff --git a/src/Statements/SelectStatement.php b/src/Statements/SelectStatement.php index 49cea0159..8677fc5d0 100644 --- a/src/Statements/SelectStatement.php +++ b/src/Statements/SelectStatement.php @@ -71,17 +71,9 @@ class SelectStatement extends Statement 'SQL_CALC_FOUND_ROWS' => 9, ]; - /** - * @var array> - * @psalm-var array 1]; + protected const STATEMENT_GROUP_OPTIONS = ['WITH ROLLUP' => 1]; - /** - * @var array> - * @psalm-var array 1, 'LOCK IN SHARE MODE' => 1, ]; @@ -332,7 +324,7 @@ class SelectStatement extends Statement /** * The end options of this query. * - * @see SelectStatement::$statementEndOptions + * @see SelectStatement::STATEMENT_END_OPTIONS * * @var OptionsArray|null */ diff --git a/src/Statements/SetStatement.php b/src/Statements/SetStatement.php index 114f33885..5a66e77f7 100644 --- a/src/Statements/SetStatement.php +++ b/src/Statements/SetStatement.php @@ -67,11 +67,7 @@ class SetStatement extends Statement '@@PERSIST_ONLY' => 3, ]; - /** - * @var array> - * @psalm-var array [ 1, 'var', @@ -89,7 +85,7 @@ class SetStatement extends Statement /** * The end options of this query. * - * @see SetStatement::$statementEndOptions + * @see SetStatement::STATEMENT_END_OPTIONS * * @var OptionsArray|null */ diff --git a/src/Tools/CustomJsonSerializer.php b/src/Tools/CustomJsonSerializer.php index 455840fa3..f6134bc0a 100644 --- a/src/Tools/CustomJsonSerializer.php +++ b/src/Tools/CustomJsonSerializer.php @@ -16,33 +16,9 @@ class CustomJsonSerializer extends JsonSerializer { public const SKIP_PROPERTIES = [ - 'allowedKeywords', - 'statementGroupOptions', - 'statementEndOptions', - 'keywordParsers', - 'statementParsers', - 'keywordNameIndicators',// Not static - 'operatorNameIndicators',// Not static 'defaultDelimiter', - 'parserMethods', - 'OPTIONS', 'clauses', - 'databaseOptions', - 'delimiters', - 'joins', 'statementOptions', - 'statementFieldsOptions', - 'statementLinesOptions', - 'triggerOptions', - 'functionOptions', - 'tableOptions', - 'fieldOptions', - 'dataTypeOptions', - 'referencesOptions', - 'keyOptions', - 'viewOptions', - 'eventOptions', - 'userOptions', ]; /** diff --git a/src/Utils/Formatter.php b/src/Utils/Formatter.php index f5227a808..b1456d02a 100644 --- a/src/Utils/Formatter.php +++ b/src/Utils/Formatter.php @@ -463,11 +463,11 @@ public function formatList($list): string // Inline JOINs if ( - ($prev->type === Token::TYPE_KEYWORD && isset(JoinKeyword::$joins[$prev->value])) + ($prev->type === Token::TYPE_KEYWORD && isset(JoinKeyword::JOINS[$prev->value])) || (in_array($curr->value, ['ON', 'USING'], true) - && isset(JoinKeyword::$joins[$list->tokens[$list->idx - 2]->value])) - || isset($list->tokens[$list->idx - 4], JoinKeyword::$joins[$list->tokens[$list->idx - 4]->value]) - || isset($list->tokens[$list->idx - 6], JoinKeyword::$joins[$list->tokens[$list->idx - 6]->value]) + && isset(JoinKeyword::JOINS[$list->tokens[$list->idx - 2]->value])) + || isset($list->tokens[$list->idx - 4], JoinKeyword::JOINS[$list->tokens[$list->idx - 4]->value]) + || isset($list->tokens[$list->idx - 6], JoinKeyword::JOINS[$list->tokens[$list->idx - 6]->value]) ) { $lineEnded = false; } @@ -758,13 +758,13 @@ public static function getGroupLength($list): int public static function isClause($token): int|false { if ( - ($token->type === Token::TYPE_KEYWORD && isset(Parser::$statementParsers[$token->keyword])) + ($token->type === Token::TYPE_KEYWORD && isset(Parser::STATEMENT_PARSERS[$token->keyword])) || ($token->type === Token::TYPE_NONE && strtoupper($token->token) === 'DELIMITER') ) { return 2; } - if ($token->type === Token::TYPE_KEYWORD && isset(Parser::$keywordParsers[$token->keyword])) { + if ($token->type === Token::TYPE_KEYWORD && isset(Parser::KEYWORD_PARSERS[$token->keyword])) { return 1; }