mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge pull request #23956 from Kingwl/emit-var-at-top
emit temporary vars at the top of the scope
This commit is contained in:
@@ -951,6 +951,21 @@ namespace ts {
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a range of value to begin of an array, returning the array.
|
||||
*
|
||||
* @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
|
||||
* is created if `value` was appended.
|
||||
* @param from The values to append to the array. If `from` is `undefined`, nothing is
|
||||
* appended. If an element of `from` is `undefined`, that element is not appended.
|
||||
*/
|
||||
export function prependRange<T>(to: T[], from: ReadonlyArray<T> | undefined): T[] | undefined {
|
||||
if (from === undefined || from.length === 0) return to;
|
||||
if (to === undefined) return from.slice();
|
||||
to.unshift(...from);
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the value was added.
|
||||
*/
|
||||
|
||||
@@ -529,7 +529,7 @@ namespace ts {
|
||||
createVariableStatement(/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(taggedTemplateStringDeclarations)));
|
||||
}
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
prependRange(statements, endLexicalEnvironment());
|
||||
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
|
||||
return updateSourceFileNode(
|
||||
node,
|
||||
@@ -836,7 +836,7 @@ namespace ts {
|
||||
setEmitFlags(statement, EmitFlags.NoComments | EmitFlags.NoTokenSourceMaps);
|
||||
statements.push(statement);
|
||||
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
prependRange(statements, endLexicalEnvironment());
|
||||
|
||||
const block = createBlock(setTextRange(createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true);
|
||||
setEmitFlags(block, EmitFlags.NoComments);
|
||||
@@ -979,7 +979,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
prependRange(statements, endLexicalEnvironment());
|
||||
|
||||
if (constructor) {
|
||||
prependCaptureNewTargetIfNeeded(statements, constructor, /*copyOnWrite*/ false);
|
||||
@@ -1894,7 +1894,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const lexicalEnvironment = context.endLexicalEnvironment();
|
||||
addRange(statements, lexicalEnvironment);
|
||||
prependRange(statements, lexicalEnvironment);
|
||||
|
||||
prependCaptureNewTargetIfNeeded(statements, node, /*copyOnWrite*/ false);
|
||||
|
||||
@@ -2712,7 +2712,7 @@ namespace ts {
|
||||
if (loopOutParameters.length) {
|
||||
copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements);
|
||||
}
|
||||
addRange(statements, lexicalEnvironment);
|
||||
prependRange(statements, lexicalEnvironment);
|
||||
loopBody = createBlock(statements, /*multiline*/ true);
|
||||
}
|
||||
|
||||
@@ -3309,10 +3309,12 @@ namespace ts {
|
||||
// expression, but we will restore them later to preserve comments and source maps.
|
||||
const body = cast(cast(skipOuterExpressions(node.expression), isArrowFunction).body, isBlock);
|
||||
|
||||
// The class statements are the statements generated by visiting the first statement of the
|
||||
// The class statements are the statements generated by visiting the first statement with initializer of the
|
||||
// body (1), while all other statements are added to remainingStatements (2)
|
||||
const classStatements = visitNodes(body.statements, visitor, isStatement, 0, 1);
|
||||
const remainingStatements = visitNodes(body.statements, visitor, isStatement, 1, body.statements.length - 1);
|
||||
const isVariableStatementWithInitializer = (stmt: Statement) => isVariableStatement(stmt) && !!firstOrUndefined(stmt.declarationList.declarations).initializer;
|
||||
const bodyStatements = visitNodes(body.statements, visitor, isStatement);
|
||||
const classStatements = filter(bodyStatements, isVariableStatementWithInitializer);
|
||||
const remainingStatements = filter(bodyStatements, stmt => !isVariableStatementWithInitializer(stmt));
|
||||
const varStatement = cast(firstOrUndefined(classStatements), isVariableStatement);
|
||||
|
||||
// We know there is only one variable declaration here as we verified this in an
|
||||
@@ -3324,6 +3326,7 @@ namespace ts {
|
||||
// we see as an assignment, for example:
|
||||
//
|
||||
// (function () {
|
||||
// var C_1;
|
||||
// var C = C_1 = (function () {
|
||||
// function C() {
|
||||
// }
|
||||
@@ -3332,7 +3335,6 @@ namespace ts {
|
||||
// }());
|
||||
// C = C_1 = __decorate([dec], C);
|
||||
// return C;
|
||||
// var C_1;
|
||||
// }())
|
||||
//
|
||||
const aliasAssignment = tryCast(initializer, isAssignmentExpression);
|
||||
|
||||
@@ -412,7 +412,7 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
prependRange(statements, endLexicalEnvironment());
|
||||
|
||||
const block = createBlock(statements, /*multiLine*/ true);
|
||||
setTextRange(block, node.body);
|
||||
@@ -443,7 +443,7 @@ namespace ts {
|
||||
const declarations = endLexicalEnvironment();
|
||||
if (some(declarations)) {
|
||||
const block = convertToFunctionBody(expression);
|
||||
result = updateBlock(block, setTextRange(createNodeArray(concatenate(block.statements, declarations)), block.statements));
|
||||
result = updateBlock(block, setTextRange(createNodeArray(concatenate(declarations, block.statements)), block.statements));
|
||||
}
|
||||
else {
|
||||
result = expression;
|
||||
|
||||
@@ -663,7 +663,7 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
prependRange(statements, endLexicalEnvironment());
|
||||
const block = updateBlock(node.body, statements);
|
||||
|
||||
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
|
||||
@@ -692,11 +692,11 @@ namespace ts {
|
||||
statementOffset = addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
|
||||
}
|
||||
addRange(statements, appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node));
|
||||
const trailingStatements = endLexicalEnvironment();
|
||||
if (statementOffset > 0 || some(statements) || some(trailingStatements)) {
|
||||
const leadingStatements = endLexicalEnvironment();
|
||||
if (statementOffset > 0 || some(statements) || some(leadingStatements)) {
|
||||
const block = convertToFunctionBody(body, /*multiLine*/ true);
|
||||
prependRange(statements, leadingStatements);
|
||||
addRange(statements, block.statements.slice(statementOffset));
|
||||
addRange(statements, trailingStatements);
|
||||
return updateBlock(block, setTextRange(createNodeArray(statements), block.statements));
|
||||
}
|
||||
return body;
|
||||
|
||||
@@ -586,7 +586,7 @@ namespace ts {
|
||||
transformAndEmitStatements(body.statements, statementOffset);
|
||||
|
||||
const buildResult = build();
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
prependRange(statements, endLexicalEnvironment());
|
||||
statements.push(createReturn(buildResult));
|
||||
|
||||
// Restore previous generator state
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace ts {
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement));
|
||||
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
|
||||
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
prependRange(statements, endLexicalEnvironment());
|
||||
|
||||
const updated = updateSourceFileNode(node, setTextRange(createNodeArray(statements), node.statements));
|
||||
if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
|
||||
@@ -426,7 +426,7 @@ namespace ts {
|
||||
|
||||
// End the lexical environment for the module body
|
||||
// and merge any new lexical declarations.
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
prependRange(statements, endLexicalEnvironment());
|
||||
|
||||
const body = createBlock(statements, /*multiLine*/ true);
|
||||
if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
|
||||
|
||||
@@ -257,7 +257,7 @@ namespace ts {
|
||||
// We emit hoisted variables early to align roughly with our previous emit output.
|
||||
// Two key differences in this approach are:
|
||||
// - Temporary variables will appear at the top rather than at the bottom of the file
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
prependRange(statements, endLexicalEnvironment());
|
||||
|
||||
const exportStarFunction = addExportStarIfNeeded(statements);
|
||||
const moduleObject = createObjectLiteral([
|
||||
|
||||
@@ -669,7 +669,7 @@ namespace ts {
|
||||
setEmitFlags(statement, EmitFlags.NoComments | EmitFlags.NoTokenSourceMaps);
|
||||
statements.push(statement);
|
||||
|
||||
addRange(statements, context.endLexicalEnvironment());
|
||||
prependRange(statements, context.endLexicalEnvironment());
|
||||
|
||||
const iife = createImmediatelyInvokedArrowFunction(statements);
|
||||
setEmitFlags(iife, EmitFlags.TypeScriptClassWrapper);
|
||||
@@ -2685,8 +2685,9 @@ namespace ts {
|
||||
|
||||
const statements: Statement[] = [];
|
||||
startLexicalEnvironment();
|
||||
addRange(statements, map(node.members, transformEnumMember));
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
const members = map(node.members, transformEnumMember);
|
||||
prependRange(statements, endLexicalEnvironment());
|
||||
addRange(statements, members);
|
||||
|
||||
currentNamespaceContainerName = savedCurrentNamespaceLocalName;
|
||||
return createBlock(
|
||||
@@ -3000,7 +3001,7 @@ namespace ts {
|
||||
statementsLocation = moveRangePos(moduleBlock.statements, -1);
|
||||
}
|
||||
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
prependRange(statements, endLexicalEnvironment());
|
||||
currentNamespaceContainerName = savedCurrentNamespaceContainerName;
|
||||
currentNamespace = savedCurrentNamespace;
|
||||
currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
|
||||
|
||||
@@ -145,7 +145,7 @@ namespace ts {
|
||||
statements = setTextRange(createNodeArray([createStatement(createLiteral("use strict")), ...statements]), statements);
|
||||
}
|
||||
const declarations = context.endLexicalEnvironment();
|
||||
return setTextRange(createNodeArray(concatenate(statements, declarations)), statements);
|
||||
return setTextRange(createNodeArray(concatenate(declarations, statements)), statements);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1468,8 +1468,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
return isNodeArray(statements)
|
||||
? setTextRange(createNodeArray(concatenate(statements, declarations)), statements)
|
||||
: addRange(statements, declarations);
|
||||
? setTextRange(createNodeArray(concatenate(declarations, statements)), statements)
|
||||
: prependRange(statements, declarations);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user