
# Vormindaja

Phasis sisaldab algupärast JavaScript vormindajat, mis põhineb oma parseril. See prindib lähtekoodi uuesti prettieriga ühilduva paigutusega, täielikult PHP: pole vaja Node.js, tõlgendatud vormindajapakette ega väliseid protsesse.

## formatSource

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

Ühe väljakutsega sisenemispunkt `Phasis\Formatter\Formatter`-is. `$sourceType` valib keele: `script` või `module` vastavalt sellele, kas tegu on JavaScript, `json` või `css`-ga. JavaScript parsib määratud eesmärgi järgi, lisab kommentaarid tagasi ja prindib seadistatud reavahe laiuse järgi.

```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"
```

Vigane lähtekood põhjustab sama `Phasis\Exceptions\SyntaxError` vea nagu parseris, koos rea, veeru ja nihkega.

## FormatOptions

Paigutuse valikud järgivad prettier 3.x-i ja kasutavad vaikimisi prettieri vaikeväärtusi:

| Valik           | Vaikeväärtus | Tähendus                                                        |
| --------------- | ---------- | -------------------------------------------------------------- |
| `printWidth`    | `80`       | Sihtrea laius, mille järgi paigutus kohandatakse.                |
| `tabWidth`      | `2`        | Tühikuid taande taseme kohta (ja tabulaatori mõõdetud laius).     |
| `useTabs`       | `false`    | Taanda tühikute asemel tabulaatoritega.                            |
| `semi`          | `true`     | Lausete semikoolonid.                                          |
| `singleQuote`   | `false`    | Eelista `'` vormingule `"`, kui see nõuab vähem paomärke.              |
| `trailingComma` | `'all'`    | `'all'`, `'es5'` või `'none'`.                                 |
| `bracketSpacing`| `true`     | Objektisuludesse jäävad tühikud: `{ a }` versus `{a}`.             |
| `arrowParens`   | `'always'` | `'always'` või `'avoid'` ühe parameetriga noolefunktsioonide puhul.  |

## CSS

`formatSource($css, 'css')` vormindab stiililehed prettieri stiililehepaigutuse järgi: valijaloendis üks valija rea kohta, üks deklaratsioon rea kohta, normaliseeritud kombinaatorite ja väärtuste vahed, lihtsate väärtuste loendite täitmine ridade kaupa, varjude ja gradientide komaloendid üks väärtus rea kohta, funktsiooniargumendid kõik või mitte midagi, tühjade ridade ja kommentaaride säilitamine ning tundmatute at-reeglite, näiteks Tailwind `@apply`-i päiste puutumata jätmine. Pikad liitvalijad murtakse järeltulevate kombinaatorite kohalt ja liiga pikad pseudoklassi argumendid murtakse sulgude sees.

## JSON

`formatSource($json, 'json')` kasutab JavaScript parserit ja printereid koos prettieri JSON-reeglitega: võtmed jäävad jutumärkidesse, stringid jäävad `singleQuote`-ist olenemata topeltjutumärkidesse, lõpukomasid ei lisata ja dokumendi sees olevad `//` kommentaarid säilivad.

## Paigutuse semantika

Printer rakendab prettieri dokumendimudelit: rühmad tasandatakse, kui need mahuvad prindilaiuse sisse, ja murtakse muul juhul; väljakutseargumendid paigutuvad lõpus oleva funktsiooni- või objektiargumendi lähedale; liikmeahelad murtakse enne iga punkti, kui need kasvavad reast pikemaks; mitmele reale kirjutatud objektid jäävad mitmerealiseks ja lausete vahele säilitatakse maksimaalselt üks tühi rida. Prettieriga vormindatud sisend annab samade valikute korral päris koodis bait-baidilt identse tulemuse; vastavustest kontrollib seda täpselt prettieri enda loodud näidisfailidega.

## Kommentaarid

Kommentaarid kogutakse tokeniseerimise käigus (`Parser::setCollectComments(true)`, parseris tööriistadele kättesaadavad) ja seotakse puuga uuesti juhtivate, järgnevate või eraldiseisvate manustena. Reakommentaarid jäävad oma ridadele, samal real olevad lõpukommentaarid jäävad lause juurde, kommentaaride ümber olevad tühjad read säilivad ning `/** ... */` plokid taandatakse uuesti nii, et nende `*` veeris joondub.

## Garantii

Iga vormindatud väljundi puhul kehtib kolm invarianti, mida testikomplekt kontrollib:

- Väljund parsitakse samaväärseks programmiks (asukohad välja arvatud).
- Kõik sisendi kommentaarid säilivad väljundis.
- Vormindamine on idempotentne: vormindatud väljundi vormindamine ei muuda midagi.

## Jõudlus

Vormindamine toimub parseri kiirusel: päris failide vormindamiseks kulub kümneid millisekundeid ja tüüpilise projekti käsitsi kirjutatud JavaScript vormindatakse otsast lõpuni ühe protsessiga tublisti alla sekundiga.
