mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Implement export as namespace from (#34903)
* init export start as decl * fix some broken * fix more case * fix more and more case * make it work * make lint happy and accept baseline * add more tests * fix system module * add more case * delete useless assert * accept baseline * make lint happy * fix missing utils * update api * make lint happy * add missing semi * fix minor issue * fix locally bound * avoid useless check * update public api * add more case * fix some case * Use multi-module selection in test runner to cut down on duplication. * Accepted baselines. * remove superfluous tests. * Remove baseline. * Downlevel `export * as ns` in es2015. * Accepted baselines. * Update names of things. Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>
This commit is contained in:
committed by
Daniel Rosenwasser
co-authored by
Daniel Rosenwasser
parent
2f0d07c29a
commit
4c7844be74
+10
-2
@@ -56,9 +56,10 @@ namespace ts {
|
||||
break;
|
||||
// 4. Export alias declarations pointing at only uninstantiated modules or things uninstantiated modules contain
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
if (!(node as ExportDeclaration).moduleSpecifier && !!(node as ExportDeclaration).exportClause) {
|
||||
const exportDeclaration = node as ExportDeclaration;
|
||||
if (!exportDeclaration.moduleSpecifier && exportDeclaration.exportClause && exportDeclaration.exportClause.kind === SyntaxKind.NamedExports) {
|
||||
let state = ModuleInstanceState.NonInstantiated;
|
||||
for (const specifier of (node as ExportDeclaration).exportClause!.elements) {
|
||||
for (const specifier of exportDeclaration.exportClause.elements) {
|
||||
const specifierState = getModuleInstanceStateForAliasTarget(specifier, visited);
|
||||
if (specifierState > state) {
|
||||
state = specifierState;
|
||||
@@ -2575,6 +2576,9 @@ namespace ts {
|
||||
// All export * declarations are collected in an __export symbol
|
||||
declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, SymbolFlags.None);
|
||||
}
|
||||
else if (isNamespaceExport(node.exportClause)) {
|
||||
declareSymbol(container.symbol.exports, container.symbol, node.exportClause, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
|
||||
}
|
||||
}
|
||||
|
||||
function bindImportClause(node: ImportClause) {
|
||||
@@ -4111,6 +4115,10 @@ namespace ts {
|
||||
case SyntaxKind.SourceFile:
|
||||
break;
|
||||
|
||||
case SyntaxKind.NamespaceExport:
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ReturnStatement:
|
||||
// Return statements may require an `await` in ES2018.
|
||||
transformFlags |= TransformFlags.ContainsHoistedDeclarationOrCompletion | TransformFlags.AssertES2018;
|
||||
|
||||
+34
-11
@@ -1551,7 +1551,7 @@ namespace ts {
|
||||
const moduleExport = moduleExports.get(name);
|
||||
if (moduleExport &&
|
||||
moduleExport.flags === SymbolFlags.Alias &&
|
||||
getDeclarationOfKind(moduleExport, SyntaxKind.ExportSpecifier)) {
|
||||
(getDeclarationOfKind(moduleExport, SyntaxKind.ExportSpecifier) || getDeclarationOfKind(moduleExport, SyntaxKind.NamespaceExport))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2221,6 +2221,11 @@ namespace ts {
|
||||
return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false);
|
||||
}
|
||||
|
||||
function getTargetOfNamespaceExport(node: NamespaceExport, dontResolveAlias: boolean): Symbol | undefined {
|
||||
const moduleSpecifier = node.parent.moduleSpecifier;
|
||||
return moduleSpecifier && resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false);
|
||||
}
|
||||
|
||||
// This function creates a synthetic symbol that combines the value side of one symbol with the
|
||||
// type/namespace side of another symbol. Consider this example:
|
||||
//
|
||||
@@ -2386,6 +2391,8 @@ namespace ts {
|
||||
return getTargetOfImportClause(<ImportClause>node, dontRecursivelyResolve);
|
||||
case SyntaxKind.NamespaceImport:
|
||||
return getTargetOfNamespaceImport(<NamespaceImport>node, dontRecursivelyResolve);
|
||||
case SyntaxKind.NamespaceExport:
|
||||
return getTargetOfNamespaceExport(<NamespaceExport>node, dontRecursivelyResolve);
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
return getTargetOfImportSpecifier(<ImportSpecifier>node, dontRecursivelyResolve);
|
||||
case SyntaxKind.ExportSpecifier:
|
||||
@@ -5081,18 +5088,18 @@ namespace ts {
|
||||
|
||||
function mergeExportDeclarations(statements: Statement[]) {
|
||||
// Pass 2: Combine all `export {}` declarations
|
||||
const exports = filter(statements, d => isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause) as ExportDeclaration[];
|
||||
const exports = filter(statements, d => isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause && isNamedExports(d.exportClause)) as ExportDeclaration[];
|
||||
if (length(exports) > 1) {
|
||||
const nonExports = filter(statements, d => !isExportDeclaration(d) || !!d.moduleSpecifier || !d.exportClause);
|
||||
statements = [...nonExports, createExportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createNamedExports(flatMap(exports, e => e.exportClause!.elements)),
|
||||
createNamedExports(flatMap(exports, e => cast(e.exportClause, isNamedExports).elements)),
|
||||
/*moduleSpecifier*/ undefined
|
||||
)];
|
||||
}
|
||||
// Pass 2b: Also combine all `export {} from "..."` declarations as needed
|
||||
const reexports = filter(statements, d => isExportDeclaration(d) && !!d.moduleSpecifier && !!d.exportClause) as ExportDeclaration[];
|
||||
const reexports = filter(statements, d => isExportDeclaration(d) && !!d.moduleSpecifier && !!d.exportClause && isNamedExports(d.exportClause)) as ExportDeclaration[];
|
||||
if (length(reexports) > 1) {
|
||||
const groups = group(reexports, decl => isStringLiteral(decl.moduleSpecifier!) ? ">" + decl.moduleSpecifier.text : ">");
|
||||
if (groups.length !== reexports.length) {
|
||||
@@ -5104,7 +5111,7 @@ namespace ts {
|
||||
createExportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createNamedExports(flatMap(group, e => e.exportClause!.elements)),
|
||||
createNamedExports(flatMap(group, e => cast(e.exportClause, isNamedExports).elements)),
|
||||
group[0].moduleSpecifier
|
||||
)
|
||||
];
|
||||
@@ -5118,8 +5125,8 @@ namespace ts {
|
||||
function inlineExportModifiers(statements: Statement[]) {
|
||||
// Pass 3: Move all `export {}`'s to `export` modifiers where possible
|
||||
const exportDecl = find(statements, d => isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause) as ExportDeclaration | undefined;
|
||||
if (exportDecl) {
|
||||
const replacements = mapDefined(exportDecl.exportClause!.elements, e => {
|
||||
if (exportDecl && exportDecl.exportClause && isNamedExports(exportDecl.exportClause)) {
|
||||
const replacements = mapDefined(exportDecl.exportClause.elements, e => {
|
||||
if (!e.propertyName) {
|
||||
// export {name} - look thru `statements` for `name`, and if all results can take an `export` modifier, do so and filter it
|
||||
const associated = filter(statements, s => nodeHasName(s, e.name));
|
||||
@@ -5137,7 +5144,7 @@ namespace ts {
|
||||
else {
|
||||
// some items filtered, others not - update the export declaration
|
||||
// (mutating because why not, we're building a whole new tree here anyway)
|
||||
exportDecl.exportClause!.elements = createNodeArray(replacements);
|
||||
exportDecl.exportClause.elements = createNodeArray(replacements);
|
||||
}
|
||||
}
|
||||
return statements;
|
||||
@@ -5653,6 +5660,14 @@ namespace ts {
|
||||
createLiteral(getSpecifierForModuleSymbol(target, context))
|
||||
), ModifierFlags.None);
|
||||
break;
|
||||
case SyntaxKind.NamespaceExport:
|
||||
addResult(createExportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createNamespaceExport(createIdentifier(localName)),
|
||||
createLiteral(getSpecifierForModuleSymbol(target, context))
|
||||
), ModifierFlags.None);
|
||||
break;
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
addResult(createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
@@ -32608,7 +32623,7 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkAliasSymbol(node: ImportEqualsDeclaration | ImportClause | NamespaceImport | ImportSpecifier | ExportSpecifier) {
|
||||
function checkAliasSymbol(node: ImportEqualsDeclaration | ImportClause | NamespaceImport | ImportSpecifier | ExportSpecifier | NamespaceExport) {
|
||||
let symbol = getSymbolOfNode(node);
|
||||
const target = resolveAlias(symbol);
|
||||
|
||||
@@ -32727,7 +32742,12 @@ namespace ts {
|
||||
if (node.exportClause) {
|
||||
// export { x, y }
|
||||
// export { x, y } from "foo"
|
||||
forEach(node.exportClause.elements, checkExportSpecifier);
|
||||
if (isNamedExports(node.exportClause)) {
|
||||
forEach(node.exportClause.elements, checkExportSpecifier);
|
||||
}
|
||||
else if(!isNamespaceExport(node.exportClause)) {
|
||||
checkImportBinding(node.exportClause);
|
||||
}
|
||||
|
||||
const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && isAmbientModule(node.parent.parent);
|
||||
const inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === SyntaxKind.ModuleBlock &&
|
||||
@@ -34157,7 +34177,10 @@ namespace ts {
|
||||
return isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol);
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
const exportClause = (<ExportDeclaration>node).exportClause;
|
||||
return !!exportClause && some(exportClause.elements, isValueAliasDeclaration);
|
||||
return !!exportClause && (
|
||||
isNamespaceExport(exportClause) ||
|
||||
some(exportClause.elements, isValueAliasDeclaration)
|
||||
);
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return (<ExportAssignment>node).expression && (<ExportAssignment>node).expression.kind === SyntaxKind.Identifier ?
|
||||
isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol) :
|
||||
|
||||
@@ -1435,6 +1435,8 @@ namespace ts {
|
||||
return emitImportClause(<ImportClause>node);
|
||||
case SyntaxKind.NamespaceImport:
|
||||
return emitNamespaceImport(<NamespaceImport>node);
|
||||
case SyntaxKind.NamespaceExport:
|
||||
return emitNamespaceExport(<NamespaceExport>node);
|
||||
case SyntaxKind.NamedImports:
|
||||
return emitNamedImports(<NamedImports>node);
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
@@ -3104,6 +3106,14 @@ namespace ts {
|
||||
writeTrailingSemicolon();
|
||||
}
|
||||
|
||||
function emitNamespaceExport(node: NamespaceExport) {
|
||||
const asPos = emitTokenWithComment(SyntaxKind.AsteriskToken, node.pos, writePunctuation, node);
|
||||
writeSpace();
|
||||
emitTokenWithComment(SyntaxKind.AsKeyword, asPos, writeKeyword, node);
|
||||
writeSpace();
|
||||
emit(node.name);
|
||||
}
|
||||
|
||||
function emitNamedExports(node: NamedExports) {
|
||||
emitNamedImportsOrExports(node);
|
||||
}
|
||||
@@ -4408,6 +4418,9 @@ namespace ts {
|
||||
case SyntaxKind.NamespaceImport:
|
||||
generateNameIfNeeded((<NamespaceImport>node).name);
|
||||
break;
|
||||
case SyntaxKind.NamespaceExport:
|
||||
generateNameIfNeeded((<NamespaceExport>node).name);
|
||||
break;
|
||||
case SyntaxKind.NamedImports:
|
||||
forEach((<NamedImports>node).elements, generateNames);
|
||||
break;
|
||||
|
||||
@@ -2278,12 +2278,24 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createNamespaceExport(name: Identifier): NamespaceExport {
|
||||
const node = <NamespaceExport>createSynthesizedNode(SyntaxKind.NamespaceExport);
|
||||
node.name = name;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateNamespaceImport(node: NamespaceImport, name: Identifier) {
|
||||
return node.name !== name
|
||||
? updateNode(createNamespaceImport(name), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function updateNamespaceExport(node: NamespaceExport, name: Identifier) {
|
||||
return node.name !== name
|
||||
? updateNode(createNamespaceExport(name), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createNamedImports(elements: readonly ImportSpecifier[]): NamedImports {
|
||||
const node = <NamedImports>createSynthesizedNode(SyntaxKind.NamedImports);
|
||||
node.elements = createNodeArray(elements);
|
||||
@@ -2327,7 +2339,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createExportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExports | undefined, moduleSpecifier?: Expression) {
|
||||
export function createExportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExportBindings | undefined, moduleSpecifier?: Expression) {
|
||||
const node = <ExportDeclaration>createSynthesizedNode(SyntaxKind.ExportDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -2340,7 +2352,7 @@ namespace ts {
|
||||
node: ExportDeclaration,
|
||||
decorators: readonly Decorator[] | undefined,
|
||||
modifiers: readonly Modifier[] | undefined,
|
||||
exportClause: NamedExports | undefined,
|
||||
exportClause: NamedExportBindings | undefined,
|
||||
moduleSpecifier: Expression | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|
||||
@@ -390,6 +390,8 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.NamespaceImport:
|
||||
return visitNode(cbNode, (<NamespaceImport>node).name);
|
||||
case SyntaxKind.NamespaceExport:
|
||||
return visitNode(cbNode, (<NamespaceExport>node).name);
|
||||
case SyntaxKind.NamedImports:
|
||||
case SyntaxKind.NamedExports:
|
||||
return visitNodes(cbNode, cbNodes, (<NamedImportsOrExports>node).elements);
|
||||
@@ -6470,9 +6472,18 @@ namespace ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseNamespaceExport(): NamespaceExport {
|
||||
const node = <NamespaceExport>createNode(SyntaxKind.NamespaceExport);
|
||||
node.name = parseIdentifier();
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseExportDeclaration(node: ExportDeclaration): ExportDeclaration {
|
||||
node.kind = SyntaxKind.ExportDeclaration;
|
||||
if (parseOptional(SyntaxKind.AsteriskToken)) {
|
||||
if (parseOptional(SyntaxKind.AsKeyword)) {
|
||||
node.exportClause = parseNamespaceExport();
|
||||
}
|
||||
parseExpected(SyntaxKind.FromKeyword);
|
||||
node.moduleSpecifier = parseModuleSpecifier();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace ts {
|
||||
switch (moduleKind) {
|
||||
case ModuleKind.ESNext:
|
||||
case ModuleKind.ES2015:
|
||||
return transformES2015Module;
|
||||
return transformECMAScriptModule;
|
||||
case ModuleKind.System:
|
||||
return transformSystemModule;
|
||||
default:
|
||||
|
||||
+39
-1
@@ -1,6 +1,6 @@
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
export function transformES2015Module(context: TransformationContext) {
|
||||
export function transformECMAScriptModule(context: TransformationContext) {
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
const previousOnEmitNode = context.onEmitNode;
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
@@ -44,6 +44,9 @@ namespace ts {
|
||||
return undefined;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return visitExportAssignment(<ExportAssignment>node);
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
const exportDecl = (node as ExportDeclaration);
|
||||
return visitExportDeclaration(exportDecl);
|
||||
}
|
||||
|
||||
return node;
|
||||
@@ -54,6 +57,41 @@ namespace ts {
|
||||
return node.isExportEquals ? undefined : node;
|
||||
}
|
||||
|
||||
function visitExportDeclaration(node: ExportDeclaration) {
|
||||
// `export * as ns` only needs to be transformed in ES2015
|
||||
if (compilerOptions.module !== undefined && compilerOptions.module > ModuleKind.ES2015) {
|
||||
return node;
|
||||
}
|
||||
|
||||
// Either ill-formed or don't need to be tranformed.
|
||||
if (!node.exportClause || !isNamespaceExport(node.exportClause) || !node.moduleSpecifier) {
|
||||
return node;
|
||||
}
|
||||
|
||||
const oldIdentifier = node.exportClause.name;
|
||||
const synthName = getGeneratedNameForNode(oldIdentifier);
|
||||
const importDecl = createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createImportClause(/*name*/ undefined,
|
||||
createNamespaceImport(
|
||||
synthName
|
||||
)
|
||||
),
|
||||
node.moduleSpecifier,
|
||||
);
|
||||
setOriginalNode(importDecl, node.exportClause);
|
||||
|
||||
const exportDecl = createExportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createNamedExports([createExportSpecifier(synthName, oldIdentifier)]),
|
||||
);
|
||||
setOriginalNode(exportDecl, node);
|
||||
|
||||
return [importDecl, exportDecl];
|
||||
}
|
||||
|
||||
//
|
||||
// Emit Notification
|
||||
//
|
||||
@@ -747,6 +747,17 @@ namespace ts {
|
||||
return createCall(createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]);
|
||||
}
|
||||
|
||||
function getHelperExpressionForExport(node: ExportDeclaration, innerExpr: Expression) {
|
||||
if (!compilerOptions.esModuleInterop || getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) {
|
||||
return innerExpr;
|
||||
}
|
||||
if (getExportNeedsImportStarHelper(node)) {
|
||||
context.requestEmitHelper(importStarHelper);
|
||||
return createCall(getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]);
|
||||
}
|
||||
return innerExpr;
|
||||
}
|
||||
|
||||
function getHelperExpressionForImport(node: ImportDeclaration, innerExpr: Expression) {
|
||||
if (!compilerOptions.esModuleInterop || getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) {
|
||||
return innerExpr;
|
||||
@@ -967,7 +978,7 @@ namespace ts {
|
||||
|
||||
const generatedName = getGeneratedNameForNode(node);
|
||||
|
||||
if (node.exportClause) {
|
||||
if (node.exportClause && isNamedExports(node.exportClause)) {
|
||||
const statements: Statement[] = [];
|
||||
// export { x, y } from "mod";
|
||||
if (moduleKind !== ModuleKind.AMD) {
|
||||
@@ -1008,6 +1019,28 @@ namespace ts {
|
||||
|
||||
return singleOrMany(statements);
|
||||
}
|
||||
else if (node.exportClause) {
|
||||
const statements: Statement[] = [];
|
||||
// export * as ns from "mod";
|
||||
statements.push(
|
||||
setOriginalNode(
|
||||
setTextRange(
|
||||
createExpressionStatement(
|
||||
createExportExpression(
|
||||
getSynthesizedClone(node.exportClause.name),
|
||||
moduleKind !== ModuleKind.AMD ?
|
||||
getHelperExpressionForExport(node, createRequireCall(node)) :
|
||||
createIdentifier(idText(node.exportClause.name))
|
||||
)
|
||||
),
|
||||
node
|
||||
),
|
||||
node
|
||||
)
|
||||
);
|
||||
|
||||
return singleOrMany(statements);
|
||||
}
|
||||
else {
|
||||
// export * from "mod";
|
||||
return setOriginalNode(
|
||||
|
||||
@@ -346,11 +346,21 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const element of externalImport.exportClause.elements) {
|
||||
// write name of indirectly exported entry, i.e. 'export {x} from ...'
|
||||
if (isNamedExports(externalImport.exportClause)) {
|
||||
for (const element of externalImport.exportClause.elements) {
|
||||
// write name of indirectly exported entry, i.e. 'export {x} from ...'
|
||||
exportedNames.push(
|
||||
createPropertyAssignment(
|
||||
createLiteral(idText(element.name || element.propertyName)),
|
||||
createTrue()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
exportedNames.push(
|
||||
createPropertyAssignment(
|
||||
createLiteral(idText(element.name || element.propertyName)),
|
||||
createLiteral(idText(externalImport.exportClause.name)),
|
||||
createTrue()
|
||||
)
|
||||
);
|
||||
@@ -489,36 +499,52 @@ namespace ts {
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
Debug.assert(importVariableName !== undefined);
|
||||
if (entry.exportClause) {
|
||||
// export {a, b as c} from 'foo'
|
||||
//
|
||||
// emit as:
|
||||
//
|
||||
// exports_({
|
||||
// "a": _["a"],
|
||||
// "c": _["b"]
|
||||
// });
|
||||
const properties: PropertyAssignment[] = [];
|
||||
for (const e of entry.exportClause.elements) {
|
||||
properties.push(
|
||||
createPropertyAssignment(
|
||||
createLiteral(idText(e.name)),
|
||||
createElementAccess(
|
||||
parameterName,
|
||||
createLiteral(idText(e.propertyName || e.name))
|
||||
if (isNamedExports(entry.exportClause)) {
|
||||
// export {a, b as c} from 'foo'
|
||||
//
|
||||
// emit as:
|
||||
//
|
||||
// exports_({
|
||||
// "a": _["a"],
|
||||
// "c": _["b"]
|
||||
// });
|
||||
const properties: PropertyAssignment[] = [];
|
||||
for (const e of entry.exportClause.elements) {
|
||||
properties.push(
|
||||
createPropertyAssignment(
|
||||
createLiteral(idText(e.name)),
|
||||
createElementAccess(
|
||||
parameterName,
|
||||
createLiteral(idText(e.propertyName || e.name))
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
statements.push(
|
||||
createExpressionStatement(
|
||||
createCall(
|
||||
exportFunction,
|
||||
/*typeArguments*/ undefined,
|
||||
[createObjectLiteral(properties, /*multiline*/ true)]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
statements.push(
|
||||
createExpressionStatement(
|
||||
createCall(
|
||||
exportFunction,
|
||||
/*typeArguments*/ undefined,
|
||||
[createObjectLiteral(properties, /*multiline*/ true)]
|
||||
else {
|
||||
statements.push(
|
||||
createExpressionStatement(
|
||||
createCall(
|
||||
exportFunction,
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createLiteral(idText(entry.exportClause.name)),
|
||||
parameterName
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export * from 'foo'
|
||||
@@ -574,9 +600,7 @@ namespace ts {
|
||||
return visitImportEqualsDeclaration(<ImportEqualsDeclaration>node);
|
||||
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
// ExportDeclarations are elided as they are handled via
|
||||
// `appendExportsOfDeclaration`.
|
||||
return undefined;
|
||||
return visitExportDeclaration(<ExportDeclaration>node);
|
||||
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return visitExportAssignment(<ExportAssignment>node);
|
||||
@@ -609,6 +633,11 @@ namespace ts {
|
||||
return singleOrMany(statements);
|
||||
}
|
||||
|
||||
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement> {
|
||||
Debug.assertDefined(node);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an ImportEqualsDeclaration node.
|
||||
*
|
||||
|
||||
@@ -2849,7 +2849,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Elide the export declaration if all of its named exports are elided.
|
||||
const exportClause = visitNode(node.exportClause, visitNamedExports, isNamedExports);
|
||||
const exportClause = visitNode(node.exportClause, visitNamedExportBindings, isNamedImportBindings);
|
||||
return exportClause
|
||||
? updateExportDeclaration(
|
||||
node,
|
||||
@@ -2872,6 +2872,14 @@ namespace ts {
|
||||
return some(elements) ? updateNamedExports(node, elements) : undefined;
|
||||
}
|
||||
|
||||
function visitNamespaceExports(node: NamespaceExport): VisitResult<NamespaceExport> {
|
||||
return updateNamespaceExport(node, visitNode(node.name, visitor, isIdentifier));
|
||||
}
|
||||
|
||||
function visitNamedExportBindings(node: NamedExportBindings): VisitResult<NamedExportBindings> {
|
||||
return isNamespaceExport(node) ? visitNamespaceExports(node) : visitNamedExports(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an export specifier, eliding it if it does not resolve to a value.
|
||||
*
|
||||
|
||||
@@ -37,6 +37,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function getExportNeedsImportStarHelper(node: ExportDeclaration): boolean {
|
||||
return !!getNamespaceDeclarationNode(node);
|
||||
}
|
||||
|
||||
export function getImportNeedsImportStarHelper(node: ImportDeclaration): boolean {
|
||||
if (!!getNamespaceDeclarationNode(node)) {
|
||||
return true;
|
||||
@@ -105,13 +109,14 @@ namespace ts {
|
||||
hasExportStarsToExportValues = true;
|
||||
}
|
||||
else {
|
||||
// export * as ns from "mod"
|
||||
// export { x, y } from "mod"
|
||||
externalImports.push(<ExportDeclaration>node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export { x, y }
|
||||
for (const specifier of (<ExportDeclaration>node).exportClause!.elements) {
|
||||
for (const specifier of cast((<ExportDeclaration>node).exportClause, isNamedExports).elements) {
|
||||
if (!uniqueExports.get(idText(specifier.name))) {
|
||||
const name = specifier.propertyName || specifier.name;
|
||||
exportSpecifiers.add(idText(name), specifier);
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
"transformers/generators.ts",
|
||||
"transformers/module/module.ts",
|
||||
"transformers/module/system.ts",
|
||||
"transformers/module/es2015.ts",
|
||||
"transformers/module/esnextAnd2015.ts",
|
||||
"transformers/declarations/diagnostics.ts",
|
||||
"transformers/declarations.ts",
|
||||
"transformer.ts",
|
||||
|
||||
@@ -403,6 +403,7 @@ namespace ts {
|
||||
ExportAssignment,
|
||||
ExportDeclaration,
|
||||
NamedExports,
|
||||
NamespaceExport,
|
||||
ExportSpecifier,
|
||||
MissingDeclaration,
|
||||
|
||||
@@ -2442,6 +2443,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export type NamedImportBindings = NamespaceImport | NamedImports;
|
||||
export type NamedExportBindings = NamespaceExport | NamedExports;
|
||||
|
||||
// In case of:
|
||||
// import d from "mod" => name = d, namedBinding = undefined
|
||||
@@ -2462,6 +2464,12 @@ namespace ts {
|
||||
name: Identifier;
|
||||
}
|
||||
|
||||
export interface NamespaceExport extends NamedDeclaration {
|
||||
kind: SyntaxKind.NamespaceExport;
|
||||
parent: ExportDeclaration;
|
||||
name: Identifier
|
||||
}
|
||||
|
||||
export interface NamespaceExportDeclaration extends DeclarationStatement {
|
||||
kind: SyntaxKind.NamespaceExportDeclaration;
|
||||
name: Identifier;
|
||||
@@ -2471,7 +2479,7 @@ namespace ts {
|
||||
kind: SyntaxKind.ExportDeclaration;
|
||||
parent: SourceFile | ModuleBlock;
|
||||
/** Will not be assigned in the case of `export * from "foo";` */
|
||||
exportClause?: NamedExports;
|
||||
exportClause?: NamedExportBindings;
|
||||
/** If this is not a StringLiteral it will be a grammar error. */
|
||||
moduleSpecifier?: Expression;
|
||||
}
|
||||
|
||||
@@ -2237,14 +2237,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): ImportEqualsDeclaration | NamespaceImport | undefined {
|
||||
export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): ImportEqualsDeclaration | NamespaceImport | NamespaceExport | undefined {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return node.importClause && tryCast(node.importClause.namedBindings, isNamespaceImport);
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return node;
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return undefined;
|
||||
return node.exportClause && tryCast(node.exportClause, isNamespaceExport);
|
||||
default:
|
||||
return Debug.assertNever(node);
|
||||
}
|
||||
@@ -2681,6 +2681,7 @@ namespace ts {
|
||||
// import * as <symbol> from ...
|
||||
// import { x as <symbol> } from ...
|
||||
// export { x as <symbol> } from ...
|
||||
// export * as ns <symbol> from ...
|
||||
// export = <EntityNameExpression>
|
||||
// export default <EntityNameExpression>
|
||||
// module.exports = <EntityNameExpression>
|
||||
@@ -2691,6 +2692,7 @@ namespace ts {
|
||||
node.kind === SyntaxKind.NamespaceExportDeclaration ||
|
||||
node.kind === SyntaxKind.ImportClause && !!(<ImportClause>node).name ||
|
||||
node.kind === SyntaxKind.NamespaceImport ||
|
||||
node.kind === SyntaxKind.NamespaceExport ||
|
||||
node.kind === SyntaxKind.ImportSpecifier ||
|
||||
node.kind === SyntaxKind.ExportSpecifier ||
|
||||
node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node) ||
|
||||
|
||||
@@ -1366,6 +1366,14 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.NamespaceImport;
|
||||
}
|
||||
|
||||
export function isNamespaceExport(node: Node): node is NamespaceExport {
|
||||
return node.kind === SyntaxKind.NamespaceExport;
|
||||
}
|
||||
|
||||
export function isNamedExportBindings(node: Node): node is NamedExportBindings {
|
||||
return node.kind === SyntaxKind.NamespaceExport || node.kind === SyntaxKind.NamedExports;
|
||||
}
|
||||
|
||||
export function isNamedImports(node: Node): node is NamedImports {
|
||||
return node.kind === SyntaxKind.NamedImports;
|
||||
}
|
||||
@@ -2263,6 +2271,7 @@ namespace ts {
|
||||
|| kind === SyntaxKind.ModuleDeclaration
|
||||
|| kind === SyntaxKind.NamespaceExportDeclaration
|
||||
|| kind === SyntaxKind.NamespaceImport
|
||||
|| kind === SyntaxKind.NamespaceExport
|
||||
|| kind === SyntaxKind.Parameter
|
||||
|| kind === SyntaxKind.PropertyAssignment
|
||||
|| kind === SyntaxKind.PropertyDeclaration
|
||||
|
||||
@@ -386,6 +386,10 @@ namespace ts {
|
||||
result = reduceNode((<NamespaceImport>node).name, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.NamespaceExport:
|
||||
result = reduceNode((<NamespaceExport>node).name, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.NamedImports:
|
||||
case SyntaxKind.NamedExports:
|
||||
result = reduceNodes((<NamedImports | NamedExports>node).elements, cbNodes, result);
|
||||
|
||||
@@ -798,6 +798,10 @@ namespace ts {
|
||||
return updateNamespaceImport(<NamespaceImport>node,
|
||||
visitNode((<NamespaceImport>node).name, visitor, isIdentifier));
|
||||
|
||||
case SyntaxKind.NamespaceExport:
|
||||
return updateNamespaceExport(<NamespaceExport>node,
|
||||
visitNode((<NamespaceExport>node).name, visitor, isIdentifier));
|
||||
|
||||
case SyntaxKind.NamedImports:
|
||||
return updateNamedImports(<NamedImports>node,
|
||||
nodesVisitor((<NamedImports>node).elements, visitor, isImportSpecifier));
|
||||
@@ -817,7 +821,7 @@ namespace ts {
|
||||
return updateExportDeclaration(<ExportDeclaration>node,
|
||||
nodesVisitor((<ExportDeclaration>node).decorators, visitor, isDecorator),
|
||||
nodesVisitor((<ExportDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<ExportDeclaration>node).exportClause, visitor, isNamedExports),
|
||||
visitNode((<ExportDeclaration>node).exportClause, visitor, isNamedExportBindings),
|
||||
visitNode((<ExportDeclaration>node).moduleSpecifier, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.NamedExports:
|
||||
|
||||
@@ -240,7 +240,9 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
|
||||
if (decl.kind === SyntaxKind.ExportDeclaration) {
|
||||
searchForNamedImport(decl.exportClause);
|
||||
if (decl.exportClause && isNamedExports(decl.exportClause)) {
|
||||
searchForNamedImport(decl.exportClause);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -326,7 +328,7 @@ namespace ts.FindAllReferences {
|
||||
return !!forEachPossibleImportOrExportStatement(sourceFileLike, statement => {
|
||||
if (!isExportDeclaration(statement)) return;
|
||||
const { exportClause, moduleSpecifier } = statement;
|
||||
return !moduleSpecifier && exportClause &&
|
||||
return !moduleSpecifier && exportClause && isNamedExports(exportClause) &&
|
||||
exportClause.elements.some(element => checker.getExportSpecifierLocalTargetSymbol(element) === namespaceImportSymbol);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -307,7 +307,7 @@ namespace ts.OrganizeImports {
|
||||
}
|
||||
|
||||
const newExportSpecifiers: ExportSpecifier[] = [];
|
||||
newExportSpecifiers.push(...flatMap(namedExports, i => (i.exportClause!).elements));
|
||||
newExportSpecifiers.push(...flatMap(namedExports, i => i.exportClause && isNamedExports(i.exportClause) ? i.exportClause.elements : emptyArray));
|
||||
|
||||
const sortedExportSpecifiers = sortSpecifiers(newExportSpecifiers);
|
||||
|
||||
@@ -317,7 +317,11 @@ namespace ts.OrganizeImports {
|
||||
exportDecl,
|
||||
exportDecl.decorators,
|
||||
exportDecl.modifiers,
|
||||
updateNamedExports(exportDecl.exportClause!, sortedExportSpecifiers),
|
||||
exportDecl.exportClause && (
|
||||
isNamedExports(exportDecl.exportClause) ?
|
||||
updateNamedExports(exportDecl.exportClause, sortedExportSpecifiers) :
|
||||
updateNamespaceExport(exportDecl.exportClause, exportDecl.exportClause.name)
|
||||
),
|
||||
exportDecl.moduleSpecifier));
|
||||
|
||||
return coalescedExports;
|
||||
|
||||
@@ -752,8 +752,14 @@ namespace ts {
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
// Handle named exports case e.g.:
|
||||
// export {a, b as B} from "mod";
|
||||
if ((<ExportDeclaration>node).exportClause) {
|
||||
forEach((<ExportDeclaration>node).exportClause!.elements, visit);
|
||||
const exportDeclaration = (<ExportDeclaration>node);
|
||||
if (exportDeclaration.exportClause) {
|
||||
if (isNamedExports(exportDeclaration.exportClause)) {
|
||||
forEach(exportDeclaration.exportClause.elements, visit);
|
||||
}
|
||||
else {
|
||||
visit(exportDeclaration.exportClause.name);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -373,6 +373,7 @@ namespace ts {
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
case SyntaxKind.ExportSpecifier:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
case SyntaxKind.NamespaceExport:
|
||||
return ScriptElementKind.alias;
|
||||
case SyntaxKind.BinaryExpression:
|
||||
const kind = getAssignmentDeclarationKind(node as BinaryExpression);
|
||||
|
||||
Reference in New Issue
Block a user