mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 11:35:42 -06:00
Emit 'exports.foo' assignments for bindings that are exported in specifiers.
This commit is contained in:
parent
da72357562
commit
e13a07e3bd
@ -559,34 +559,64 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitVariableStatement(node: VariableStatement): VisitResult<Statement> {
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
// If the variable is for a declaration that has a local name,
|
||||
// do not elide the declaration.
|
||||
const original = getOriginalNode(node);
|
||||
if (original.kind === SyntaxKind.EnumDeclaration
|
||||
|| original.kind === SyntaxKind.ModuleDeclaration) {
|
||||
return setOriginalNode(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
node.declarationList
|
||||
),
|
||||
node
|
||||
);
|
||||
// If the variable is for a generated declaration,
|
||||
// we should maintain it and just strip off the 'export' modifier if necesary.
|
||||
const original = getOriginalNode(node);
|
||||
if (original.kind === SyntaxKind.EnumDeclaration || original.kind === SyntaxKind.ModuleDeclaration) {
|
||||
if (!hasModifier(node, ModifierFlags.Export)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
const variables = getInitializedVariables(node.declarationList);
|
||||
if (variables.length === 0) {
|
||||
// elide statement if there are no initialized variables
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return createStatement(
|
||||
inlineExpressions(
|
||||
map(variables, transformInitializedVariable)
|
||||
)
|
||||
return setOriginalNode(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
node.declarationList
|
||||
),
|
||||
node
|
||||
);
|
||||
}
|
||||
return node;
|
||||
|
||||
const resultStatements: Statement[] = [];
|
||||
|
||||
// If we're exporting these variables, then these just become assignments to 'exports.blah'.
|
||||
// We only want to emit assignments for variables with initializers.
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
const variables = getInitializedVariables(node.declarationList);
|
||||
if (variables.length > 0) {
|
||||
let inlineAssignments = createStatement(
|
||||
inlineExpressions(
|
||||
map(variables, transformInitializedVariable)
|
||||
)
|
||||
);
|
||||
resultStatements.push(inlineAssignments);
|
||||
}
|
||||
}
|
||||
else {
|
||||
resultStatements.push(node);
|
||||
}
|
||||
|
||||
// While we might not have been exported here, each variable might have been exported
|
||||
// later on in an export specifier (e.g. `export {foo as blah, bar}`).
|
||||
for (const decl of node.declarationList.declarations) {
|
||||
addExportMemberAssignmentsForBindingName(resultStatements, decl.name);
|
||||
}
|
||||
|
||||
return resultStatements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates appropriate assignments for each binding identifier that is exported in an export specifier,
|
||||
* and inserts it into 'resultStatements'.
|
||||
*/
|
||||
function addExportMemberAssignmentsForBindingName(resultStatements: Statement[], name: BindingName): void {
|
||||
if (isBindingPattern(name)) {
|
||||
for (const element of name.elements) {
|
||||
addExportMemberAssignmentsForBindingName(resultStatements, element.name)
|
||||
}
|
||||
}
|
||||
else {
|
||||
addExportMemberAssignments(resultStatements, name);
|
||||
}
|
||||
}
|
||||
|
||||
function transformInitializedVariable(node: VariableDeclaration): Expression {
|
||||
@ -665,28 +695,34 @@ namespace ts {
|
||||
|
||||
function visitExpressionStatement(node: ExpressionStatement): VisitResult<Statement> {
|
||||
const original = getOriginalNode(node);
|
||||
if (original.kind === SyntaxKind.EnumDeclaration
|
||||
&& hasModifier(original, ModifierFlags.Export)) {
|
||||
return visitExpressionStatementForEnumDeclaration(node, <EnumDeclaration>original);
|
||||
const origKind = original.kind;
|
||||
if (origKind === SyntaxKind.EnumDeclaration || origKind === SyntaxKind.ModuleDeclaration) {
|
||||
return visitExpressionStatementForEnumOrNamespaceDeclaration(node, <EnumDeclaration | ModuleDeclaration>original);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function visitExpressionStatementForEnumDeclaration(node: ExpressionStatement, original: EnumDeclaration): VisitResult<Statement> {
|
||||
if (isFirstDeclarationOfKind(original, SyntaxKind.EnumDeclaration)) {
|
||||
const statements: Statement[] = [node];
|
||||
addVarForExportedEnumDeclaration(statements, original);
|
||||
return statements;
|
||||
function visitExpressionStatementForEnumOrNamespaceDeclaration(node: ExpressionStatement, original: EnumDeclaration | ModuleDeclaration): VisitResult<Statement> {
|
||||
const statements: Statement[] = [node];
|
||||
|
||||
// Preserve old behavior for enums in which a variable statement is emitted after the body itself.
|
||||
if (hasModifier(original, ModifierFlags.Export) &&
|
||||
original.kind === SyntaxKind.EnumDeclaration &&
|
||||
isFirstDeclarationOfKind(original, SyntaxKind.EnumDeclaration)) {
|
||||
addVarForExportedEnumOrNamespaceDeclaration(statements, original);
|
||||
}
|
||||
else {
|
||||
addExportMemberAssignments(statements, original.name);
|
||||
}
|
||||
|
||||
return node;
|
||||
return statements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a trailing VariableStatement for an enum or module declaration.
|
||||
*/
|
||||
function addVarForExportedEnumDeclaration(statements: Statement[], node: EnumDeclaration | ModuleDeclaration) {
|
||||
function addVarForExportedEnumOrNamespaceDeclaration(statements: Statement[], node: EnumDeclaration | ModuleDeclaration) {
|
||||
statements.push(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
|
||||
@ -2229,14 +2229,17 @@ namespace ts {
|
||||
function addVarForEnumDeclaration(statements: Statement[], node: EnumDeclaration) {
|
||||
// Emit a variable statement for the enum.
|
||||
statements.push(
|
||||
createVariableStatement(
|
||||
isES6ExportedDeclaration(node)
|
||||
? visitNodes(node.modifiers, visitor, isModifier)
|
||||
: undefined,
|
||||
[createVariableDeclaration(
|
||||
getDeclarationName(node)
|
||||
)],
|
||||
/*location*/ node
|
||||
setOriginalNode(
|
||||
createVariableStatement(
|
||||
isES6ExportedDeclaration(node)
|
||||
? visitNodes(node.modifiers, visitor, isModifier)
|
||||
: undefined,
|
||||
[createVariableDeclaration(
|
||||
getDeclarationName(node)
|
||||
)],
|
||||
/*location*/ node
|
||||
),
|
||||
/*original*/ node
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -2398,7 +2401,7 @@ namespace ts {
|
||||
|
||||
function isES6ExportedDeclaration(node: Node) {
|
||||
return isExternalModuleExport(node)
|
||||
&& moduleKind >= ModuleKind.ES6;
|
||||
&& moduleKind === ModuleKind.ES6;
|
||||
}
|
||||
|
||||
function shouldEmitVarForModuleDeclaration(node: ModuleDeclaration) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user