diff --git a/src/SqlFormatter.php b/src/SqlFormatter.php index b3ff6d9..67be7ae 100644 --- a/src/SqlFormatter.php +++ b/src/SqlFormatter.php @@ -11,13 +11,12 @@ namespace Doctrine\SqlFormatter; +use function array_pop; use function array_search; -use function array_shift; -use function array_unshift; use function assert; +use function end; use function in_array; use function preg_replace; -use function reset; use function rtrim; use function str_repeat; use function str_replace; @@ -68,7 +67,7 @@ public function format(string $string, string $indentString = ' '): string $inlineIndented = false; $clauseLimit = false; - $appendNewLineIfNotAddedFx = static function () use (&$addedNewline, &$return, $tab, &$indentLevel): void { + $appendNewLineIfNotAddedFx = static function () use (&$addedNewline, &$return, $tab, &$indentLevel): void { // Add a newline if not already added if ($addedNewline) { // @phpstan-ignore if.alwaysFalse return; @@ -77,7 +76,10 @@ public function format(string $string, string $indentString = ' '): string $return = rtrim($return, ' ' . $tab); $return .= "\n" . str_repeat($tab, $indentLevel); }; - $redoIndentationFx = static function () use (&$return, $tab, &$indentLevel): void { + $decreaseIndentationLevelFx = static function () use (&$return, &$indentTypes, $tab, &$indentLevel): void { + array_pop($indentTypes); + $indentLevel--; + // Redo the indentation since it may be different now $lastPossiblyIndentLine = substr($return, -($indentLevel + 2)); if (rtrim($lastPossiblyIndentLine, $tab) !== "\n") { @@ -101,14 +103,14 @@ public function format(string $string, string $indentString = ' '): string if ($increaseSpecialIndent) { $indentLevel++; $increaseSpecialIndent = false; - array_unshift($indentTypes, self::INDENT_TYPE_SPECIAL); + $indentTypes[] = self::INDENT_TYPE_SPECIAL; } // If we are increasing the block indent level now if ($increaseBlockIndent) { $indentLevel++; $increaseBlockIndent = false; - array_unshift($indentTypes, self::INDENT_TYPE_BLOCK); + $indentTypes[] = self::INDENT_TYPE_BLOCK; } // If we need a new line before the token @@ -141,8 +143,8 @@ public function format(string $string, string $indentString = ' '): string $return = rtrim($return, ' '); if ($inlineIndented) { - array_shift($indentTypes); - $indentLevel--; + $decreaseIndentationLevelFx(); + $return = rtrim($return, ' '); $return .= "\n" . str_repeat($tab, $indentLevel); } @@ -227,17 +229,12 @@ public function format(string $string, string $indentString = ' '): string // Remove whitespace before the closing parentheses $return = rtrim($return, ' '); - $indentLevel--; - - // Reset indent level - while ($j = array_shift($indentTypes)) { - if ($j !== self::INDENT_TYPE_SPECIAL) { - break; - } - - $indentLevel--; + while (end($indentTypes) === self::INDENT_TYPE_SPECIAL) { + $decreaseIndentationLevelFx(); } + $decreaseIndentationLevelFx(); + if ($indentLevel < 0) { // This is an error $indentLevel = 0; @@ -252,10 +249,8 @@ public function format(string $string, string $indentString = ' '): string $increaseSpecialIndent = true; // If the last indent type was special, decrease the special indent for this round - if (reset($indentTypes) === self::INDENT_TYPE_SPECIAL) { - $indentLevel--; - array_shift($indentTypes); - $redoIndentationFx(); + if (end($indentTypes) === self::INDENT_TYPE_SPECIAL) { + $decreaseIndentationLevelFx(); } // Add a newline after the top level reserved word @@ -273,10 +268,8 @@ public function format(string $string, string $indentString = ' '): string } } elseif ($token->value() === ';') { // If the last indent type was special, decrease the special indent for this round - if (reset($indentTypes) === self::INDENT_TYPE_SPECIAL) { - $indentLevel--; - array_shift($indentTypes); - $redoIndentationFx(); + if (end($indentTypes) === self::INDENT_TYPE_SPECIAL) { + $decreaseIndentationLevelFx(); } $newline = true; @@ -287,9 +280,7 @@ public function format(string $string, string $indentString = ' '): string $increaseBlockIndent = true; } elseif (in_array(strtoupper($token->value()), ['WHEN', 'THEN', 'ELSE', 'END'], true)) { if (strtoupper($token->value()) !== 'THEN') { - array_shift($indentTypes); - $indentLevel--; - $redoIndentationFx(); + $decreaseIndentationLevelFx(); $prevNotWhitespaceToken = $cursor->subCursor()->previous(Token::TOKEN_TYPE_WHITESPACE); if ($prevNotWhitespaceToken !== null && strtoupper($prevNotWhitespaceToken->value()) !== 'CASE') {