Файловый менеджер - Редактировать - /home/autoovt/www/DelimiterStack.php.tar
Назад
home/autoovt/www/vendor-old/league/commonmark/src/Delimiter/DelimiterStack.php 0000666 00000031603 14771773433 0023650 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of the league/commonmark package. * * (c) Colin O'Dell <colinodell@gmail.com> * * Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js) * - (c) John MacFarlane * * Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java) * - (c) Atlassian Pty Ltd * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace League\CommonMark\Delimiter; use League\CommonMark\Delimiter\Processor\CacheableDelimiterProcessorInterface; use League\CommonMark\Delimiter\Processor\DelimiterProcessorCollection; use League\CommonMark\Node\Inline\AdjacentTextMerger; use League\CommonMark\Node\Node; final class DelimiterStack { /** @psalm-readonly-allow-private-mutation */ private ?DelimiterInterface $top = null; /** @psalm-readonly-allow-private-mutation */ private ?Bracket $brackets = null; /** * @deprecated This property will be removed in 3.0 once all delimiters MUST have an index/position * * @var \SplObjectStorage<DelimiterInterface, int>|\WeakMap<DelimiterInterface, int> */ private $missingIndexCache; private int $remainingDelimiters = 0; public function __construct(int $maximumStackSize = PHP_INT_MAX) { $this->remainingDelimiters = $maximumStackSize; if (\PHP_VERSION_ID >= 80000) { /** @psalm-suppress PropertyTypeCoercion */ $this->missingIndexCache = new \WeakMap(); // @phpstan-ignore-line } else { $this->missingIndexCache = new \SplObjectStorage(); // @phpstan-ignore-line } } public function push(DelimiterInterface $newDelimiter): void { if ($this->remainingDelimiters-- <= 0) { return; } $newDelimiter->setPrevious($this->top); if ($this->top !== null) { $this->top->setNext($newDelimiter); } $this->top = $newDelimiter; } /** * @internal */ public function addBracket(Node $node, int $index, bool $image): void { if ($this->brackets !== null) { $this->brackets->setHasNext(true); } $this->brackets = new Bracket($node, $this->brackets, $index, $image); } /** * @psalm-immutable */ public function getLastBracket(): ?Bracket { return $this->brackets; } private function findEarliest(int $stackBottom): ?DelimiterInterface { // Move back to first relevant delim. $delimiter = $this->top; $lastChecked = null; while ($delimiter !== null && self::getIndex($delimiter) > $stackBottom) { $lastChecked = $delimiter; $delimiter = $delimiter->getPrevious(); } return $lastChecked; } /** * @internal */ public function removeBracket(): void { if ($this->brackets === null) { return; } $this->brackets = $this->brackets->getPrevious(); if ($this->brackets !== null) { $this->brackets->setHasNext(false); } } public function removeDelimiter(DelimiterInterface $delimiter): void { if ($delimiter->getPrevious() !== null) { /** @psalm-suppress PossiblyNullReference */ $delimiter->getPrevious()->setNext($delimiter->getNext()); } if ($delimiter->getNext() === null) { // top of stack $this->top = $delimiter->getPrevious(); } else { /** @psalm-suppress PossiblyNullReference */ $delimiter->getNext()->setPrevious($delimiter->getPrevious()); } // Nullify all references from the removed delimiter to other delimiters. // All references to this particular delimiter in the linked list should be gone, // but it's possible we're still hanging on to other references to things that // have been (or soon will be) removed, which may interfere with efficient // garbage collection by the PHP runtime. // Explicitly releasing these references should help to avoid possible // segfaults like in https://bugs.php.net/bug.php?id=68606. $delimiter->setPrevious(null); $delimiter->setNext(null); // TODO: Remove the line below once PHP 7.4 support is dropped, as WeakMap won't hold onto the reference, making this unnecessary unset($this->missingIndexCache[$delimiter]); } private function removeDelimiterAndNode(DelimiterInterface $delimiter): void { $delimiter->getInlineNode()->detach(); $this->removeDelimiter($delimiter); } private function removeDelimitersBetween(DelimiterInterface $opener, DelimiterInterface $closer): void { $delimiter = $closer->getPrevious(); $openerPosition = self::getIndex($opener); while ($delimiter !== null && self::getIndex($delimiter) > $openerPosition) { $previous = $delimiter->getPrevious(); $this->removeDelimiter($delimiter); $delimiter = $previous; } } /** * @param DelimiterInterface|int|null $stackBottom */ public function removeAll($stackBottom = null): void { $stackBottomPosition = \is_int($stackBottom) ? $stackBottom : self::getIndex($stackBottom); while ($this->top && $this->getIndex($this->top) > $stackBottomPosition) { $this->removeDelimiter($this->top); } } /** * @deprecated This method is no longer used internally and will be removed in 3.0 */ public function removeEarlierMatches(string $character): void { $opener = $this->top; while ($opener !== null) { if ($opener->getChar() === $character) { $opener->setActive(false); } $opener = $opener->getPrevious(); } } /** * @internal */ public function deactivateLinkOpeners(): void { $opener = $this->brackets; while ($opener !== null && $opener->isActive()) { $opener->setActive(false); $opener = $opener->getPrevious(); } } /** * @deprecated This method is no longer used internally and will be removed in 3.0 * * @param string|string[] $characters */ public function searchByCharacter($characters): ?DelimiterInterface { if (! \is_array($characters)) { $characters = [$characters]; } $opener = $this->top; while ($opener !== null) { if (\in_array($opener->getChar(), $characters, true)) { break; } $opener = $opener->getPrevious(); } return $opener; } /** * @param DelimiterInterface|int|null $stackBottom * * @todo change $stackBottom to an int in 3.0 */ public function processDelimiters($stackBottom, DelimiterProcessorCollection $processors): void { /** @var array<string, int> $openersBottom */ $openersBottom = []; $stackBottomPosition = \is_int($stackBottom) ? $stackBottom : self::getIndex($stackBottom); // Find first closer above stackBottom $closer = $this->findEarliest($stackBottomPosition); // Move forward, looking for closers, and handling each while ($closer !== null) { $closingDelimiterChar = $closer->getChar(); $delimiterProcessor = $processors->getDelimiterProcessor($closingDelimiterChar); if (! $closer->canClose() || $delimiterProcessor === null) { $closer = $closer->getNext(); continue; } if ($delimiterProcessor instanceof CacheableDelimiterProcessorInterface) { $openersBottomCacheKey = $delimiterProcessor->getCacheKey($closer); } else { $openersBottomCacheKey = $closingDelimiterChar; } $openingDelimiterChar = $delimiterProcessor->getOpeningCharacter(); $useDelims = 0; $openerFound = false; $potentialOpenerFound = false; $opener = $closer->getPrevious(); while ($opener !== null && ($openerPosition = self::getIndex($opener)) > $stackBottomPosition && $openerPosition >= ($openersBottom[$openersBottomCacheKey] ?? 0)) { if ($opener->canOpen() && $opener->getChar() === $openingDelimiterChar) { $potentialOpenerFound = true; $useDelims = $delimiterProcessor->getDelimiterUse($opener, $closer); if ($useDelims > 0) { $openerFound = true; break; } } $opener = $opener->getPrevious(); } if (! $openerFound) { // Set lower bound for future searches // TODO: Remove this conditional check in 3.0. It only exists to prevent behavioral BC breaks in 2.x. if ($potentialOpenerFound === false || $delimiterProcessor instanceof CacheableDelimiterProcessorInterface) { $openersBottom[$openersBottomCacheKey] = self::getIndex($closer); } if (! $potentialOpenerFound && ! $closer->canOpen()) { // We can remove a closer that can't be an opener, // once we've seen there's no matching opener. $next = $closer->getNext(); $this->removeDelimiter($closer); $closer = $next; } else { $closer = $closer->getNext(); } continue; } \assert($opener !== null); $openerNode = $opener->getInlineNode(); $closerNode = $closer->getInlineNode(); // Remove number of used delimiters from stack and inline nodes. $opener->setLength($opener->getLength() - $useDelims); $closer->setLength($closer->getLength() - $useDelims); $openerNode->setLiteral(\substr($openerNode->getLiteral(), 0, -$useDelims)); $closerNode->setLiteral(\substr($closerNode->getLiteral(), 0, -$useDelims)); $this->removeDelimitersBetween($opener, $closer); // The delimiter processor can re-parent the nodes between opener and closer, // so make sure they're contiguous already. Exclusive because we want to keep opener/closer themselves. AdjacentTextMerger::mergeTextNodesBetweenExclusive($openerNode, $closerNode); $delimiterProcessor->process($openerNode, $closerNode, $useDelims); // No delimiter characters left to process, so we can remove delimiter and the now empty node. if ($opener->getLength() === 0) { $this->removeDelimiterAndNode($opener); } // phpcs:disable SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed if ($closer->getLength() === 0) { $next = $closer->getNext(); $this->removeDelimiterAndNode($closer); $closer = $next; } } // Remove all delimiters $this->removeAll($stackBottomPosition); } /** * @internal */ public function __destruct() { while ($this->top) { $this->removeDelimiter($this->top); } while ($this->brackets) { $this->removeBracket(); } } /** * @deprecated This method will be dropped in 3.0 once all delimiters MUST have an index/position */ private function getIndex(?DelimiterInterface $delimiter): int { if ($delimiter === null) { return -1; } if (($index = $delimiter->getIndex()) !== null) { return $index; } if (isset($this->missingIndexCache[$delimiter])) { return $this->missingIndexCache[$delimiter]; } $prev = $delimiter->getPrevious(); $next = $delimiter->getNext(); $i = 0; do { $i++; if ($prev === null) { break; } if ($prev->getIndex() !== null) { return $this->missingIndexCache[$delimiter] = $prev->getIndex() + $i; } } while ($prev = $prev->getPrevious()); $j = 0; do { $j++; if ($next === null) { break; } if ($next->getIndex() !== null) { return $this->missingIndexCache[$delimiter] = $next->getIndex() - $j; } } while ($next = $next->getNext()); // No index was defined on this delimiter, and none could be guesstimated based on the stack. return $this->missingIndexCache[$delimiter] = $this->getIndex($delimiter->getPrevious()) + 1; } }
| ver. 1.4 |
Github
|
.
| PHP 5.4.45 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка