bracesPosition

Otevírací složená závorka stojí u tříd a funkcí na vlastním řádku a u řídicích struktur, closure (anonymní funkce) a anonymních tříd na řádku hlavičky; tělo začíná na novém řádku, zavírací závorka má řádek pro sebe a else, catch či finally stojí na jejím řádku.

Opravuje · v presetech perCs, psr12, nette, symfony · pokrývá braces_position, control_structure_continuation_position, PSR12.Classes.AnonClassDeclaration, PSR12.Files.DeclareStatement, PSR2.Classes.ClassDeclaration, Squiz.ControlStructures.ControlSignature, Squiz.Functions.MultiLineFunctionDeclaration, Squiz.WhiteSpace.ScopeClosingBrace

Co pravidlo hlídá

Kam patří {, je nejviditelnější rozhodnutí každého stylu a zároveň to, na kterém se styly nejčastěji rozcházejí. Pravidlo má pro každý druh konstrukce volbu: třídy, rozhraní, traity a výčty (class), anonymní třídy, closure a řídicí struktury. Výchozí hodnoty jsou ty z PSR-12 a z PER Coding Style 3.1: deklarace mají závorku na dalším řádku, všechno ostatní na témže. Od specifikací se liší jen výchozí hodnoty dvou výjimek popsaných níže: singlelineAnonymousFunction: keep nepřipouští PSR-12 ani PER Coding Style a emptyBody: ownLine odpovídá PSR-12, ale ne PER Coding Style; hodnoty podle specifikací nastavují presety psr12 a perCs. U funkce s parametry na několika řádcích rozhoduje volba multilineParameters, protože tam říká PER Coding Style něco jiného než některé domácí styly.

Vedle otevírací závorky pravidlo hlídá, že za ní tělo začíná na novém řádku a že zavírací závorka stojí na řádku sama. Výjimky jsou tři a každá má vlastní volbu: closure napsaná celá na jednom řádku (singlelineAnonymousFunction), prázdná anonymní třída zapsaná jako {} (emptyAnonymousClass) a prázdné tělo třídy nebo funkce jako {} (emptyBody). Property hooky mají závorku na řádku vlastnosti a zkrácený zápis { get; set; } zůstává, kdežto rozepsané hooky dostanou každý svůj řádek.

K závorkám patří i klíčové slovo, které strukturu za zavírací závorkou rozvíjí: else, elseif, catch, finally a while u do. Kam se píše, říká volba continuation: na řádek zavírací závorky jako } else {, nebo na řádek další.

Pravidlo rozhoduje, kde se řádky lámou, ne jak hluboko jsou odsazené. Odsazení řádků, které tak vzniknou, je věc pravidla indentation.

Příklad

class Cart {  // A line break before the opening brace
	public function add(Item $item): void {  // A line break before the opening brace
		if ($item->isFree())
		{  // No line break before the opening brace
			return;
		}
		$this->items[] = $item;
	}
}
class Cart
{
	public function add(Item $item): void
	{
		if ($item->isFree()) {
			return;
		}
		$this->items[] = $item;
	}
}

Volby

multilineParameters

sameLine, nextLine nebo nextLineAfterReturnType, výchozí sameLine. Kam jde závorka funkce, jejíž parametry zabírají několik řádků a zavírací kulatá závorka začíná vlastní řádek: hned za ni (PER Coding Style), na další řádek, nebo na další řádek jen tehdy, když má funkce návratový typ. Když zavírací kulatá závorka stojí na řádku posledního parametru, jde { na další řádek jako u každé jiné funkce. Poslední hodnotu nastavuje preset nette: funkce bez návratového typu má ) { jako v PER Coding Style, u funkce s návratovým typem stojí ): void na samostatném řádku a závorka jde pod něj.

rules:
	bracesPosition:
		multilineParameters: nextLineAfterReturnType
function send(
	string $to,
	string $subject,
): void {  // A line break before the opening brace
	mail($to, $subject);
}

function log(
	string $message,
)
{  // No line break before the opening brace
	echo $message;
}
function send(
	string $to,
	string $subject,
): void
{
	mail($to, $subject);
}

function log(
	string $message,
) {
	echo $message;
}

class

sameLine nebo nextLine, výchozí nextLine. Třídy, rozhraní, traity a výčty.

rules:
	bracesPosition:
		class: sameLine
class Cart
{  // No line break before the opening brace
	private array $items = [];
}
class Cart {
	private array $items = [];
}

anonymousClass

sameLine nebo nextLine, výchozí sameLine. Anonymní třída, jejíž seznam implements pokračuje na dalších řádcích, dostane závorku na další řádek vždy.

rules:
	bracesPosition:
		anonymousClass: nextLine
$logger = new class implements Logger {  // A line break before the opening brace
	public function log(string $message): void
	{
		echo $message;
	}
};
$logger = new class implements Logger
{
	public function log(string $message): void
	{
		echo $message;
	}
};

anonymousFunction

sameLine nebo nextLine, výchozí sameLine.

rules:
	bracesPosition:
		anonymousFunction: nextLine
$double = function (int $x) {  // A line break before the opening brace
	return $x * 2;
};
$double = function (int $x)
{
	return $x * 2;
};

controlStructure

sameLine nebo nextLine, výchozí sameLine. Podmínky, cykly, switch, match, try, declare s tělem v závorkách a jejich pokračování.

rules:
	bracesPosition:
		controlStructure: nextLine
if ($ready) {  // A line break before the opening brace
	start();
}
if ($ready)
{
	start();
}

singlelineAnonymousFunction

always nebo keep, výchozí keep. Closure napsaná celá na jednom řádku dostane s always závorky na stejná místa jako každá jiná, s keep smí tak zůstat. Presety psr12 a perCs nastavují always, protože PSR-12 chce tělo každé closure na vlastních řádcích.

rules:
	bracesPosition:
		singlelineAnonymousFunction: always
$ids = array_map(function ($row) { return $row->id; }, $rows);  // A line break after the opening brace // A line break before the closing brace
$ids = array_map(function ($row) {
	return $row->id;
}, $rows);

emptyAnonymousClass

sameLine nebo ownLine, výchozí sameLine. S sameLine smí prázdná anonymní třída zapsaná jako {} na řádku new tak zůstat, s ownLine dostane zavírací závorka vlastní řádek. Rozepsanou prázdnou anonymní třídu ani sameLine nesbalí; to dělá emptyBody: sameLine, které má přednost i před ownLine.

rules:
	bracesPosition:
		emptyAnonymousClass: ownLine
$marker = new class {};  // A line break after the opening brace
$marker = new class {
};

emptyBody

sameLine nebo ownLine, výchozí ownLine. Prázdné tělo třídy, anonymní třídy, funkce, metody, closure nebo property hooku: buď {} na řádku hlavičky, nebo otevírací a zavírací závorka každá na svém řádku. Komentář uvnitř dělá z těla neprázdné. Preset perCs nastavuje sameLine, protože PER Coding Style prázdná těla zkracuje.

rules:
	bracesPosition:
		emptyBody: sameLine
class NotFound extends Exception
{  // No line break before the opening brace
}  // No line break before the closing brace

class Point
{
	public function __construct(private int $x, private int $y)
	{  // No line break before the opening brace
	}  // No line break before the closing brace
}
class NotFound extends Exception {}

class Point
{
	public function __construct(private int $x, private int $y) {}
}

continuation

sameLine nebo nextLine, výchozí sameLine. Klíčové slovo, které strukturu rozvíjí (else, elseif, catch, finally, while u do), stojí na řádku zavírací závorky, nebo na dalším.

try {
	connect();
}
catch (ConnectionException $e) {  // No line break before the `catch` keyword
	retry();
}
try {
	connect();
} catch (ConnectionException $e) {
	retry();
}

Styl, který každou větev začíná na novém řádku, nastaví nextLine:

rules:
	bracesPosition:
		continuation: nextLine
if ($ready) {
	start();
} else {  // A line break before the `else` keyword
	wait();
}
if ($ready) {
	start();
}
else {
	wait();
}

Související pravidla

  • indentation odsadí řádky, které tohle pravidlo otevřelo
  • controlStructureBraces doplní závorky kolem těla řídicí struktury, které je nemá
  • blankLines rozhoduje o prázdných řádcích za otevírací a před zavírací závorkou

Zdroj

Třída BracesPositionRule, fixtury bracesPosition.