
# Formaterare

Phasis har en inbyggd JavaScript-formaterare baserad på sin egen parser. Den skriver om källkoden med layoutsemantik som är kompatibel med prettier, helt i PHP: inget Node.js, inga tolkade formateringspaket och inga externa processer.

## formatSource

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

Ingångspunkten med ett anrop i `Phasis\Formatter\Formatter`. `$sourceType` väljer språk: `script` eller `module` för JavaScript, `json` eller `css`. JavaScript parsar enligt det angivna målet, återkopplar kommentarerna och skriver ut enligt den konfigurerade utskriftsbredden.

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

Ogiltig källkod ger samma `Phasis\Exceptions\SyntaxError` som parsern, med rad, kolumn och position.

## FormatOptions

Layoutalternativen speglar prettiers 3.x och använder prettiers standardvärden:

| Alternativ      | Standardvärde | Betydelse                                                      |
| --------------- | ---------- | -------------------------------------------------------------- |
| `printWidth`    | `80`       | Mållinjebredd som layouten anpassas efter.                |
| `tabWidth`      | `2`        | Mellanslag per indenteringsnivå (och uppmätt bredd för en tabb).     |
| `useTabs`       | `false`    | Indentera med tabbar i stället för mellanslag.                            |
| `semi`          | `true`     | Semikolon efter satser.                                          |
| `singleQuote`   | `false`    | Föredra `'` framför `"` där det kräver färre escape-tecken.              |
| `trailingComma` | `'all'`    | `'all'`, `'es5'` eller `'none'`.                                 |
| `bracketSpacing`| `true`     | Mellanslag inuti objektklamrar: `{ a }` jämfört med `{a}`.             |
| `arrowParens`   | `'always'` | `'always'` eller `'avoid'` för pilfunktioner med en parameter.  |

## CSS

`formatSource($css, 'css')` formaterar formatmallar med prettiers formatmallslayout: en selektor per rad i selektorlistor, en deklaration per rad, normaliserade mellanrum kring kombinatorer och värden, enkla värdelistor packade så tätt som möjligt, kommaseparerade listor med skuggor och gradienter med ett objekt per rad, funktionsargument som antingen ryms på samma rad eller bryts helt, bevarade tomrader och kommentarer samt orörda förtexter för okända at-regler som Tailwinds `@apply`. Långa sammansatta selektorer bryts vid ättlingkombinatorer, och för långa pseudo-klassargument radbryts inom parenteserna.

## JSON

`formatSource($json, 'json')` återanvänder parsern och skrivarna i JavaScript med prettiers json-regler: nycklar förblir citerade, strängar förblir dubbelt citerade oavsett `singleQuote`, avslutande kommatecken förekommer aldrig och kommentarer i `//` inuti dokumentet bevaras.

## Layoutsemantik

Skrivaren implementerar prettiers dokumentmodell: grupper plattas till när de ryms inom utskriftsbredden och radbryts annars, anropsargument ligger tätt intill ett avslutande funktions- eller objektargument, medlemkedjor bryts före varje punkt när de blir för långa för raden, objekt som skrivits över flera rader förblir flerradiga och högst en tomrad bevaras mellan satser. På prettier-formaterad indata med matchande alternativ är formateraren byteidentisk för verklig kod; dess konformitetstestsvit verifierar detta exakt mot fixturer som genererats av prettier.

## Kommentarer

Kommentarer samlas in under tokenisering (`Parser::setCollectComments(true)`, tillgängliga i parsern för verktyg) och kopplas tillbaka till trädet som inledande, avslutande eller fristående kommentarer. Radkommentarer behåller sina egna rader, avslutande kommentarer på samma rad stannar vid sin sats, tomrader kring kommentarer bevaras och `/** ... */`-block indenteras om så att deras `*`-marginal är linjerad.

## Garantier

Tre invarianta egenskaper gäller för varje formaterad utdata och verifieras av testsviten:

- Utdata kan parsas om till ett likvärdigt program (bortsett från positioner).
- Varje kommentar i indata finns kvar i utdata.
- Formateringen är idempotent: formatering av formaterad utdata ändrar ingenting.

## Prestanda

Formatering går i parserhastighet: verkliga filer formateras på några tiotals millisekunder, och en typisk handskriven JavaScript i ett projekt formateras från början till slut på långt under en sekund i en enda process.
