Split addPrologue into string + custom directives

The original function is now named addPrologue.
There are then three places than need to call the two split functions
separately.
This commit is contained in:
Nathan Shively-Sanders
2017-04-13 10:29:32 -07:00
parent 24852b6be4
commit 5496096ee3
9 changed files with 59 additions and 19 deletions

View File

@@ -3058,14 +3058,26 @@ namespace ts {
* @param ensureUseStrict: boolean determining whether the function need to add prologue-directives
* @param visitor: Optional callback used to visit any custom prologue directives.
*/
export function addPrologueDirectives(target: Statement[], source: Statement[], ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult<Node>): number {
export function addPrologue(target: Statement[], source: Statement[], ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult<Node>): number {
const offset = addPrologueDirectives(target, source, ensureUseStrict);
return addCustomPrologue(target, source, offset, visitor);
}
/**
* Add just the standard (string-expression) prologue-directives into target statement-array.
* The function needs to be called during each transformation step.
* This function needs to be called whenever we transform the statement
* list of a source file, namespace, or function-like body.
*/
export function addPrologueDirectives(target: Statement[], source: Statement[], ensureUseStrict?: boolean): number {
Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array");
let foundUseStrict = false;
let statementOffset = 0;
const numStatements = source.length;
while (statementOffset < numStatements) {
const statement = source[statementOffset];
if (isPrologueDirective(statement)) {
if (isUseStrictPrologue(statement as ExpressionStatement)) {
if (isUseStrictPrologue(statement)) {
foundUseStrict = true;
}
target.push(statement);
@@ -3078,6 +3090,17 @@ namespace ts {
if (ensureUseStrict && !foundUseStrict) {
target.push(startOnNewLine(createStatement(createLiteral("use strict"))));
}
return statementOffset;
}
/**
* Add just the custom prologue-directives into target statement-array.
* The function needs to be called during each transformation step.
* This function needs to be called whenever we transform the statement
* list of a source file, namespace, or function-like body.
*/
export function addCustomPrologue(target: Statement[], source: Statement[], statementOffset: number, visitor?: (node: Node) => VisitResult<Node>): number {
const numStatements = source.length;
while (statementOffset < numStatements) {
const statement = source[statementOffset];
if (getEmitFlags(statement) & EmitFlags.CustomPrologue) {

View File

@@ -515,8 +515,9 @@ namespace ts {
const ancestorFacts = enterSubtree(HierarchyFacts.SourceFileExcludes, HierarchyFacts.SourceFileIncludes);
const statements: Statement[] = [];
startLexicalEnvironment();
let statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ false);
addCaptureThisForNodeIfNeeded(statements, node);
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ false, visitor);
statementOffset = addCustomPrologue(statements, node.statements, statementOffset, visitor);
addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset));
addRange(statements, endLexicalEnvironment());
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
@@ -923,13 +924,16 @@ namespace ts {
// The assumption is that no prior step in the pipeline has added any prologue directives.
statementOffset = 0;
}
else if (constructor) {
statementOffset = addPrologueDirectives(statements, constructor.body.statements, /*ensureUseStrict*/ false);
}
if (constructor) {
addDefaultValueAssignmentsIfNeeded(statements, constructor);
addRestParameterIfNeeded(statements, constructor, hasSynthesizedSuper);
if (!hasSynthesizedSuper) {
// If no super call has been synthesized, try to emit all potential prologue directives.
statementOffset = addPrologueDirectives(statements, constructor.body.statements, /*ensureUseStrict*/ false, visitor);
// If no super call has been synthesized, emit custom prologue directives.
statementOffset = addCustomPrologue(statements, constructor.body.statements, statementOffset, visitor);
}
Debug.assert(statementOffset >= 0, "statementOffset not initialized correctly!");
@@ -1816,8 +1820,15 @@ namespace ts {
const statements: Statement[] = [];
const body = node.body;
let statementOffset: number;
resumeLexicalEnvironment();
if (isBlock(body)) {
// ensureUseStrict is false because no new prologue-directive should be added.
// addPrologueDirectives will put already-existing directives at the beginning of the target statement-array
statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false);
}
addCaptureThisForNodeIfNeeded(statements, node);
addDefaultValueAssignmentsIfNeeded(statements, node);
addRestParameterIfNeeded(statements, node, /*inConstructorWithSynthesizedSuper*/ false);
@@ -1828,9 +1839,8 @@ namespace ts {
}
if (isBlock(body)) {
// ensureUseStrict is false because no new prologue-directive should be added.
// addPrologueDirectives will simply put already-existing directives at the beginning of the target statement-array
const statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor);
// addCustomPrologue puts already-existing directives at the beginning of the target statement-array
statementOffset = addCustomPrologue(statements, body.statements, statementOffset, visitor);
statementsLocation = body.statements;
addRange(statements, visitNodes(body.statements, visitor, isStatement, statementOffset));

View File

@@ -222,7 +222,7 @@ namespace ts {
if (!isArrowFunction) {
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, (<Block>node.body).statements, /*ensureUseStrict*/ false, visitor);
const statementOffset = addPrologue(statements, (<Block>node.body).statements, /*ensureUseStrict*/ false, visitor);
statements.push(
createReturn(
createAwaiterHelper(

View File

@@ -618,7 +618,7 @@ namespace ts {
function transformAsyncGeneratorFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody {
resumeLexicalEnvironment();
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
const statementOffset = addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
appendObjectRestAssignmentsIfNeeded(statements, node);
statements.push(
@@ -663,12 +663,19 @@ namespace ts {
function transformFunctionBody(node: ArrowFunction): ConciseBody;
function transformFunctionBody(node: FunctionLikeDeclaration): ConciseBody {
resumeLexicalEnvironment();
const leadingStatements = appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node);
let statementOffset = 0;
const statements: Statement[] = [];
const body = visitNode(node.body, visitor, isConciseBody);
if (isBlock(body)) {
statementOffset = addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
}
addRange(statements, appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node));
const trailingStatements = endLexicalEnvironment();
if (some(leadingStatements) || some(trailingStatements)) {
if (statementOffset > 0 || some(statements) || some(trailingStatements)) {
const block = convertToFunctionBody(body, /*multiLine*/ true);
return updateBlock(block, setTextRange(createNodeArray(concatenate(concatenate(leadingStatements, block.statements), trailingStatements)), block.statements));
addRange(statements, block.statements.slice(statementOffset));
addRange(statements, trailingStatements);
return updateBlock(block, setTextRange(createNodeArray(statements), block.statements));
}
return body;
}

View File

@@ -587,7 +587,7 @@ namespace ts {
// Build the generator
resumeLexicalEnvironment();
const statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor);
const statementOffset = addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
transformAndEmitStatements(body.statements, statementOffset);

View File

@@ -24,7 +24,7 @@ namespace ts {
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions);
if (externalHelpersModuleName) {
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, node.statements);
const statementOffset = addPrologue(statements, node.statements);
append(statements,
createImportDeclaration(
/*decorators*/ undefined,

View File

@@ -90,7 +90,7 @@ namespace ts {
const statements: Statement[] = [];
const ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
const statementOffset = addPrologueDirectives(statements, node.statements, ensureUseStrict, sourceElementVisitor);
const statementOffset = addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
if (shouldEmitUnderscoreUnderscoreESModule()) {
append(statements, createUnderscoreUnderscoreESModule());
@@ -388,7 +388,7 @@ namespace ts {
startLexicalEnvironment();
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
const statementOffset = addPrologue(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
if (shouldEmitUnderscoreUnderscoreESModule()) {
append(statements, createUnderscoreUnderscoreESModule());

View File

@@ -228,7 +228,7 @@ namespace ts {
// Add any prologue directives.
const ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
const statementOffset = addPrologueDirectives(statements, node.statements, ensureUseStrict, sourceElementVisitor);
const statementOffset = addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
// var __moduleName = context_1 && context_1.id;
statements.push(

View File

@@ -954,7 +954,7 @@ namespace ts {
if (ctor.body) {
const statements = ctor.body.statements;
// add prologue directives to the list (if any)
const index = addPrologueDirectives(result, statements, /*ensureUseStrict*/ false, visitor);
const index = addPrologue(result, statements, /*ensureUseStrict*/ false, visitor);
if (index === statements.length) {
// list contains nothing but prologue directives (or empty) - exit
return index;