Skip to content

Commit

Permalink
reland
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek committed Jan 8, 2024
1 parent 8ebd458 commit 4040754
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 72 deletions.
2 changes: 2 additions & 0 deletions dev-tools/doc.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/usr/bin/env php
<?php

declare(strict_types=1);

/*
* This file is part of PHP CS Fixer.
*
Expand Down
2 changes: 2 additions & 0 deletions dev-tools/info-extractor.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/usr/bin/env php
<?php

declare(strict_types=1);

/*
* This file is part of PHP CS Fixer.
*
Expand Down
16 changes: 10 additions & 6 deletions src/Fixer/Comment/HeaderCommentFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,15 @@ public function getDefinition(): FixerDefinitionInterface

public function isCandidate(Tokens $tokens): bool
{
return $tokens->isMonolithicPhp();
if ($tokens->isMonolithicPhp()) {

$openTagIndex = $tokens[0]->isGivenKind(T_INLINE_HTML) ? 1 : 0;
if (!$tokens[$openTagIndex]->isGivenKind(T_OPEN_TAG_WITH_ECHO)) {
return true;
}
}

return false;
}

/**
Expand Down Expand Up @@ -266,11 +274,7 @@ private function findHeaderCommentCurrentIndex(Tokens $tokens, int $headerNewInd
*/
private function findHeaderCommentInsertionIndex(Tokens $tokens, string $location): int
{
$openTagIndex = $tokens[0]->isGivenKind(T_OPEN_TAG) ? 0 : $tokens->getNextTokenOfKind(0, [[T_OPEN_TAG]]);

if (null === $openTagIndex) {
return 1;
}
$openTagIndex = $tokens[0]->isGivenKind(T_INLINE_HTML) ? 1 : 0;

if ('after_open' === $location) {
return $openTagIndex + 1;
Expand Down
32 changes: 17 additions & 15 deletions src/Fixer/PhpTag/BlankLineAfterOpeningTagFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,24 @@ public function getPriority(): int

public function isCandidate(Tokens $tokens): bool
{
return $tokens->isTokenKindFound(T_OPEN_TAG);
if ($tokens->isMonolithicPhp()) {

$openTagIndex = $tokens[0]->isGivenKind(T_INLINE_HTML) ? 1 : 0;
if (!$tokens[$openTagIndex]->isGivenKind(T_OPEN_TAG_WITH_ECHO)) {
return true;
}
}

return false;
}

protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
{
$lineEnding = $this->whitespacesConfig->getLineEnding();

// ignore files with short open tag and ignore non-monolithic files
if (!$tokens[0]->isGivenKind(T_OPEN_TAG) || !$tokens->isMonolithicPhp()) {
return;
}

$newlineFound = false;

/** @var Token $token */
foreach ($tokens as $token) {
if ($token->isWhitespace() && str_contains($token->getContent(), "\n")) {
if (($token->isWhitespace() || $token->isGivenKind(T_OPEN_TAG)) && str_contains($token->getContent(), "\n")) {
$newlineFound = true;

break;
Expand All @@ -76,17 +77,18 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
return;
}

$token = $tokens[0];
$openTagIndex = $tokens[0]->isGivenKind(T_INLINE_HTML) ? 1 : 0;
$token = $tokens[$openTagIndex];

if (!str_contains($token->getContent(), "\n")) {
$tokens[0] = new Token([$token->getId(), rtrim($token->getContent()).$lineEnding]);
$tokens[$openTagIndex] = new Token([$token->getId(), rtrim($token->getContent()).$lineEnding]);
}

if (!str_contains($tokens[1]->getContent(), "\n")) {
if ($tokens[1]->isWhitespace()) {
$tokens[1] = new Token([T_WHITESPACE, $lineEnding.$tokens[1]->getContent()]);
if (!str_contains($tokens[$openTagIndex + 1]->getContent(), "\n")) {
if ($tokens[$openTagIndex + 1]->isWhitespace()) {
$tokens[$openTagIndex + 1] = new Token([T_WHITESPACE, $lineEnding.$tokens[$openTagIndex + 1]->getContent()]);
} else {
$tokens->insertAt(1, new Token([T_WHITESPACE, $lineEnding]));
$tokens->insertAt($openTagIndex + 1, new Token([T_WHITESPACE, $lineEnding]));
}
}
}
Expand Down
21 changes: 13 additions & 8 deletions src/Fixer/PhpTag/LinebreakAfterOpeningTagFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,29 @@ public function getDefinition(): FixerDefinitionInterface

public function isCandidate(Tokens $tokens): bool
{
return $tokens->isTokenKindFound(T_OPEN_TAG);
if ($tokens->isMonolithicPhp()) {

$openTagIndex = $tokens[0]->isGivenKind(T_INLINE_HTML) ? 1 : 0;
if (!$tokens[$openTagIndex]->isGivenKind(T_OPEN_TAG_WITH_ECHO)) {
return true;
}
}

return false;
}

protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
{
// ignore files with short open tag and ignore non-monolithic files
if (!$tokens[0]->isGivenKind(T_OPEN_TAG) || !$tokens->isMonolithicPhp()) {
return;
}
$openTagIndex = $tokens[0]->isGivenKind(T_INLINE_HTML) ? 1 : 0;

// ignore if linebreak already present
if (str_contains($tokens[0]->getContent(), "\n")) {
if (str_contains($tokens[$openTagIndex]->getContent(), "\n")) {
return;
}

$newlineFound = false;
foreach ($tokens as $token) {
if ($token->isWhitespace() && str_contains($token->getContent(), "\n")) {
if (($token->isWhitespace() || $token->isGivenKind(T_OPEN_TAG)) && str_contains($token->getContent(), "\n")) {
$newlineFound = true;

break;
Expand All @@ -66,6 +71,6 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
return;
}

$tokens[0] = new Token([T_OPEN_TAG, rtrim($tokens[0]->getContent()).$this->whitespacesConfig->getLineEnding()]);
$tokens[$openTagIndex] = new Token([T_OPEN_TAG, rtrim($tokens[$openTagIndex]->getContent()).$this->whitespacesConfig->getLineEnding()]);
}
}
6 changes: 1 addition & 5 deletions src/Fixer/PhpTag/NoClosingTagFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,11 @@ public function getDefinition(): FixerDefinitionInterface

public function isCandidate(Tokens $tokens): bool
{
return $tokens->isTokenKindFound(T_CLOSE_TAG);
return \count($tokens) >= 2 && $tokens->isMonolithicPhp() && $tokens->isTokenKindFound(T_CLOSE_TAG);
}

protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
{
if (\count($tokens) < 2 || !$tokens->isMonolithicPhp() || !$tokens->isTokenKindFound(T_CLOSE_TAG)) {
return;
}

$closeTags = $tokens->findGivenKind(T_CLOSE_TAG);
$index = array_key_first($closeTags);

Expand Down
50 changes: 25 additions & 25 deletions src/Fixer/Strict/DeclareStrictTypesFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,15 @@ public function getPriority(): int

public function isCandidate(Tokens $tokens): bool
{
return isset($tokens[0]) && $tokens[0]->isGivenKind(T_OPEN_TAG);
if ($tokens->isMonolithicPhp()) {

$openTagIndex = $tokens[0]->isGivenKind(T_INLINE_HTML) ? 1 : 0;
if (!$tokens[$openTagIndex]->isGivenKind(T_OPEN_TAG_WITH_ECHO)) {
return true;
}
}

return false;
}

public function isRisky(): bool
Expand All @@ -63,17 +71,11 @@ public function isRisky(): bool

protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
{
// check if the declaration is already done
$searchIndex = $tokens->getNextMeaningfulToken(0);
if (null === $searchIndex) {
$this->insertSequence($tokens); // declaration not found, insert one

return;
}
$openTagIndex = $tokens[0]->isGivenKind(T_INLINE_HTML) ? 1 : 0;

$sequenceLocation = $tokens->findSequence([[T_DECLARE, 'declare'], '(', [T_STRING, 'strict_types'], '=', [T_LNUMBER], ')'], $searchIndex, null, false);
$sequenceLocation = $tokens->findSequence([[T_DECLARE, 'declare'], '(', [T_STRING, 'strict_types'], '=', [T_LNUMBER], ')'], $openTagIndex, null, false);
if (null === $sequenceLocation) {
$this->insertSequence($tokens); // declaration not found, insert one
$this->insertSequence($openTagIndex, $tokens); // declaration not found, insert one

return;
}
Expand Down Expand Up @@ -102,7 +104,7 @@ private function fixStrictTypesCasingAndValue(Tokens $tokens, array $sequence):
}
}

private function insertSequence(Tokens $tokens): void
private function insertSequence(int $openTagIndex, Tokens $tokens): void
{
$sequence = [
new Token([T_DECLARE, 'declare']),
Expand All @@ -113,28 +115,26 @@ private function insertSequence(Tokens $tokens): void
new Token(')'),
new Token(';'),
];
$endIndex = \count($sequence);
$nextIndex = $openTagIndex + \count($sequence) + 1;

$tokens->insertAt(1, $sequence);
$tokens->insertAt($openTagIndex + 1, $sequence);

// start index of the sequence is always 1 here, 0 is always open tag
// transform "<?php\n" to "<?php " if needed
if (str_contains($tokens[0]->getContent(), "\n")) {
$tokens[0] = new Token([$tokens[0]->getId(), trim($tokens[0]->getContent()).' ']);
// transform "<?php" or "<?php\n" to "<?php " if needed
$content = $tokens[$openTagIndex]->getContent();
if (!str_contains($content, ' ') || str_contains($content, "\n")) {
$tokens[$openTagIndex] = new Token([$tokens[$openTagIndex]->getId(), trim($tokens[$openTagIndex]->getContent()).' ']);
}

if ($endIndex === \count($tokens) - 1) {
if (\count($tokens) === $nextIndex) {
return; // no more tokens after sequence, single_blank_line_at_eof might add a line
}

$lineEnding = $this->whitespacesConfig->getLineEnding();
if (!$tokens[1 + $endIndex]->isWhitespace()) {
$tokens->insertAt(1 + $endIndex, new Token([T_WHITESPACE, $lineEnding]));

return;
if ($tokens[$nextIndex]->isWhitespace()) {
$content = $tokens[$nextIndex]->getContent();
$tokens[$nextIndex] = new Token([T_WHITESPACE, $lineEnding.ltrim($content, " \t")]);
} else {
$tokens->insertAt($nextIndex, new Token([T_WHITESPACE, $lineEnding]));
}

$content = $tokens[1 + $endIndex]->getContent();
$tokens[1 + $endIndex] = new Token([T_WHITESPACE, $lineEnding.ltrim($content, " \t")]);
}
}
20 changes: 11 additions & 9 deletions src/Tokenizer/Tokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -1107,19 +1107,21 @@ public function clearRange(int $indexStart, int $indexEnd): void
*/
public function isMonolithicPhp(): bool
{
if (0 === $this->count()) {
return false;
}
if ((1 === $this->countTokenKind(T_OPEN_TAG) && 0 === $this->countTokenKind(T_OPEN_TAG_WITH_ECHO))
|| (0 === $this->countTokenKind(T_OPEN_TAG) && 1 === $this->countTokenKind(T_OPEN_TAG_WITH_ECHO))
) {
if ($this->countTokenKind(T_INLINE_HTML) > 1) {
return false;
}

if ($this->countTokenKind(T_INLINE_HTML) > 1) {
return false;
}
if (1 === $this->countTokenKind(T_INLINE_HTML)) {
return Preg::match('/^#!.+$/', $this[0]->getContent());
}

if (1 === $this->countTokenKind(T_INLINE_HTML)) {
return Preg::match('/^#!.+$/', $this[0]->getContent());
return true;
}

return 1 === ($this->countTokenKind(T_OPEN_TAG) + $this->countTokenKind(T_OPEN_TAG_WITH_ECHO));
return false;
}

/**
Expand Down
16 changes: 14 additions & 2 deletions tests/Fixer/PhpTag/BlankLineAfterOpeningTagFixerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,8 @@ public static function provideFixCases(): iterable
yield [
'<?php
$a = 0;
echo 1;',
'<?php
$a = 0;
echo 1;',
];

Expand Down Expand Up @@ -138,6 +136,20 @@ class SomeClass
$foo = $bar;
?>',
];

yield 'file with shebang' => [
<<<'EOD'
#!x
<?php
echo 1;
EOD,
<<<'EOD'
#!x
<?php
echo 1;
EOD,
];
}

/**
Expand Down
14 changes: 14 additions & 0 deletions tests/Fixer/PhpTag/LinebreakAfterOpeningTagFixerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,20 @@ public static function provideFixCases(): iterable
// linebreak already present in file with Windows line endings
'),
];

yield 'file with shebang' => [
<<<'EOD'
#!x
<?php
echo 1;
echo 2;
EOD,
<<<'EOD'
#!x
<?php echo 1;
echo 2;
EOD,
];
}

/**
Expand Down

0 comments on commit 4040754

Please sign in to comment.