diff --git a/src/Report/Reporter/TextReporter.php b/src/Report/Reporter/TextReporter.php index 35b6c441..52b88f19 100644 --- a/src/Report/Reporter/TextReporter.php +++ b/src/Report/Reporter/TextReporter.php @@ -9,7 +9,6 @@ use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; -use TwigCsFixer\File\FileHelper; use TwigCsFixer\Report\Report; use TwigCsFixer\Report\Violation; @@ -47,16 +46,18 @@ public function display( } $content = @file_get_contents($file); + $lines = false !== $content ? preg_split("/\r\n?|\n/", $content) : false; + $rows = []; foreach ($fileViolations as $violation) { $formattedText = []; $line = $violation->getLine(); - if (null === $line || false === $content) { + if (null === $line || false === $lines) { $formattedText[] = $this->formatErrorMessage($violation, $debug); } else { - $lines = $this->getContext($content, $line); - foreach ($lines as $no => $code) { + $context = $this->getContext($lines, $line); + foreach ($context as $no => $code) { $formattedText[] = sprintf( self::ERROR_LINE_FORMAT, $no, @@ -103,22 +104,22 @@ public function display( } /** + * @param array $templatesLines + * * @return array */ - private function getContext(string $template, int $line): array + private function getContext(array $templatesLines, int $line): array { - $eol = FileHelper::detectEOL($template); - $lines = explode($eol, $template); $position = max(0, $line - 2); - $max = min(\count($lines), $line + 1); + $max = min(\count($templatesLines), $line + 1); $result = []; $indents = []; do { - preg_match('/^[\s\t]+/', $lines[$position], $match); + preg_match('/^[\s\t]+/', $templatesLines[$position], $match); $indents[] = \strlen($match[0] ?? ''); - $result[$position + 1] = $lines[$position]; + $result[$position + 1] = $templatesLines[$position]; ++$position; } while ($position < $max); diff --git a/src/Token/Tokenizer.php b/src/Token/Tokenizer.php index 51f918b8..c429148c 100644 --- a/src/Token/Tokenizer.php +++ b/src/Token/Tokenizer.php @@ -7,7 +7,6 @@ use Twig\Environment; use Twig\Source; use TwigCsFixer\Exception\CannotTokenizeException; -use TwigCsFixer\File\FileHelper; use TwigCsFixer\Report\ViolationId; use Webmozart\Assert\Assert; @@ -47,8 +46,6 @@ final class Tokenizer implements TokenizerInterface private int $cursor = 0; - private string $eol = \PHP_EOL; - private int $lastEOL = 0; private ?int $end = null; @@ -177,7 +174,6 @@ private function resetState(Source $source): void $this->code = $source->getCode(); $this->end = \strlen($this->code); $this->filename = $source->getName(); - $this->eol = FileHelper::detectEOL($this->code); } /** @@ -297,7 +293,9 @@ private function pushToken(int|string $type, string $value = '', ?Token $related $this->tokens[] = $token; $this->cursor += \strlen($value); - $this->line += substr_count($value, $this->eol); + + $eolNb = preg_match_all("/\r\n?|\n/", $value); + $this->line += false !== $eolNb ? $eolNb : 0; return $token; } @@ -315,7 +313,7 @@ private function lexExpression(): void $this->lexTab(); } elseif (' ' === $currentCode) { $this->lexWhitespace(); - } elseif (1 === preg_match("/^{$this->eol}/", $currentCode.$nextToken, $match)) { + } elseif (1 === preg_match("/^\r\n?|^\n/", $currentCode.$nextToken, $match)) { $this->lexEOL($match[0]); } elseif ('.' === $currentCode && '.' === $nextToken && '.' === $next2Token) { $this->lexSpread(); @@ -450,7 +448,7 @@ private function lexData(int $limit = 0): void $this->lexTab(); } elseif (' ' === $currentCode) { $this->lexWhitespace(); - } elseif (1 === preg_match("/^{$this->eol}/", $currentCode.$nextToken, $match)) { + } elseif (1 === preg_match("/^\r\n?|^\n/", $currentCode.$nextToken, $match)) { $this->lexEOL($match[0]); } elseif (1 === preg_match('/\S+/', $this->code, $match, 0, $this->cursor)) { $value = $match[0]; diff --git a/tests/Token/Tokenizer/TokenizerTest.php b/tests/Token/Tokenizer/TokenizerTest.php index 319ccb43..abad8cae 100644 --- a/tests/Token/Tokenizer/TokenizerTest.php +++ b/tests/Token/Tokenizer/TokenizerTest.php @@ -39,20 +39,22 @@ public function testTokenize(): void ); } - public function testTokenizeWindowsEOL(): void + public function testTokenizeMixedEOL(): void { $env = new StubbedEnvironment(); $tokenizer = new Tokenizer($env); - $source = new Source("\r\n{#\r\n#}", 'path'); + $source = new Source("{#\r\n\n#}\r\n\n", 'path'); static::assertEquals( [ [ - new Token(Token::EOL_TYPE, 1, 1, 'path', "\r\n"), - new Token(Token::COMMENT_START_TYPE, 2, 1, 'path', '{#'), - new Token(Token::COMMENT_EOL_TYPE, 2, 3, 'path', "\r\n"), + new Token(Token::COMMENT_START_TYPE, 1, 1, 'path', '{#'), + new Token(Token::COMMENT_EOL_TYPE, 1, 3, 'path', "\r\n"), + new Token(Token::COMMENT_EOL_TYPE, 2, 1, 'path', "\n"), new Token(Token::COMMENT_END_TYPE, 3, 1, 'path', '#}'), - new Token(Token::EOF_TYPE, 3, 3, 'path'), + new Token(Token::EOL_TYPE, 3, 3, 'path', "\r\n"), + new Token(Token::EOL_TYPE, 4, 1, 'path', "\n"), + new Token(Token::EOF_TYPE, 5, 1, 'path'), ], [], ],