
# Formattatore

Phasis fornisce un formattatore JavaScript nativo basato sul proprio parser. Ristampa il codice sorgente con una disposizione compatibile con prettier, interamente in PHP: senza Node.js, pacchetti di formattazione interpretati o processi esterni.

## formatSource

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

Il punto di accesso con una sola chiamata su `Phasis\Formatter\Formatter`. `$sourceType` seleziona il linguaggio: `script` o `module` per JavaScript, `json` o `css`. JavaScript analizza il codice secondo l’obiettivo specificato, riassocia i commenti e stampa il risultato rispettando la larghezza configurata.

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

Il codice sorgente non valido genera la stessa eccezione di `Phasis\Exceptions\SyntaxError`, con riga, colonna e offset.

## FormatOptions

Le opzioni di impaginazione rispecchiano quelle di prettier 3.x e usano i valori predefiniti di prettier:

| Opzione         | Predefinito | Significato                                                  |
| --------------- | ----------- | ------------------------------------------------------------ |
| `printWidth`    | `80`       | Larghezza di riga obiettivo per l’impaginazione.             |
| `tabWidth`      | `2`        | Spazi per livello di rientro (e larghezza misurata di una tabulazione). |
| `useTabs`       | `false`    | Usa le tabulazioni invece degli spazi per il rientro.        |
| `semi`          | `true`     | Punti e virgola nelle istruzioni.                            |
| `singleQuote`   | `false`    | Preferisce `'` a `"` quando richiede meno caratteri di escape. |
| `trailingComma` | `'all'`    | `'all'`, `'es5'` o `'none'`.                       |
| `bracketSpacing`| `true`     | Spazi all’interno delle graffe degli oggetti: `{ a }` rispetto a `{a}`. |
| `arrowParens`   | `'always'` | `'always'` o `'avoid'` per le funzioni freccia con un solo parametro. |

## CSS

`formatSource($css, 'css')` formatta i fogli di stile con le regole di impaginazione di prettier: un selettore per riga negli elenchi di selettori, una dichiarazione per riga, spaziatura normalizzata per combinatori e valori, elenchi semplici di valori compattati quando possibile, valori separati da virgole disposti uno per riga per ombre e gradienti, argomenti delle funzioni mantenuti insieme o disposti su più righe, righe vuote e commenti conservati e preludi intatti per regole at sconosciute come Tailwind di `@apply`. I selettori composti lunghi vanno a capo in corrispondenza dei combinatori discendenti; gli argomenti troppo lunghi delle pseudoclassi vengono disposti su più righe all’interno delle parentesi.

## JSON

`formatSource($json, 'json')` riutilizza il parser e i printer JavaScript con le regole JSON di prettier: le chiavi restano tra virgolette, le stringhe restano tra virgolette doppie indipendentemente da `singleQuote`, non vengono mai aggiunte virgole finali e i commenti `//` all’interno del documento vengono conservati.

## Semantica dell’impaginazione

Il printer implementa il modello di documenti di prettier: i gruppi vengono disposti su una riga se rientrano nella larghezza di stampa, altrimenti vanno a capo; gli argomenti di chiamata restano vicini a un argomento finale di funzione o oggetto; le catene di membri vanno a capo prima di ogni punto quando superano la larghezza; gli oggetti scritti su più righe restano su più righe; tra le istruzioni viene conservata al massimo una riga vuota. Con opzioni corrispondenti, il formattatore produce un output identico byte per byte su codice reale già formattato con prettier; la suite di conformità lo verifica usando fixture generate direttamente da prettier.

## Commenti

I commenti vengono raccolti durante la tokenizzazione (`Parser::setCollectComments(true)`, esposti nel parser per gli strumenti) e riassociati all’albero come allegati iniziali, finali o isolati. I commenti di riga mantengono la propria riga, quelli finali sulla stessa riga restano associati alla loro istruzione, le righe vuote intorno ai commenti vengono conservate e i blocchi `/** ... */` vengono rientrati allineando il margine `*`.

## Garanzie

La suite di test verifica tre invarianti per ogni output formattato:

- L’output viene analizzato di nuovo in un programma equivalente (a parte le posizioni).
- Tutti i commenti dell’input sono presenti nell’output.
- La formattazione è idempotente: riformattare l’output non cambia nulla.

## Prestazioni

La formattazione richiede il tempo del parser: i file reali vengono formattati in decine di millisecondi e il codice JavaScript scritto a mano in un progetto tipico viene formattato da cima a fondo in meno di un secondo in un singolo processo.
