
# Muotoilija

Phasis sisältää natiivin JavaScript-muotoilijan, joka perustuu sen omaan jäsentimeen. Se tulostaa lähdekoodin uudelleen Prettier-yhteensopivilla asettelusäännöillä kokonaan PHP-kielellä: ei Node.js-riippuvuutta, tulkittuja muotoilijapaketteja eikä ulkoisia prosesseja.

## formatSource

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

Yhden kutsun aloituspiste kohteessa `Phasis\Formatter\Formatter`. `$sourceType` valitsee kielen: `script` tai `module` kohteelle JavaScript, `json` tai `css`. JavaScript jäsentää koodin annetun tavoitteen mukaan, liittää kommentit takaisin ja tulostaa sen määritetyn tulostusleveyden mukaisesti.

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

Virheellinen lähdekoodi aiheuttaa saman poikkeuksen kuin jäsennin `Phasis\Exceptions\SyntaxError`; poikkeus sisältää rivin, sarakkeen ja siirtymän.

## FormatOptions

Asetteluasetukset vastaavat Prettierin 3.x-asetuksia, ja niiden oletusarvot ovat Prettierin oletusarvoja:

| Asetus | Oletusarvo | Merkitys |
| --------------- | ---------- | -------------------------------------------------------------- |
| `printWidth` | `80` | Rivin tavoiteleveys, johon asettelu sovitetaan. |
| `tabWidth` | `2` | Välilyöntien määrä sisennystasoa kohti (ja sarkaimen mitattu leveys). |
| `useTabs` | `false` | Sisennä sarkaimilla välilyöntien sijaan. |
| `semi` | `true` | Puolipisteet lausekkeiden perään. |
| `singleQuote` | `false` | Suosi arvoa `'` arvon `"` sijaan, jos se vaatii vähemmän escapemerkkijonoja. |
| `trailingComma` | `'all'` | `'all'`, `'es5'` tai `'none'`. |
| `bracketSpacing` | `true` | Välilyönnit olka­sulkeiden sisällä: `{ a }` vai `{a}`. |
| `arrowParens` | `'always'` | `'always'` tai `'avoid'` yksiparametrisille nuolifunktioille. |

## CSS

`formatSource($css, 'css')` muotoilee tyylitiedostot Prettierin tyylisäännöillä: valitsinlistoissa yksi valitsin riviä kohti, yksi määritys riviä kohti, yhdistimien ja arvojen välit normalisoituina, yksinkertaiset arvolistat täyteen pakattuina, varjojen ja liukuvärien pilkuilla erotellut listat yksi alkio riviä kohti, funktion argumentit joko kaikki samalle riville tai jokainen omalle rivilleen, tyhjät rivit ja kommentit säilytettyinä sekä tuntemattomien at-sääntöjen, kuten Tailwind-kohteen `@apply`-säännön esiosat ennallaan. Pitkät yhdistelmävalitsimet katkaistaan jälkeläisyhdistimien kohdalla, ja liian pitkät pseudoluokkien argumentit rivitetään sulkeiden sisään.

## JSON

`formatSource($json, 'json')` käyttää uudelleen JavaScript-jäsennintä ja tulostimia Prettierin JSON-säännöillä: avainten ympärillä säilyvät lainausmerkit, merkkijonot pysyvät lainausmerkeissä `singleQuote`-asetuksesta riippumatta, loppupilkut eivät koskaan ilmesty ja asiakirjan sisäiset `//`-kommentit säilyvät.

## Asettelun semantiikka

Tulostin toteuttaa Prettierin dokumenttimallin: ryhmät litistetään, jos ne mahtuvat tulostusleveyteen, ja muutoin ne rivitetään; kutsun argumentit pysyvät tiiviisti perässä, kun funktion tai olion viimeinen argumentti tulee rivin loppuun; ketjun osat rivitetään ennen jokaista pistettä, jos ketju kasvaa liian pitkäksi; usealle riville kirjoitetut oliot pysyvät monirivisinä, ja lausekkeiden välissä säilytetään enintään yksi tyhjä rivi. Kun lähdekoodi on muotoiltu Prettierillä vastaavilla asetuksilla, tulostus on tavutasolla sama oikean maailman koodissa; vaatimustenmukaisuustestisarja varmistaa tämän vertaamalla tulosta Prettierillä luotuihin testitiedostoihin.

## Kommentit

Kommentit kerätään tokenisoinnin aikana (`Parser::setCollectComments(true)`, saatavilla jäsentimessä työkaluja varten) ja liitetään takaisin puuhun johtavina, päättävinä tai irrallisina liitteinä. Rivikommentit pysyvät omilla riveillään, saman rivin loppukommentit säilyvät lausekkeensa yhteydessä, kommenttien ympärillä olevat tyhjät rivit säilyvät, ja `/** ... */`-lohkot sisennetään uudelleen niin, että niiden `*`-reunus on linjassa.

## Takuut

Kolme ehtoa pätee jokaiseen muotoiltuun tulosteeseen, ja testisarja varmistaa ne:

- Tuloste jäsentyy uudelleen vastaavaksi ohjelmaksi (sijainteja lukuun ottamatta).
- Jokainen lähdekoodin kommentti säilyy tulosteessa.
- Muotoilu on idempotenttia: muotoillun tulosteen uudelleenmuotoilu ei muuta mitään.

## Suorituskyky

Muotoilu on jäsentimen nopeudella toimivaa työtä: oikean maailman tiedostot muotoillaan kymmenissä millisekunneissa, ja tyypillisen projektin käsin kirjoitettu JavaScript muotoillaan alusta loppuun yhdessä prosessissa selvästi alle sekunnissa.
