mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 12:51:30 -05:00
Merge pull request #4179 from Microsoft/exportDeclarationsInSystem
emit export declarations for system modules as a part of 'execute' me…
This commit is contained in:
@@ -3091,31 +3091,38 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
}
|
||||
|
||||
function emitExportMemberAssignments(name: Identifier) {
|
||||
if (compilerOptions.module === ModuleKind.System) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!exportEquals && exportSpecifiers && hasProperty(exportSpecifiers, name.text)) {
|
||||
for (let specifier of exportSpecifiers[name.text]) {
|
||||
writeLine();
|
||||
if (compilerOptions.module === ModuleKind.System) {
|
||||
emitStart(specifier.name);
|
||||
write(`${exportFunctionForFile}("`);
|
||||
emitNodeWithoutSourceMap(specifier.name);
|
||||
write(`", `);
|
||||
emitExpressionIdentifier(name);
|
||||
write(")");
|
||||
emitEnd(specifier.name);
|
||||
}
|
||||
else {
|
||||
emitStart(specifier.name);
|
||||
emitContainingModuleName(specifier);
|
||||
write(".");
|
||||
emitNodeWithoutSourceMap(specifier.name);
|
||||
emitEnd(specifier.name);
|
||||
write(" = ");
|
||||
emitExpressionIdentifier(name);
|
||||
}
|
||||
emitStart(specifier.name);
|
||||
emitContainingModuleName(specifier);
|
||||
write(".");
|
||||
emitNodeWithoutSourceMap(specifier.name);
|
||||
emitEnd(specifier.name);
|
||||
write(" = ");
|
||||
emitExpressionIdentifier(name);
|
||||
write(";");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitExportSpecifierInSystemModule(specifier: ExportSpecifier): void {
|
||||
Debug.assert(compilerOptions.module === ModuleKind.System);
|
||||
|
||||
writeLine();
|
||||
emitStart(specifier.name);
|
||||
write(`${exportFunctionForFile}("`);
|
||||
emitNodeWithoutSourceMap(specifier.name);
|
||||
write(`", `);
|
||||
emitExpressionIdentifier(specifier.propertyName || specifier.name);
|
||||
write(")");
|
||||
emitEnd(specifier.name);
|
||||
write(";");
|
||||
}
|
||||
|
||||
function emitDestructuring(root: BinaryExpression | VariableDeclaration | ParameterDeclaration, isAssignmentExpressionStatement: boolean, value?: Expression) {
|
||||
let emitCount = 0;
|
||||
@@ -6060,7 +6067,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
return compilerOptions.module === ModuleKind.System && isExternalModule(currentSourceFile);
|
||||
}
|
||||
|
||||
function emitSystemModuleBody(node: SourceFile, startIndex: number): void {
|
||||
function emitSystemModuleBody(node: SourceFile, dependencyGroups: DependencyGroup[], startIndex: number): void {
|
||||
// shape of the body in system modules:
|
||||
// function (exports) {
|
||||
// <list of local aliases for imports>
|
||||
@@ -6105,7 +6112,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
write("return {");
|
||||
increaseIndent();
|
||||
writeLine();
|
||||
emitSetters(exportStarFunction);
|
||||
emitSetters(exportStarFunction, dependencyGroups);
|
||||
writeLine();
|
||||
emitExecute(node, startIndex);
|
||||
decreaseIndent();
|
||||
@@ -6114,115 +6121,90 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
emitTempDeclarations(/*newLine*/ true);
|
||||
}
|
||||
|
||||
function emitSetters(exportStarFunction: string) {
|
||||
function emitSetters(exportStarFunction: string, dependencyGroups: DependencyGroup[]) {
|
||||
write("setters:[");
|
||||
for (let i = 0; i < externalImports.length; ++i) {
|
||||
|
||||
for (let i = 0; i < dependencyGroups.length; ++i) {
|
||||
if (i !== 0) {
|
||||
write(",");
|
||||
}
|
||||
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
let importNode = externalImports[i];
|
||||
let importVariableName = getLocalNameForExternalImport(importNode) || "";
|
||||
let parameterName = "_" + importVariableName;
|
||||
|
||||
let group = dependencyGroups[i];
|
||||
|
||||
// derive a unique name for parameter from the first named entry in the group
|
||||
let parameterName = makeUniqueName(forEach(group, getLocalNameForExternalImport) || "");
|
||||
write(`function (${parameterName}) {`);
|
||||
increaseIndent();
|
||||
|
||||
for(let entry of group) {
|
||||
let importVariableName = getLocalNameForExternalImport(entry) || "";
|
||||
|
||||
switch (entry.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
if (!(<ImportDeclaration>entry).importClause) {
|
||||
// 'import "..."' case
|
||||
// module is imported only for side-effects, no emit required
|
||||
break;
|
||||
}
|
||||
// fall-through
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
Debug.assert(importVariableName !== "");
|
||||
|
||||
switch (importNode.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
if (!(<ImportDeclaration>importNode).importClause) {
|
||||
// 'import "..."' case
|
||||
// module is imported only for side-effects, setter body will be empty
|
||||
break;
|
||||
}
|
||||
// fall-through
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
Debug.assert(importVariableName !== "");
|
||||
|
||||
increaseIndent();
|
||||
writeLine();
|
||||
// save import into the local
|
||||
write(`${importVariableName} = ${parameterName};`);
|
||||
writeLine();
|
||||
|
||||
let defaultName =
|
||||
importNode.kind === SyntaxKind.ImportDeclaration
|
||||
? (<ImportDeclaration>importNode).importClause.name
|
||||
: (<ImportEqualsDeclaration>importNode).name;
|
||||
|
||||
if (defaultName) {
|
||||
// emit re-export for imported default name
|
||||
// import n1 from 'foo1'
|
||||
// import n2 = require('foo2')
|
||||
// export {n1}
|
||||
// export {n2}
|
||||
emitExportMemberAssignments(defaultName);
|
||||
writeLine();
|
||||
}
|
||||
// save import into the local
|
||||
write(`${importVariableName} = ${parameterName};`);
|
||||
writeLine();
|
||||
break;
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
Debug.assert(importVariableName !== "");
|
||||
|
||||
if (importNode.kind === SyntaxKind.ImportDeclaration &&
|
||||
(<ImportDeclaration>importNode).importClause.namedBindings) {
|
||||
|
||||
let namedBindings = (<ImportDeclaration>importNode).importClause.namedBindings;
|
||||
if (namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||
// emit re-export for namespace
|
||||
// import * as n from 'foo'
|
||||
// export {n}
|
||||
emitExportMemberAssignments((<NamespaceImport>namedBindings).name);
|
||||
if ((<ExportDeclaration>entry).exportClause) {
|
||||
// export {a, b as c} from 'foo'
|
||||
// emit as:
|
||||
// exports_({
|
||||
// "a": _["a"],
|
||||
// "c": _["b"]
|
||||
// });
|
||||
writeLine();
|
||||
write(`${exportFunctionForFile}({`);
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
for (let i = 0, len = (<ExportDeclaration>entry).exportClause.elements.length; i < len; ++i) {
|
||||
if (i !== 0) {
|
||||
write(",");
|
||||
writeLine();
|
||||
}
|
||||
|
||||
let e = (<ExportDeclaration>entry).exportClause.elements[i];
|
||||
write(`"`);
|
||||
emitNodeWithoutSourceMap(e.name);
|
||||
write(`": ${parameterName}["`);
|
||||
emitNodeWithoutSourceMap(e.propertyName || e.name);
|
||||
write(`"]`);
|
||||
}
|
||||
decreaseIndent();
|
||||
writeLine();
|
||||
write("});")
|
||||
}
|
||||
else {
|
||||
// emit re-exports for named imports
|
||||
// import {a, b} from 'foo'
|
||||
// export {a, b as c}
|
||||
for (let element of (<NamedImports>namedBindings).elements) {
|
||||
emitExportMemberAssignments(element.name || element.propertyName);
|
||||
writeLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decreaseIndent();
|
||||
break;
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
Debug.assert(importVariableName !== "");
|
||||
|
||||
increaseIndent();
|
||||
|
||||
if ((<ExportDeclaration>importNode).exportClause) {
|
||||
// export {a, b as c} from 'foo'
|
||||
// emit as:
|
||||
// var reexports = {}
|
||||
// reexports['a'] = _foo["a"];
|
||||
// reexports['c'] = _foo["b"];
|
||||
// exports_(reexports);
|
||||
let reexportsVariableName = makeUniqueName("reexports");
|
||||
writeLine();
|
||||
write(`var ${reexportsVariableName} = {};`);
|
||||
writeLine();
|
||||
for (let e of (<ExportDeclaration>importNode).exportClause.elements) {
|
||||
write(`${reexportsVariableName}["`);
|
||||
emitNodeWithoutSourceMap(e.name);
|
||||
write(`"] = ${parameterName}["`);
|
||||
emitNodeWithoutSourceMap(e.propertyName || e.name);
|
||||
write(`"];`);
|
||||
writeLine();
|
||||
// export * from 'foo'
|
||||
// emit as:
|
||||
// exportStar(_foo);
|
||||
write(`${exportStarFunction}(${parameterName});`);
|
||||
}
|
||||
write(`${exportFunctionForFile}(${reexportsVariableName});`);
|
||||
}
|
||||
else {
|
||||
writeLine();
|
||||
// export * from 'foo'
|
||||
// emit as:
|
||||
// exportStar(_foo);
|
||||
write(`${exportStarFunction}(${parameterName});`);
|
||||
}
|
||||
|
||||
writeLine();
|
||||
decreaseIndent();
|
||||
break;
|
||||
writeLine();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
decreaseIndent();
|
||||
|
||||
write("}");
|
||||
decreaseIndent();
|
||||
}
|
||||
@@ -6235,26 +6217,40 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
writeLine();
|
||||
for (let i = startIndex; i < node.statements.length; ++i) {
|
||||
let statement = node.statements[i];
|
||||
// - external module related imports/exports are not emitted for system modules
|
||||
// - function declarations are not emitted because they were already hoisted
|
||||
switch (statement.kind) {
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
// - function declarations are not emitted because they were already hoisted
|
||||
// - import declarations are not emitted since they are already handled in setters
|
||||
// - export declarations with module specifiers are not emitted since they were already written in setters
|
||||
// - export declarations without module specifiers are emitted preserving the order
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
continue;
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
if (!(<ExportDeclaration>statement).moduleSpecifier) {
|
||||
for (let element of (<ExportDeclaration>statement).exportClause.elements) {
|
||||
// write call to exporter function for every export specifier in exports list
|
||||
emitExportSpecifierInSystemModule(element);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
if (!isInternalModuleImportEqualsDeclaration(statement)) {
|
||||
// - import equals declarations that import external modules are not emitted
|
||||
continue;
|
||||
}
|
||||
}
|
||||
writeLine();
|
||||
emit(statement);
|
||||
// fall-though for import declarations that import internal modules
|
||||
default:
|
||||
writeLine();
|
||||
emit(statement);
|
||||
}
|
||||
}
|
||||
decreaseIndent();
|
||||
writeLine();
|
||||
write("}"); // execute
|
||||
}
|
||||
|
||||
|
||||
type DependencyGroup = Array<ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration>;
|
||||
|
||||
function emitSystemModule(node: SourceFile, startIndex: number): void {
|
||||
collectExternalModuleInfo(node);
|
||||
// System modules has the following shape
|
||||
@@ -6274,8 +6270,23 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
write(`"${node.moduleName}", `);
|
||||
}
|
||||
write("[");
|
||||
|
||||
let groupIndices: Map<number> = {};
|
||||
let dependencyGroups: DependencyGroup[] = [];
|
||||
|
||||
for (let i = 0; i < externalImports.length; ++i) {
|
||||
let text = getExternalModuleNameText(externalImports[i]);
|
||||
if (hasProperty(groupIndices, text)) {
|
||||
// deduplicate/group entries in dependency list by the dependency name
|
||||
let groupIndex = groupIndices[text];
|
||||
dependencyGroups[groupIndex].push(externalImports[i]);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
groupIndices[text] = dependencyGroups.length;
|
||||
dependencyGroups.push([externalImports[i]]);
|
||||
}
|
||||
|
||||
if (i !== 0) {
|
||||
write(", ");
|
||||
}
|
||||
@@ -6286,7 +6297,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
|
||||
increaseIndent();
|
||||
emitEmitHelpers(node);
|
||||
emitCaptureThisForNodeIfNecessary(node);
|
||||
emitSystemModuleBody(node, startIndex);
|
||||
emitSystemModuleBody(node, dependencyGroups, startIndex);
|
||||
decreaseIndent();
|
||||
writeLine();
|
||||
write("});");
|
||||
|
||||
Reference in New Issue
Block a user