
# Formátovač

Phasis obsahuje natívny formátovač JavaScript založený na vlastnom analyzátore. Zdrojový kód vypíše nanovo s pravidlami rozloženia kompatibilnými s prettier, celý v PHP: bez Node.js, interpretovaných balíkov formátovača či externých procesov.

## formatSource

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

Jednovolací vstupný bod v `Phasis\Formatter\Formatter`. Jazyk vyberá `$sourceType`: `script` alebo `module` pre JavaScript, `json` alebo `css`. JavaScript analyzuje kód podľa zadaného cieľa, znovu priradí komentáre a vypíše ho podľa nastavenej šírky riadka.

```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á rovnakú chybu `Phasis\Exceptions\SyntaxError` ako analyzátor, vrátane riadka, stĺpca a posunu.

## FormatOptions

Možnosti rozloženia kopírujú 3.x prettier a predvolene používajú nastavenia prettier:

| Možnosť        | Predvolená hodnota | Význam                                                        |
| --------------- | ---------- | -------------------------------------------------------------- |
| `printWidth`    | `80`       | Cieľová šírka riadka, podľa ktorej sa prispôsobuje rozloženie.                |
| `tabWidth`      | `2`        | Počet medzier na úroveň odsadenia (a meraná šírka tabulátora).     |
| `useTabs`       | `false`    | Odsadzovať tabulátormi namiesto medzier.                            |
| `semi`          | `true`     | Bodkočiarky za príkazmi.                                          |
| `singleQuote`   | `false`    | Uprednostniť `'` pred `"`, ak vyžaduje menej escape sekvencií.              |
| `trailingComma` | `'all'`    | `'all'`, `'es5'` alebo `'none'`.                                 |
| `bracketSpacing`| `true`     | Medzery v zložených zátvorkách objektu: `{ a }` oproti `{a}`.             |
| `arrowParens`   | `'always'` | `'always'` alebo `'avoid'` pre šípkové funkcie s jedným parametrom.  |

## CSS

`formatSource($css, 'css')` formátuje štýly pomocou rozloženia štýlových súborov z prettier: v zoznamoch selektorov je jeden selektor na riadok, jedno deklarovanie na riadok, normalizované medzery pri kombinátoroch a hodnotách, jednoduché zoznamy hodnôt vyplnené na riadok, zoznamy tieňov a gradientov oddelené čiarkami po jednom na riadok, argumenty funkcií buď všetky na jednom riadku, alebo každý na samostatnom riadku, zachované prázdne riadky a komentáre a nezmenené úvody neznámych pravidiel at-rule, ako je Tailwind od `@apply`. Dlhé zložené selektory sa zalomia pri kombinátoroch potomkov a príliš dlhé argumenty pseudo-tried sa zalomia v zátvorkách.

## JSON

`formatSource($json, 'json')` opätovne používa analyzátor a tlačiarne JavaScript s pravidlami JSON z prettier: kľúče zostávajú v úvodzovkách, reťazce zostávajú v dvojitých úvodzovkách bez ohľadu na `singleQuote`, koncové čiarky sa nikdy nepoužijú a komentáre `//` v dokumente sa zachovajú.

## Pravidlá rozloženia

Tlačiareň implementuje model dokumentu z prettier: skupiny sa zreťazia, ak sa zmestia do šírky riadka, inak sa zalomia; argumenty volania priliehajú k záverečnému argumentu funkcie alebo objektu; reťazce prístupov k členom sa pri prekročení šírky zalomia pred každou bodkou; objekty zapísané na viacerých riadkoch zostanú viacriadkové a medzi príkazmi sa zachová najviac jeden prázdny riadok. Pri vstupe formátovanom pomocou prettier s rovnakými možnosťami je výstup bajtovo identický pre skutočný kód; testovacia súprava zhody to overuje na vzorových súboroch vytvorených priamo nástrojom prettier.

## Komentáre

Komentáre sa zhromažďujú počas tokenizácie (`Parser::setCollectComments(true)`, sprístupnené v analyzátore pre nástroje) a znovu sa pripájajú k stromu ako úvodné, záverečné alebo voľne pripojené komentáre. Riadkové komentáre zostávajú na vlastných riadkoch, záverečné komentáre na tom istom riadku zostávajú pri svojom príkaze, prázdne riadky okolo komentárov sa zachovajú a bloky `/** ... */` sa znova odsadia tak, aby bol ich okraj `*` zarovnaný.

## Záruky

Pre každý formátovaný výstup platia tri invarianty, ktoré vynucuje testovacia súprava:

- Výstup sa dá znova analyzovať na ekvivalentný program (bez ohľadu na umiestnenia).
- Všetky komentáre zo vstupu sa zachovajú vo výstupe.
- Formátovanie je idempotentné: opätovné formátovanie výstupu nič nezmení.

## Výkon

Formátovanie je rýchle ako analýza: súbory z reálnej praxe sa naformátujú za desiatky milisekúnd a ručne napísaný JavaScript typického projektu sa v jednom procese naformátuje od začiatku do konca za výrazne menej než sekundu.
