Emit unique prologue directives at the top of bundle output file

This commit is contained in:
Kanchalai Tanglertsampan
2017-02-24 11:37:34 -08:00
parent d219f8afc5
commit 097bc77d0b

View File

@@ -212,6 +212,7 @@ namespace ts {
} = comments;
let currentSourceFile: SourceFile;
let statementOffset: number; // We cache the index of first non prologue so we don't have to recalculate it multiple times like in emitBodyInDirect
let nodeIdToGeneratedName: string[]; // Map of generated names for specific nodes.
let autoGeneratedIdToGeneratedName: string[]; // Map of generated names for temp and loop variables.
let generatedNames: Map<string>; // Set of names generated by the NameGenerator.
@@ -275,6 +276,7 @@ namespace ts {
const previousWriter = writer;
setWriter(output);
emitShebangIfNeeded(bundle);
emitPrologueDirectivesIfNeeded(bundle);
emitHelpersIndirect(bundle);
for (const sourceFile of bundle.sourceFiles) {
print(EmitHint.SourceFile, sourceFile, sourceFile);
@@ -287,6 +289,7 @@ namespace ts {
const previousWriter = writer;
setWriter(output);
emitShebangIfNeeded(sourceFile);
emitPrologueDirectivesIfNeeded(sourceFile);
print(EmitHint.SourceFile, sourceFile, sourceFile);
reset();
writer = previousWriter;
@@ -309,6 +312,7 @@ namespace ts {
function setSourceFile(sourceFile: SourceFile) {
currentSourceFile = sourceFile;
statementOffset = getIndexOfFirstNonPrologueDirectives(sourceFile.statements);
comments.setSourceFile(sourceFile);
if (onSetSourceFile) {
onSetSourceFile(sourceFile);
@@ -733,7 +737,11 @@ namespace ts {
}
function emitBodyIndirect(node: Node, elements: NodeArray<Node>, emitCallback: (node: Node) => void): void {
if (emitBodyWithDetachedComments) {
// If the node is a sourceFile and it has prologueDirective (statmentOffSet is not zero) that is synthesize
// We will need to emit detached comment here because emitPrologueDirective will not emit comments of such prologue directive
const shouldEmitDetachedComment = node.kind !== SyntaxKind.SourceFile ? true :
statementOffset === 0 || nodeIsSynthesized((node as SourceFile).statements[statementOffset - 1]);
if (emitBodyWithDetachedComments && shouldEmitDetachedComment) {
emitBodyWithDetachedComments(node, elements, emitCallback);
}
else {
@@ -2058,7 +2066,6 @@ namespace ts {
function emitSourceFileWorker(node: SourceFile) {
const statements = node.statements;
const statementOffset = emitPrologueDirectives(statements);
pushNameGenerationScope();
emitHelpersIndirect(node);
emitList(node, statements, ListFormat.MultiLine, statementOffset);
@@ -2075,13 +2082,20 @@ namespace ts {
* Emits any prologue directives at the start of a Statement list, returning the
* number of prologue directives written to the output.
*/
function emitPrologueDirectives(statements: Node[], startWithNewLine?: boolean): number {
function emitPrologueDirectives(statements: Node[], startWithNewLine?: boolean, seenPrologueDirectives?: Map<String>): number {
for (let i = 0; i < statements.length; i++) {
if (isPrologueDirective(statements[i])) {
if (startWithNewLine || i > 0) {
writeLine();
const statement = statements[i];
if (isPrologueDirective(statement)) {
const shouldEmitPrologueDirective = seenPrologueDirectives ? !seenPrologueDirectives.has(statement.expression.text) : true;
if (shouldEmitPrologueDirective) {
if (startWithNewLine || i > 0) {
writeLine();
}
emit(statement);
if (seenPrologueDirectives) {
seenPrologueDirectives.set(statement.expression.text, statement.expression.text);
}
}
emit(statements[i]);
}
else {
// return index of the first non prologue directive
@@ -2092,9 +2106,19 @@ namespace ts {
return statements.length;
}
//
// Helpers
//
function emitPrologueDirectivesIfNeeded(sourceFileOrBundle: Bundle | SourceFile) {
if (sourceFileOrBundle.kind === SyntaxKind.SourceFile) {
setSourceFile(sourceFileOrBundle as SourceFile);
emitPrologueDirectives((sourceFileOrBundle as SourceFile).statements);
}
else {
const seenProgolueDirectives = createMap<String>();
for (const sourceFile of (sourceFileOrBundle as Bundle).sourceFiles) {
setSourceFile(sourceFile);
emitPrologueDirectives(sourceFile.statements, /*startWithNewLine*/ true, seenProgolueDirectives);
}
}
}
function emitShebangIfNeeded(sourceFileOrBundle: Bundle | SourceFile) {
if (sourceFileOrBundle.kind === SyntaxKind.SourceFile) {
@@ -2119,6 +2143,19 @@ namespace ts {
}
}
//
// Helpers
//
function getIndexOfFirstNonPrologueDirectives(statements: Statement[]): number {
for (let i = 0; i < statements.length; i++) {
if (!isPrologueDirective(statements[i])) {
return i;
}
}
return statements.length;
}
function emitModifiers(node: Node, modifiers: NodeArray<Modifier>) {
if (modifiers && modifiers.length) {
emitList(node, modifiers, ListFormat.Modifiers);