Přejít k obsahu

Formátovač

Phasis poskytuje nativní formátovač JavaScript postavený na vlastním parseru. Zdrojový kód znovu vypisuje s rozvržením kompatibilním se sémantikou Prettieru, celý v PHP: bez Node.js, interpretovaných balíčků formátovače a externích procesů.

formatSource

PHP
public static function formatSource(
    string $source,
    string $sourceType = 'script',
    ?FormatOptions $options = null,
): string

Jedno volání na Phasis\Formatter\Formatter stačí. Jazyk vybírá $sourceType: script nebo module pro JavaScript, json či css. JavaScript parsuje podle zadaného cíle, znovu připojí komentáře a vypíše kód podle nastavené šířky řádku.

PHP
use Phasis\Formatter\Formatter;
use Phasis\Formatter\FormatOptions;

$formatted = Formatter::formatSource(
    "const a={x:1,y:2};",
    'script',
    new FormatOptions(useTabs: true, singleQuote: true),
);
// "const a = { x: 1, y: 2 };\n"

Neplatný zdrojový kód vyvolá stejnou chybu Phasis\Exceptions\SyntaxError jako parser, včetně řádku, sloupce a posunu.

FormatOptions

Možnosti rozvržení odpovídají 3.x Prettieru a ve výchozím nastavení používají jeho výchozí hodnoty:

Možnost Výchozí hodnota Význam
printWidth 80 Cílová šířka řádku, podle které se rozvržení upravuje.
tabWidth 2 Počet mezer na úroveň odsazení (a měřená šířka tabulátoru).
useTabs false Odsazovat tabulátory místo mezer.
semi true Středníky za příkazy.
singleQuote false Upřednostnit ' před ", pokud vyžaduje méně escape sekvencí.
trailingComma 'all' 'all', 'es5' nebo 'none'.
bracketSpacing true Mezery uvnitř složených závorek objektu: { a } oproti {a}.
arrowParens 'always' 'always' nebo 'avoid' u šipkových funkcí s jedním parametrem.

CSS

formatSource($css, 'css') formátuje styly podle rozvržení stylů Prettieru: jeden selektor na řádek v seznamech selektorů, jedno deklarované pravidlo na řádek, normalizované mezery kolem kombinátorů a hodnot, jednoduché seznamy hodnot vyplněné do řádku, seznamy stínů a přechodů s čárkami po jednom na řádek, argumenty funkcí buď všechny zalomené, nebo všechny v řádku, zachované prázdné řádky a komentáře a nedotčené předřazené zápisy neznámých pravidel at-rule, například Tailwind @apply. Dlouhé složené selektory se zalamují u potomkových kombinátorů a příliš dlouhé argumenty pseudo-tříd se zalamují uvnitř závorek.

JSON

formatSource($json, 'json') používá parser a tiskové nástroje JavaScript znovu s pravidly Prettieru pro JSON: klíče zůstávají v uvozovkách, řetězce mají vždy dvojité uvozovky bez ohledu na singleQuote, čárky na konci se nikdy nevyskytují a komentáře // uvnitř dokumentu zůstávají zachované.

Sémantika rozvržení

Tiskový nástroj implementuje model dokumentu Prettieru: skupiny se zploští, pokud se vejdou do šířky řádku, jinak se zalomí; argumenty volání těsně přiléhají k závěrečné funkci nebo argumentu objektu; řetězce přístupů k členům se při překročení šířky řádku zalamují před každou tečkou; objekty zapsané na více řádcích zůstávají víceřádkové a mezi příkazy se zachová nejvýše jeden prázdný řádek. Na vstupu formátovaném Prettierem se stejnými možnostmi vytváří formátovač bajtově totožný výstup pro skutečný kód; jeho testovací sada to přesně ověřuje pomocí testovacích dat vygenerovaných samotným Prettierem.

Komentáře

Komentáře se shromažďují během tokenizace (Parser::setCollectComments(true), zpřístupněné parserem pro nástroje) a znovu se připojují ke stromu jako úvodní, závěrečné nebo volně připojené. Řádkové komentáře zůstávají na vlastních řádcích, závěrečné komentáře na stejném řádku zůstávají u svého příkazu, prázdné řádky kolem komentářů se zachovávají a bloky /** ... */ se znovu odsazují tak, aby jejich okraj * lícoval.

Záruky

Pro každý formátovaný výstup platí tři invarianty, které vynucuje testovací sada:

  • Výstup lze znovu parsovat na ekvivalentní program (bez ohledu na pozice).
  • Ve výstupu zůstane zachován každý komentář ze vstupu.
  • Formátování je idempotentní: opakované formátování již naformátovaného výstupu nic nezmění.

Výkon

Formátování probíhá rychlostí parseru: skutečné soubory se formátují v řádu desítek milisekund a ručně psaný JavaScript běžného projektu se zpracuje celý za výrazně méně než sekundu v jediném procesu.