Skip to content

Commit 7a05f24

Browse files
committed
feat(53656): Add support for the revised import attributes proposal
1 parent f07077c commit 7a05f24

File tree

176 files changed

+32564
-267
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

176 files changed

+32564
-267
lines changed

src/compiler/checker.ts

+89-47
Large diffs are not rendered by default.

src/compiler/diagnosticMessages.json

+37-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
"category": "Error",
2020
"code": 1007
2121
},
22+
"The 'assert' keyword in import attributes is deprecated and it has been replaced by the 'with' keyword.": {
23+
"category": "Error",
24+
"code": 1008
25+
},
2226
"Trailing comma not allowed.": {
2327
"category": "Error",
2428
"code": 1009
@@ -1472,7 +1476,7 @@
14721476
"category": "Message",
14731477
"code": 1449
14741478
},
1475-
"Dynamic imports can only accept a module specifier and an optional assertion as arguments": {
1479+
"Dynamic imports can only accept a module specifier and an optional set of attributes as arguments": {
14761480
"category": "Message",
14771481
"code": 1450
14781482
},
@@ -1520,6 +1524,18 @@
15201524
"category": "Message",
15211525
"code": 1461
15221526
},
1527+
"'resolution-mode' attribute are only supported when `moduleResolution` is `node16` or `nodenext`.": {
1528+
"category": "Error",
1529+
"code": 1462
1530+
},
1531+
"`resolution-mode` is the only valid key for type import attributes.": {
1532+
"category": "Error",
1533+
"code": 1463
1534+
},
1535+
"Type import attributes should have exactly one key - `resolution-mode` - with value `import` or `require`.": {
1536+
"category": "Error",
1537+
"code": 1464
1538+
},
15231539

15241540
"The 'import.meta' meta-property is not allowed in files which will build into CommonJS output.": {
15251541
"category": "Error",
@@ -1625,6 +1641,10 @@
16251641
"category": "Error",
16261642
"code": 1495
16271643
},
1644+
"Identifier, string literal or number literal expected.": {
1645+
"category": "Error",
1646+
"code": 1496
1647+
},
16281648

16291649
"The types of '{0}' are incompatible between these types.": {
16301650
"category": "Error",
@@ -3663,6 +3683,18 @@
36633683
"category": "Error",
36643684
"code": 2854
36653685
},
3686+
"Import attributes are not allowed on statements that transpile to CommonJS 'require' calls.": {
3687+
"category": "Error",
3688+
"code": 2855
3689+
},
3690+
"Import attributes cannot be used with type-only imports or exports.": {
3691+
"category": "Error",
3692+
"code": 2856
3693+
},
3694+
"Import attribute values must be string literal expressions.": {
3695+
"category": "Error",
3696+
"code": 2857
3697+
},
36663698

36673699
"Import declaration '{0}' is using private name '{1}'.": {
36683700
"category": "Error",
@@ -4100,6 +4132,10 @@
41004132
"category": "Error",
41014133
"code": 4125
41024134
},
4135+
"'resolution-mode' attributes are unstable. Use nightly TypeScript to silence this error. Try updating with 'npm install -D typescript@next'.": {
4136+
"category": "Error",
4137+
"code": 4126
4138+
},
41034139

41044140
"The current host does not support the '{0}' option.": {
41054141
"category": "Error",

src/compiler/emitter.ts

+31-4
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ import {
191191
Identifier,
192192
idText,
193193
IfStatement,
194+
ImportAttribute,
195+
ImportAttributes,
194196
ImportClause,
195197
ImportDeclaration,
196198
ImportEqualsDeclaration,
@@ -2058,6 +2060,10 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
20582060
return emitAssertClause(node as AssertClause);
20592061
case SyntaxKind.AssertEntry:
20602062
return emitAssertEntry(node as AssertEntry);
2063+
case SyntaxKind.ImportAttributes:
2064+
return emitImportAttributes(node as ImportAttributes);
2065+
case SyntaxKind.ImportAttribute:
2066+
return emitImportAttribute(node as ImportAttribute);
20612067
case SyntaxKind.MissingDeclaration:
20622068
return;
20632069

@@ -3991,8 +3997,8 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
39913997
writeSpace();
39923998
}
39933999
emitExpression(node.moduleSpecifier);
3994-
if (node.assertClause) {
3995-
emitWithLeadingSpace(node.assertClause);
4000+
if (node.attributes || node.assertClause) {
4001+
emitWithLeadingSpace(node.attributes || node.assertClause);
39964002
}
39974003
writeTrailingSemicolon();
39984004
}
@@ -4066,8 +4072,8 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
40664072
writeSpace();
40674073
emitExpression(node.moduleSpecifier);
40684074
}
4069-
if (node.assertClause) {
4070-
emitWithLeadingSpace(node.assertClause);
4075+
if (node.attributes || node.assertClause) {
4076+
emitWithLeadingSpace(node.attributes || node.assertClause);
40714077
}
40724078
writeTrailingSemicolon();
40734079
}
@@ -4093,6 +4099,27 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
40934099
emit(value);
40944100
}
40954101

4102+
function emitImportAttributes(node: ImportAttributes) {
4103+
emitTokenWithComment(SyntaxKind.WithKeyword, node.pos, writeKeyword, node);
4104+
writeSpace();
4105+
const elements = node.elements;
4106+
emitList(node, elements, ListFormat.ImportAttributes);
4107+
}
4108+
4109+
function emitImportAttribute(node: ImportAttribute) {
4110+
emit(node.name);
4111+
writePunctuation(":");
4112+
writeSpace();
4113+
4114+
const value = node.value;
4115+
/** @see {emitPropertyAssignment} */
4116+
if ((getEmitFlags(value) & EmitFlags.NoLeadingComments) === 0) {
4117+
const commentRange = getCommentRange(value);
4118+
emitTrailingCommentsOfPosition(commentRange.pos);
4119+
}
4120+
emit(value);
4121+
}
4122+
40964123
function emitNamespaceExportDeclaration(node: NamespaceExportDeclaration) {
40974124
let nextPos = emitTokenWithComment(SyntaxKind.ExportKeyword, node.pos, writeKeyword, node);
40984125
writeSpace();

src/compiler/factory/nodeFactory.ts

+77-5
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,15 @@ import {
137137
IfStatement,
138138
ImmediatelyInvokedArrowFunction,
139139
ImmediatelyInvokedFunctionExpression,
140+
ImportAttribute,
141+
ImportAttributeName,
142+
ImportAttributes,
140143
ImportClause,
141144
ImportDeclaration,
142145
ImportEqualsDeclaration,
143146
ImportSpecifier,
144147
ImportTypeAssertionContainer,
148+
ImportTypeAttributes,
145149
ImportTypeNode,
146150
IndexedAccessTypeNode,
147151
IndexSignatureDeclaration,
@@ -791,6 +795,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
791795
updateAssertEntry,
792796
createImportTypeAssertionContainer,
793797
updateImportTypeAssertionContainer,
798+
createImportTypeAttributes,
799+
updateImportTypeAttributes,
800+
createImportAttributes,
801+
updateImportAttributes,
802+
createImportAttribute,
803+
updateImportAttribute,
794804
createNamespaceImport,
795805
updateNamespaceImport,
796806
createNamespaceExport,
@@ -2644,13 +2654,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
26442654
function createImportTypeNode(
26452655
argument: TypeNode,
26462656
assertions?: ImportTypeAssertionContainer,
2657+
attributes?: ImportTypeAttributes,
26472658
qualifier?: EntityName,
26482659
typeArguments?: readonly TypeNode[],
26492660
isTypeOf = false,
26502661
): ImportTypeNode {
26512662
const node = createBaseNode<ImportTypeNode>(SyntaxKind.ImportType);
26522663
node.argument = argument;
26532664
node.assertions = assertions;
2665+
node.attributes = attributes;
26542666
node.qualifier = qualifier;
26552667
node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments);
26562668
node.isTypeOf = isTypeOf;
@@ -2663,16 +2675,18 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
26632675
node: ImportTypeNode,
26642676
argument: TypeNode,
26652677
assertions: ImportTypeAssertionContainer | undefined,
2678+
attributes: ImportTypeAttributes | undefined,
26662679
qualifier: EntityName | undefined,
26672680
typeArguments: readonly TypeNode[] | undefined,
26682681
isTypeOf: boolean = node.isTypeOf,
26692682
): ImportTypeNode {
26702683
return node.argument !== argument
2684+
|| node.attributes !== attributes
26712685
|| node.assertions !== assertions
26722686
|| node.qualifier !== qualifier
26732687
|| node.typeArguments !== typeArguments
26742688
|| node.isTypeOf !== isTypeOf
2675-
? update(createImportTypeNode(argument, assertions, qualifier, typeArguments, isTypeOf), node)
2689+
? update(createImportTypeNode(argument, assertions, attributes, qualifier, typeArguments, isTypeOf), node)
26762690
: node;
26772691
}
26782692

@@ -4697,12 +4711,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
46974711
importClause: ImportClause | undefined,
46984712
moduleSpecifier: Expression,
46994713
assertClause: AssertClause | undefined,
4714+
attributes: ImportAttributes | undefined,
47004715
): ImportDeclaration {
47014716
const node = createBaseNode<ImportDeclaration>(SyntaxKind.ImportDeclaration);
47024717
node.modifiers = asNodeArray(modifiers);
47034718
node.importClause = importClause;
47044719
node.moduleSpecifier = moduleSpecifier;
47054720
node.assertClause = assertClause;
4721+
node.attributes = attributes;
47064722
node.transformFlags |= propagateChildFlags(node.importClause) |
47074723
propagateChildFlags(node.moduleSpecifier);
47084724
node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context
@@ -4718,12 +4734,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
47184734
importClause: ImportClause | undefined,
47194735
moduleSpecifier: Expression,
47204736
assertClause: AssertClause | undefined,
4737+
attributes: ImportAttributes | undefined,
47214738
) {
47224739
return node.modifiers !== modifiers
47234740
|| node.importClause !== importClause
47244741
|| node.moduleSpecifier !== moduleSpecifier
47254742
|| node.assertClause !== assertClause
4726-
? update(createImportDeclaration(modifiers, importClause, moduleSpecifier, assertClause), node)
4743+
|| node.attributes !== attributes
4744+
? update(createImportDeclaration(modifiers, importClause, moduleSpecifier, assertClause, attributes), node)
47274745
: node;
47284746
}
47294747

@@ -4801,6 +4819,56 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
48014819
: node;
48024820
}
48034821

4822+
// @api
4823+
function createImportTypeAttributes(attributes: ImportAttributes, multiLine?: boolean): ImportTypeAttributes {
4824+
const node = createBaseNode<ImportTypeAttributes>(SyntaxKind.ImportTypeAttributes);
4825+
node.attributes = attributes;
4826+
node.multiLine = multiLine;
4827+
return node;
4828+
}
4829+
4830+
// @api
4831+
function updateImportTypeAttributes(node: ImportTypeAttributes, attributes: ImportAttributes, multiLine?: boolean): ImportTypeAttributes {
4832+
return node.attributes !== attributes
4833+
|| node.multiLine !== multiLine
4834+
? update(createImportTypeAttributes(attributes, multiLine), node)
4835+
: node;
4836+
}
4837+
4838+
// @api
4839+
function createImportAttributes(elements: readonly ImportAttribute[], multiLine?: boolean): ImportAttributes {
4840+
const node = createBaseNode<ImportAttributes>(SyntaxKind.ImportAttributes);
4841+
node.elements = createNodeArray(elements);
4842+
node.multiLine = multiLine;
4843+
node.transformFlags |= TransformFlags.ContainsESNext;
4844+
return node;
4845+
}
4846+
4847+
// @api
4848+
function updateImportAttributes(node: ImportAttributes, elements: readonly ImportAttribute[], multiLine?: boolean): ImportAttributes {
4849+
return node.elements !== elements
4850+
|| node.multiLine !== multiLine
4851+
? update(createImportAttributes(elements, multiLine), node)
4852+
: node;
4853+
}
4854+
4855+
// @api
4856+
function createImportAttribute(name: ImportAttributeName, value: Expression): ImportAttribute {
4857+
const node = createBaseNode<ImportAttribute>(SyntaxKind.ImportAttribute);
4858+
node.name = name;
4859+
node.value = value;
4860+
node.transformFlags |= TransformFlags.ContainsESNext;
4861+
return node;
4862+
}
4863+
4864+
// @api
4865+
function updateImportAttribute(node: ImportAttribute, name: ImportAttributeName, value: Expression): ImportAttribute {
4866+
return node.name !== name
4867+
|| node.value !== value
4868+
? update(createImportAttribute(name, value), node)
4869+
: node;
4870+
}
4871+
48044872
// @api
48054873
function createNamespaceImport(name: Identifier): NamespaceImport {
48064874
const node = createBaseDeclaration<NamespaceImport>(SyntaxKind.NamespaceImport);
@@ -4909,13 +4977,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
49094977
exportClause: NamedExportBindings | undefined,
49104978
moduleSpecifier?: Expression,
49114979
assertClause?: AssertClause,
4980+
attributes?: ImportAttributes,
49124981
) {
49134982
const node = createBaseDeclaration<ExportDeclaration>(SyntaxKind.ExportDeclaration);
49144983
node.modifiers = asNodeArray(modifiers);
49154984
node.isTypeOnly = isTypeOnly;
49164985
node.exportClause = exportClause;
49174986
node.moduleSpecifier = moduleSpecifier;
49184987
node.assertClause = assertClause;
4988+
node.attributes = attributes;
49194989
node.transformFlags |= propagateChildrenFlags(node.modifiers) |
49204990
propagateChildFlags(node.exportClause) |
49214991
propagateChildFlags(node.moduleSpecifier);
@@ -4933,13 +5003,15 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
49335003
exportClause: NamedExportBindings | undefined,
49345004
moduleSpecifier: Expression | undefined,
49355005
assertClause: AssertClause | undefined,
5006+
attributes: ImportAttributes | undefined,
49365007
) {
49375008
return node.modifiers !== modifiers
49385009
|| node.isTypeOnly !== isTypeOnly
49395010
|| node.exportClause !== exportClause
49405011
|| node.moduleSpecifier !== moduleSpecifier
49415012
|| node.assertClause !== assertClause
4942-
? finishUpdateExportDeclaration(createExportDeclaration(modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause), node)
5013+
|| node.attributes !== attributes
5014+
? finishUpdateExportDeclaration(createExportDeclaration(modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause, attributes), node)
49435015
: node;
49445016
}
49455017

@@ -7084,9 +7156,9 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
70847156
isEnumDeclaration(node) ? updateEnumDeclaration(node, modifierArray, node.name, node.members) :
70857157
isModuleDeclaration(node) ? updateModuleDeclaration(node, modifierArray, node.name, node.body) :
70867158
isImportEqualsDeclaration(node) ? updateImportEqualsDeclaration(node, modifierArray, node.isTypeOnly, node.name, node.moduleReference) :
7087-
isImportDeclaration(node) ? updateImportDeclaration(node, modifierArray, node.importClause, node.moduleSpecifier, node.assertClause) :
7159+
isImportDeclaration(node) ? updateImportDeclaration(node, modifierArray, node.importClause, node.moduleSpecifier, node.assertClause, node.attributes) :
70887160
isExportAssignment(node) ? updateExportAssignment(node, modifierArray, node.expression) :
7089-
isExportDeclaration(node) ? updateExportDeclaration(node, modifierArray, node.isTypeOnly, node.exportClause, node.moduleSpecifier, node.assertClause) :
7161+
isExportDeclaration(node) ? updateExportDeclaration(node, modifierArray, node.isTypeOnly, node.exportClause, node.moduleSpecifier, node.assertClause, node.attributes) :
70907162
Debug.assertNever(node);
70917163
}
70927164

src/compiler/factory/nodeTests.ts

+17
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,15 @@ import {
6767
HeritageClause,
6868
Identifier,
6969
IfStatement,
70+
ImportAttribute,
71+
ImportAttributes,
7072
ImportClause,
7173
ImportDeclaration,
7274
ImportEqualsDeclaration,
7375
ImportExpression,
7476
ImportSpecifier,
7577
ImportTypeAssertionContainer,
78+
ImportTypeAttributes,
7679
ImportTypeNode,
7780
IndexedAccessTypeNode,
7881
IndexSignatureDeclaration,
@@ -847,14 +850,28 @@ export function isImportTypeAssertionContainer(node: Node): node is ImportTypeAs
847850
return node.kind === SyntaxKind.ImportTypeAssertionContainer;
848851
}
849852

853+
export function isImportTypeAttributes(node: Node): node is ImportTypeAttributes {
854+
return node.kind === SyntaxKind.ImportTypeAttributes;
855+
}
856+
857+
/** @deprecated */
850858
export function isAssertClause(node: Node): node is AssertClause {
851859
return node.kind === SyntaxKind.AssertClause;
852860
}
853861

862+
/** @deprecated */
854863
export function isAssertEntry(node: Node): node is AssertEntry {
855864
return node.kind === SyntaxKind.AssertEntry;
856865
}
857866

867+
export function isImportAttributes(node: Node): node is ImportAttributes {
868+
return node.kind === SyntaxKind.ImportAttributes;
869+
}
870+
871+
export function isImportAttribute(node: Node): node is ImportAttribute {
872+
return node.kind === SyntaxKind.ImportAttribute;
873+
}
874+
858875
export function isNamespaceImport(node: Node): node is NamespaceImport {
859876
return node.kind === SyntaxKind.NamespaceImport;
860877
}

0 commit comments

Comments
 (0)