Форматиращ инструмент
Phasis предоставя нативен форматиращ инструмент за JavaScript, изграден върху собствен парсер. Той отпечатва повторно изходния код със семантика на оформление, съвместима с prettier, изцяло в PHP: без Node.js, интерпретирани пакети за форматиране или външни процеси.
formatSource
public static function formatSource(
string $source,
string $sourceType = 'script',
?FormatOptions $options = null,
): string
Единствената входна точка за Phasis\Formatter\Formatter. $sourceType избира езика: script или module за JavaScript, json или css. JavaScript анализира кода според зададената цел, връща коментарите на местата им и го отпечатва с конфигурираната ширина на реда.
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"
При невалиден изходен код се хвърля същата Phasis\Exceptions\SyntaxError като от парсера, с ред, колона и отместване.
FormatOptions
Опциите за оформление отразяват 3.x на prettier и по подразбиране използват настройките му:
| Опция | По подразбиране | Значение |
|---|---|---|
printWidth |
80 |
Целева ширина на реда, спрямо която се напасва оформлението. |
tabWidth |
2 |
Брой интервали за ниво на отстъп (и измерената ширина на табулация). |
useTabs |
false |
Отстъп с табулации вместо с интервали. |
semi |
true |
Точка и запетая след инструкции. |
singleQuote |
false |
Предпочита ' пред ", когато изисква по-малко екраниране. |
trailingComma |
'all' |
'all', 'es5' или 'none'. |
bracketSpacing |
true |
Интервали във фигурните скоби на обект: { a } срещу {a}. |
arrowParens |
'always' |
'always' или 'avoid' за стрелкови функции с един параметър. |
CSS
formatSource($css, 'css') форматира таблици със стиловото оформление на prettier: по един селектор на ред в списъците със селектори, по една декларация на ред, нормализирани интервали около комбинатори и стойности, компактно подреждане на прости списъци със стойности, списъци със сенки и градиенти с по една стойност на ред, аргументи на функции без разделяне, запазени празни редове и коментари, както и непроменени уводни части за неизвестни at-правила като Tailwind на @apply. Дългите съставни селектори се пренасят при комбинаторите-потомци, а прекалено дългите аргументи на псевдокласове се пренасят вътре в скобите им.
JSON
formatSource($json, 'json') използва повторно парсера и принтерите на JavaScript с правилата за json на prettier: ключовете остават в кавички, низовете остават в двойни кавички независимо от singleQuote, запетаи в края не се добавят, а коментарите // в документа се запазват.
Семантика на оформлението
Принтерът реализира модела на документи на prettier: групите се разгъват, когато се побират в ширината на реда, и се пренасят в противен случай; аргументите на извикване прилепват до завършващ аргумент, който е функция или обект; веригите от членове се пренасят преди всяка точка, когато надхвърлят ширината на реда; обектите, записани на няколко реда, остават така подредени, а между инструкциите се запазва най-много един празен ред. За вход, форматиран с prettier и със същите опции, форматерът създава побитовo идентичен резултат върху реален код; наборът му за съответствие потвърждава точно това чрез фикстури, генерирани от самия prettier.
Коментари
Коментарите се събират при токенизацията (Parser::setCollectComments(true), достъпни чрез парсера за инструменти) и се прикрепят отново към дървото като предхождащи, следващи или висящи коментари. Коментарите на ред запазват собствените си редове, следващите коментари на същия ред остават към съответната инструкция, празните редове около коментарите се запазват, а блоковете /** ... */ се преформатират с подравнено поле *.
Гаранции
Три инварианта важат за всеки форматиран изход и се проверяват от тестовия набор:
- Изходът се анализира повторно до еквивалентна програма (без да се отчитат местоположенията).
- Всеки коментар от входа се запазва в изхода.
- Форматирането е идемпотентно: повторното форматиране на резултата не променя нищо.
Производителност
Форматирането е бързо като парсера: реални файлове се форматират за десетки милисекунди, а типичният ръчно написан JavaScript на проект се форматира от начало до край за много под секунда в един процес.