From fd9aba66bf4bc835297983ace3740c7f749ed9b3 Mon Sep 17 00:00:00 2001 From: Titian Cernicova-Dragomir Date: Fri, 8 Dec 2023 00:45:29 +0000 Subject: [PATCH] ImportAttributes should go through the same emit phases when in an ImportTypeNode (#56395) --- src/compiler/emitter.ts | 24 ++++++++++------- src/compiler/types.ts | 15 ++++++----- tests/baselines/reference/api/typescript.d.ts | 1 + ...efactorToReturnTypeWithImportAssertions.ts | 27 +++++++++++++++++++ 4 files changed, 51 insertions(+), 16 deletions(-) create mode 100644 tests/cases/fourslash/refactorToReturnTypeWithImportAssertions.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index e8f1de91603..9e8f97a248c 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -223,6 +223,7 @@ import { isGeneratedIdentifier, isGeneratedPrivateIdentifier, isIdentifier, + isImportAttributes, isIncrementalCompilation, isInJsonFile, isInternalDeclaration, @@ -1840,6 +1841,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri if (hint === EmitHint.IdentifierName) return emitIdentifier(cast(node, isIdentifier)); if (hint === EmitHint.JsxAttributeValue) return emitLiteral(cast(node, isStringLiteral), /*jsxAttributeEscape*/ true); if (hint === EmitHint.MappedTypeParameter) return emitMappedTypeParameter(cast(node, isTypeParameterDeclaration)); + if (hint === EmitHint.ImportTypeNodeAttributes) return emitImportTypeNodeAttributes(cast(node, isImportAttributes)); if (hint === EmitHint.EmbeddedStatement) { Debug.assertNode(node, isEmptyStatement); return emitEmptyStatement(/*isEmbeddedStatement*/ true); @@ -2944,15 +2946,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri if (node.attributes) { writePunctuation(","); writeSpace(); - writePunctuation("{"); - writeSpace(); - writeKeyword(node.attributes.token === SyntaxKind.AssertKeyword ? "assert" : "with"); - writePunctuation(":"); - writeSpace(); - const elements = node.attributes.elements; - emitList(node.attributes, elements, ListFormat.ImportAttributes); - writeSpace(); - writePunctuation("}"); + pipelineEmit(EmitHint.ImportTypeNodeAttributes, node.attributes); } writePunctuation(")"); if (node.qualifier) { @@ -4077,6 +4071,18 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri writeTrailingSemicolon(); } + function emitImportTypeNodeAttributes(node: ImportAttributes) { + writePunctuation("{"); + writeSpace(); + writeKeyword(node.token === SyntaxKind.AssertKeyword ? "assert" : "with"); + writePunctuation(":"); + writeSpace(); + const elements = node.elements; + emitList(node, elements, ListFormat.ImportAttributes); + writeSpace(); + writePunctuation("}"); + } + function emitImportAttributes(node: ImportAttributes) { emitTokenWithComment(node.token, node.pos, writeKeyword, node); writeSpace(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f430e27b853..b55a308e91f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8143,13 +8143,14 @@ export const enum ExternalEmitHelpers { // dprint-ignore export const enum EmitHint { - SourceFile, // Emitting a SourceFile - Expression, // Emitting an Expression - IdentifierName, // Emitting an IdentifierName - MappedTypeParameter, // Emitting a TypeParameterDeclaration inside of a MappedTypeNode - Unspecified, // Emitting an otherwise unspecified node - EmbeddedStatement, // Emitting an embedded statement - JsxAttributeValue, // Emitting a JSX attribute value + SourceFile, // Emitting a SourceFile + Expression, // Emitting an Expression + IdentifierName, // Emitting an IdentifierName + MappedTypeParameter, // Emitting a TypeParameterDeclaration inside of a MappedTypeNode + Unspecified, // Emitting an otherwise unspecified node + EmbeddedStatement, // Emitting an embedded statement + JsxAttributeValue, // Emitting a JSX attribute value + ImportTypeNodeAttributes,// Emitting attributes as part of an ImportTypeNode } /** @internal */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index a55b003f6c8..450444f4cc7 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -7896,6 +7896,7 @@ declare namespace ts { Unspecified = 4, EmbeddedStatement = 5, JsxAttributeValue = 6, + ImportTypeNodeAttributes = 7, } enum OuterExpressionKinds { Parentheses = 1, diff --git a/tests/cases/fourslash/refactorToReturnTypeWithImportAssertions.ts b/tests/cases/fourslash/refactorToReturnTypeWithImportAssertions.ts new file mode 100644 index 00000000000..97a51e55442 --- /dev/null +++ b/tests/cases/fourslash/refactorToReturnTypeWithImportAssertions.ts @@ -0,0 +1,27 @@ +/// + +// @module: NodeNext +// @traceResolution: true + +// @filename: node_modules/inner/index.d.mts +//// export const esm = true; + +// @filename: node_modules/inner/package.json +//// { "name": "inner", "exports": { "./mjs": "./index.mjs" } } + +// @filename: foo.ts +//// export /*a*/function/*b*/ fn() { +//// return import("inner/mjs") +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Infer function return type", + actionName: "Infer function return type", + actionDescription: "Infer function return type", + newContent: +`export function fn(): Promise { + return import("inner/mjs") +}` +}); +