Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

declare(strict_types=1);

namespace Symplify\CodingStandard\Fixer\Spacing;

use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use PhpCsFixer\Tokenizer\TokensAnalyzer;
use PhpCsFixer\WhitespacesFixerConfig;
use SplFileInfo;
use Symplify\CodingStandard\Fixer\AbstractSymplifyFixer;

/**
* @see \Symplify\CodingStandard\Tests\Fixer\Spacing\NoBlankLineBetweenImportsFixer\NoBlankLineBetweenImportsFixerTest
*/
final class NoBlankLineBetweenImportsFixer extends AbstractSymplifyFixer implements WhitespacesAwareFixerInterface
{
private const string ERROR_MESSAGE = 'There must be no blank line between import "use" statements.';

private WhitespacesFixerConfig $whitespacesFixerConfig;

public function getDefinition(): FixerDefinitionInterface
{
return new FixerDefinition(self::ERROR_MESSAGE, [new CodeSample("<?php\nuse Foo\\Bar;\n\nuse function Foo\\baz;\n")]);
}

// run after OrderedImportsFixer and BlankLineBetweenImportGroupsFixer
public function getPriority(): int
{
return -50;
}

/**
* @param Tokens<Token> $tokens
*/
public function isCandidate(Tokens $tokens): bool
{
return $tokens->isTokenKindFound(T_USE);
}

public function setWhitespacesConfig(WhitespacesFixerConfig $whitespacesFixerConfig): void
{
$this->whitespacesFixerConfig = $whitespacesFixerConfig;
}

/**
* @param Tokens<Token> $tokens
*/
public function fix(SplFileInfo $fileInfo, Tokens $tokens): void
{
$tokensAnalyzer = new TokensAnalyzer($tokens);
$useIndexes = $tokensAnalyzer->getImportUseIndexes();

$lineEnding = $this->whitespacesFixerConfig->getLineEnding();

// start at the 2nd use, so the blank line after the namespace stays untouched
for ($i = 1, $count = count($useIndexes); $i < $count; ++$i) {
$useIndex = $useIndexes[$i];

$previousIndex = $tokens->getPrevMeaningfulToken($useIndex);
if ($previousIndex === null || ! $tokens[$previousIndex]->equals(';')) {
continue;
}

$whitespaceIndex = $useIndex - 1;
if (! $tokens[$whitespaceIndex]->isWhitespace()) {
continue;
}

if (substr_count($tokens[$whitespaceIndex]->getContent(), "\n") < 2) {
continue;
}

$tokens[$whitespaceIndex] = new Token([T_WHITESPACE, $lineEnding]);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Symplify\CodingStandard\Tests\Fixer\Spacing\NoBlankLineBetweenImportsFixer\Fixture;

use Foo\Bar;

use Foo\Baz;

class BlankLineBetweenImports
{
}

?>
-----
<?php

namespace Symplify\CodingStandard\Tests\Fixer\Spacing\NoBlankLineBetweenImportsFixer\Fixture;

use Foo\Bar;
use Foo\Baz;

class BlankLineBetweenImports
{
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Symplify\CodingStandard\Tests\Fixer\Spacing\NoBlankLineBetweenImportsFixer\Fixture;

use Foo\Bar;
use Foo\Baz;

class SkipNamespaceBlankLine
{
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Symplify\CodingStandard\Tests\Fixer\Spacing\NoBlankLineBetweenImportsFixer;

use Iterator;
use PHPUnit\Framework\Attributes\DataProvider;
use Symplify\EasyCodingStandard\Testing\PHPUnit\AbstractCheckerTestCase;

final class NoBlankLineBetweenImportsFixerTest extends AbstractCheckerTestCase
{
#[DataProvider('provideData')]
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

public static function provideData(): Iterator
{
return self::yieldFiles(__DIR__ . '/Fixture');
}

public function provideConfig(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

use Symplify\CodingStandard\Fixer\Spacing\NoBlankLineBetweenImportsFixer;
use Symplify\EasyCodingStandard\Config\ECSConfig;

return static function (ECSConfig $ecsConfig): void {
$ecsConfig->rule(NoBlankLineBetweenImportsFixer::class);
};
1 change: 0 additions & 1 deletion scoper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
require __DIR__ . '/vendor/autoload.php';

$timestamp = (new DateTime('now'))->format('Ym');

use Symplify\EasyCodingStandard\Application\Version\StaticVersionResolver;

// excluding polyfills in generic way
Expand Down
2 changes: 2 additions & 0 deletions src/Config/Level/SpacesLevel.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use PhpCsFixer\Fixer\Whitespace\TypeDeclarationSpacesFixer;
use PhpCsFixer\Fixer\Whitespace\TypesSpacesFixer;
use Symplify\CodingStandard\Fixer\Spacing\MethodChainingNewlineFixer;
use Symplify\CodingStandard\Fixer\Spacing\NoBlankLineBetweenImportsFixer;
use Symplify\CodingStandard\Fixer\Spacing\SpaceAfterCommaHereNowDocFixer;
use Symplify\CodingStandard\Fixer\Spacing\StandaloneLinePromotedPropertyFixer;
use Symplify\CodingStandard\Fixer\Spacing\StandaloneLineRequiredParamFixer;
Expand Down Expand Up @@ -63,6 +64,7 @@ final class SpacesLevel
SingleTraitInsertPerStatementFixer::class,
PhpdocSingleLineVarSpacingFixer::class,
LanguageConstructSpacingSniff::class,
NoBlankLineBetweenImportsFixer::class,

// operator and type spacing
CastSpacesFixer::class,
Expand Down
Loading