Skip to content

Commit

Permalink
feat(53656): Add support for the revised import attributes proposal
Browse files Browse the repository at this point in the history
  • Loading branch information
a-tarasyuk committed Aug 25, 2023
1 parent f07077c commit 7a05f24
Show file tree
Hide file tree
Showing 176 changed files with 32,564 additions and 267 deletions.
136 changes: 89 additions & 47 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

38 changes: 37 additions & 1 deletion src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
"category": "Error",
"code": 1007
},
"The 'assert' keyword in import attributes is deprecated and it has been replaced by the 'with' keyword.": {
"category": "Error",
"code": 1008
},
"Trailing comma not allowed.": {
"category": "Error",
"code": 1009
Expand Down Expand Up @@ -1472,7 +1476,7 @@
"category": "Message",
"code": 1449
},
"Dynamic imports can only accept a module specifier and an optional assertion as arguments": {
"Dynamic imports can only accept a module specifier and an optional set of attributes as arguments": {
"category": "Message",
"code": 1450
},
Expand Down Expand Up @@ -1520,6 +1524,18 @@
"category": "Message",
"code": 1461
},
"'resolution-mode' attribute are only supported when `moduleResolution` is `node16` or `nodenext`.": {
"category": "Error",
"code": 1462
},
"`resolution-mode` is the only valid key for type import attributes.": {
"category": "Error",
"code": 1463
},
"Type import attributes should have exactly one key - `resolution-mode` - with value `import` or `require`.": {
"category": "Error",
"code": 1464
},

"The 'import.meta' meta-property is not allowed in files which will build into CommonJS output.": {
"category": "Error",
Expand Down Expand Up @@ -1625,6 +1641,10 @@
"category": "Error",
"code": 1495
},
"Identifier, string literal or number literal expected.": {
"category": "Error",
"code": 1496
},

"The types of '{0}' are incompatible between these types.": {
"category": "Error",
Expand Down Expand Up @@ -3663,6 +3683,18 @@
"category": "Error",
"code": 2854
},
"Import attributes are not allowed on statements that transpile to CommonJS 'require' calls.": {
"category": "Error",
"code": 2855
},
"Import attributes cannot be used with type-only imports or exports.": {
"category": "Error",
"code": 2856
},
"Import attribute values must be string literal expressions.": {
"category": "Error",
"code": 2857
},

"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
Expand Down Expand Up @@ -4100,6 +4132,10 @@
"category": "Error",
"code": 4125
},
"'resolution-mode' attributes are unstable. Use nightly TypeScript to silence this error. Try updating with 'npm install -D typescript@next'.": {
"category": "Error",
"code": 4126
},

"The current host does not support the '{0}' option.": {
"category": "Error",
Expand Down
35 changes: 31 additions & 4 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ import {
Identifier,
idText,
IfStatement,
ImportAttribute,
ImportAttributes,
ImportClause,
ImportDeclaration,
ImportEqualsDeclaration,
Expand Down Expand Up @@ -2058,6 +2060,10 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
return emitAssertClause(node as AssertClause);
case SyntaxKind.AssertEntry:
return emitAssertEntry(node as AssertEntry);
case SyntaxKind.ImportAttributes:
return emitImportAttributes(node as ImportAttributes);
case SyntaxKind.ImportAttribute:
return emitImportAttribute(node as ImportAttribute);
case SyntaxKind.MissingDeclaration:
return;

Expand Down Expand Up @@ -3991,8 +3997,8 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
writeSpace();
}
emitExpression(node.moduleSpecifier);
if (node.assertClause) {
emitWithLeadingSpace(node.assertClause);
if (node.attributes || node.assertClause) {
emitWithLeadingSpace(node.attributes || node.assertClause);
}
writeTrailingSemicolon();
}
Expand Down Expand Up @@ -4066,8 +4072,8 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
writeSpace();
emitExpression(node.moduleSpecifier);
}
if (node.assertClause) {
emitWithLeadingSpace(node.assertClause);
if (node.attributes || node.assertClause) {
emitWithLeadingSpace(node.attributes || node.assertClause);
}
writeTrailingSemicolon();
}
Expand All @@ -4093,6 +4099,27 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
emit(value);
}

function emitImportAttributes(node: ImportAttributes) {
emitTokenWithComment(SyntaxKind.WithKeyword, node.pos, writeKeyword, node);
writeSpace();
const elements = node.elements;
emitList(node, elements, ListFormat.ImportAttributes);
}

function emitImportAttribute(node: ImportAttribute) {
emit(node.name);
writePunctuation(":");
writeSpace();

const value = node.value;
/** @see {emitPropertyAssignment} */
if ((getEmitFlags(value) & EmitFlags.NoLeadingComments) === 0) {
const commentRange = getCommentRange(value);
emitTrailingCommentsOfPosition(commentRange.pos);
}
emit(value);
}

function emitNamespaceExportDeclaration(node: NamespaceExportDeclaration) {
let nextPos = emitTokenWithComment(SyntaxKind.ExportKeyword, node.pos, writeKeyword, node);
writeSpace();
Expand Down
82 changes: 77 additions & 5 deletions src/compiler/factory/nodeFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,15 @@ import {
IfStatement,
ImmediatelyInvokedArrowFunction,
ImmediatelyInvokedFunctionExpression,
ImportAttribute,
ImportAttributeName,
ImportAttributes,
ImportClause,
ImportDeclaration,
ImportEqualsDeclaration,
ImportSpecifier,
ImportTypeAssertionContainer,
ImportTypeAttributes,
ImportTypeNode,
IndexedAccessTypeNode,
IndexSignatureDeclaration,
Expand Down Expand Up @@ -791,6 +795,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
updateAssertEntry,
createImportTypeAssertionContainer,
updateImportTypeAssertionContainer,
createImportTypeAttributes,
updateImportTypeAttributes,
createImportAttributes,
updateImportAttributes,
createImportAttribute,
updateImportAttribute,
createNamespaceImport,
updateNamespaceImport,
createNamespaceExport,
Expand Down Expand Up @@ -2644,13 +2654,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
function createImportTypeNode(
argument: TypeNode,
assertions?: ImportTypeAssertionContainer,
attributes?: ImportTypeAttributes,
qualifier?: EntityName,
typeArguments?: readonly TypeNode[],
isTypeOf = false,
): ImportTypeNode {
const node = createBaseNode<ImportTypeNode>(SyntaxKind.ImportType);
node.argument = argument;
node.assertions = assertions;
node.attributes = attributes;
node.qualifier = qualifier;
node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments);
node.isTypeOf = isTypeOf;
Expand All @@ -2663,16 +2675,18 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
node: ImportTypeNode,
argument: TypeNode,
assertions: ImportTypeAssertionContainer | undefined,
attributes: ImportTypeAttributes | undefined,
qualifier: EntityName | undefined,
typeArguments: readonly TypeNode[] | undefined,
isTypeOf: boolean = node.isTypeOf,
): ImportTypeNode {
return node.argument !== argument
|| node.attributes !== attributes
|| node.assertions !== assertions
|| node.qualifier !== qualifier
|| node.typeArguments !== typeArguments
|| node.isTypeOf !== isTypeOf
? update(createImportTypeNode(argument, assertions, qualifier, typeArguments, isTypeOf), node)
? update(createImportTypeNode(argument, assertions, attributes, qualifier, typeArguments, isTypeOf), node)
: node;
}

Expand Down Expand Up @@ -4697,12 +4711,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
importClause: ImportClause | undefined,
moduleSpecifier: Expression,
assertClause: AssertClause | undefined,
attributes: ImportAttributes | undefined,
): ImportDeclaration {
const node = createBaseNode<ImportDeclaration>(SyntaxKind.ImportDeclaration);
node.modifiers = asNodeArray(modifiers);
node.importClause = importClause;
node.moduleSpecifier = moduleSpecifier;
node.assertClause = assertClause;
node.attributes = attributes;
node.transformFlags |= propagateChildFlags(node.importClause) |
propagateChildFlags(node.moduleSpecifier);
node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context
Expand All @@ -4718,12 +4734,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
importClause: ImportClause | undefined,
moduleSpecifier: Expression,
assertClause: AssertClause | undefined,
attributes: ImportAttributes | undefined,
) {
return node.modifiers !== modifiers
|| node.importClause !== importClause
|| node.moduleSpecifier !== moduleSpecifier
|| node.assertClause !== assertClause
? update(createImportDeclaration(modifiers, importClause, moduleSpecifier, assertClause), node)
|| node.attributes !== attributes
? update(createImportDeclaration(modifiers, importClause, moduleSpecifier, assertClause, attributes), node)
: node;
}

Expand Down Expand Up @@ -4801,6 +4819,56 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
: node;
}

// @api
function createImportTypeAttributes(attributes: ImportAttributes, multiLine?: boolean): ImportTypeAttributes {
const node = createBaseNode<ImportTypeAttributes>(SyntaxKind.ImportTypeAttributes);
node.attributes = attributes;
node.multiLine = multiLine;
return node;
}

// @api
function updateImportTypeAttributes(node: ImportTypeAttributes, attributes: ImportAttributes, multiLine?: boolean): ImportTypeAttributes {
return node.attributes !== attributes
|| node.multiLine !== multiLine
? update(createImportTypeAttributes(attributes, multiLine), node)
: node;
}

// @api
function createImportAttributes(elements: readonly ImportAttribute[], multiLine?: boolean): ImportAttributes {
const node = createBaseNode<ImportAttributes>(SyntaxKind.ImportAttributes);
node.elements = createNodeArray(elements);
node.multiLine = multiLine;
node.transformFlags |= TransformFlags.ContainsESNext;
return node;
}

// @api
function updateImportAttributes(node: ImportAttributes, elements: readonly ImportAttribute[], multiLine?: boolean): ImportAttributes {
return node.elements !== elements
|| node.multiLine !== multiLine
? update(createImportAttributes(elements, multiLine), node)
: node;
}

// @api
function createImportAttribute(name: ImportAttributeName, value: Expression): ImportAttribute {
const node = createBaseNode<ImportAttribute>(SyntaxKind.ImportAttribute);
node.name = name;
node.value = value;
node.transformFlags |= TransformFlags.ContainsESNext;
return node;
}

// @api
function updateImportAttribute(node: ImportAttribute, name: ImportAttributeName, value: Expression): ImportAttribute {
return node.name !== name
|| node.value !== value
? update(createImportAttribute(name, value), node)
: node;
}

// @api
function createNamespaceImport(name: Identifier): NamespaceImport {
const node = createBaseDeclaration<NamespaceImport>(SyntaxKind.NamespaceImport);
Expand Down Expand Up @@ -4909,13 +4977,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
exportClause: NamedExportBindings | undefined,
moduleSpecifier?: Expression,
assertClause?: AssertClause,
attributes?: ImportAttributes,
) {
const node = createBaseDeclaration<ExportDeclaration>(SyntaxKind.ExportDeclaration);
node.modifiers = asNodeArray(modifiers);
node.isTypeOnly = isTypeOnly;
node.exportClause = exportClause;
node.moduleSpecifier = moduleSpecifier;
node.assertClause = assertClause;
node.attributes = attributes;
node.transformFlags |= propagateChildrenFlags(node.modifiers) |
propagateChildFlags(node.exportClause) |
propagateChildFlags(node.moduleSpecifier);
Expand All @@ -4933,13 +5003,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
exportClause: NamedExportBindings | undefined,
moduleSpecifier: Expression | undefined,
assertClause: AssertClause | undefined,
attributes: ImportAttributes | undefined,
) {
return node.modifiers !== modifiers
|| node.isTypeOnly !== isTypeOnly
|| node.exportClause !== exportClause
|| node.moduleSpecifier !== moduleSpecifier
|| node.assertClause !== assertClause
? finishUpdateExportDeclaration(createExportDeclaration(modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause), node)
|| node.attributes !== attributes
? finishUpdateExportDeclaration(createExportDeclaration(modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause, attributes), node)
: node;
}

Expand Down Expand Up @@ -7084,9 +7156,9 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
isEnumDeclaration(node) ? updateEnumDeclaration(node, modifierArray, node.name, node.members) :
isModuleDeclaration(node) ? updateModuleDeclaration(node, modifierArray, node.name, node.body) :
isImportEqualsDeclaration(node) ? updateImportEqualsDeclaration(node, modifierArray, node.isTypeOnly, node.name, node.moduleReference) :
isImportDeclaration(node) ? updateImportDeclaration(node, modifierArray, node.importClause, node.moduleSpecifier, node.assertClause) :
isImportDeclaration(node) ? updateImportDeclaration(node, modifierArray, node.importClause, node.moduleSpecifier, node.assertClause, node.attributes) :
isExportAssignment(node) ? updateExportAssignment(node, modifierArray, node.expression) :
isExportDeclaration(node) ? updateExportDeclaration(node, modifierArray, node.isTypeOnly, node.exportClause, node.moduleSpecifier, node.assertClause) :
isExportDeclaration(node) ? updateExportDeclaration(node, modifierArray, node.isTypeOnly, node.exportClause, node.moduleSpecifier, node.assertClause, node.attributes) :
Debug.assertNever(node);
}

Expand Down
17 changes: 17 additions & 0 deletions src/compiler/factory/nodeTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,15 @@ import {
HeritageClause,
Identifier,
IfStatement,
ImportAttribute,
ImportAttributes,
ImportClause,
ImportDeclaration,
ImportEqualsDeclaration,
ImportExpression,
ImportSpecifier,
ImportTypeAssertionContainer,
ImportTypeAttributes,
ImportTypeNode,
IndexedAccessTypeNode,
IndexSignatureDeclaration,
Expand Down Expand Up @@ -847,14 +850,28 @@ export function isImportTypeAssertionContainer(node: Node): node is ImportTypeAs
return node.kind === SyntaxKind.ImportTypeAssertionContainer;
}

export function isImportTypeAttributes(node: Node): node is ImportTypeAttributes {
return node.kind === SyntaxKind.ImportTypeAttributes;
}

/** @deprecated */
export function isAssertClause(node: Node): node is AssertClause {
return node.kind === SyntaxKind.AssertClause;
}

/** @deprecated */
export function isAssertEntry(node: Node): node is AssertEntry {
return node.kind === SyntaxKind.AssertEntry;
}

export function isImportAttributes(node: Node): node is ImportAttributes {
return node.kind === SyntaxKind.ImportAttributes;
}

export function isImportAttribute(node: Node): node is ImportAttribute {
return node.kind === SyntaxKind.ImportAttribute;
}

export function isNamespaceImport(node: Node): node is NamespaceImport {
return node.kind === SyntaxKind.NamespaceImport;
}
Expand Down
Loading

0 comments on commit 7a05f24

Please sign in to comment.