Saltar al contenido

Formateador

Phasis incluye un formateador nativo de JavaScript basado en su propio analizador. Vuelve a imprimir el código fuente con reglas de disposición compatibles con prettier, completamente en PHP: sin Node.js, sin paquetes de formateo interpretados y sin procesos externos.

formatSource

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

El punto de entrada de una sola llamada en Phasis\Formatter\Formatter. $sourceType selecciona el lenguaje: script o module para JavaScript, json o css. JavaScript analiza según el objetivo indicado, vuelve a asociar los comentarios y genera la salida con el ancho configurado.

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"

El código fuente no válido genera el mismo Phasis\Exceptions\SyntaxError que el analizador, con línea, columna y desplazamiento.

FormatOptions

Las opciones de disposición reflejan las de prettier 3.x y usan sus valores predeterminados:

Opción Valor predeterminado Significado
printWidth 80 Ancho de línea objetivo al que se ajusta la disposición.
tabWidth 2 Espacios por nivel de sangría (y ancho medido de una tabulación).
useTabs false Sangría con tabulaciones en lugar de espacios.
semi true Punto y coma en las instrucciones.
singleQuote false Preferir ' frente a " cuando requiere menos escapes.
trailingComma 'all' 'all', 'es5' o 'none'.
bracketSpacing true Espacios dentro de las llaves de objetos: { a } frente a {a}.
arrowParens 'always' 'always' o 'avoid' para funciones flecha de un solo parámetro.

CSS

formatSource($css, 'css') formatea hojas de estilo con la disposición de hojas de estilo de prettier: un selector por línea en listas de selectores, una declaración por línea, espaciado normalizado de combinadores y valores, listas sencillas de valores agrupadas hasta llenar la línea, listas separadas por comas con un elemento por línea para sombras y degradados, argumentos de función que se mantienen juntos o se separan por completo, líneas en blanco y comentarios conservados, y preludios intactos para reglas at desconocidas como Tailwind de @apply. Los selectores compuestos largos se dividen en los combinadores descendientes, y los argumentos demasiado largos de las pseudoclases se ajustan dentro de sus paréntesis.

JSON

formatSource($json, 'json') reutiliza el analizador y los generadores de JavaScript con las reglas JSON de prettier: las claves mantienen las comillas, las cadenas siguen entre comillas dobles independientemente de singleQuote, nunca aparecen comas finales y se conservan los comentarios // dentro del documento.

Reglas de disposición

El generador implementa el modelo de documentos de prettier: los grupos se aplanan si caben en el ancho de impresión y se dividen en caso contrario; los argumentos de llamada se mantienen junto a un argumento final de función u objeto; las cadenas de miembros se dividen antes de cada punto cuando exceden el ancho de línea; los objetos escritos en varias líneas se mantienen así, y se conserva como máximo una línea en blanco entre instrucciones. Con entrada formateada por prettier y opciones coincidentes, el formateador produce resultados idénticos byte por byte en código real; su conjunto de conformidad lo verifica exactamente con archivos de prueba generados por prettier.

Comentarios

Los comentarios se recopilan durante la tokenización (Parser::setCollectComments(true), expuestos en el analizador para las herramientas) y se vuelven a asociar al árbol como elementos iniciales, finales o sueltos. Los comentarios de línea conservan sus propias líneas, los comentarios finales en la misma línea permanecen en su instrucción, se conservan las líneas en blanco alrededor de los comentarios y los bloques /** ... */ se reindentan alineando su margen *.

Garantías

El conjunto de pruebas hace cumplir tres invariantes en cada salida formateada:

  • La salida se vuelve a analizar como un programa equivalente (salvo las ubicaciones).
  • Todos los comentarios de la entrada se conservan en la salida.
  • El formato es idempotente: volver a formatear la salida no cambia nada.

Rendimiento

El formateo funciona a la velocidad del analizador: los archivos reales se formatean en decenas de milisegundos, y un JavaScript típico de un proyecto se formatea de principio a fin en mucho menos de un segundo en un solo proceso.