Skip to content

Commit ffbb445

Browse files
author
Yui T
committed
wip-Emit import call expression for commonjs
1 parent 369af08 commit ffbb445

6 files changed

Lines changed: 66 additions & 9 deletions

File tree

src/compiler/factory.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,6 +1644,7 @@ namespace ts {
16441644
if (node.resolvedTypeReferenceDirectiveNames !== undefined) updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames;
16451645
if (node.imports !== undefined) updated.imports = node.imports;
16461646
if (node.moduleAugmentations !== undefined) updated.moduleAugmentations = node.moduleAugmentations;
1647+
if (node.containsDynamicImport !== undefined) updated.containsDynamicImport = node.containsDynamicImport;
16471648
return updateNode(updated, node);
16481649
}
16491650

src/compiler/parser.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ namespace ts {
461461
}
462462

463463
export function isExternalModule(file: SourceFile): boolean {
464-
return file.externalModuleIndicator !== undefined;
464+
return file.externalModuleIndicator !== undefined || file.containsDynamicImport;
465465
}
466466

467467
// Produces a new SourceFile for the 'newText' provided. The 'textChangeRange' parameter
@@ -2778,6 +2778,7 @@ namespace ts {
27782778
case SyntaxKind.SlashToken:
27792779
case SyntaxKind.SlashEqualsToken:
27802780
case SyntaxKind.Identifier:
2781+
case SyntaxKind.ImportKeyword:
27812782
return true;
27822783
default:
27832784
return isIdentifier();
@@ -3698,6 +3699,7 @@ namespace ts {
36983699
if (importCall.specifier.kind === SyntaxKind.StringLiteral) {
36993700
(sourceFile.imports || (sourceFile.imports = [])).push(importCall.specifier as StringLiteral);
37003701
}
3702+
sourceFile.containsDynamicImport = true;
37013703
return importCall;
37023704
}
37033705
const expression = token() === SyntaxKind.SuperKeyword ? parseSuperExpression() : parseMemberExpressionOrHigher();

src/compiler/transformers/module/module.ts

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -482,12 +482,35 @@ namespace ts {
482482
return visitEndOfDeclarationMarker(<EndOfDeclarationMarker>node);
483483

484484
default:
485-
// This visitor does not descend into the tree, as export/import statements
486-
// are only transformed at the top level of a file.
487-
return node;
485+
return visitEachChild(node, visitor, context);
488486
}
489487
}
490488

489+
function visitor(node: Node): VisitResult<Node> {
490+
// This visitor does not need to descend into the tree if there is no dynamic import,
491+
// as export/import statements are only transformed at the top level of a file.
492+
if (!currentSourceFile.containsDynamicImport) {
493+
return node;
494+
}
495+
496+
switch (node.kind) {
497+
case SyntaxKind.ImportCallExpression:
498+
return visitImportCallExpression(<ImportCallExpression>node);
499+
default:
500+
return visitEachChild(node, visitor, context);
501+
}
502+
}
503+
504+
function visitImportCallExpression(node: ImportCallExpression): Expression{
505+
return createCall(
506+
createPropertyAccess(
507+
createCall(/*expression*/ createPropertyAccess(createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []),
508+
"then"),
509+
/*typeArguments*/ undefined,
510+
[ createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, /*parameters*/ undefined, /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), createCall(createIdentifier("require"), /*typeArguments*/ undefined, [node.specifier]))]
511+
);
512+
}
513+
491514
/**
492515
* Visits an ImportDeclaration node.
493516
*
@@ -780,7 +803,7 @@ namespace ts {
780803
node.asteriskToken,
781804
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
782805
/*typeParameters*/ undefined,
783-
node.parameters,
806+
visitNodes(node.parameters, visitor),
784807
/*type*/ undefined,
785808
node.body
786809
),
@@ -822,7 +845,7 @@ namespace ts {
822845
visitNodes(node.modifiers, modifierVisitor, isModifier),
823846
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
824847
/*typeParameters*/ undefined,
825-
node.heritageClauses,
848+
visitNodes(node.heritageClauses, visitor),
826849
node.members
827850
),
828851
node
@@ -884,7 +907,7 @@ namespace ts {
884907
}
885908
}
886909
else {
887-
statements = append(statements, node);
910+
statements = append(statements, visitEachChild(node, visitor, context));
888911
}
889912

890913
if (hasAssociatedEndOfDeclarationMarker(node)) {
@@ -907,7 +930,7 @@ namespace ts {
907930
function transformInitializedVariable(node: VariableDeclaration): Expression {
908931
if (isBindingPattern(node.name)) {
909932
return flattenDestructuringAssignment(
910-
node,
933+
visitNode(node, visitor),
911934
/*visitor*/ undefined,
912935
context,
913936
FlattenLevel.All,
@@ -924,7 +947,7 @@ namespace ts {
924947
),
925948
/*location*/ node.name
926949
),
927-
node.initializer
950+
visitNode(node.initializer, visitor)
928951
);
929952
}
930953
}

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2282,6 +2282,7 @@ namespace ts {
22822282
/* @internal */ moduleAugmentations: LiteralExpression[];
22832283
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
22842284
/* @internal */ ambientModuleNames: string[];
2285+
/* @internal */ containsDynamicImport?: boolean;
22852286
}
22862287

22872288
export interface Bundle extends Node {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @module: commonjs
2+
// @target: esnext
3+
// @filename: 0.ts
4+
export function foo() { return "foo"; }
5+
6+
// @filename: 1.ts
7+
import("./0");
8+
var p1 = import("./0");
9+
p1.then(zero => {
10+
return zero.foo();
11+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// @module: commonjs
2+
// @target: esnext
3+
// @filename: 0.ts
4+
export function foo() { return "foo"; }
5+
6+
// @filename: 1.ts
7+
export function backup() { return "backup"; }
8+
9+
// @filename: 2.ts
10+
async function compute(promise: Promise<any>) {
11+
let j = await promise;
12+
if (!j) {
13+
j = await import("./1");
14+
return j.backup();
15+
}
16+
return j.foo();
17+
}
18+
19+
compute(import("./0"));

0 commit comments

Comments
 (0)