Skip to content

Commit e1b3b78

Browse files
committed
Add parsing
1 parent 7c6462a commit e1b3b78

File tree

12 files changed

+162
-33
lines changed

12 files changed

+162
-33
lines changed

src/compiler/checker.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -6130,7 +6130,7 @@ namespace ts {
61306130

61316131
function inlineExportModifiers(statements: Statement[]) {
61326132
// Pass 3: Move all `export {}`'s to `export` modifiers where possible
6133-
const index = findIndex(statements, d => isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause && isNamedExports(d.exportClause));
6133+
const index = findIndex(statements, d => isExportDeclaration(d) && !d.moduleSpecifier && !d.assertClause && !!d.exportClause && isNamedExports(d.exportClause));
61346134
if (index >= 0) {
61356135
const exportDecl = statements[index] as ExportDeclaration & { readonly exportClause: NamedExports };
61366136
const replacements = mapDefined(exportDecl.exportClause.elements, e => {
@@ -6162,7 +6162,8 @@ namespace ts {
61626162
exportDecl.exportClause,
61636163
replacements
61646164
),
6165-
exportDecl.moduleSpecifier
6165+
exportDecl.moduleSpecifier,
6166+
exportDecl.assertClause
61666167
);
61676168
}
61686169
}
@@ -6798,15 +6799,17 @@ namespace ts {
67986799
// We use `target.parent || target` below as `target.parent` is unset when the target is a module which has been export assigned
67996800
// And then made into a default by the `esModuleInterop` or `allowSyntheticDefaultImports` flag
68006801
// In such cases, the `target` refers to the module itself already
6801-
factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context))
6802+
factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)),
6803+
/*assertClause*/ undefined
68026804
), ModifierFlags.None);
68036805
break;
68046806
case SyntaxKind.NamespaceImport:
68056807
addResult(factory.createImportDeclaration(
68066808
/*decorators*/ undefined,
68076809
/*modifiers*/ undefined,
68086810
factory.createImportClause(/*isTypeOnly*/ false, /*importClause*/ undefined, factory.createNamespaceImport(factory.createIdentifier(localName))),
6809-
factory.createStringLiteral(getSpecifierForModuleSymbol(target, context))
6811+
factory.createStringLiteral(getSpecifierForModuleSymbol(target, context)),
6812+
/*assertClause*/ undefined
68106813
), ModifierFlags.None);
68116814
break;
68126815
case SyntaxKind.NamespaceExport:
@@ -6831,7 +6834,8 @@ namespace ts {
68316834
factory.createIdentifier(localName)
68326835
)
68336836
])),
6834-
factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context))
6837+
factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)),
6838+
/*assertClause*/ undefined
68356839
), ModifierFlags.None);
68366840
break;
68376841
case SyntaxKind.ExportSpecifier:

src/compiler/factory/nodeFactory.ts

+52-8
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,10 @@ namespace ts {
287287
updateImportDeclaration,
288288
createImportClause,
289289
updateImportClause,
290+
createAssertClause,
291+
updateAssertClause,
292+
createAssertEntry,
293+
updateAssertEntry,
290294
createNamespaceImport,
291295
updateNamespaceImport,
292296
createNamespaceExport,
@@ -3790,7 +3794,8 @@ namespace ts {
37903794
decorators: readonly Decorator[] | undefined,
37913795
modifiers: readonly Modifier[] | undefined,
37923796
importClause: ImportClause | undefined,
3793-
moduleSpecifier: Expression
3797+
moduleSpecifier: Expression,
3798+
assertClause: AssertClause | undefined
37943799
): ImportDeclaration {
37953800
const node = createBaseDeclaration<ImportDeclaration>(
37963801
SyntaxKind.ImportDeclaration,
@@ -3799,6 +3804,7 @@ namespace ts {
37993804
);
38003805
node.importClause = importClause;
38013806
node.moduleSpecifier = moduleSpecifier;
3807+
node.assertClause = assertClause;
38023808
node.transformFlags |=
38033809
propagateChildFlags(node.importClause) |
38043810
propagateChildFlags(node.moduleSpecifier);
@@ -3812,13 +3818,15 @@ namespace ts {
38123818
decorators: readonly Decorator[] | undefined,
38133819
modifiers: readonly Modifier[] | undefined,
38143820
importClause: ImportClause | undefined,
3815-
moduleSpecifier: Expression
3821+
moduleSpecifier: Expression,
3822+
assertClause: AssertClause | undefined
38163823
) {
38173824
return node.decorators !== decorators
38183825
|| node.modifiers !== modifiers
38193826
|| node.importClause !== importClause
38203827
|| node.moduleSpecifier !== moduleSpecifier
3821-
? update(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier), node)
3828+
|| node.assertClause !== assertClause
3829+
? update(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier, assertClause), node)
38223830
: node;
38233831
}
38243832

@@ -3847,6 +3855,38 @@ namespace ts {
38473855
: node;
38483856
}
38493857

3858+
// @api
3859+
function createAssertClause(elements: NodeArray<AssertEntry> | undefined): AssertClause {
3860+
const node = createBaseNode<AssertClause>(SyntaxKind.AssertClause);
3861+
node.elements = elements;
3862+
node.transformFlags |= TransformFlags.ContainsESNext;
3863+
return node;
3864+
}
3865+
3866+
// @api
3867+
function updateAssertClause(node: AssertClause, elements: NodeArray<AssertEntry> | undefined): AssertClause {
3868+
return node.elements !== elements
3869+
? update(createAssertClause(elements), node)
3870+
: node;
3871+
}
3872+
3873+
// @api
3874+
function createAssertEntry(name: AssertionKey, value: StringLiteral): AssertEntry {
3875+
const node = createBaseNode<AssertEntry>(SyntaxKind.AssertEntry);
3876+
node.name = name;
3877+
node.value = value;
3878+
node.transformFlags |= TransformFlags.ContainsESNext;
3879+
return node;
3880+
}
3881+
3882+
// @api
3883+
function updateAssertEntry (node: AssertEntry, name: AssertionKey, value: StringLiteral): AssertEntry {
3884+
return node.name !== name
3885+
|| node.value !== value
3886+
? update(createAssertEntry(name, value), node)
3887+
: node;
3888+
}
3889+
38503890
// @api
38513891
function createNamespaceImport(name: Identifier): NamespaceImport {
38523892
const node = createBaseNode<NamespaceImport>(SyntaxKind.NamespaceImport);
@@ -3958,7 +3998,8 @@ namespace ts {
39583998
modifiers: readonly Modifier[] | undefined,
39593999
isTypeOnly: boolean,
39604000
exportClause: NamedExportBindings | undefined,
3961-
moduleSpecifier?: Expression
4001+
moduleSpecifier?: Expression,
4002+
assertClause?: AssertClause
39624003
) {
39634004
const node = createBaseDeclaration<ExportDeclaration>(
39644005
SyntaxKind.ExportDeclaration,
@@ -3968,6 +4009,7 @@ namespace ts {
39684009
node.isTypeOnly = isTypeOnly;
39694010
node.exportClause = exportClause;
39704011
node.moduleSpecifier = moduleSpecifier;
4012+
node.assertClause = assertClause;
39714013
node.transformFlags |=
39724014
propagateChildFlags(node.exportClause) |
39734015
propagateChildFlags(node.moduleSpecifier);
@@ -3982,14 +4024,16 @@ namespace ts {
39824024
modifiers: readonly Modifier[] | undefined,
39834025
isTypeOnly: boolean,
39844026
exportClause: NamedExportBindings | undefined,
3985-
moduleSpecifier: Expression | undefined
4027+
moduleSpecifier: Expression | undefined,
4028+
assertClause: AssertClause | undefined
39864029
) {
39874030
return node.decorators !== decorators
39884031
|| node.modifiers !== modifiers
39894032
|| node.isTypeOnly !== isTypeOnly
39904033
|| node.exportClause !== exportClause
39914034
|| node.moduleSpecifier !== moduleSpecifier
3992-
? update(createExportDeclaration(decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier), node)
4035+
|| node.assertClause !== assertClause
4036+
? update(createExportDeclaration(decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause), node)
39934037
: node;
39944038
}
39954039

@@ -5776,9 +5820,9 @@ namespace ts {
57765820
isEnumDeclaration(node) ? updateEnumDeclaration(node, node.decorators, modifiers, node.name, node.members) :
57775821
isModuleDeclaration(node) ? updateModuleDeclaration(node, node.decorators, modifiers, node.name, node.body) :
57785822
isImportEqualsDeclaration(node) ? updateImportEqualsDeclaration(node, node.decorators, modifiers, node.name, node.moduleReference) :
5779-
isImportDeclaration(node) ? updateImportDeclaration(node, node.decorators, modifiers, node.importClause, node.moduleSpecifier) :
5823+
isImportDeclaration(node) ? updateImportDeclaration(node, node.decorators, modifiers, node.importClause, node.moduleSpecifier, node.assertClause) :
57805824
isExportAssignment(node) ? updateExportAssignment(node, node.decorators, modifiers, node.expression) :
5781-
isExportDeclaration(node) ? updateExportDeclaration(node, node.decorators, modifiers, node.isTypeOnly, node.exportClause, node.moduleSpecifier) :
5825+
isExportDeclaration(node) ? updateExportDeclaration(node, node.decorators, modifiers, node.isTypeOnly, node.exportClause, node.moduleSpecifier, node.assertClause) :
57825826
Debug.assertNever(node);
57835827
}
57845828

src/compiler/factory/nodeTests.ts

+8
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,14 @@ namespace ts {
517517
return node.kind === SyntaxKind.ImportClause;
518518
}
519519

520+
export function isAssertClause(node: Node): node is AssertClause {
521+
return node.kind === SyntaxKind.AssertClause;
522+
}
523+
524+
export function isAssertEntry(node: Node): node is AssertEntry {
525+
return node.kind === SyntaxKind.AssertEntry;
526+
}
527+
520528
export function isNamespaceImport(node: Node): node is NamespaceImport {
521529
return node.kind === SyntaxKind.NamespaceImport;
522530
}

src/compiler/factory/utilities.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,8 @@ namespace ts {
446446
/*decorators*/ undefined,
447447
/*modifiers*/ undefined,
448448
nodeFactory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, namedBindings),
449-
nodeFactory.createStringLiteral(externalHelpersModuleNameText)
449+
nodeFactory.createStringLiteral(externalHelpersModuleNameText),
450+
/*assertClause*/ undefined
450451
);
451452
addEmitFlags(externalHelpersImportDeclaration, EmitFlags.NeverApplyImportHelper);
452453
return externalHelpersImportDeclaration;

src/compiler/parser.ts

+38-4
Original file line numberDiff line numberDiff line change
@@ -1690,6 +1690,11 @@ namespace ts {
16901690
token() === SyntaxKind.NumericLiteral;
16911691
}
16921692

1693+
function isAssertionKey(): boolean {
1694+
return tokenIsIdentifierOrKeyword(token()) ||
1695+
token() === SyntaxKind.StringLiteral;
1696+
}
1697+
16931698
function parsePropertyNameWorker(allowComputedPropertyNames: boolean): PropertyName {
16941699
if (token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NumericLiteral) {
16951700
const node = <StringLiteral | NumericLiteral>parseLiteralNode();
@@ -1854,6 +1859,8 @@ namespace ts {
18541859
return isLiteralPropertyName();
18551860
case ParsingContext.ObjectBindingElements:
18561861
return token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.DotDotDotToken || isLiteralPropertyName();
1862+
case ParsingContext.AssertEntries:
1863+
return isAssertionKey()
18571864
case ParsingContext.HeritageClauseElement:
18581865
// If we see `{ ... }` then only consume it as an expression if it is followed by `,` or `{`
18591866
// That way we won't consume the body of a class in its heritage clause.
@@ -1974,6 +1981,7 @@ namespace ts {
19741981
case ParsingContext.ObjectLiteralMembers:
19751982
case ParsingContext.ObjectBindingElements:
19761983
case ParsingContext.ImportOrExportSpecifiers:
1984+
case ParsingContext.AssertEntries:
19771985
return token() === SyntaxKind.CloseBraceToken;
19781986
case ParsingContext.SwitchClauseStatements:
19791987
return token() === SyntaxKind.CloseBraceToken || token() === SyntaxKind.CaseKeyword || token() === SyntaxKind.DefaultKeyword;
@@ -6901,13 +6909,33 @@ namespace ts {
69016909
importClause = parseImportClause(identifier, afterImportPos, isTypeOnly);
69026910
parseExpected(SyntaxKind.FromKeyword);
69036911
}
6904-
69056912
const moduleSpecifier = parseModuleSpecifier();
6913+
const afterSpecifierPos = scanner.getStartPos();
6914+
6915+
let assertClause: AssertClause | undefined;
6916+
if (token() === SyntaxKind.AssertKeyword && !scanner.hasPrecedingLineBreak()) {
6917+
assertClause = parseAssertClause(afterSpecifierPos);
6918+
}
6919+
69066920
parseSemicolon();
6907-
const node = factory.createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier);
6921+
const node = factory.createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier, assertClause);
69086922
return withJSDoc(finishNode(node, pos), hasJSDoc);
69096923
}
69106924

6925+
function parseAssertEntry () {
6926+
const pos = getNodePos();
6927+
const name = tokenIsIdentifierOrKeyword(token()) ? parseIdentifierName() : parseLiteralLikeNode(SyntaxKind.StringLiteral) as StringLiteral;
6928+
parseExpected(SyntaxKind.ColonToken)
6929+
const value = parseLiteralLikeNode(SyntaxKind.StringLiteral) as StringLiteral;
6930+
return finishNode(factory.createAssertEntry(name, value), pos);
6931+
}
6932+
6933+
function parseAssertClause(pos: number) {
6934+
parseExpected(SyntaxKind.AssertKeyword)
6935+
const elements = parseList(ParsingContext.AssertEntries, parseAssertEntry)
6936+
return finishNode(factory.createAssertClause(elements), pos);
6937+
}
6938+
69116939
function tokenAfterImportDefinitelyProducesImportDeclaration() {
69126940
return token() === SyntaxKind.AsteriskToken || token() === SyntaxKind.OpenBraceToken;
69136941
}
@@ -7058,6 +7086,7 @@ namespace ts {
70587086
setAwaitContext(/*value*/ true);
70597087
let exportClause: NamedExportBindings | undefined;
70607088
let moduleSpecifier: Expression | undefined;
7089+
let assertClause: AssertClause | undefined;
70617090
const isTypeOnly = parseOptional(SyntaxKind.TypeKeyword);
70627091
const namespaceExportPos = getNodePos();
70637092
if (parseOptional(SyntaxKind.AsteriskToken)) {
@@ -7077,9 +7106,13 @@ namespace ts {
70777106
moduleSpecifier = parseModuleSpecifier();
70787107
}
70797108
}
7109+
if (token() === SyntaxKind.AssertKeyword && !scanner.hasPrecedingLineBreak()) {
7110+
const posAfterSpecifier = getNodePos();
7111+
assertClause = parseAssertClause(posAfterSpecifier);
7112+
}
70807113
parseSemicolon();
70817114
setAwaitContext(savedAwaitContext);
7082-
const node = factory.createExportDeclaration(decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier);
7115+
const node = factory.createExportDeclaration(decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause);
70837116
return withJSDoc(finishNode(node, pos), hasJSDoc);
70847117
}
70857118

@@ -7159,7 +7192,8 @@ namespace ts {
71597192
TypeArguments, // Type arguments in type argument list
71607193
TupleElementTypes, // Element types in tuple element type list
71617194
HeritageClauses, // Heritage clauses for a class or interface declaration.
7162-
ImportOrExportSpecifiers, // Named import clause's import specifier list
7195+
ImportOrExportSpecifiers, // Named import clause's import specifier list,
7196+
AssertEntries, // Import entries list.
71637197
Count // Number of parsing contexts
71647198
}
71657199

src/compiler/program.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2120,7 +2120,7 @@ namespace ts {
21202120
&& !file.isDeclarationFile) {
21212121
// synthesize 'import "tslib"' declaration
21222122
const externalHelpersModuleReference = factory.createStringLiteral(externalHelpersModuleNameText);
2123-
const importDecl = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference);
2123+
const importDecl = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference, /*assertClause*/ undefined);
21242124
addEmitFlags(importDecl, EmitFlags.NeverApplyImportHelper);
21252125
setParent(externalHelpersModuleReference, importDecl);
21262126
setParent(importDecl, file);

0 commit comments

Comments
 (0)