
# Formatador

Phasis oferece um formatador JavaScript nativo, baseado no próprio parser. Ele reimprime o código-fonte com regras de layout compatíveis com prettier, inteiramente em PHP: sem Node.js, sem pacotes de formatação interpretados, sem processos externos.

## formatSource

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

O ponto de entrada de chamada única em `Phasis\Formatter\Formatter`. `$sourceType` seleciona a linguagem: `script` ou `module` para JavaScript, `json` ou `css`. JavaScript analisa conforme o objetivo informado, reanexa os comentários e imprime com a largura de impressão configurada.

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

Código-fonte inválido gera o mesmo `Phasis\Exceptions\SyntaxError` que o parser, com linha, coluna e deslocamento.

## FormatOptions

As opções de layout espelham 3.x do prettier e usam os valores padrão do prettier:

| Opção          | Padrão    | Significado                                                        |
| --------------- | ---------- | -------------------------------------------------------------- |
| `printWidth`    | `80`       | Largura de linha desejada para ajustar o layout.                |
| `tabWidth`      | `2`        | Espaços por nível de indentação (e largura medida de uma tabulação).     |
| `useTabs`       | `false`    | Indentar com tabulações em vez de espaços.                            |
| `semi`          | `true`     | Ponto e vírgula em instruções.                                          |
| `singleQuote`   | `false`    | Preferir `'` a `"` quando exigir menos escapes.              |
| `trailingComma` | `'all'`    | `'all'`, `'es5'` ou `'none'`.                                 |
| `bracketSpacing`| `true`     | Espaços dentro de chaves de objetos: `{ a }` versus `{a}`.             |
| `arrowParens`   | `'always'` | `'always'` ou `'avoid'` para funções arrow de parâmetro único.  |

## CSS

`formatSource($css, 'css')` formata folhas de estilo com o layout de folhas de estilo do prettier: um seletor por linha em listas de seletores, uma declaração por linha, espaçamento normalizado de combinadores e valores, listas simples de valores compactadas ao preencher a linha, listas separadas por vírgulas de sombras e gradientes com um item por linha, argumentos de função que são formatados todos juntos ou não são formatados, linhas em branco e comentários preservados e preâmbulos intocados para regras at desconhecidas, como Tailwind de `@apply`. Seletores compostos longos quebram nos combinadores descendentes, e argumentos extensos de pseudoclasses são distribuídos dentro dos parênteses.

## JSON

`formatSource($json, 'json')` reutiliza o parser e os formatadores JavaScript com as regras json do prettier: as chaves permanecem entre aspas, as strings continuam entre aspas duplas independentemente de `singleQuote`, nunca são adicionadas vírgulas finais e os comentários `//` dentro do documento são preservados.

## Regras de layout

O formatador implementa o modelo de documento do prettier: grupos são achatados quando cabem na largura de impressão e quebram caso contrário; os argumentos de chamadas ficam junto ao argumento de função ou objeto no fim; cadeias de membros quebram antes de cada ponto quando ultrapassam a linha; objetos escritos em várias linhas continuam em várias linhas; e no máximo uma linha em branco é preservada entre instruções. Com opções correspondentes, o formatador gera saída idêntica byte a byte para código real formatado pelo prettier; a suíte de conformidade verifica isso exatamente com fixtures gerados pelo próprio prettier.

## Comentários

Os comentários são coletados durante a tokenização (`Parser::setCollectComments(true)`, expostos no parser para ferramentas) e reanexados à árvore como anexos iniciais, finais ou soltos. Comentários de linha mantêm suas próprias linhas, comentários finais na mesma linha permanecem na instrução, as linhas em branco ao redor dos comentários são preservadas e blocos `/** ... */` são reindentados com o recuo de margem `*` alinhado.

## Garantias

Três invariantes valem para toda saída formatada, conforme verificado pela suíte de testes:

- A saída é analisada novamente como um programa equivalente (exceto pelas localizações).
- Todos os comentários da entrada são preservados na saída.
- A formatação é idempotente: formatar uma saída já formatada não altera nada.

## Desempenho

A formatação é tão rápida quanto a análise: arquivos reais são formatados em dezenas de milissegundos, e o código-fonte JavaScript escrito à mão em um projeto típico é formatado de ponta a ponta em bem menos de um segundo, em um único processo.
