mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-11 02:15:10 -05:00
Handle emit helpers in --out scenario
This commit is contained in:
@@ -1136,16 +1136,16 @@ namespace ts {
|
||||
if (bundle && moduleKind === ModuleKind.None) {
|
||||
return;
|
||||
}
|
||||
|
||||
const numNodes = bundle ? bundle.sourceFiles.length : 1;
|
||||
const numPrepends = bundle ? bundle.prepends.length : 0;
|
||||
const numNodes = bundle ? bundle.sourceFiles.length + numPrepends : 1;
|
||||
for (let i = 0; i < numNodes; i++) {
|
||||
const currentNode = bundle ? bundle.sourceFiles[i] : node;
|
||||
const sourceFile = isSourceFile(currentNode) ? currentNode : currentSourceFile!;
|
||||
const shouldSkip = printerOptions.noEmitHelpers || getExternalHelpersModuleName(sourceFile) !== undefined;
|
||||
const shouldBundle = isSourceFile(currentNode) && !isOwnFileEmit;
|
||||
const helpers = getEmitHelpers(currentNode);
|
||||
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 shouldBundle = (isSourceFile(currentNode) || isUnparsedSource(currentNode)) && !isOwnFileEmit;
|
||||
const helpers = isUnparsedSource(currentNode) ? currentNode.helpers : getSortedEmitHelpers(currentNode);
|
||||
if (helpers) {
|
||||
for (const helper of stableSort(helpers, compareEmitHelpers)) {
|
||||
for (const helper of helpers) {
|
||||
if (!helper.scoped) {
|
||||
// Skip the helper if it can be skipped and the noEmitHelpers compiler
|
||||
// option is set, or if it can be imported and the importHelpers compiler
|
||||
@@ -1181,6 +1181,11 @@ namespace ts {
|
||||
return helpersEmitted;
|
||||
}
|
||||
|
||||
function getSortedEmitHelpers(node: Node) {
|
||||
const helpers = getEmitHelpers(node);
|
||||
return helpers && stableSort(helpers, compareEmitHelpers);
|
||||
}
|
||||
|
||||
//
|
||||
// Literals/Pseudo-literals
|
||||
//
|
||||
|
||||
@@ -2629,6 +2629,71 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
interface UnscopedEmitHelpersWithLines {
|
||||
helper: UnscopedEmitHelpers;
|
||||
lines: ReadonlyArray<string>;
|
||||
}
|
||||
|
||||
let allUnscopedEmitHelpers: ReadonlyArray<UnscopedEmitHelpersWithLines> | undefined;
|
||||
function getAllUnscopedEmitHelpers() {
|
||||
return allUnscopedEmitHelpers ||
|
||||
(allUnscopedEmitHelpers = [
|
||||
getUnscopedEmitHelperWithLines(valuesHelper),
|
||||
getUnscopedEmitHelperWithLines(readHelper),
|
||||
getUnscopedEmitHelperWithLines(spreadHelper),
|
||||
getUnscopedEmitHelperWithLines(restHelper),
|
||||
getUnscopedEmitHelperWithLines(decorateHelper),
|
||||
getUnscopedEmitHelperWithLines(metadataHelper),
|
||||
getUnscopedEmitHelperWithLines(paramHelper),
|
||||
getUnscopedEmitHelperWithLines(awaiterHelper),
|
||||
getUnscopedEmitHelperWithLines(assignHelper),
|
||||
getUnscopedEmitHelperWithLines(awaitHelper),
|
||||
getUnscopedEmitHelperWithLines(asyncGeneratorHelper),
|
||||
getUnscopedEmitHelperWithLines(asyncDelegator),
|
||||
getUnscopedEmitHelperWithLines(asyncValues),
|
||||
getUnscopedEmitHelperWithLines(extendsHelper),
|
||||
getUnscopedEmitHelperWithLines(templateObjectHelper),
|
||||
getUnscopedEmitHelperWithLines(generatorHelper),
|
||||
getUnscopedEmitHelperWithLines(importStarHelper),
|
||||
getUnscopedEmitHelperWithLines(importDefaultHelper)
|
||||
]);
|
||||
}
|
||||
|
||||
function getUnscopedEmitHelperWithLines(helper: UnscopedEmitHelpers): UnscopedEmitHelpersWithLines {
|
||||
const helperLines = helper.text.split(/\r\n?|\n/g);
|
||||
const indentation = guessIndentation(helperLines);
|
||||
const lines: string[] = [];
|
||||
for (const lineText of helperLines) {
|
||||
const line = indentation ? lineText.slice(indentation) : lineText;
|
||||
if (line.length) {
|
||||
lines.push(line);
|
||||
}
|
||||
}
|
||||
return { helper, lines };
|
||||
}
|
||||
|
||||
function tryGetUnscopedEmitHelper(text: string, pos: number) {
|
||||
const allHelpers = getAllUnscopedEmitHelpers();
|
||||
if (pos >= text.length) return undefined;
|
||||
for (const { helper, lines } of allHelpers) {
|
||||
let newPos = pos;
|
||||
for (const line of lines) {
|
||||
const startIndex = text.indexOf(line, newPos);
|
||||
if (startIndex !== newPos) {
|
||||
newPos = -1;
|
||||
break;
|
||||
}
|
||||
newPos = skipTrivia(text, newPos + line.length, /*stopAfterLineBreak*/ true);
|
||||
}
|
||||
|
||||
// Found match
|
||||
if (newPos !== -1) {
|
||||
return { helper, newPos };
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function createUnparsedSourceFile(text: string): UnparsedSource;
|
||||
export function createUnparsedSourceFile(inputFile: InputFiles, type: "js" | "dts"): UnparsedSource;
|
||||
export function createUnparsedSourceFile(text: string, mapPath: string | undefined, map: string | undefined): UnparsedSource;
|
||||
@@ -2649,7 +2714,11 @@ namespace ts {
|
||||
node.sourceMapText = map;
|
||||
}
|
||||
const text = node.text;
|
||||
|
||||
// Shebang
|
||||
let pos = isShebangTrivia(text, 0) ? skipTrivia(text, 0, /*stopAfterLineBreak*/ true) : 0;
|
||||
|
||||
// Prologue
|
||||
const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true, /*languageVariant*/ undefined, text, /*onError*/ undefined, pos);
|
||||
let prologues: UnparsedPrologue[] | undefined;
|
||||
while (scanner.scan() === SyntaxKind.StringLiteral) {
|
||||
@@ -2663,8 +2732,20 @@ namespace ts {
|
||||
prologue.text = prologueText;
|
||||
(prologues || (prologues = [])).push(prologue);
|
||||
}
|
||||
|
||||
// Helpers
|
||||
let helpers: UnscopedEmitHelpers[] | undefined;
|
||||
while (true) {
|
||||
const helperInfo = tryGetUnscopedEmitHelper(text, pos);
|
||||
if (!helperInfo) break;
|
||||
pos = helperInfo.newPos;
|
||||
(helpers || (helpers = [])).push(helperInfo.helper);
|
||||
}
|
||||
|
||||
// Rest of the text
|
||||
node.pos = pos;
|
||||
node.prologues = prologues || emptyArray;
|
||||
node.helpers = helpers;
|
||||
node.getLineAndCharacterOfPosition = pos => getLineAndCharacterOfPosition(node, pos);
|
||||
return node;
|
||||
}
|
||||
@@ -3390,7 +3471,7 @@ namespace ts {
|
||||
return setEmitFlags(createIdentifier(name), EmitFlags.HelperName | EmitFlags.AdviseOnEmitNode);
|
||||
}
|
||||
|
||||
const valuesHelper: EmitHelper = {
|
||||
export const valuesHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:values",
|
||||
scoped: false,
|
||||
text: `
|
||||
@@ -3418,7 +3499,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
const readHelper: EmitHelper = {
|
||||
export const readHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:read",
|
||||
scoped: false,
|
||||
text: `
|
||||
@@ -3454,7 +3535,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
const spreadHelper: EmitHelper = {
|
||||
export const spreadHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:spread",
|
||||
scoped: false,
|
||||
text: `
|
||||
|
||||
@@ -512,7 +512,7 @@ namespace ts {
|
||||
return name;
|
||||
}
|
||||
|
||||
const restHelper: EmitHelper = {
|
||||
export const restHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:rest",
|
||||
scoped: false,
|
||||
text: `
|
||||
|
||||
@@ -4383,7 +4383,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
const extendsHelper: EmitHelper = {
|
||||
export const extendsHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:extends",
|
||||
scoped: false,
|
||||
priority: 0,
|
||||
@@ -4404,7 +4404,7 @@ namespace ts {
|
||||
})();`
|
||||
};
|
||||
|
||||
const templateObjectHelper: EmitHelper = {
|
||||
export const templateObjectHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:makeTemplateObject",
|
||||
scoped: false,
|
||||
priority: 0,
|
||||
|
||||
@@ -750,7 +750,7 @@ namespace ts {
|
||||
NodeFlags.Const));
|
||||
}
|
||||
|
||||
const awaiterHelper: EmitHelper = {
|
||||
export const awaiterHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:awaiter",
|
||||
scoped: false,
|
||||
priority: 5,
|
||||
|
||||
@@ -929,7 +929,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const assignHelper: EmitHelper = {
|
||||
export const assignHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:assign",
|
||||
scoped: false,
|
||||
priority: 1,
|
||||
@@ -961,7 +961,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
const awaitHelper: EmitHelper = {
|
||||
export const awaitHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:await",
|
||||
scoped: false,
|
||||
text: `
|
||||
@@ -973,7 +973,7 @@ namespace ts {
|
||||
return createCall(getHelperName("__await"), /*typeArguments*/ undefined, [expression]);
|
||||
}
|
||||
|
||||
const asyncGeneratorHelper: EmitHelper = {
|
||||
export const asyncGeneratorHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:asyncGenerator",
|
||||
scoped: false,
|
||||
text: `
|
||||
@@ -1008,7 +1008,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
const asyncDelegator: EmitHelper = {
|
||||
export const asyncDelegator: UnscopedEmitHelpers = {
|
||||
name: "typescript:asyncDelegator",
|
||||
scoped: false,
|
||||
text: `
|
||||
@@ -1032,7 +1032,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
const asyncValues: EmitHelper = {
|
||||
export const asyncValues: UnscopedEmitHelpers = {
|
||||
name: "typescript:asyncValues",
|
||||
scoped: false,
|
||||
text: `
|
||||
|
||||
@@ -3240,7 +3240,7 @@ namespace ts {
|
||||
// entering a finally block.
|
||||
//
|
||||
// For examples of how these are used, see the comments in ./transformers/generators.ts
|
||||
const generatorHelper: EmitHelper = {
|
||||
export const generatorHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:generator",
|
||||
scoped: false,
|
||||
priority: 6,
|
||||
|
||||
@@ -1806,7 +1806,7 @@ namespace ts {
|
||||
};
|
||||
|
||||
// emit helper for `import * as Name from "foo"`
|
||||
const importStarHelper: EmitHelper = {
|
||||
export const importStarHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:commonjsimportstar",
|
||||
scoped: false,
|
||||
text: `
|
||||
@@ -1820,7 +1820,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
};
|
||||
|
||||
// emit helper for `import Name from "foo"`
|
||||
const importDefaultHelper: EmitHelper = {
|
||||
export const importDefaultHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:commonjsimportdefault",
|
||||
scoped: false,
|
||||
text: `
|
||||
|
||||
@@ -3675,7 +3675,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
const decorateHelper: EmitHelper = {
|
||||
export const decorateHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:decorate",
|
||||
scoped: false,
|
||||
priority: 2,
|
||||
@@ -3700,7 +3700,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
const metadataHelper: EmitHelper = {
|
||||
export const metadataHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:metadata",
|
||||
scoped: false,
|
||||
priority: 3,
|
||||
@@ -3725,7 +3725,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
const paramHelper: EmitHelper = {
|
||||
export const paramHelper: UnscopedEmitHelpers = {
|
||||
name: "typescript:param",
|
||||
scoped: false,
|
||||
priority: 4,
|
||||
|
||||
@@ -2777,6 +2777,7 @@ namespace ts {
|
||||
fileName?: string;
|
||||
text: string;
|
||||
prologues: ReadonlyArray<UnparsedPrologue>;
|
||||
helpers: ReadonlyArray<UnscopedEmitHelpers> | undefined;
|
||||
sourceMapPath?: string;
|
||||
sourceMapText?: string;
|
||||
/*@internal*/ parsedSourceMap?: RawSourceMap | false | undefined;
|
||||
@@ -5189,6 +5190,11 @@ namespace ts {
|
||||
readonly priority?: number; // Helpers with a higher priority are emitted earlier than other helpers on the node.
|
||||
}
|
||||
|
||||
export interface UnscopedEmitHelpers extends EmitHelper {
|
||||
readonly scoped: false; // Indicates whether the helper MUST be emitted in the current scope.
|
||||
readonly text: string; // ES3-compatible raw script text, or a function yielding such a string
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type UniqueNameHandler = (baseName: string, checkFn?: (name: string) => boolean, optimistic?: boolean) => string;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user