Skip to content

Commit ada8b2e

Browse files
committed
refactor(fmt): simplify SWC Next postprocessing
1 parent 0121471 commit ada8b2e

2 files changed

Lines changed: 28 additions & 28 deletions

File tree

‎packages/rstack/src/fmt/swcNextPlugin.ts‎

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
// Adapted from @prettier/plugin-yuku to use SWC Next:
2-
// https://github.com/prettier/prettier/tree/main/packages/plugin-yuku
1+
// Differences from @prettier/plugin-yuku at the original port's upstream revision:
2+
// https://github.com/prettier/prettier/blob/315f28198200d7678dadd3fd5eece499b127ff2a/packages/plugin-yuku/index.js
3+
// https://github.com/prettier/prettier/blob/315f28198200d7678dadd3fd5eece499b127ff2a/src/language-js/parse/postprocess/index.js
4+
// - Reuses the ESTree printer and keeps only SWC Next's JS/TS normalization.
5+
// - Masks comments in one pass and uses binary search for type-cast comments.
6+
// - Omits Hack pipelines (unsupported) and template-shape checks (guaranteed by SWC Next).
7+
// - Adds babel/typescript parser aliases, with a Babel File root for Vue.
38

49
import * as prettierEstreePlugin from 'prettier/plugins/estree';
510
import type { Parser, ParserOptions, Plugin } from 'prettier';
@@ -305,7 +310,8 @@ const visitNode = (value: unknown, options: VisitOptions): unknown => {
305310
return value;
306311
}
307312

308-
let node = asAstNode(value);
313+
// Trust the parser's child nodes; validate the root at the parser entry point.
314+
let node = value as AstNode;
309315

310316
if (options.onEnter) {
311317
const result = options.onEnter(node) ?? node;
@@ -323,25 +329,23 @@ const visitNode = (value: unknown, options: VisitOptions): unknown => {
323329
};
324330

325331
const isUnbalancedLogicalTree = (node: AstNode): boolean => {
326-
if (node.type !== 'LogicalExpression' || !isAstNode(node.right)) {
332+
if (node.type !== 'LogicalExpression') {
327333
return false;
328334
}
329335

330-
return (
331-
node.right.type === 'LogicalExpression' &&
332-
node.operator === node.right.operator
333-
);
336+
const right = node.right as AstNode;
337+
return right.type === 'LogicalExpression' && node.operator === right.operator;
334338
};
335339

336340
const rebalanceLogicalTree = (node: AstNode): AstNode => {
337341
if (!isUnbalancedLogicalTree(node)) {
338342
return node;
339343
}
340344

341-
const left = asAstNode(node.left);
342-
const right = asAstNode(node.right);
343-
const rightLeft = asAstNode(right.left);
344-
const rightRight = asAstNode(right.right);
345+
const left = node.left as AstNode;
346+
const right = node.right as AstNode;
347+
const rightLeft = right.left as AstNode;
348+
const rightRight = right.right as AstNode;
345349

346350
return rebalanceLogicalTree({
347351
type: 'LogicalExpression',
@@ -387,7 +391,7 @@ const postprocess = (
387391

388392
switch (node.type) {
389393
case 'ParenthesizedExpression': {
390-
const expression = asAstNode(node.expression);
394+
const expression = node.expression as AstNode;
391395
const start = locStart(node);
392396

393397
// SWC Next comments are in source order, so these end offsets are sorted.
@@ -411,15 +415,6 @@ const postprocess = (
411415
return expression;
412416
}
413417

414-
case 'TemplateLiteral': {
415-
const expressions = node.expressions as unknown[];
416-
const quasis = node.quasis as unknown[];
417-
if (expressions.length !== quasis.length - 1) {
418-
throw new Error('Malformed template literal.');
419-
}
420-
break;
421-
}
422-
423418
case 'TemplateElement': {
424419
if (astType === 'swc-next-ts') {
425420
const start = locStart(node) + 1;
@@ -430,17 +425,13 @@ const postprocess = (
430425
}
431426

432427
case 'TSParenthesizedType':
433-
return asAstNode(node.typeAnnotation);
434-
435-
case 'TopicReference':
436-
ast.extra = withExtra(ast, { __isUsingHackPipeline: true });
437-
break;
428+
return node.typeAnnotation as AstNode;
438429

439430
case 'TSUnionType':
440431
case 'TSIntersectionType': {
441432
const types = node.types as unknown[];
442433
if (types.length === 1) {
443-
return asAstNode(types[0]);
434+
return types[0] as AstNode;
444435
}
445436
break;
446437
}

‎packages/rstack/tests/fmt/swcNextPlugin.test.ts‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,15 @@ test('reports SWC Next diagnostics with Prettier locations', async () => {
355355
});
356356
});
357357

358+
test.each(['swc-next', 'swc-next-ts'] as const)(
359+
'rejects malformed template literals with %s diagnostics',
360+
async (parser) => {
361+
await expect(
362+
formatWithSwcNext('const value = `value: ${}`', { parser }),
363+
).rejects.toBeInstanceOf(SyntaxError);
364+
},
365+
);
366+
358367
test.each(['js', 'jsx', 'ts', 'tsx'])(
359368
'uses SWC Next by default for .%s files',
360369
async (extension) => {

0 commit comments

Comments
 (0)