From d382865d5527ed5914786f978b9b85359bd04d2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Wed, 26 Oct 2022 23:09:34 +0200 Subject: [PATCH] Automatically print inner comments --- .../babel-generator/src/generators/base.ts | 6 +- .../babel-generator/src/generators/classes.ts | 3 - .../src/generators/expressions.ts | 22 ++++--- .../babel-generator/src/generators/jsx.ts | 5 +- .../babel-generator/src/generators/methods.ts | 25 ++++---- .../babel-generator/src/generators/modules.ts | 24 ++++++-- .../src/generators/statements.ts | 2 +- .../babel-generator/src/generators/types.ts | 4 -- packages/babel-generator/src/printer.ts | 60 ++++++++++++------- .../arrow-single-param-comment/output.js | 2 +- .../output.js | 2 +- .../output.js | 2 +- .../output.js | 2 +- .../decorators-before-export/output.js | 2 +- .../decorators-legacy-before-export/output.js | 2 +- .../for-await-using-of-comments/output.js | 2 +- .../import-assertion-inner-comment/output.js | 2 +- .../import-reflection-inner-comment/output.js | 2 +- 18 files changed, 97 insertions(+), 72 deletions(-) diff --git a/packages/babel-generator/src/generators/base.ts b/packages/babel-generator/src/generators/base.ts index 951d23584341..ca2a5ed3769a 100644 --- a/packages/babel-generator/src/generators/base.ts +++ b/packages/babel-generator/src/generators/base.ts @@ -12,7 +12,10 @@ export function File(this: Printer, node: t.File) { } export function Program(this: Printer, node: t.Program) { - this.printInnerComments(node, false); + // An empty Program doesn't have any inner tokens, so + // we must explicitly print its inner comments. + this.noIndentInnerCommentsHere(); + this.printInnerComments(); const directivesLen = node.directives?.length; if (directivesLen) { @@ -30,7 +33,6 @@ export function Program(this: Printer, node: t.Program) { export function BlockStatement(this: Printer, node: t.BlockStatement) { this.token("{"); - this.printInnerComments(node); const directivesLen = node.directives?.length; if (directivesLen) { diff --git a/packages/babel-generator/src/generators/classes.ts b/packages/babel-generator/src/generators/classes.ts index 0f8ef2179ac6..c687582df4be 100644 --- a/packages/babel-generator/src/generators/classes.ts +++ b/packages/babel-generator/src/generators/classes.ts @@ -35,7 +35,6 @@ export function ClassDeclaration( } this.word("class"); - this.printInnerComments(node); if (node.id) { this.space(); @@ -67,7 +66,6 @@ export { ClassDeclaration as ClassExpression }; export function ClassBody(this: Printer, node: t.ClassBody) { this.token("{"); - this.printInnerComments(node); if (node.body.length === 0) { this.token("}"); } else { @@ -137,7 +135,6 @@ export function ClassAccessorProperty( this.tsPrintClassMemberModifiers(node); this.word("accessor"); - this.printInnerComments(node); this.space(); if (node.computed) { diff --git a/packages/babel-generator/src/generators/expressions.ts b/packages/babel-generator/src/generators/expressions.ts index be0779be5f7d..02d926d85226 100644 --- a/packages/babel-generator/src/generators/expressions.ts +++ b/packages/babel-generator/src/generators/expressions.ts @@ -26,14 +26,14 @@ export function UnaryExpression(this: Printer, node: t.UnaryExpression) { } export function DoExpression(this: Printer, node: t.DoExpression) { - if (node.async) { - this.word("async"); - this.ensureNoLineTerminator(() => { - this.printInnerComments(node); + // ensure no line terminator between `async` and `do` + this.ensureNoLineTerminator(() => { + if (node.async) { + this.word("async"); this.space(); - }); - } - this.word("do"); + } + this.word("do"); + }); this.space(); this.print(node.body, node); } @@ -234,9 +234,8 @@ export function YieldExpression(this: Printer, node: t.YieldExpression) { if (node.delegate) { this.ensureNoLineTerminator(() => { - this.printInnerComments(node); + this.token("*"); }); - this.token("*"); if (node.argument) { this.space(); // line terminators are allowed after yield* @@ -362,12 +361,11 @@ export function V8IntrinsicIdentifier( export function ModuleExpression(this: Printer, node: t.ModuleExpression) { this.word("module"); + this.space(); // ensure no line terminator between `module` and `{` this.ensureNoLineTerminator(() => { - this.printInnerComments(node); - this.space(); + this.token("{"); }); - this.token("{"); this.indent(); const { body } = node; if (body.body.length || body.directives.length) { diff --git a/packages/babel-generator/src/generators/jsx.ts b/packages/babel-generator/src/generators/jsx.ts index 92185143282b..b037c477613a 100644 --- a/packages/babel-generator/src/generators/jsx.ts +++ b/packages/babel-generator/src/generators/jsx.ts @@ -101,8 +101,9 @@ export function JSXClosingElement(this: Printer, node: t.JSXClosingElement) { this.token(">"); } -export function JSXEmptyExpression(this: Printer, node: t.JSXEmptyExpression) { - this.printInnerComments(node); +export function JSXEmptyExpression(this: Printer) { + // This node is empty, so forcefully print its inner comments. + this.printInnerComments(); } export function JSXFragment(this: Printer, node: t.JSXFragment) { diff --git a/packages/babel-generator/src/generators/methods.ts b/packages/babel-generator/src/generators/methods.ts index 4cfeaf151c16..c560540e64ce 100644 --- a/packages/babel-generator/src/generators/methods.ts +++ b/packages/babel-generator/src/generators/methods.ts @@ -34,9 +34,6 @@ export function _parameters( this.space(); } } - if (paramLength === 0) { - this.printInnerComments(parent); - } } export function _param( @@ -89,9 +86,6 @@ export function _methodHead(this: Printer, node: t.Method | t.TSDeclareMethod) { kind === "init" ) { if (node.generator) { - if (node.async) { - this.printInnerComments(node); - } this.token("*"); this._noLineTerminator = _noLineTerminator; } @@ -102,7 +96,6 @@ export function _methodHead(this: Printer, node: t.Method | t.TSDeclareMethod) { this._noLineTerminator = _noLineTerminator; this.print(key, node); this.token("]"); - this.printInnerComments(node); } else { this.print(key, node); this._noLineTerminator = _noLineTerminator; @@ -141,11 +134,20 @@ export function _functionHead( ) { if (node.async) { this.word("async"); + // We prevent inner comments from being printed here, + // so that they are always consistently printed in the + // same place regardless of the function type. + this._endsWithInnerRaw = false; this.space(); } this.word("function"); - if (node.generator) this.token("*"); - this.printInnerComments(node); + if (node.generator) { + // We prevent inner comments from being printed here, + // so that they are always consistently printed in the + // same place regardless of the function type. + this._endsWithInnerRaw = false; + this.token("*"); + } this.space(); if (node.id) { @@ -196,7 +198,10 @@ export function ArrowFunctionExpression( this._predicate(node); this.ensureNoLineTerminator(() => { this.space(); - this.printInnerComments(node); + // When printing (x)/*1*/=>{}, we remove the parentheses + // and thus there aren't two contiguous inner tokens. + // We forcefully print inner comments here. + this.printInnerComments(); this.token("=>"); }); diff --git a/packages/babel-generator/src/generators/modules.ts b/packages/babel-generator/src/generators/modules.ts index 1ccd29d45719..3a711f4144a0 100644 --- a/packages/babel-generator/src/generators/modules.ts +++ b/packages/babel-generator/src/generators/modules.ts @@ -66,6 +66,18 @@ export function ExportNamespaceSpecifier( this.print(node.exported, node); } +export function _printAssertions( + this: Printer, + node: Extract, +) { + this.space(); + this.token("{"); + this.space(); + this.printList(node.assertions, node); + this.space(); + this.token("}"); +} + export function ExportAllDeclaration( this: Printer, node: t.ExportAllDeclaration | t.DeclareExportAllDeclaration, @@ -88,7 +100,7 @@ export function ExportAllDeclaration( this.word("assert"); }); // @ts-expect-error Fixme: assertions is not defined in DeclareExportAllDeclaration - this.printAssertions(node); + this._printAssertions(node); } else { this.print(node.source, node); } @@ -162,7 +174,7 @@ export function ExportNamedDeclaration( this.space(); this.word("assert"); }); - this.printAssertions(node); + this._printAssertions(node); } else { this.print(node.source, node); } @@ -186,7 +198,7 @@ export function ExportDefaultDeclaration( } this.word("export"); - this.printInnerComments(node); + this.noIndentInnerCommentsHere(); this.space(); this.word("default"); this.space(); @@ -201,11 +213,11 @@ export function ImportDeclaration(this: Printer, node: t.ImportDeclaration) { const isTypeKind = node.importKind === "type" || node.importKind === "typeof"; if (isTypeKind) { - this.printInnerComments(node, false); + this.noIndentInnerCommentsHere(); this.word(node.importKind); this.space(); } else if (node.module) { - this.printInnerComments(node, false); + this.noIndentInnerCommentsHere(); this.word("module"); this.space(); } @@ -250,7 +262,7 @@ export function ImportDeclaration(this: Printer, node: t.ImportDeclaration) { this.space(); this.word("assert"); }); - this.printAssertions(node); + this._printAssertions(node); } else { this.print(node.source, node); } diff --git a/packages/babel-generator/src/generators/statements.ts b/packages/babel-generator/src/generators/statements.ts index e010fa61c018..534230447e44 100644 --- a/packages/babel-generator/src/generators/statements.ts +++ b/packages/babel-generator/src/generators/statements.ts @@ -103,7 +103,7 @@ function ForXStatement(this: Printer, node: t.ForXStatement) { this.word("await"); this.space(); } - this.printInnerComments(node, false); + this.noIndentInnerCommentsHere(); this.token("("); this.print(node.left, node); this.space(); diff --git a/packages/babel-generator/src/generators/types.ts b/packages/babel-generator/src/generators/types.ts index 54f0418292d4..ce9addd525f0 100644 --- a/packages/babel-generator/src/generators/types.ts +++ b/packages/babel-generator/src/generators/types.ts @@ -22,7 +22,6 @@ export function ObjectExpression(this: Printer, node: t.ObjectExpression) { const props = node.properties; this.token("{"); - this.printInnerComments(node); if (props.length) { this.space(); @@ -86,7 +85,6 @@ export function ArrayExpression(this: Printer, node: t.ArrayExpression) { const len = elems.length; this.token("["); - this.printInnerComments(node); for (let i = 0; i < elems.length; i++) { const elem = elems[i]; @@ -132,7 +130,6 @@ export function RecordExpression(this: Printer, node: t.RecordExpression) { } this.token(startToken); - this.printInnerComments(node); if (props.length) { this.space(); @@ -161,7 +158,6 @@ export function TupleExpression(this: Printer, node: t.TupleExpression) { } this.token(startToken); - this.printInnerComments(node); for (let i = 0; i < elems.length; i++) { const elem = elems[i]; diff --git a/packages/babel-generator/src/printer.ts b/packages/babel-generator/src/printer.ts index 05277d029ec6..59b6e0e1c48b 100644 --- a/packages/babel-generator/src/printer.ts +++ b/packages/babel-generator/src/printer.ts @@ -110,6 +110,8 @@ class Printer { _endsWithInteger = false; _endsWithWord = false; _lastCommentLine = 0; + _endsWithInnerRaw: boolean = false; + _indentInnerComments: boolean = true; generate(ast: t.Node) { this.print(ast); @@ -184,6 +186,8 @@ class Printer { */ word(str: string): void { + this._maybePrintInnerComments(); + // prevent concatenating words and creating // comment out of division and regex if ( this._endsWithWord || @@ -220,6 +224,8 @@ class Printer { */ token(str: string, maybeNewline = false): void { + this._maybePrintInnerComments(); + // space is mandatory to avoid outputting