Support tree-shakable imports for --target es2015 (#32742)
* Support tree-shakable imports for --target es2015 * Alias external helper imports for --module es2015
This commit is contained in:
parent
85b8d27ea3
commit
05af8faac6
|
@ -1609,7 +1609,7 @@ namespace ts {
|
|||
for (let i = 0; i < numNodes; i++) {
|
||||
const currentNode = bundle ? i < numPrepends ? bundle.prepends[i] : bundle.sourceFiles[i - numPrepends] : node;
|
||||
const sourceFile = isSourceFile(currentNode) ? currentNode : isUnparsedSource(currentNode) ? undefined : currentSourceFile!;
|
||||
const shouldSkip = printerOptions.noEmitHelpers || (!!sourceFile && getExternalHelpersModuleName(sourceFile) !== undefined);
|
||||
const shouldSkip = printerOptions.noEmitHelpers || (!!sourceFile && hasRecordedExternalHelpers(sourceFile));
|
||||
const shouldBundle = (isSourceFile(currentNode) || isUnparsedSource(currentNode)) && !isOwnFileEmit;
|
||||
const helpers = isUnparsedSource(currentNode) ? currentNode.helpers : getSortedEmitHelpers(currentNode);
|
||||
if (helpers) {
|
||||
|
|
|
@ -3628,12 +3628,16 @@ namespace ts {
|
|||
|
||||
// Helpers
|
||||
|
||||
export function getHelperName(name: string) {
|
||||
/**
|
||||
* Gets an identifier for the name of an *unscoped* emit helper.
|
||||
*/
|
||||
export function getUnscopedHelperName(name: string) {
|
||||
return setEmitFlags(createIdentifier(name), EmitFlags.HelperName | EmitFlags.AdviseOnEmitNode);
|
||||
}
|
||||
|
||||
export const valuesHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:values",
|
||||
importName: "__values",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __values = (this && this.__values) || function(o) {
|
||||
|
@ -3653,7 +3657,7 @@ namespace ts {
|
|||
context.requestEmitHelper(valuesHelper);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__values"),
|
||||
getUnscopedHelperName("__values"),
|
||||
/*typeArguments*/ undefined,
|
||||
[expression]
|
||||
),
|
||||
|
@ -3663,6 +3667,7 @@ namespace ts {
|
|||
|
||||
export const readHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:read",
|
||||
importName: "__read",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __read = (this && this.__read) || function (o, n) {
|
||||
|
@ -3687,7 +3692,7 @@ namespace ts {
|
|||
context.requestEmitHelper(readHelper);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__read"),
|
||||
getUnscopedHelperName("__read"),
|
||||
/*typeArguments*/ undefined,
|
||||
count !== undefined
|
||||
? [iteratorRecord, createLiteral(count)]
|
||||
|
@ -3699,6 +3704,7 @@ namespace ts {
|
|||
|
||||
export const spreadHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:spread",
|
||||
importName: "__spread",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __spread = (this && this.__spread) || function () {
|
||||
|
@ -3712,7 +3718,7 @@ namespace ts {
|
|||
context.requestEmitHelper(spreadHelper);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__spread"),
|
||||
getUnscopedHelperName("__spread"),
|
||||
/*typeArguments*/ undefined,
|
||||
argumentList
|
||||
),
|
||||
|
@ -3722,6 +3728,7 @@ namespace ts {
|
|||
|
||||
export const spreadArraysHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:spreadArrays",
|
||||
importName: "__spreadArrays",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __spreadArrays = (this && this.__spreadArrays) || function () {
|
||||
|
@ -3737,7 +3744,7 @@ namespace ts {
|
|||
context.requestEmitHelper(spreadArraysHelper);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__spreadArrays"),
|
||||
getUnscopedHelperName("__spreadArrays"),
|
||||
/*typeArguments*/ undefined,
|
||||
argumentList
|
||||
),
|
||||
|
@ -4863,6 +4870,65 @@ namespace ts {
|
|||
return emitNode && emitNode.externalHelpersModuleName;
|
||||
}
|
||||
|
||||
export function hasRecordedExternalHelpers(sourceFile: SourceFile) {
|
||||
const parseNode = getOriginalNode(sourceFile, isSourceFile);
|
||||
const emitNode = parseNode && parseNode.emitNode;
|
||||
return !!emitNode && (!!emitNode.externalHelpersModuleName || !!emitNode.externalHelpers);
|
||||
}
|
||||
|
||||
export function createExternalHelpersImportDeclarationIfNeeded(sourceFile: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStar?: boolean, hasImportDefault?: boolean) {
|
||||
if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions)) {
|
||||
let namedBindings: NamedImportBindings | undefined;
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
if (moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) {
|
||||
// use named imports
|
||||
const helpers = getEmitHelpers(sourceFile);
|
||||
if (helpers) {
|
||||
const helperNames: string[] = [];
|
||||
for (const helper of helpers) {
|
||||
if (!helper.scoped) {
|
||||
const importName = (helper as UnscopedEmitHelper).importName;
|
||||
if (importName) {
|
||||
pushIfUnique(helperNames, importName);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (some(helperNames)) {
|
||||
helperNames.sort(compareStringsCaseSensitive);
|
||||
// Alias the imports if the names are used somewhere in the file.
|
||||
// NOTE: We don't need to care about global import collisions as this is a module.
|
||||
namedBindings = createNamedImports(
|
||||
map(helperNames, name => isFileLevelUniqueName(sourceFile, name)
|
||||
? createImportSpecifier(/*propertyName*/ undefined, createIdentifier(name))
|
||||
: createImportSpecifier(createIdentifier(name), getUnscopedHelperName(name))
|
||||
)
|
||||
);
|
||||
const parseNode = getOriginalNode(sourceFile, isSourceFile);
|
||||
const emitNode = getOrCreateEmitNode(parseNode);
|
||||
emitNode.externalHelpers = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// use a namespace import
|
||||
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar || hasImportDefault);
|
||||
if (externalHelpersModuleName) {
|
||||
namedBindings = createNamespaceImport(externalHelpersModuleName);
|
||||
}
|
||||
}
|
||||
if (namedBindings) {
|
||||
const externalHelpersImportDeclaration = createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createImportClause(/*name*/ undefined, namedBindings),
|
||||
createLiteral(externalHelpersModuleNameText)
|
||||
);
|
||||
addEmitFlags(externalHelpersImportDeclaration, EmitFlags.NeverApplyImportHelper);
|
||||
return externalHelpersImportDeclaration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStarOrImportDefault?: boolean) {
|
||||
if (compilerOptions.importHelpers && isEffectiveExternalModule(node, compilerOptions)) {
|
||||
const externalHelpersModuleName = getExternalHelpersModuleName(node);
|
||||
|
|
|
@ -514,6 +514,7 @@ namespace ts {
|
|||
|
||||
export const restHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:rest",
|
||||
importName: "__rest",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
|
@ -557,7 +558,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
return createCall(
|
||||
getHelperName("__rest"),
|
||||
getUnscopedHelperName("__rest"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
value,
|
||||
|
|
|
@ -4339,7 +4339,7 @@ namespace ts {
|
|||
function createExtendsHelper(context: TransformationContext, name: Identifier) {
|
||||
context.requestEmitHelper(extendsHelper);
|
||||
return createCall(
|
||||
getHelperName("__extends"),
|
||||
getUnscopedHelperName("__extends"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
name,
|
||||
|
@ -4351,7 +4351,7 @@ namespace ts {
|
|||
function createTemplateObjectHelper(context: TransformationContext, cooked: ArrayLiteralExpression, raw: ArrayLiteralExpression) {
|
||||
context.requestEmitHelper(templateObjectHelper);
|
||||
return createCall(
|
||||
getHelperName("__makeTemplateObject"),
|
||||
getUnscopedHelperName("__makeTemplateObject"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
cooked,
|
||||
|
@ -4362,6 +4362,7 @@ namespace ts {
|
|||
|
||||
export const extendsHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:extends",
|
||||
importName: "__extends",
|
||||
scoped: false,
|
||||
priority: 0,
|
||||
text: `
|
||||
|
@ -4383,6 +4384,7 @@ namespace ts {
|
|||
|
||||
export const templateObjectHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:makeTemplateObject",
|
||||
importName: "__makeTemplateObject",
|
||||
scoped: false,
|
||||
priority: 0,
|
||||
text: `
|
||||
|
|
|
@ -771,6 +771,7 @@ namespace ts {
|
|||
|
||||
export const awaiterHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:awaiter",
|
||||
importName: "__awaiter",
|
||||
scoped: false,
|
||||
priority: 5,
|
||||
text: `
|
||||
|
@ -802,7 +803,7 @@ namespace ts {
|
|||
(generatorFunc.emitNode || (generatorFunc.emitNode = {} as EmitNode)).flags |= EmitFlags.AsyncFunctionBody | EmitFlags.ReuseTempVariableScope;
|
||||
|
||||
return createCall(
|
||||
getHelperName("__awaiter"),
|
||||
getUnscopedHelperName("__awaiter"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
|
|
|
@ -995,6 +995,7 @@ namespace ts {
|
|||
|
||||
export const assignHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:assign",
|
||||
importName: "__assign",
|
||||
scoped: false,
|
||||
priority: 1,
|
||||
text: `
|
||||
|
@ -1019,7 +1020,7 @@ namespace ts {
|
|||
}
|
||||
context.requestEmitHelper(assignHelper);
|
||||
return createCall(
|
||||
getHelperName("__assign"),
|
||||
getUnscopedHelperName("__assign"),
|
||||
/*typeArguments*/ undefined,
|
||||
attributesSegments
|
||||
);
|
||||
|
@ -1027,6 +1028,7 @@ namespace ts {
|
|||
|
||||
export const awaitHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:await",
|
||||
importName: "__await",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }`
|
||||
|
@ -1034,11 +1036,12 @@ namespace ts {
|
|||
|
||||
function createAwaitHelper(context: TransformationContext, expression: Expression) {
|
||||
context.requestEmitHelper(awaitHelper);
|
||||
return createCall(getHelperName("__await"), /*typeArguments*/ undefined, [expression]);
|
||||
return createCall(getUnscopedHelperName("__await"), /*typeArguments*/ undefined, [expression]);
|
||||
}
|
||||
|
||||
export const asyncGeneratorHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:asyncGenerator",
|
||||
importName: "__asyncGenerator",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
||||
|
@ -1062,7 +1065,7 @@ namespace ts {
|
|||
(generatorFunc.emitNode || (generatorFunc.emitNode = {} as EmitNode)).flags |= EmitFlags.AsyncFunctionBody;
|
||||
|
||||
return createCall(
|
||||
getHelperName("__asyncGenerator"),
|
||||
getUnscopedHelperName("__asyncGenerator"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
|
@ -1074,6 +1077,7 @@ namespace ts {
|
|||
|
||||
export const asyncDelegator: UnscopedEmitHelper = {
|
||||
name: "typescript:asyncDelegator",
|
||||
importName: "__asyncDelegator",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
|
@ -1088,7 +1092,7 @@ namespace ts {
|
|||
context.requestEmitHelper(asyncDelegator);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__asyncDelegator"),
|
||||
getUnscopedHelperName("__asyncDelegator"),
|
||||
/*typeArguments*/ undefined,
|
||||
[expression]
|
||||
),
|
||||
|
@ -1098,6 +1102,7 @@ namespace ts {
|
|||
|
||||
export const asyncValues: UnscopedEmitHelper = {
|
||||
name: "typescript:asyncValues",
|
||||
importName: "__asyncValues",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
||||
|
@ -1113,7 +1118,7 @@ namespace ts {
|
|||
context.requestEmitHelper(asyncValues);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__asyncValues"),
|
||||
getUnscopedHelperName("__asyncValues"),
|
||||
/*typeArguments*/ undefined,
|
||||
[expression]
|
||||
),
|
||||
|
|
|
@ -3176,7 +3176,7 @@ namespace ts {
|
|||
function createGeneratorHelper(context: TransformationContext, body: FunctionExpression) {
|
||||
context.requestEmitHelper(generatorHelper);
|
||||
return createCall(
|
||||
getHelperName("__generator"),
|
||||
getUnscopedHelperName("__generator"),
|
||||
/*typeArguments*/ undefined,
|
||||
[createThis(), body]);
|
||||
}
|
||||
|
@ -3242,6 +3242,7 @@ namespace ts {
|
|||
// For examples of how these are used, see the comments in ./transformers/generators.ts
|
||||
export const generatorHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:generator",
|
||||
importName: "__generator",
|
||||
scoped: false,
|
||||
priority: 6,
|
||||
text: `
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace ts {
|
|||
context.enableEmitNotification(SyntaxKind.SourceFile);
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
|
||||
let currentSourceFile: SourceFile | undefined;
|
||||
let helperNameSubstitutions: Map<Identifier> | undefined;
|
||||
return chainBundle(transformSourceFile);
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
|
@ -18,18 +18,11 @@ namespace ts {
|
|||
}
|
||||
|
||||
if (isExternalModule(node) || compilerOptions.isolatedModules) {
|
||||
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions);
|
||||
if (externalHelpersModuleName) {
|
||||
const externalHelpersImportDeclaration = createExternalHelpersImportDeclarationIfNeeded(node, compilerOptions);
|
||||
if (externalHelpersImportDeclaration) {
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologue(statements, node.statements);
|
||||
const tslibImport = createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
|
||||
createLiteral(externalHelpersModuleNameText)
|
||||
);
|
||||
addEmitFlags(tslibImport, EmitFlags.NeverApplyImportHelper);
|
||||
append(statements, tslibImport);
|
||||
append(statements, externalHelpersImportDeclaration);
|
||||
|
||||
addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset));
|
||||
return updateSourceFileNode(
|
||||
|
@ -74,9 +67,9 @@ namespace ts {
|
|||
*/
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
if (isSourceFile(node)) {
|
||||
currentSourceFile = node;
|
||||
helperNameSubstitutions = createMap<Identifier>();
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
currentSourceFile = undefined;
|
||||
helperNameSubstitutions = undefined;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
|
@ -95,21 +88,20 @@ namespace ts {
|
|||
*/
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (isIdentifier(node) && hint === EmitHint.Expression) {
|
||||
return substituteExpressionIdentifier(node);
|
||||
if (helperNameSubstitutions && isIdentifier(node) && getEmitFlags(node) & EmitFlags.HelperName) {
|
||||
return substituteHelperName(node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteExpressionIdentifier(node: Identifier): Expression {
|
||||
if (getEmitFlags(node) & EmitFlags.HelperName) {
|
||||
const externalHelpersModuleName = getExternalHelpersModuleName(currentSourceFile!);
|
||||
if (externalHelpersModuleName) {
|
||||
return createPropertyAccess(externalHelpersModuleName, node);
|
||||
}
|
||||
function substituteHelperName(node: Identifier): Expression {
|
||||
const name = idText(node);
|
||||
let substitution = helperNameSubstitutions!.get(name);
|
||||
if (!substitution) {
|
||||
helperNameSubstitutions!.set(name, substitution = createFileLevelUniqueName(name));
|
||||
}
|
||||
return node;
|
||||
return substitution;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -698,7 +698,7 @@ namespace ts {
|
|||
const promise = createNew(createIdentifier("Promise"), /*typeArguments*/ undefined, [func]);
|
||||
if (compilerOptions.esModuleInterop) {
|
||||
context.requestEmitHelper(importStarHelper);
|
||||
return createCall(createPropertyAccess(promise, createIdentifier("then")), /*typeArguments*/ undefined, [getHelperName("__importStar")]);
|
||||
return createCall(createPropertyAccess(promise, createIdentifier("then")), /*typeArguments*/ undefined, [getUnscopedHelperName("__importStar")]);
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
@ -713,7 +713,7 @@ namespace ts {
|
|||
let requireCall = createCall(createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []);
|
||||
if (compilerOptions.esModuleInterop) {
|
||||
context.requestEmitHelper(importStarHelper);
|
||||
requireCall = createCall(getHelperName("__importStar"), /*typeArguments*/ undefined, [requireCall]);
|
||||
requireCall = createCall(getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [requireCall]);
|
||||
}
|
||||
|
||||
let func: FunctionExpression | ArrowFunction;
|
||||
|
@ -753,11 +753,11 @@ namespace ts {
|
|||
}
|
||||
if (getImportNeedsImportStarHelper(node)) {
|
||||
context.requestEmitHelper(importStarHelper);
|
||||
return createCall(getHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]);
|
||||
return createCall(getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]);
|
||||
}
|
||||
if (getImportNeedsImportDefaultHelper(node)) {
|
||||
context.requestEmitHelper(importDefaultHelper);
|
||||
return createCall(getHelperName("__importDefault"), /*typeArguments*/ undefined, [innerExpr]);
|
||||
return createCall(getUnscopedHelperName("__importDefault"), /*typeArguments*/ undefined, [innerExpr]);
|
||||
}
|
||||
return innerExpr;
|
||||
}
|
||||
|
@ -1793,7 +1793,7 @@ namespace ts {
|
|||
function createExportStarHelper(context: TransformationContext, module: Expression) {
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
return compilerOptions.importHelpers
|
||||
? createCall(getHelperName("__exportStar"), /*typeArguments*/ undefined, [module, createIdentifier("exports")])
|
||||
? createCall(getUnscopedHelperName("__exportStar"), /*typeArguments*/ undefined, [module, createIdentifier("exports")])
|
||||
: createCall(createIdentifier("__export"), /*typeArguments*/ undefined, [module]);
|
||||
}
|
||||
|
||||
|
@ -1808,6 +1808,7 @@ namespace ts {
|
|||
// emit helper for `import * as Name from "foo"`
|
||||
export const importStarHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:commonjsimportstar",
|
||||
importName: "__importStar",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
|
@ -1822,6 +1823,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||
// emit helper for `import Name from "foo"`
|
||||
export const importDefaultHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:commonjsimportdefault",
|
||||
importName: "__importDefault",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
|
|
|
@ -3282,7 +3282,7 @@ namespace ts {
|
|||
context.requestEmitHelper(decorateHelper);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__decorate"),
|
||||
getUnscopedHelperName("__decorate"),
|
||||
/*typeArguments*/ undefined,
|
||||
argumentsArray
|
||||
),
|
||||
|
@ -3292,6 +3292,7 @@ namespace ts {
|
|||
|
||||
export const decorateHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:decorate",
|
||||
importName: "__decorate",
|
||||
scoped: false,
|
||||
priority: 2,
|
||||
text: `
|
||||
|
@ -3306,7 +3307,7 @@ namespace ts {
|
|||
function createMetadataHelper(context: TransformationContext, metadataKey: string, metadataValue: Expression) {
|
||||
context.requestEmitHelper(metadataHelper);
|
||||
return createCall(
|
||||
getHelperName("__metadata"),
|
||||
getUnscopedHelperName("__metadata"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createLiteral(metadataKey),
|
||||
|
@ -3317,6 +3318,7 @@ namespace ts {
|
|||
|
||||
export const metadataHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:metadata",
|
||||
importName: "__metadata",
|
||||
scoped: false,
|
||||
priority: 3,
|
||||
text: `
|
||||
|
@ -3329,7 +3331,7 @@ namespace ts {
|
|||
context.requestEmitHelper(paramHelper);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__param"),
|
||||
getUnscopedHelperName("__param"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createLiteral(parameterOffset),
|
||||
|
@ -3342,6 +3344,7 @@ namespace ts {
|
|||
|
||||
export const paramHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:param",
|
||||
importName: "__param",
|
||||
scoped: false,
|
||||
priority: 4,
|
||||
text: `
|
||||
|
|
|
@ -70,7 +70,8 @@ namespace ts {
|
|||
let hasExportDefault = false;
|
||||
let exportEquals: ExportAssignment | undefined;
|
||||
let hasExportStarsToExportValues = false;
|
||||
let hasImportStarOrImportDefault = false;
|
||||
let hasImportStar = false;
|
||||
let hasImportDefault = false;
|
||||
|
||||
for (const node of sourceFile.statements) {
|
||||
switch (node.kind) {
|
||||
|
@ -80,7 +81,12 @@ namespace ts {
|
|||
// import * as x from "mod"
|
||||
// import { x, y } from "mod"
|
||||
externalImports.push(<ImportDeclaration>node);
|
||||
hasImportStarOrImportDefault = hasImportStarOrImportDefault || getImportNeedsImportStarHelper(<ImportDeclaration>node) || getImportNeedsImportDefaultHelper(<ImportDeclaration>node);
|
||||
if (!hasImportStar && getImportNeedsImportStarHelper(<ImportDeclaration>node)) {
|
||||
hasImportStar = true;
|
||||
}
|
||||
if (!hasImportDefault && getImportNeedsImportDefaultHelper(<ImportDeclaration>node)) {
|
||||
hasImportDefault = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
|
@ -183,15 +189,8 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStarOrImportDefault);
|
||||
const externalHelpersImportDeclaration = externalHelpersModuleName && createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
|
||||
createLiteral(externalHelpersModuleNameText));
|
||||
|
||||
const externalHelpersImportDeclaration = createExternalHelpersImportDeclarationIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar, hasImportDefault);
|
||||
if (externalHelpersImportDeclaration) {
|
||||
addEmitFlags(externalHelpersImportDeclaration, EmitFlags.NeverApplyImportHelper);
|
||||
externalImports.unshift(externalHelpersImportDeclaration);
|
||||
}
|
||||
|
||||
|
|
|
@ -4760,6 +4760,10 @@ namespace ts {
|
|||
AMD = 2,
|
||||
UMD = 3,
|
||||
System = 4,
|
||||
|
||||
// NOTE: ES module kinds should be contiguous to more easily check whether a module kind is *any* ES module kind.
|
||||
// Non-ES module kinds should not come between ES2015 (the earliest ES module kind) and ESNext (the last ES
|
||||
// module kind).
|
||||
ES2015 = 5,
|
||||
ESNext = 99
|
||||
}
|
||||
|
@ -5289,6 +5293,7 @@ namespace ts {
|
|||
tokenSourceMapRanges?: (SourceMapRange | undefined)[]; // The text range to use when emitting source mappings for tokens
|
||||
constantValue?: string | number; // The constant value of an expression
|
||||
externalHelpersModuleName?: Identifier; // The local name for an imported helpers module
|
||||
externalHelpers?: boolean;
|
||||
helpers?: EmitHelper[]; // Emit helpers for the node
|
||||
startsOnNewLine?: boolean; // If the node should begin on a new line
|
||||
}
|
||||
|
@ -5310,7 +5315,7 @@ namespace ts {
|
|||
NoTrailingComments = 1 << 10, // Do not emit trailing comments for this node.
|
||||
NoComments = NoLeadingComments | NoTrailingComments, // Do not emit comments for this node.
|
||||
NoNestedComments = 1 << 11,
|
||||
HelperName = 1 << 12,
|
||||
HelperName = 1 << 12, // The Identifier refers to an *unscoped* emit helper (one that is emitted at the top of the file)
|
||||
ExportName = 1 << 13, // Ensure an export prefix is added for an identifier that points to an exported declaration with a local name (see SymbolFlags.ExportHasLocal).
|
||||
LocalName = 1 << 14, // Ensure an export prefix is not added for an identifier that points to an exported declaration.
|
||||
InternalName = 1 << 15, // The name is internal to an ES5 class body function.
|
||||
|
@ -5336,6 +5341,8 @@ namespace ts {
|
|||
|
||||
export interface UnscopedEmitHelper extends EmitHelper {
|
||||
readonly scoped: false; // Indicates whether the helper MUST be emitted in the current scope.
|
||||
/* @internal */
|
||||
readonly importName?: string; // The name of the helper to use when importing via `--importHelpers`.
|
||||
readonly text: string; // ES3-compatible raw script text, or a function yielding such a string
|
||||
}
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge
|
|||
|
||||
|
||||
//// [a.js]
|
||||
import * as tslib_1 from "tslib";
|
||||
import { __decorate } from "tslib";
|
||||
let A = class A {
|
||||
};
|
||||
A = tslib_1.__decorate([
|
||||
A = __decorate([
|
||||
dec
|
||||
], A);
|
||||
export { A };
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
//// [tests/cases/compiler/importHelpersWithLocalCollisions.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
declare var dec: any, __decorate: any;
|
||||
@dec export class A {
|
||||
|
||||
}
|
||||
|
||||
const o = { a: 1 };
|
||||
const y = { ...o };
|
||||
|
||||
//// [tslib.d.ts]
|
||||
export declare function __extends(d: Function, b: Function): void;
|
||||
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
|
||||
export declare function __param(paramIndex: number, decorator: Function): Function;
|
||||
export declare function __metadata(metadataKey: any, metadataValue: any): Function;
|
||||
export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any;
|
||||
|
||||
|
||||
//// [a.js]
|
||||
define(["require", "exports", "tslib"], function (require, exports, tslib_1) {
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
let A = class A {
|
||||
};
|
||||
A = tslib_1.__decorate([
|
||||
dec
|
||||
], A);
|
||||
exports.A = A;
|
||||
const o = { a: 1 };
|
||||
const y = Object.assign({}, o);
|
||||
});
|
|
@ -0,0 +1,31 @@
|
|||
//// [tests/cases/compiler/importHelpersWithLocalCollisions.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
declare var dec: any, __decorate: any;
|
||||
@dec export class A {
|
||||
|
||||
}
|
||||
|
||||
const o = { a: 1 };
|
||||
const y = { ...o };
|
||||
|
||||
//// [tslib.d.ts]
|
||||
export declare function __extends(d: Function, b: Function): void;
|
||||
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
|
||||
export declare function __param(paramIndex: number, decorator: Function): Function;
|
||||
export declare function __metadata(metadataKey: any, metadataValue: any): Function;
|
||||
export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any;
|
||||
|
||||
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tslib_1 = require("tslib");
|
||||
let A = class A {
|
||||
};
|
||||
A = tslib_1.__decorate([
|
||||
dec
|
||||
], A);
|
||||
exports.A = A;
|
||||
const o = { a: 1 };
|
||||
const y = Object.assign({}, o);
|
|
@ -0,0 +1,29 @@
|
|||
//// [tests/cases/compiler/importHelpersWithLocalCollisions.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
declare var dec: any, __decorate: any;
|
||||
@dec export class A {
|
||||
|
||||
}
|
||||
|
||||
const o = { a: 1 };
|
||||
const y = { ...o };
|
||||
|
||||
//// [tslib.d.ts]
|
||||
export declare function __extends(d: Function, b: Function): void;
|
||||
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
|
||||
export declare function __param(paramIndex: number, decorator: Function): Function;
|
||||
export declare function __metadata(metadataKey: any, metadataValue: any): Function;
|
||||
export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any;
|
||||
|
||||
|
||||
//// [a.js]
|
||||
import { __decorate as __decorate_1 } from "tslib";
|
||||
let A = class A {
|
||||
};
|
||||
A = __decorate_1([
|
||||
dec
|
||||
], A);
|
||||
export { A };
|
||||
const o = { a: 1 };
|
||||
const y = Object.assign({}, o);
|
|
@ -0,0 +1,42 @@
|
|||
//// [tests/cases/compiler/importHelpersWithLocalCollisions.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
declare var dec: any, __decorate: any;
|
||||
@dec export class A {
|
||||
|
||||
}
|
||||
|
||||
const o = { a: 1 };
|
||||
const y = { ...o };
|
||||
|
||||
//// [tslib.d.ts]
|
||||
export declare function __extends(d: Function, b: Function): void;
|
||||
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
|
||||
export declare function __param(paramIndex: number, decorator: Function): Function;
|
||||
export declare function __metadata(metadataKey: any, metadataValue: any): Function;
|
||||
export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any;
|
||||
|
||||
|
||||
//// [a.js]
|
||||
System.register(["tslib"], function (exports_1, context_1) {
|
||||
"use strict";
|
||||
var tslib_1, A, o, y;
|
||||
var __moduleName = context_1 && context_1.id;
|
||||
return {
|
||||
setters: [
|
||||
function (tslib_1_1) {
|
||||
tslib_1 = tslib_1_1;
|
||||
}
|
||||
],
|
||||
execute: function () {
|
||||
A = class A {
|
||||
};
|
||||
A = tslib_1.__decorate([
|
||||
dec
|
||||
], A);
|
||||
exports_1("A", A);
|
||||
o = { a: 1 };
|
||||
y = Object.assign({}, o);
|
||||
}
|
||||
};
|
||||
});
|
21
tests/cases/compiler/importHelpersWithLocalCollisions.ts
Normal file
21
tests/cases/compiler/importHelpersWithLocalCollisions.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
// @importHelpers: true
|
||||
// @target: es6
|
||||
// @module: commonjs, system, amd, es2015
|
||||
// @moduleResolution: classic
|
||||
// @experimentalDecorators: true
|
||||
// @filename: a.ts
|
||||
// @noTypesAndSymbols: true
|
||||
declare var dec: any, __decorate: any;
|
||||
@dec export class A {
|
||||
|
||||
}
|
||||
|
||||
const o = { a: 1 };
|
||||
const y = { ...o };
|
||||
|
||||
// @filename: tslib.d.ts
|
||||
export declare function __extends(d: Function, b: Function): void;
|
||||
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
|
||||
export declare function __param(paramIndex: number, decorator: Function): Function;
|
||||
export declare function __metadata(metadataKey: any, metadataValue: any): Function;
|
||||
export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any;
|
Loading…
Reference in a new issue