blank-lines
Prázdné řádky tam, kde je standard chce: v hlavičce souboru kolem declare,
namespace a importů, ve třídě mezi metodami a členy, za otevírací a před zavírací závorkou bloku a kolem
příkazů jako return.
Opravuje · v presetech dresscode/per, dresscode/psr12,
dresscode/nette, dresscode/symfony, dresscode/nette-style · pokrývá
blank_line_after_namespace, blank_line_after_opening_tag, blank_line_before_statement,
blank_line_between_import_groups, blank_lines_before_namespace,
no_blank_lines_after_class_opening, no_blank_lines_after_phpdoc, no_extra_blank_lines,
single_line_after_imports, PSR12.Files.FileHeader, PSR2.Namespaces.UseDeclaration,
SlevomatCodingStandard.Attributes.AttributeAndTargetSpacing,
SlevomatCodingStandard.Classes.ConstantSpacing,
SlevomatCodingStandard.Classes.EmptyLinesAroundClassBraces,
SlevomatCodingStandard.Classes.PropertySpacing, SlevomatCodingStandard.Classes.TraitUseSpacing,
SlevomatCodingStandard.ControlStructures.BlockControlStructureSpacing,
SlevomatCodingStandard.ControlStructures.JumpStatementsSpacing,
Squiz.WhiteSpace.ControlStructureSpacing,
Squiz.WhiteSpace.FunctionOpeningBraceSpace, Squiz.WhiteSpace.FunctionSpacing
Co pravidlo hlídá
Prázdné řádky jsou to, co dělá soubor čitelným na první pohled: hlavička oddělená od kódu, metody od sebe výrazně, vlastnosti a konstanty pohromadě, komentář přilepený k tomu, co popisuje. Všechna taková místa hlídá jedno pravidlo a každé z nich má vlastní volbu, ve čtyřech skupinách:
- hlavička souboru: za otevíracím tagem, kolem
namespace, za importy a mezi jejich skupinami, před první deklarací; - třída: mezi metodami (v rozhraní zvlášť), před první a za poslední metodou, za otevírací a před zavírací
závorkou třídy, kolem
usetraitů, mezi vlastnostmi, konstantami a případy výčtu, před dokumentovaným členem a mezi dokumentačním komentářem či atributem a deklarací; - blok: za otevírací a před zavírací závorkou těla funkce nebo řídicí struktury;
- příkazy: kolem třídy nebo funkce deklarované mezi příkazy, před příkazem daného druhu a za ním, třeba
prázdný řádek před
return.
Každá volba je buď počet prázdných řádků, nebo rozsah [min, max] s otevřeným koncem zapsaným jako
null, nebo keep, které dané místo nechá, jak je. Rozsah se hodí tam, kde chcete připustit dvojí
zápis: betweenMembers: [0, 1] dovolí psát vlastnosti těsně pod sebe i oddělené jedním řádkem, ale dva už
ne. Počet, který do rozsahu nespadá, pravidlo posune k nejbližší povolené hodnotě.
Výchozí hodnoty odpovídají stylu se dvěma prázdnými řádky mezi metodami. Preset dresscode/psr12 nechává
na keep všechno, o čem PSR-12 mlčí (počet řádků mezi metodami a členy a kolem deklarací mezi příkazy),
dresscode/nette-style má vlastní čísla pro hlavičku i třídu. Protože se mapa voleb slévá s presetem po
klíčích, změníte jedno místo jediným klíčem a ostatní zůstanou, jak je preset nastavil; testy s jinou hlavičkou
dostanou jiné číslo v bloku for.
Příklad
class Cart
{
private array $items = []; // Expected 0 blank lines before the property, 1 found
public function add(Item $item): void // Expected 2 blank lines before the method, 0 found
{
$this->items[] = $item;
}
public function total(): int // Expected 2 blank lines before the method, 1 found
{
return array_sum($this->items);
}
}
class Cart
{
private array $items = [];
public function add(Item $item): void
{
$this->items[] = $item;
}
public function total(): int
{
return array_sum($this->items);
}
}
Volby: hlavička souboru
afterOpeningTag
Počet, rozsah nebo keep, výchozí 1. Za řádkem s <?php, na kterém pak žádný
kód nestojí. Soubor s HTML mimo PHP tagy si svůj tag nechá. Styl, který píše declare(strict_types=1) na
řádek tagu, nastaví keep; tak to dělá dresscode/nette-style.
<?php // Expected 1 blank line before the declare, 0 found
declare(strict_types=1);
<?php
declare(strict_types=1);
beforeNamespace
Počet, rozsah nebo keep, výchozí 1. Před deklarací jmenného prostoru.
<?php
declare(strict_types=1);
namespace App; // Expected 1 blank line before the namespace, 0 found
<?php
declare(strict_types=1);
namespace App;
afterNamespace
Počet, rozsah nebo keep, výchozí 1. Za deklarací jmenného prostoru bez složených závorek.
<?php
namespace App;
use App\Model\User; // Expected 1 blank line before the import, 0 found
<?php
namespace App;
use App\Model\User;
afterImports
Počet, rozsah nebo keep, výchozí 1. Za posledním importem, před zbytkem kódu.
<?php
namespace App;
use App\Model\User;
$user = new User; // Expected 1 blank line before the statement, 0 found
<?php
namespace App;
use App\Model\User;
$user = new User;
betweenImportGroups
Počet, rozsah nebo keep, výchozí 1. Mezi importy tříd, funkcí a konstant. Importy jedné
skupiny mezi sebou prázdný řádek nemají nikdy.
<?php
namespace App;
use App\Model\User;
use function App\format; // Expected 1 blank line before the import, 0 found
<?php
namespace App;
use App\Model\User;
use function App\format;
beforeDeclaration
Počet, rozsah nebo keep, výchozí keep. Před třídou, rozhraním, traitem, výčtem nebo funkcí,
která následuje hned za jmenným prostorem nebo za importy; tam nahrazuje afterNamespace a
afterImports. Nette Coding Standard tu chce dva řádky, aby deklarace od hlavičky odstoupila víc než kód:
rules:
dresscode/blank-lines:
beforeDeclaration: 2
<?php
namespace App;
use App\Model\User;
class Cart // Expected 2 blank lines before the class, 1 found
{
}
<?php
namespace App;
use App\Model\User;
class Cart
{
}
Volby: třída
betweenMethods
Počet, rozsah nebo keep, výchozí 2. Před metodou a za ní; první a poslední metoda třídy se
řídí volbami beforeFirstMethod a afterLastMethod. Funkce deklarované mimo třídu řídí betweenDeclarations.
rules:
dresscode/blank-lines:
betweenMethods: 1
class Cart
{
public function add(Item $item): void
{
}
public function total(): int // Expected 1 blank line before the method, 2 found
{
}
}
class Cart
{
public function add(Item $item): void
{
}
public function total(): int
{
}
}
betweenMethodsInInterface
Počet, rozsah nebo keep, výchozí 1. Mezi metodami rozhraní, které nemají tělo, a stačí jim
proto menší odstup.
rules:
dresscode/blank-lines:
betweenMethodsInInterface: 0
interface Storage
{
public function read(string $key): mixed;
public function write(string $key, mixed $value): void; // Expected 0 blank lines before the method, 1 found
}
interface Storage
{
public function read(string $key): mixed;
public function write(string $key, mixed $value): void;
}
beforeFirstMethod
Počet, rozsah nebo keep, výchozí 0. Před metodou, která je prvním členem třídy.
rules:
dresscode/blank-lines:
beforeFirstMethod: 1
class Cart
{
public function add(Item $item): void // Expected 1 blank line before the method, 0 found
{
}
}
class Cart
{
public function add(Item $item): void
{
}
}
afterLastMethod
Počet, rozsah nebo keep, výchozí 0. Za metodou, která je posledním členem třídy.
rules:
dresscode/blank-lines:
afterLastMethod: 1
class Cart
{
public function add(Item $item): void
{
}
} // Expected 1 blank line after the method, 0 found
class Cart
{
public function add(Item $item): void
{
}
}
afterClassBrace
Počet, rozsah nebo keep, výchozí 0. Před prvním členem třídy, pokud to není metoda; pak
platí beforeFirstMethod.
rules:
dresscode/blank-lines:
afterClassBrace: 1
class Cart
{
private array $items = []; // Expected 1 blank line before the property, 0 found
}
class Cart
{
private array $items = [];
}
beforeClassBrace
Počet, rozsah nebo keep, výchozí 0. Za posledním členem třídy, pokud to není metoda; pak
platí afterLastMethod.
rules:
dresscode/blank-lines:
beforeClassBrace: 1
class Cart
{
private array $items = [];
} // Expected 1 blank line before the closing brace, 0 found
class Cart
{
private array $items = [];
}
betweenTraitUses
Počet, rozsah nebo keep, výchozí 0. Mezi use traitů na začátku třídy.
class Cart
{
use Countable;
use Serializable; // Expected 0 blank lines before the trait use, 1 found
}
class Cart
{
use Countable;
use Serializable;
}
afterTraitUses
Počet, rozsah nebo keep, výchozí 1. Před členem, který následuje za use traitů,
pokud to není metoda; pak platí betweenMethods.
class Cart
{
use Countable;
private array $items = []; // Expected 1 blank line before the property, 0 found
}
class Cart
{
use Countable;
private array $items = [];
}
betweenMembers
Počet, rozsah nebo keep, výchozí [0, 1]. Mezi vlastnostmi, konstantami a případy výčtu bez
dokumentačního komentáře a atributu. Výchozí rozsah dovolí členy psát těsně pod sebe i oddělené jedním
řádkem.
class Cart
{
private array $items = [];
private int $count = 0;
private ?Customer $customer = null; // Expected at most 1 blank line before the property, 2 found
}
class Cart
{
private array $items = [];
private int $count = 0;
private ?Customer $customer = null;
}
S pevným počtem musí být odstup všude stejný:
rules:
dresscode/blank-lines:
betweenMembers: 1
class Cart
{
private array $items = [];
private int $count = 0; // Expected 1 blank line before the property, 0 found
}
class Cart
{
private array $items = [];
private int $count = 0;
}
beforeDocumentedMember
Počet, rozsah nebo keep, výchozí 1. Před vlastností, konstantou nebo případem výčtu, který
má dokumentační komentář nebo atribut; komentář potřebuje odstup od předchozího člena, aby bylo vidět, ke
kterému patří.
class Cart
{
private array $items = [];
/** @var int<0, max> */
private int $count = 0; // Expected 1 blank line before the property, 0 found
}
class Cart
{
private array $items = [];
/** @var int<0, max> */
private int $count = 0;
}
afterPhpDoc
Počet, rozsah nebo keep, výchozí 0. Mezi dokumentačním komentářem nebo atributem a deklarací,
ke které patří.
class Cart
{
/**
* Adds an item.
*/
public function add(Item $item): void // Expected 0 blank lines after the doc comment, 1 found
{
}
}
class Cart
{
/**
* Adds an item.
*/
public function add(Item $item): void
{
}
}
Volby: blok
afterBlockBrace
Počet, rozsah nebo keep, výchozí 0. Za otevírací závorkou těla funkce, řídicí struktury,
switch nebo match.
function add(Item $item): void
{
$this->items[] = $item; // Expected 0 blank lines after the opening brace, 1 found
}
function add(Item $item): void
{
$this->items[] = $item;
}
beforeBlockBrace
Počet, rozsah nebo keep, výchozí keep. Před zavírací závorkou bloku. Výchozí je
keep, protože prázdný řádek před } bývá záměrný oddělovač větví v řetězu
} catch nebo } else; kdo ho nechce nikde, nastaví nulu.
rules:
dresscode/blank-lines:
beforeBlockBrace: 0
function add(Item $item): void
{
$this->items[] = $item;
} // Expected 0 blank lines before the closing brace, 1 found
function add(Item $item): void
{
$this->items[] = $item;
}
Volby: příkazy
betweenDeclarations
Počet, rozsah nebo keep, výchozí 2. Před třídou, rozhraním, traitem, výčtem nebo funkcí
deklarovanou mezi příkazy a za ní, tedy všude, kde o odstupu nerozhoduje hlavička souboru (beforeDeclaration,
afterNamespace, afterImports). Patří sem i deklarace uvnitř podmínky.
dresscode/nette-style dovoluje jeden nebo dva řádky ([1, 2]), dresscode/symfony žádný
nebo jeden ([0, 1]).
function format(string $s): string
{
return trim($s);
}
class Cart // Expected 2 blank lines before the class, 0 found
{
}
echo format('x'); // Expected 2 blank lines after the class, 0 found
function format(string $s): string
{
return trim($s);
}
class Cart
{
}
echo format('x');
before
Mapa druh příkazu → počet nebo rozsah, výchozí {"return":[1,null]}: před return je aspoň
jeden prázdný řádek, pokud není prvním příkazem bloku. Druhů je dvanáct a jiný klíč schéma odmítne:
break, continue, do, for, foreach, if,
return, switch, throw, try, while a yield, které
znamená příkaz tvořený výrazem yield. Presety podle specifikací PER a PSR-12 mapu vyprázdní, protože
o prázdných řádcích mezi příkazy neříkají nic.
function total(array $items): int
{
$sum = array_sum($items);
return $sum; // Expected at least 1 blank line before the return, 0 found
}
function total(array $items): int
{
$sum = array_sum($items);
return $sum;
}
after
Mapa druh příkazu → počet nebo rozsah, výchozí []. Za příkazem daného druhu, před dalším
příkazem bloku.
rules:
dresscode/blank-lines:
after: {if: 1}
if ($item->isFree()) {
return;
}
$this->items[] = $item; // Expected 1 blank line after the if, 0 found
if ($item->isFree()) {
return;
}
$this->items[] = $item;
Související pravidla
- braces-position rozhoduje o zalomení řádku u složených závorek; tohle pravidlo o prázdných řádcích za nimi
single-statement-per-linedá každému příkazu vlastní řádek, teprve pak mezi nimi mají prázdné řádky smysl
Zdroj
Třída BlankLinesRule, fixtury blank-lines.