Skip to content

Commit 69bd059

Browse files
committed
CommonJS emit for ES6 import declarations
1 parent 7e187ef commit 69bd059

File tree

7 files changed

+245
-100
lines changed

7 files changed

+245
-100
lines changed

Diff for: src/compiler/binder.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ module ts {
2020
return ModuleInstanceState.ConstEnumOnly;
2121
}
2222
// 3. non - exported import declarations
23-
else if (node.kind === SyntaxKind.ImportEqualsDeclaration && !(node.flags & NodeFlags.Export)) {
23+
else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && !(node.flags & NodeFlags.Export)) {
2424
return ModuleInstanceState.NonInstantiated;
2525
}
2626
// 4. other uninstantiated module declarations.
@@ -207,7 +207,8 @@ module ts {
207207
exportKind |= SymbolFlags.ExportNamespace;
208208
}
209209

210-
if (getCombinedNodeFlags(node) & NodeFlags.Export || (node.kind !== SyntaxKind.ImportEqualsDeclaration && isAmbientContext(container))) {
210+
if (getCombinedNodeFlags(node) & NodeFlags.Export ||
211+
(node.kind !== SyntaxKind.ImportDeclaration && node.kind !== SyntaxKind.ImportEqualsDeclaration && isAmbientContext(container))) {
211212
if (exportKind) {
212213
var local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes);
213214
local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);

Diff for: src/compiler/checker.ts

+55-45
Original file line numberDiff line numberDiff line change
@@ -442,12 +442,15 @@ module ts {
442442
return result;
443443
}
444444

445+
function isImportSymbolDeclaration(node: Node): boolean {
446+
return node.kind === SyntaxKind.ImportEqualsDeclaration ||
447+
node.kind === SyntaxKind.ImportClause && !!(<ImportClause>node).name ||
448+
node.kind === SyntaxKind.NamespaceImport ||
449+
node.kind === SyntaxKind.ImportSpecifier;
450+
}
451+
445452
function getDeclarationOfImportSymbol(symbol: Symbol): Declaration {
446-
return forEach(symbol.declarations, d =>
447-
d.kind === SyntaxKind.ImportEqualsDeclaration ||
448-
d.kind === SyntaxKind.ImportClause ||
449-
d.kind === SyntaxKind.NamespaceImport ||
450-
d.kind === SyntaxKind.ImportSpecifier ? d : undefined);
453+
return forEach(symbol.declarations, d => isImportSymbolDeclaration(d) ? d : undefined);
451454
}
452455

453456
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration): Symbol {
@@ -4915,42 +4918,47 @@ module ts {
49154918
// To avoid that we will give an error to users if they use arguments objects in arrow function so that they
49164919
// can explicitly bound arguments objects
49174920
if (symbol === argumentsSymbol && getContainingFunction(node).kind === SyntaxKind.ArrowFunction) {
4918-
error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_Consider_using_a_standard_function_expression);
4921+
error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_Consider_using_a_standard_function_expression);
49194922
}
49204923

49214924
if (symbol.flags & SymbolFlags.Import) {
4922-
var symbolLinks = getSymbolLinks(symbol);
4923-
symbolLinks.referenced = !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveImport(symbol));
4924-
4925-
// TODO: AndersH: This needs to be simplified. In an import of the form "import x = a.b.c;" we only need
4926-
// to resolve "a" and mark it as referenced. If "b" and/or "c" are aliases, we would be able to access them
4927-
// unless they're exported, and in that case they're already implicitly referenced.
49284925

49294926
//var symbolLinks = getSymbolLinks(symbol);
49304927
//if (!symbolLinks.referenced) {
4931-
// var importOrExportAssignment = getLeftSideOfImportEqualsOrExportAssignment(node);
4932-
4933-
// // decision about whether import is referenced can be made now if
4934-
// // - import that are used anywhere except right side of import declarations
4935-
// // - imports that are used on the right side of exported import declarations
4936-
// // for other cases defer decision until the check of left side
4937-
// if (!importOrExportAssignment ||
4938-
// (importOrExportAssignment.flags & NodeFlags.Export) ||
4939-
// (importOrExportAssignment.kind === SyntaxKind.ExportAssignment)) {
4940-
// // Mark the import as referenced so that we emit it in the final .js file.
4941-
// // exception: identifiers that appear in type queries, const enums, modules that contain only const enums
4942-
// symbolLinks.referenced = !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveImport(symbol));
4943-
// }
4944-
// else {
4945-
// var nodeLinks = getNodeLinks(importOrExportAssignment);
4946-
// Debug.assert(!nodeLinks.importOnRightSide);
4947-
// nodeLinks.importOnRightSide = symbol;
4928+
// if (!isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveImport(symbol))) {
4929+
// symbolLinks.referenced = true;
49484930
// }
49494931
//}
4932+
4933+
// TODO: AndersH: This needs to be simplified. In an import of the form "import x = a.b.c;" we only need
4934+
// to resolve "a" and mark it as referenced. If "b" and/or "c" are aliases, we would be able to access them
4935+
// unless they're exported, and in that case they're already implicitly referenced.
4936+
4937+
var symbolLinks = getSymbolLinks(symbol);
4938+
if (!symbolLinks.referenced) {
4939+
var importOrExportAssignment = getLeftSideOfImportEqualsOrExportAssignment(node);
4940+
4941+
// decision about whether import is referenced can be made now if
4942+
// - import that are used anywhere except right side of import declarations
4943+
// - imports that are used on the right side of exported import declarations
4944+
// for other cases defer decision until the check of left side
4945+
if (!importOrExportAssignment ||
4946+
(importOrExportAssignment.flags & NodeFlags.Export) ||
4947+
(importOrExportAssignment.kind === SyntaxKind.ExportAssignment)) {
4948+
// Mark the import as referenced so that we emit it in the final .js file.
4949+
// exception: identifiers that appear in type queries, const enums, modules that contain only const enums
4950+
symbolLinks.referenced = !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveImport(symbol));
4951+
}
4952+
else {
4953+
var nodeLinks = getNodeLinks(importOrExportAssignment);
4954+
Debug.assert(!nodeLinks.importOnRightSide);
4955+
nodeLinks.importOnRightSide = symbol;
4956+
}
4957+
}
49504958

4951-
//if (symbolLinks.referenced) {
4952-
// markLinkedImportsAsReferenced(<ImportEqualsDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ImportEqualsDeclaration));
4953-
//}
4959+
if (symbolLinks.referenced) {
4960+
markLinkedImportsAsReferenced(<ImportEqualsDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ImportEqualsDeclaration));
4961+
}
49544962
}
49554963

49564964
checkCollisionWithCapturedSuperVariable(node, node);
@@ -10108,7 +10116,7 @@ module ts {
1010810116
// Make sure the name in question does not collide with an import.
1010910117
if (symbolWithRelevantName.flags & SymbolFlags.Import) {
1011010118
var importEqualsDeclarationWithRelevantName = <ImportEqualsDeclaration>getDeclarationOfKind(symbolWithRelevantName, SyntaxKind.ImportEqualsDeclaration);
10111-
if (isReferencedImportEqualsDeclaration(importEqualsDeclarationWithRelevantName)) {
10119+
if (isReferencedImportDeclaration(importEqualsDeclarationWithRelevantName)) {
1011210120
return false;
1011310121
}
1011410122
}
@@ -10182,17 +10190,19 @@ module ts {
1018210190
return isConstEnumSymbol(s) || s.constEnumOnlyModule;
1018310191
}
1018410192

10185-
function isReferencedImportEqualsDeclaration(node: ImportEqualsDeclaration): boolean {
10186-
var symbol = getSymbolOfNode(node);
10187-
if (getSymbolLinks(symbol).referenced) {
10188-
return true;
10189-
}
10190-
// logic below will answer 'true' for exported import declaration in a nested module that itself is not exported.
10191-
// As a consequence this might cause emitting extra.
10192-
if (node.flags & NodeFlags.Export) {
10193-
return isImportResolvedToValue(symbol);
10193+
function isReferencedImportDeclaration(node: Node): boolean {
10194+
if (isImportSymbolDeclaration(node)) {
10195+
var symbol = getSymbolOfNode(node);
10196+
if (getSymbolLinks(symbol).referenced) {
10197+
return true;
10198+
}
10199+
// logic below will answer 'true' for exported import declaration in a nested module that itself is not exported.
10200+
// As a consequence this might cause emitting extra.
10201+
if (node.kind === SyntaxKind.ImportEqualsDeclaration && node.flags & NodeFlags.Export && isImportResolvedToValue(symbol)) {
10202+
return true;
10203+
}
1019410204
}
10195-
return false;
10205+
return forEachChild(node, isReferencedImportDeclaration);
1019610206
}
1019710207

1019810208
function isImplementationOfOverload(node: FunctionLikeDeclaration) {
@@ -10266,7 +10276,7 @@ module ts {
1026610276
getLocalNameOfContainer,
1026710277
getExpressionNamePrefix,
1026810278
getExportAssignmentName,
10269-
isReferencedImportEqualsDeclaration,
10279+
isReferencedImportDeclaration,
1027010280
getNodeCheckFlags,
1027110281
isTopLevelValueImportEqualsWithEntityName,
1027210282
isDeclarationVisible,
@@ -10440,7 +10450,7 @@ module ts {
1044010450
return grammarErrorOnNode(lastPrivate, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "private");
1044110451
}
1044210452
}
10443-
else if (node.kind === SyntaxKind.ImportEqualsDeclaration && flags & NodeFlags.Ambient) {
10453+
else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && flags & NodeFlags.Ambient) {
1044410454
return grammarErrorOnNode(lastDeclare, Diagnostics.A_declare_modifier_cannot_be_used_with_an_import_declaration, "declare");
1044510455
}
1044610456
else if (node.kind === SyntaxKind.InterfaceDeclaration && flags & NodeFlags.Ambient) {

0 commit comments

Comments
 (0)