Consolidate destructuring code paths

This commit is contained in:
Ron Buckton 2016-11-14 10:40:26 -08:00
parent 8babde0b98
commit d5b9263433
25 changed files with 889 additions and 1396 deletions

View File

@ -570,6 +570,31 @@ namespace ts {
}
}
function bindEach(nodes: NodeArray<Node>) {
if (nodes === undefined) {
return;
}
if (skipTransformFlagAggregation) {
forEach(nodes, bind);
}
else {
const savedSubtreeTransformFlags = subtreeTransformFlags;
subtreeTransformFlags = TransformFlags.None;
let nodeArrayFlags = TransformFlags.None;
for (const node of nodes) {
bind(node);
nodeArrayFlags |= node.transformFlags & ~TransformFlags.HasComputedFlags;
}
nodes.transformFlags = nodeArrayFlags | TransformFlags.HasComputedFlags;
subtreeTransformFlags |= savedSubtreeTransformFlags;
}
}
function bindEachChild(node: Node) {
forEachChild(node, bind, bindEach);
}
function bindChildrenWorker(node: Node): void {
// Binding of JsDocComment should be done before the current block scope container changes.
// because the scope of JsDocComment should not be affected by whether the current node is a
@ -578,7 +603,7 @@ namespace ts {
forEach(node.jsDocComments, bind);
}
if (checkUnreachable(node)) {
forEachChild(node, bind);
bindEachChild(node);
return;
}
switch (node.kind) {
@ -643,7 +668,7 @@ namespace ts {
bindCallExpressionFlow(<CallExpression>node);
break;
default:
forEachChild(node, bind);
bindEachChild(node);
break;
}
}
@ -976,7 +1001,7 @@ namespace ts {
return undefined;
}
function bindbreakOrContinueFlow(node: BreakOrContinueStatement, breakTarget: FlowLabel, continueTarget: FlowLabel) {
function bindBreakOrContinueFlow(node: BreakOrContinueStatement, breakTarget: FlowLabel, continueTarget: FlowLabel) {
const flowLabel = node.kind === SyntaxKind.BreakStatement ? breakTarget : continueTarget;
if (flowLabel) {
addAntecedent(flowLabel, currentFlow);
@ -990,11 +1015,11 @@ namespace ts {
const activeLabel = findActiveLabel(node.label.text);
if (activeLabel) {
activeLabel.referenced = true;
bindbreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget);
bindBreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget);
}
}
else {
bindbreakOrContinueFlow(node, currentBreakTarget, currentContinueTarget);
bindBreakOrContinueFlow(node, currentBreakTarget, currentContinueTarget);
}
}
@ -1062,6 +1087,8 @@ namespace ts {
}
function bindCaseBlock(node: CaseBlock): void {
const savedSubtreeTransformFlags = subtreeTransformFlags;
subtreeTransformFlags = 0;
const clauses = node.clauses;
let fallthroughFlow = unreachableFlow;
for (let i = 0; i < clauses.length; i++) {
@ -1081,6 +1108,8 @@ namespace ts {
errorOnFirstToken(clause, Diagnostics.Fallthrough_case_in_switch);
}
}
clauses.transformFlags = subtreeTransformFlags | TransformFlags.HasComputedFlags;
subtreeTransformFlags |= savedSubtreeTransformFlags;
}
function bindCaseClause(node: CaseClause): void {
@ -1088,7 +1117,7 @@ namespace ts {
currentFlow = preSwitchCaseFlow;
bind(node.expression);
currentFlow = saveCurrentFlow;
forEach(node.statements, bind);
bindEach(node.statements);
}
function pushActiveLabel(name: string, breakTarget: FlowLabel, continueTarget: FlowLabel): ActiveLabel {
@ -1180,12 +1209,12 @@ namespace ts {
const saveTrueTarget = currentTrueTarget;
currentTrueTarget = currentFalseTarget;
currentFalseTarget = saveTrueTarget;
forEachChild(node, bind);
bindEachChild(node);
currentFalseTarget = currentTrueTarget;
currentTrueTarget = saveTrueTarget;
}
else {
forEachChild(node, bind);
bindEachChild(node);
if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) {
bindAssignmentTargetFlow(node.operand);
}
@ -1193,7 +1222,7 @@ namespace ts {
}
function bindPostfixUnaryExpressionFlow(node: PostfixUnaryExpression) {
forEachChild(node, bind);
bindEachChild(node);
if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) {
bindAssignmentTargetFlow(node.operand);
}
@ -1212,7 +1241,7 @@ namespace ts {
}
}
else {
forEachChild(node, bind);
bindEachChild(node);
if (isAssignmentOperator(operator) && !isAssignmentTarget(node)) {
bindAssignmentTargetFlow(node.left);
if (operator === SyntaxKind.EqualsToken && node.left.kind === SyntaxKind.ElementAccessExpression) {
@ -1226,7 +1255,7 @@ namespace ts {
}
function bindDeleteExpressionFlow(node: DeleteExpression) {
forEachChild(node, bind);
bindEachChild(node);
if (node.expression.kind === SyntaxKind.PropertyAccessExpression) {
bindAssignmentTargetFlow(node.expression);
}
@ -1261,7 +1290,7 @@ namespace ts {
}
function bindVariableDeclarationFlow(node: VariableDeclaration) {
forEachChild(node, bind);
bindEachChild(node);
if (node.initializer || node.parent.parent.kind === SyntaxKind.ForInStatement || node.parent.parent.kind === SyntaxKind.ForOfStatement) {
bindInitializedVariableFlow(node);
}
@ -1276,12 +1305,12 @@ namespace ts {
expr = (<ParenthesizedExpression>expr).expression;
}
if (expr.kind === SyntaxKind.FunctionExpression || expr.kind === SyntaxKind.ArrowFunction) {
forEach(node.typeArguments, bind);
forEach(node.arguments, bind);
bindEach(node.typeArguments);
bindEach(node.arguments);
bind(node.expression);
}
else {
forEachChild(node, bind);
bindEachChild(node);
}
if (node.expression.kind === SyntaxKind.PropertyAccessExpression) {
const propertyAccess = <PropertyAccessExpression>node.expression;
@ -2514,7 +2543,7 @@ namespace ts {
transformFlags |= TransformFlags.AssertTypeScript;
}
if (subtreeFlags & TransformFlags.ContainsSpreadExpression
if (subtreeFlags & TransformFlags.ContainsSpread
|| isSuperOrSuperProperty(expression, expressionKind)) {
// If the this node contains a SpreadExpression, or is a super call, then it is an ES6
// node.
@ -2545,7 +2574,7 @@ namespace ts {
if (node.typeArguments) {
transformFlags |= TransformFlags.AssertTypeScript;
}
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
if (subtreeFlags & TransformFlags.ContainsSpread) {
// If the this node contains a SpreadElementExpression then it is an ES6
// node.
transformFlags |= TransformFlags.AssertES2015;
@ -2554,7 +2583,6 @@ namespace ts {
return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes;
}
function computeBinaryExpression(node: BinaryExpression, subtreeFlags: TransformFlags) {
let transformFlags = subtreeFlags;
const operatorTokenKind = node.operatorToken.kind;
@ -2601,7 +2629,7 @@ namespace ts {
}
// parameters with object rest destructuring are ES Next syntax
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
if (subtreeFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest)) {
transformFlags |= TransformFlags.AssertESNext;
}
@ -2723,7 +2751,7 @@ namespace ts {
}
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
return transformFlags & ~TransformFlags.NodeExcludes;
return transformFlags & ~TransformFlags.CatchClauseExcludes;
}
function computeExpressionWithTypeArguments(node: ExpressionWithTypeArguments, subtreeFlags: TransformFlags) {
@ -2839,7 +2867,7 @@ namespace ts {
}
// function declarations with object rest destructuring are ES Next syntax
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
if (subtreeFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest)) {
transformFlags |= TransformFlags.AssertESNext;
}
@ -2881,7 +2909,7 @@ namespace ts {
}
// function expressions with object rest destructuring are ES Next syntax
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
if (subtreeFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest)) {
transformFlags |= TransformFlags.AssertESNext;
}
@ -2924,7 +2952,7 @@ namespace ts {
}
// arrow functions with object rest destructuring are ES Next syntax
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
if (subtreeFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest)) {
transformFlags |= TransformFlags.AssertESNext;
}
@ -3178,16 +3206,19 @@ namespace ts {
break;
case SyntaxKind.SpreadElement:
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsSpread;
break;
case SyntaxKind.SpreadAssignment:
// This node is ES6 or ES next syntax, but is handled by a containing node.
transformFlags |= TransformFlags.ContainsSpreadExpression;
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsSpread | TransformFlags.ContainsObjectSpread;
break;
case SyntaxKind.BindingElement:
if ((node as BindingElement).dotDotDotToken) {
// this node is ES2015 or ES next syntax, but is handled by a containing node.
transformFlags |= TransformFlags.ContainsSpreadExpression;
transformFlags |= TransformFlags.AssertES2015;
if ((<BindingElement>node).dotDotDotToken) {
transformFlags |= TransformFlags.ContainsRest;
}
break;
case SyntaxKind.SuperKeyword:
// This node is ES6 syntax.
@ -3200,14 +3231,16 @@ namespace ts {
break;
case SyntaxKind.ObjectBindingPattern:
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
if (subtreeFlags & TransformFlags.ContainsSpread) {
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsObjectRest;
}
excludeFlags = TransformFlags.BindingPatternExcludes;
break;
case SyntaxKind.ArrayBindingPattern:
// These nodes are ES2015 or ES Next syntax.
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsBindingPattern;
}
else {
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
}
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
excludeFlags = TransformFlags.BindingPatternExcludes;
break;
case SyntaxKind.Decorator:
@ -3229,10 +3262,10 @@ namespace ts {
transformFlags |= TransformFlags.ContainsLexicalThis;
}
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
if (subtreeFlags & TransformFlags.ContainsSpread) {
// If an ObjectLiteralExpression contains a spread element, then it
// is an ES next node.
transformFlags |= TransformFlags.AssertESNext;
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsObjectSpread;
}
break;
@ -3240,7 +3273,7 @@ namespace ts {
case SyntaxKind.ArrayLiteralExpression:
case SyntaxKind.NewExpression:
excludeFlags = TransformFlags.ArrayLiteralOrCallOrNewExcludes;
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
if (subtreeFlags & TransformFlags.ContainsSpread) {
// If the this node contains a SpreadExpression, then it is an ES6
// node.
transformFlags |= TransformFlags.AssertES2015;
@ -3333,6 +3366,11 @@ namespace ts {
return TransformFlags.TypeExcludes;
case SyntaxKind.ObjectLiteralExpression:
return TransformFlags.ObjectLiteralExcludes;
case SyntaxKind.CatchClause:
return TransformFlags.CatchClauseExcludes;
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
return TransformFlags.BindingPatternExcludes;
default:
return TransformFlags.NodeExcludes;
}

View File

@ -2341,6 +2341,13 @@ namespace ts {
// Utilities
export function convertToFunctionBody(node: ConciseBody) {
if (isBlock(node)) {
return node;
}
return createBlock([createReturn(node, node)], node);
}
function isUseStrictPrologue(node: ExpressionStatement): boolean {
return (node.expression as StringLiteral).text === "use strict";
}
@ -3121,7 +3128,7 @@ namespace ts {
}
addCaptureThisForNodeIfNeeded(statements, node, enableSubstitutionsForCapturedThis);
addDefaultValueAssignmentsIfNeeded(statements, node, visitor, convertObjectRest);
addDefaultValueAssignmentsIfNeeded(context, statements, node, visitor, convertObjectRest);
addRestParameterIfNeeded(statements, node, /*inConstructorWithSynthesizedSuper*/ false);
// If we added any generated statements, this must be a multi-line block.
@ -3236,7 +3243,8 @@ namespace ts {
* @param statements The statements for the new function body.
* @param node A function-like node.
*/
export function addDefaultValueAssignmentsIfNeeded(statements: Statement[],
export function addDefaultValueAssignmentsIfNeeded(context: TransformationContext,
statements: Statement[],
node: FunctionLikeDeclaration,
visitor: (node: Node) => VisitResult<Node>,
convertObjectRest: boolean): void {
@ -3254,7 +3262,7 @@ namespace ts {
}
if (isBindingPattern(name)) {
addDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer, visitor, convertObjectRest);
addDefaultValueAssignmentForBindingPattern(context, statements, parameter, name, initializer, visitor, convertObjectRest);
}
else if (initializer) {
addDefaultValueAssignmentForInitializer(statements, parameter, name, initializer, visitor);
@ -3270,7 +3278,8 @@ namespace ts {
* @param name The name of the parameter.
* @param initializer The initializer for the parameter.
*/
function addDefaultValueAssignmentForBindingPattern(statements: Statement[],
function addDefaultValueAssignmentForBindingPattern(context: TransformationContext,
statements: Statement[],
parameter: ParameterDeclaration,
name: BindingPattern, initializer: Expression,
visitor: (node: Node) => VisitResult<Node>,
@ -3286,7 +3295,17 @@ namespace ts {
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
flattenParameterDestructuring(parameter, temp, visitor, convertObjectRest)
flattenDestructuringToDeclarations(
context,
parameter,
temp,
/*skipInitializer*/ convertObjectRest,
/*recordTempVariablesInLine*/ true,
convertObjectRest
? FlattenLevel.ObjectRest
: FlattenLevel.All,
visitor
)
)
),
EmitFlags.CustomPrologue
@ -3490,12 +3509,16 @@ namespace ts {
if (firstOriginalDeclaration && isBindingPattern(firstOriginalDeclaration.name)) {
// This works whether the declaration is a var, let, or const.
// It will use rhsIterationValue _a[_i] as the initializer.
const declarations = flattenVariableDestructuring(
const declarations = flattenDestructuringToDeclarations(
context,
firstOriginalDeclaration,
elementAccess,
visitor,
/*recordTempVariable*/ undefined,
/*skipInitializer*/ false,
/*recordTempVariablesInLine*/ true,
convertObjectRest
? FlattenLevel.ObjectRest
: FlattenLevel.All,
visitor
);
const declarationList = createVariableDeclarationList(declarations, /*location*/ initializer);
@ -3543,13 +3566,15 @@ namespace ts {
// This is a destructuring pattern, so we flatten the destructuring instead.
statements.push(
createStatement(
flattenDestructuringAssignment(
flattenDestructuringToExpression(
context,
assignment,
/*needsValue*/ false,
context.hoistVariableDeclaration,
visitor,
convertObjectRest
? FlattenLevel.ObjectRest
: FlattenLevel.All,
/*createAssignmentCallback*/ undefined,
visitor
)
)
);

File diff suppressed because it is too large Load Diff

View File

@ -279,7 +279,7 @@ namespace ts {
else if (node.transformFlags & TransformFlags.ContainsES2015 || (isInConstructorWithCapturedSuper && !isExpression(node))) {
// we want to dive in this branch either if node has children with ES2015 specific syntax
// or we are inside constructor that captures result of the super call so all returns without expression should be
// rewritten. Note: we skip expressions since returns should never appear there
// rewritten. Note: we skip expressions since returns should never appear there
return visitEachChild(node, visitor, context);
}
else {
@ -861,7 +861,7 @@ namespace ts {
}
if (constructor) {
addDefaultValueAssignmentsIfNeeded(statements, constructor, visitor, /*convertObjectRest*/ false);
addDefaultValueAssignmentsIfNeeded(context, statements, constructor, visitor, /*convertObjectRest*/ false);
addRestParameterIfNeeded(statements, constructor, hasSynthesizedSuper);
Debug.assert(statementOffset >= 0, "statementOffset not initialized correctly!");
@ -1328,16 +1328,10 @@ namespace ts {
// If we are here it is most likely because our expression is a destructuring assignment.
switch (node.expression.kind) {
case SyntaxKind.ParenthesizedExpression:
return updateStatement(node,
visitParenthesizedExpression(<ParenthesizedExpression>node.expression, /*needsDestructuringValue*/ false)
);
return updateStatement(node, visitParenthesizedExpression(<ParenthesizedExpression>node.expression, /*needsDestructuringValue*/ false));
case SyntaxKind.BinaryExpression:
return updateStatement(node,
visitBinaryExpression(<BinaryExpression>node.expression, /*needsDestructuringValue*/ false)
);
return updateStatement(node, visitBinaryExpression(<BinaryExpression>node.expression, /*needsDestructuringValue*/ false));
}
return visitEachChild(node, visitor, context);
}
@ -1350,22 +1344,14 @@ namespace ts {
*/
function visitParenthesizedExpression(node: ParenthesizedExpression, needsDestructuringValue: boolean): ParenthesizedExpression {
// If we are here it is most likely because our expression is a destructuring assignment.
if (needsDestructuringValue) {
if (!needsDestructuringValue) {
switch (node.expression.kind) {
case SyntaxKind.ParenthesizedExpression:
return createParen(
visitParenthesizedExpression(<ParenthesizedExpression>node.expression, /*needsDestructuringValue*/ true),
/*location*/ node
);
return updateParen(node, visitParenthesizedExpression(<ParenthesizedExpression>node.expression, /*needsDestructuringValue*/ false));
case SyntaxKind.BinaryExpression:
return createParen(
visitBinaryExpression(<BinaryExpression>node.expression, /*needsDestructuringValue*/ true),
/*location*/ node
);
return updateParen(node, visitBinaryExpression(<BinaryExpression>node.expression, /*needsDestructuringValue*/ false));
}
}
return visitEachChild(node, visitor, context);
}
@ -1379,7 +1365,13 @@ namespace ts {
function visitBinaryExpression(node: BinaryExpression, needsDestructuringValue: boolean): Expression {
// If we are here it is because this is a destructuring assignment.
Debug.assert(isDestructuringAssignment(node));
return flattenDestructuringAssignment(context, node, needsDestructuringValue, hoistVariableDeclaration, visitor);
return flattenDestructuringToExpression(
context,
<DestructuringAssignment>node,
needsDestructuringValue,
FlattenLevel.All,
/*createAssignmentCallback*/ undefined,
visitor);
}
function visitVariableStatement(node: VariableStatement): Statement {
@ -1391,7 +1383,14 @@ namespace ts {
if (decl.initializer) {
let assignment: Expression;
if (isBindingPattern(decl.name)) {
assignment = flattenVariableDestructuringToExpression(decl, hoistVariableDeclaration, /*createAssignmentCallback*/ undefined, visitor);
assignment = flattenDestructuringToExpression(
context,
decl,
/*needsValue*/ false,
FlattenLevel.All,
/*createAssignmentCallback*/ undefined,
visitor
);
}
else {
assignment = createBinary(<Identifier>decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression));
@ -1544,8 +1543,16 @@ namespace ts {
if (isBindingPattern(node.name)) {
const recordTempVariablesInLine = !enclosingVariableStatement
|| !hasModifier(enclosingVariableStatement, ModifierFlags.Export);
return flattenVariableDestructuring(node, /*value*/ undefined, visitor,
recordTempVariablesInLine ? undefined : hoistVariableDeclaration);
debugger;
return flattenDestructuringToDeclarations(
context,
node,
/*value*/ undefined,
/*skipInitializer*/ false,
recordTempVariablesInLine,
FlattenLevel.All,
visitor
);
}
return visitEachChild(node, visitor, context);
@ -2174,7 +2181,7 @@ namespace ts {
const temp = createTempVariable(undefined);
const newVariableDeclaration = createVariableDeclaration(temp, undefined, undefined, node.variableDeclaration);
const vars = flattenVariableDestructuring(node.variableDeclaration, temp, visitor);
const vars = flattenDestructuringToDeclarations(context, node.variableDeclaration, temp, /*skipInitializer*/ false, /*recordTempVariablesInLine*/ true, FlattenLevel.All, visitor);
const list = createVariableDeclarationList(vars, /*location*/node.variableDeclaration, /*flags*/node.variableDeclaration.flags);
const destructure = createVariableStatement(undefined, list);
@ -2261,7 +2268,7 @@ namespace ts {
setEmitFlags(thisArg, EmitFlags.NoSubstitution);
}
let resultingCall: CallExpression | BinaryExpression;
if (node.transformFlags & TransformFlags.ContainsSpreadExpression) {
if (node.transformFlags & TransformFlags.ContainsSpread) {
// [source]
// f(...a, b)
// x.m(...a, b)
@ -2323,7 +2330,7 @@ namespace ts {
*/
function visitNewExpression(node: NewExpression): LeftHandSideExpression {
// We are here because we contain a SpreadElementExpression.
Debug.assert((node.transformFlags & TransformFlags.ContainsSpreadExpression) !== 0);
Debug.assert((node.transformFlags & TransformFlags.ContainsSpread) !== 0);
// [source]
// new C(...a)

View File

@ -29,12 +29,6 @@ namespace ts {
*/
let enabledSubstitutions: ES2017SubstitutionFlags;
/**
* Keeps track of whether we are within any containing namespaces when performing
* just-in-time substitution while printing an expression identifier.
*/
let applicableSubstitutions: ES2017SubstitutionFlags;
/**
* This keeps track of containers where `super` is valid, for use with
* just-in-time substitution for `super` expressions inside of async methods.
@ -49,8 +43,6 @@ namespace ts {
context.onEmitNode = onEmitNode;
context.onSubstituteNode = onSubstituteNode;
let currentScope: SourceFile | Block | ModuleBlock | CaseBlock;
return transformSourceFile;
function transformSourceFile(node: SourceFile) {
@ -64,13 +56,9 @@ namespace ts {
}
function visitor(node: Node): VisitResult<Node> {
if (node.transformFlags & TransformFlags.ES2017) {
if (node.transformFlags & TransformFlags.ContainsES2017) {
return visitorWorker(node);
}
else if (node.transformFlags & TransformFlags.ContainsES2017) {
return visitEachChild(node, visitor, context);
}
return node;
}
@ -101,8 +89,7 @@ namespace ts {
return visitArrowFunction(<ArrowFunction>node);
default:
Debug.failBadSyntaxKind(node);
return node;
return visitEachChild(node, visitor, context);
}
}
@ -133,28 +120,18 @@ namespace ts {
* @param node The method node.
*/
function visitMethodDeclaration(node: MethodDeclaration) {
if (!isAsyncFunctionLike(node)) {
return node;
}
const method = createMethod(
return updateMethod(
node,
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
node.asteriskToken,
node.name,
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
visitParameterList(node.parameters, visitor, context),
/*type*/ undefined,
transformFunctionBody(node),
/*location*/ node
isAsyncFunctionLike(node)
? transformAsyncFunctionBody(node)
: visitFunctionBody(node.body, visitor, context)
);
// While we emit the source map for the node after skipping decorators and modifiers,
// we need to emit the comments for the original range.
setCommentRange(method, node);
setSourceMapRange(method, moveRangePastDecorators(node));
setOriginalNode(method, node);
return method;
}
/**
@ -166,23 +143,18 @@ namespace ts {
* @param node The function node.
*/
function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult<Statement> {
if (!isAsyncFunctionLike(node)) {
return node;
}
const func = createFunctionDeclaration(
return updateFunctionDeclaration(
node,
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
node.asteriskToken,
node.name,
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
transformFunctionBody(node),
/*location*/ node
isAsyncFunctionLike(node)
? transformAsyncFunctionBody(node)
: visitFunctionBody(node.body, visitor, context)
);
setOriginalNode(func, node);
return func;
}
/**
@ -194,27 +166,20 @@ namespace ts {
* @param node The function expression node.
*/
function visitFunctionExpression(node: FunctionExpression): Expression {
if (!isAsyncFunctionLike(node)) {
return node;
}
if (nodeIsMissing(node.body)) {
return createOmittedExpression();
}
const func = createFunctionExpression(
return updateFunctionExpression(
node,
/*modifiers*/ undefined,
node.asteriskToken,
node.name,
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
transformFunctionBody(node),
/*location*/ node
isAsyncFunctionLike(node)
? transformAsyncFunctionBody(node)
: visitFunctionBody(node.body, visitor, context)
);
setOriginalNode(func, node);
return func;
}
/**
@ -223,45 +188,21 @@ namespace ts {
* - The node is marked async
*/
function visitArrowFunction(node: ArrowFunction) {
if (!isAsyncFunctionLike(node)) {
return node;
}
const func = createArrowFunction(
return updateArrowFunction(
node,
visitNodes(node.modifiers, visitor, isModifier),
/*typeParameters*/ undefined,
visitNodes(node.parameters, visitor, isParameter),
/*type*/ undefined,
node.equalsGreaterThanToken,
transformConciseBody(node),
/*location*/ node
isAsyncFunctionLike(node)
? transformAsyncFunctionBody(node)
: visitFunctionBody(node.body, visitor, context)
);
setOriginalNode(func, node);
return func;
}
function transformFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody {
return <FunctionBody>transformAsyncFunctionBody(node);
}
function transformConciseBody(node: ArrowFunction): ConciseBody {
return transformAsyncFunctionBody(node);
}
function transformFunctionBodyWorker(body: Block, start = 0) {
const savedCurrentScope = currentScope;
currentScope = body;
startLexicalEnvironment();
const statements = visitNodes(body.statements, visitor, isStatement, start);
const visited = updateBlock(body, statements);
const declarations = endLexicalEnvironment();
currentScope = savedCurrentScope;
return mergeFunctionBodyLexicalEnvironment(visited, declarations);
}
function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody | FunctionBody {
function transformAsyncFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody;
function transformAsyncFunctionBody(node: ArrowFunction): ConciseBody;
function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody {
const original = getOriginalNode(node, isFunctionLike);
const nodeType = original.type;
const promiseConstructor = languageVersion < ScriptTarget.ES2015 ? getPromiseConstructor(nodeType) : undefined;
@ -274,7 +215,6 @@ namespace ts {
// passed to `__awaiter` is executed inside of the callback to the
// promise constructor.
if (!isArrowFunction) {
const statements: Statement[] = [];
const statementOffset = addPrologueDirectives(statements, (<Block>node.body).statements, /*ensureUseStrict*/ false, visitor);
@ -289,6 +229,7 @@ namespace ts {
)
);
addRange(statements, endLexicalEnvironment());
const block = createBlock(statements, /*location*/ node.body, /*multiLine*/ true);
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
@ -307,32 +248,32 @@ namespace ts {
return block;
}
else {
return createAwaiterHelper(
const expression = createAwaiterHelper(
currentSourceFileExternalHelpersModuleName,
hasLexicalArguments,
promiseConstructor,
<Block>transformConciseBodyWorker(node.body, /*forceBlockFunctionBody*/ true)
transformFunctionBodyWorker(node.body)
);
const declarations = endLexicalEnvironment();
if (some(declarations)) {
const block = convertToFunctionBody(expression);
return updateBlock(block, createNodeArray(concatenate(block.statements, declarations), block.statements));
}
return expression;
}
}
function transformConciseBodyWorker(body: Block | Expression, forceBlockFunctionBody: boolean) {
function transformFunctionBodyWorker(body: ConciseBody, start?: number) {
if (isBlock(body)) {
return transformFunctionBodyWorker(body);
return updateBlock(body, visitLexicalEnvironment(body.statements, visitor, context, start));
}
else {
startLexicalEnvironment();
const visited: Expression | Block = visitNode(body, visitor, isConciseBody);
const visited = convertToFunctionBody(visitNode(body, visitor, isConciseBody));
const declarations = endLexicalEnvironment();
const merged = mergeFunctionBodyLexicalEnvironment(visited, declarations);
if (forceBlockFunctionBody && !isBlock(merged)) {
return createBlock([
createReturn(<Expression>merged)
]);
}
else {
return merged;
}
return updateBlock(visited, createNodeArray(concatenate(visited.statements, declarations), visited.statements));
}
}
@ -452,18 +393,17 @@ namespace ts {
* @param emit A callback used to emit the node in the printer.
*/
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
const savedApplicableSubstitutions = applicableSubstitutions;
const savedCurrentSuperContainer = currentSuperContainer;
// If we need to support substitutions for `super` in an async method,
// we should track it here.
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
const savedCurrentSuperContainer = currentSuperContainer;
currentSuperContainer = node;
previousOnEmitNode(emitContext, node, emitCallback);
currentSuperContainer = savedCurrentSuperContainer;
}
else {
previousOnEmitNode(emitContext, node, emitCallback);
}
previousOnEmitNode(emitContext, node, emitCallback);
applicableSubstitutions = savedApplicableSubstitutions;
currentSuperContainer = savedCurrentSuperContainer;
}
/**

View File

@ -4,9 +4,6 @@
/*@internal*/
namespace ts {
export function transformESNext(context: TransformationContext) {
const {
hoistVariableDeclaration,
} = context;
let currentSourceFile: SourceFile;
return transformSourceFile;
@ -20,7 +17,7 @@ namespace ts {
return visitorWorker(node);
}
else if (node.transformFlags & TransformFlags.ContainsESNext) {
return visitEachChild(node, visitor, context);
return visitNodeContainingESNext(node);
}
else {
return node;
@ -32,7 +29,7 @@ namespace ts {
case SyntaxKind.ObjectLiteralExpression:
return visitObjectLiteralExpression(node as ObjectLiteralExpression);
case SyntaxKind.BinaryExpression:
return visitBinaryExpression(node as BinaryExpression);
return visitBinaryExpression(node as BinaryExpression, /*needsDestructuringValue*/ true);
case SyntaxKind.VariableDeclaration:
return visitVariableDeclaration(node as VariableDeclaration);
case SyntaxKind.ForOfStatement:
@ -54,6 +51,16 @@ namespace ts {
}
}
function visitNodeContainingESNext(node: Node) {
switch (node.kind) {
case SyntaxKind.ExpressionStatement:
return visitExpressionStatement(node as ExpressionStatement);
case SyntaxKind.ParenthesizedExpression:
return visitParenthesizedExpression(node as ParenthesizedExpression, /*needsDestructuringValue*/ true);
}
return visitEachChild(node, visitor, context);
}
function chunkObjectLiteralElements(elements: ObjectLiteralElement[]): Expression[] {
let chunkObject: (ShorthandPropertyAssignment | PropertyAssignment)[];
const objects: Expression[] = [];
@ -99,14 +106,43 @@ namespace ts {
return createCall(createIdentifier("__assign"), undefined, objects);
}
function visitExpressionStatement(node: ExpressionStatement): ExpressionStatement {
switch (node.expression.kind) {
case SyntaxKind.ParenthesizedExpression:
return updateStatement(node, visitParenthesizedExpression(<ParenthesizedExpression>node.expression, /*needsDestructuringValue*/ false));
case SyntaxKind.BinaryExpression:
return updateStatement(node, visitBinaryExpression(<BinaryExpression>node.expression, /*needsDestructuringValue*/ false));
}
return visitEachChild(node, visitor, context);
}
function visitParenthesizedExpression(node: ParenthesizedExpression, needsDestructuringValue: boolean): ParenthesizedExpression {
if (!needsDestructuringValue) {
switch (node.expression.kind) {
case SyntaxKind.ParenthesizedExpression:
return updateParen(node, visitParenthesizedExpression(<ParenthesizedExpression>node.expression, /*needsDestructuringValue*/ false));
case SyntaxKind.BinaryExpression:
return updateParen(node, visitBinaryExpression(<BinaryExpression>node.expression, /*needsDestructuringValue*/ false));
}
}
return visitEachChild(node, visitor, context);
}
/**
* Visits a BinaryExpression that contains a destructuring assignment.
*
* @param node A BinaryExpression node.
*/
function visitBinaryExpression(node: BinaryExpression): Expression {
function visitBinaryExpression(node: BinaryExpression, needsDestructuringValue: boolean): Expression {
if (isDestructuringAssignment(node) && node.left.transformFlags & TransformFlags.ContainsESNext) {
return flattenDestructuringAssignment(context, node, /*needsDestructuringValue*/ true, hoistVariableDeclaration, visitor, /*transformRest*/ true);
return flattenDestructuringToExpression(
context,
node,
needsDestructuringValue,
FlattenLevel.ObjectRest,
/*createAssignmentCallback*/ undefined,
visitor
);
}
return visitEachChild(node, visitor, context);
@ -120,10 +156,8 @@ namespace ts {
function visitVariableDeclaration(node: VariableDeclaration): VisitResult<VariableDeclaration> {
// If we are here it is because the name contains a binding pattern with a rest somewhere in it.
if (isBindingPattern(node.name) && node.name.transformFlags & TransformFlags.AssertESNext) {
const result = flattenVariableDestructuring(node, /*value*/ undefined, visitor, /*recordTempVariable*/ undefined, /*transformRest*/ true);
return result;
return flattenDestructuringToDeclarations(context, node, /*boundValue*/ undefined, /*skipInitializer*/ false, /*recordTempVariablesInLine*/ true, FlattenLevel.ObjectRest, visitor);
}
return visitEachChild(node, visitor, context);
}
@ -168,14 +202,14 @@ namespace ts {
const declaration = firstOrUndefined(initializer.declarations);
return declaration && declaration.name &&
declaration.name.kind === SyntaxKind.ObjectBindingPattern &&
!!(declaration.name.transformFlags & TransformFlags.ContainsSpreadExpression);
!!(declaration.name.transformFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest));
}
return false;
}
function isRestAssignment(initializer: ForInitializer) {
return initializer.kind === SyntaxKind.ObjectLiteralExpression &&
initializer.transformFlags & TransformFlags.ContainsSpreadExpression;
initializer.transformFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest);
}
function visitParameter(node: ParameterDeclaration): ParameterDeclaration {
@ -204,7 +238,7 @@ namespace ts {
function isObjectRestParameter(node: ParameterDeclaration) {
return node.name &&
node.name.kind === SyntaxKind.ObjectBindingPattern &&
!!(node.name.transformFlags & TransformFlags.ContainsSpreadExpression);
!!(node.name.transformFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest));
}
function visitFunctionDeclaration(node: FunctionDeclaration): FunctionDeclaration {

View File

@ -27,12 +27,9 @@ namespace ts {
}
function visitor(node: Node): VisitResult<Node> {
if (node.transformFlags & TransformFlags.Jsx) {
if (node.transformFlags & TransformFlags.ContainsJsx) {
return visitorWorker(node);
}
else if (node.transformFlags & TransformFlags.ContainsJsx) {
return visitEachChild(node, visitor, context);
}
else {
return node;
}
@ -50,8 +47,7 @@ namespace ts {
return visitJsxExpression(<JsxExpression>node);
default:
Debug.failBadSyntaxKind(node);
return undefined;
return visitEachChild(node, visitor, context);
}
}

View File

@ -19,8 +19,7 @@ namespace ts {
const {
startLexicalEnvironment,
endLexicalEnvironment,
hoistVariableDeclaration,
endLexicalEnvironment
} = context;
const compilerOptions = context.getCompilerOptions();
@ -757,10 +756,13 @@ namespace ts {
*/
function transformInitializedVariable(node: VariableDeclaration): Expression {
if (isBindingPattern(node.name)) {
return flattenVariableDestructuringToExpression(
return flattenDestructuringToExpression(
context,
node,
hoistVariableDeclaration,
createExportExpression
/*needsValue*/ false,
FlattenLevel.All,
createExportExpression,
/*visitor*/ undefined
);
}
else {

View File

@ -808,7 +808,7 @@ namespace ts {
function transformInitializedVariable(node: VariableDeclaration, isExportedDeclaration: boolean): Expression {
const createAssignment = isExportedDeclaration ? createExportedVariableAssignment : createNonExportedVariableAssignment;
return isBindingPattern(node.name)
? flattenVariableDestructuringToExpression(node, hoistVariableDeclaration, createAssignment, destructuringVisitor)
? flattenDestructuringToExpression(context, node, /*needsValue*/ false, FlattenLevel.All, createAssignment, destructuringVisitor)
: createAssignment(node.name, visitNode(node.initializer, destructuringVisitor, isExpression));
}
@ -1459,7 +1459,13 @@ namespace ts {
*/
function visitDestructuringAssignment(node: DestructuringAssignment): VisitResult<Expression> {
if (hasExportedReferenceInDestructuringTarget(node.left)) {
return flattenDestructuringAssignment(context, node, /*needsValue*/ true, hoistVariableDeclaration, destructuringVisitor);
return flattenDestructuringToExpression(
context,
node,
/*needsValue*/ true,
FlattenLevel.All,
/*createAssignmentCallback*/ undefined,
destructuringVisitor);
}
return visitEachChild(node, destructuringVisitor, context);

View File

@ -2353,9 +2353,11 @@ namespace ts {
function transformInitializedVariable(node: VariableDeclaration): Expression {
const name = node.name;
if (isBindingPattern(name)) {
return flattenVariableDestructuringToExpression(
return flattenDestructuringToExpression(
context,
node,
hoistVariableDeclaration,
/*needsValue*/ false,
FlattenLevel.All,
createNamespaceExportExpression,
visitor
);

View File

@ -506,6 +506,7 @@ namespace ts {
export interface NodeArray<T extends Node> extends Array<T>, TextRange {
hasTrailingComma?: boolean;
/* @internal */ transformFlags?: TransformFlags;
}
export interface Token<TKind extends SyntaxKind> extends Node {
@ -3495,45 +3496,46 @@ namespace ts {
// - Flags used to indicate that a node or subtree contains syntax that requires transformation.
TypeScript = 1 << 0,
ContainsTypeScript = 1 << 1,
Jsx = 1 << 2,
ContainsJsx = 1 << 3,
ESNext = 1 << 4,
ContainsESNext = 1 << 5,
ES2017 = 1 << 6,
ContainsES2017 = 1 << 7,
ES2016 = 1 << 8,
ContainsES2016 = 1 << 9,
ES2015 = 1 << 10,
ContainsES2015 = 1 << 11,
Generator = 1 << 12,
ContainsGenerator = 1 << 13,
DestructuringAssignment = 1 << 14,
ContainsDestructuringAssignment = 1 << 15,
ContainsJsx = 1 << 2,
ESNext = 1 << 3,
ContainsESNext = 1 << 4,
ContainsES2017 = 1 << 5,
ES2016 = 1 << 6,
ContainsES2016 = 1 << 7,
ES2015 = 1 << 8,
ContainsES2015 = 1 << 9,
Generator = 1 << 10,
ContainsGenerator = 1 << 11,
DestructuringAssignment = 1 << 12,
ContainsDestructuringAssignment = 1 << 13,
// Markers
// - Flags used to indicate that a subtree contains a specific transformation.
ContainsDecorators = 1 << 16,
ContainsPropertyInitializer = 1 << 17,
ContainsLexicalThis = 1 << 18,
ContainsCapturedLexicalThis = 1 << 19,
ContainsLexicalThisInComputedPropertyName = 1 << 20,
ContainsDefaultValueAssignments = 1 << 21,
ContainsParameterPropertyAssignments = 1 << 22,
ContainsSpreadExpression = 1 << 23,
ContainsComputedPropertyName = 1 << 24,
ContainsBlockScopedBinding = 1 << 25,
ContainsBindingPattern = 1 << 26,
ContainsYield = 1 << 27,
ContainsHoistedDeclarationOrCompletion = 1 << 28,
ContainsDecorators = 1 << 14,
ContainsPropertyInitializer = 1 << 15,
ContainsLexicalThis = 1 << 16,
ContainsCapturedLexicalThis = 1 << 17,
ContainsLexicalThisInComputedPropertyName = 1 << 18,
ContainsDefaultValueAssignments = 1 << 19,
ContainsParameterPropertyAssignments = 1 << 20,
ContainsSpread = 1 << 21,
ContainsRest = ContainsSpread,
ContainsObjectSpread = 1 << 22,
ContainsObjectRest = ContainsObjectSpread,
ContainsComputedPropertyName = 1 << 23,
ContainsBlockScopedBinding = 1 << 24,
ContainsBindingPattern = 1 << 25,
ContainsYield = 1 << 26,
ContainsHoistedDeclarationOrCompletion = 1 << 27,
HasComputedFlags = 1 << 29, // Transform flags have been computed.
// Assertions
// - Bitmasks that are used to assert facts about the syntax of a node and its subtree.
AssertTypeScript = TypeScript | ContainsTypeScript,
AssertJsx = Jsx | ContainsJsx,
AssertJsx = ContainsJsx,
AssertESNext = ESNext | ContainsESNext,
AssertES2017 = ES2017 | ContainsES2017,
AssertES2017 = ContainsES2017,
AssertES2016 = ES2016 | ContainsES2016,
AssertES2015 = ES2015 | ContainsES2015,
AssertGenerator = Generator | ContainsGenerator,
@ -3542,18 +3544,20 @@ namespace ts {
// Scope Exclusions
// - Bitmasks that exclude flags from propagating out of a specific context
// into the subtree flags of their container.
NodeExcludes = TypeScript | Jsx | ESNext | ES2017 | ES2016 | ES2015 | DestructuringAssignment | Generator | HasComputedFlags,
ArrowFunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion,
FunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion,
ConstructorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion,
MethodOrAccessorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion,
NodeExcludes = TypeScript | ESNext | ES2016 | ES2015 | DestructuringAssignment | Generator | HasComputedFlags,
ArrowFunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest,
FunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest,
ConstructorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest,
MethodOrAccessorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest,
ClassExcludes = NodeExcludes | ContainsDecorators | ContainsPropertyInitializer | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsComputedPropertyName | ContainsParameterPropertyAssignments | ContainsLexicalThisInComputedPropertyName,
ModuleExcludes = NodeExcludes | ContainsDecorators | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsHoistedDeclarationOrCompletion,
TypeExcludes = ~ContainsTypeScript,
ObjectLiteralExcludes = NodeExcludes | ContainsDecorators | ContainsComputedPropertyName | ContainsLexicalThisInComputedPropertyName,
ArrayLiteralOrCallOrNewExcludes = NodeExcludes | ContainsSpreadExpression,
VariableDeclarationListExcludes = NodeExcludes | ContainsBindingPattern,
ParameterExcludes = NodeExcludes | ContainsBindingPattern,
ObjectLiteralExcludes = NodeExcludes | ContainsDecorators | ContainsComputedPropertyName | ContainsLexicalThisInComputedPropertyName | ContainsObjectSpread,
ArrayLiteralOrCallOrNewExcludes = NodeExcludes | ContainsSpread,
VariableDeclarationListExcludes = NodeExcludes | ContainsBindingPattern | ContainsObjectSpread,
ParameterExcludes = NodeExcludes,
CatchClauseExcludes = NodeExcludes | ContainsObjectSpread,
BindingPatternExcludes = NodeExcludes | ContainsSpread,
// Masks
// - Additional bitmasks
@ -3622,7 +3626,6 @@ namespace ts {
endLexicalEnvironment(): Statement[];
}
export interface TextSpan {
start: number;
length: number;

View File

@ -99,20 +99,26 @@ namespace ts {
return node ? f(initial, node) : initial;
}
function reduceNodeArray<T>(nodes: Node[], f: (memo: T, nodes: Node[]) => T, initial: T) {
return nodes ? f(initial, nodes) : initial;
}
/**
* Similar to `reduceLeft`, performs a reduction against each child of a node.
* NOTE: Unlike `forEachChild`, this does *not* visit every node. Only nodes added to the
* `nodeEdgeTraversalMap` above will be visited.
*
* @param node The node containing the children to reduce.
* @param f The callback function
* @param initial The initial value to supply to the reduction.
* @param f The callback function
*/
export function reduceEachChild<T>(node: Node, f: (memo: T, node: Node) => T, initial: T): T {
export function reduceEachChild<T>(node: Node, initial: T, cbNode: (memo: T, node: Node) => T, cbNodeArray?: (memo: T, nodes: Node[]) => T): T {
if (node === undefined) {
return initial;
}
const reduceNodes: (nodes: Node[], f: (memo: T, node: Node | Node[]) => T, initial: T) => T = cbNodeArray ? reduceNodeArray : reduceLeft;
const cbNodes = cbNodeArray || cbNode;
const kind = node.kind;
// No need to visit nodes with no children.
@ -138,127 +144,127 @@ namespace ts {
// Names
case SyntaxKind.ComputedPropertyName:
result = reduceNode((<ComputedPropertyName>node).expression, f, result);
result = reduceNode((<ComputedPropertyName>node).expression, cbNode, result);
break;
// Signature elements
case SyntaxKind.Parameter:
result = reduceLeft((<ParameterDeclaration>node).decorators, f, result);
result = reduceLeft((<ParameterDeclaration>node).modifiers, f, result);
result = reduceNode((<ParameterDeclaration>node).name, f, result);
result = reduceNode((<ParameterDeclaration>node).type, f, result);
result = reduceNode((<ParameterDeclaration>node).initializer, f, result);
result = reduceNodes((<ParameterDeclaration>node).decorators, cbNodes, result);
result = reduceNodes((<ParameterDeclaration>node).modifiers, cbNodes, result);
result = reduceNode((<ParameterDeclaration>node).name, cbNode, result);
result = reduceNode((<ParameterDeclaration>node).type, cbNode, result);
result = reduceNode((<ParameterDeclaration>node).initializer, cbNode, result);
break;
case SyntaxKind.Decorator:
result = reduceNode((<Decorator>node).expression, f, result);
result = reduceNode((<Decorator>node).expression, cbNode, result);
break;
// Type member
case SyntaxKind.PropertyDeclaration:
result = reduceLeft((<PropertyDeclaration>node).decorators, f, result);
result = reduceLeft((<PropertyDeclaration>node).modifiers, f, result);
result = reduceNode((<PropertyDeclaration>node).name, f, result);
result = reduceNode((<PropertyDeclaration>node).type, f, result);
result = reduceNode((<PropertyDeclaration>node).initializer, f, result);
result = reduceNodes((<PropertyDeclaration>node).decorators, cbNodes, result);
result = reduceNodes((<PropertyDeclaration>node).modifiers, cbNodes, result);
result = reduceNode((<PropertyDeclaration>node).name, cbNode, result);
result = reduceNode((<PropertyDeclaration>node).type, cbNode, result);
result = reduceNode((<PropertyDeclaration>node).initializer, cbNode, result);
break;
case SyntaxKind.MethodDeclaration:
result = reduceLeft((<MethodDeclaration>node).decorators, f, result);
result = reduceLeft((<MethodDeclaration>node).modifiers, f, result);
result = reduceNode((<MethodDeclaration>node).name, f, result);
result = reduceLeft((<MethodDeclaration>node).typeParameters, f, result);
result = reduceLeft((<MethodDeclaration>node).parameters, f, result);
result = reduceNode((<MethodDeclaration>node).type, f, result);
result = reduceNode((<MethodDeclaration>node).body, f, result);
result = reduceNodes((<MethodDeclaration>node).decorators, cbNodes, result);
result = reduceNodes((<MethodDeclaration>node).modifiers, cbNodes, result);
result = reduceNode((<MethodDeclaration>node).name, cbNode, result);
result = reduceNodes((<MethodDeclaration>node).typeParameters, cbNodes, result);
result = reduceNodes((<MethodDeclaration>node).parameters, cbNodes, result);
result = reduceNode((<MethodDeclaration>node).type, cbNode, result);
result = reduceNode((<MethodDeclaration>node).body, cbNode, result);
break;
case SyntaxKind.Constructor:
result = reduceLeft((<ConstructorDeclaration>node).modifiers, f, result);
result = reduceLeft((<ConstructorDeclaration>node).parameters, f, result);
result = reduceNode((<ConstructorDeclaration>node).body, f, result);
result = reduceNodes((<ConstructorDeclaration>node).modifiers, cbNodes, result);
result = reduceNodes((<ConstructorDeclaration>node).parameters, cbNodes, result);
result = reduceNode((<ConstructorDeclaration>node).body, cbNode, result);
break;
case SyntaxKind.GetAccessor:
result = reduceLeft((<GetAccessorDeclaration>node).decorators, f, result);
result = reduceLeft((<GetAccessorDeclaration>node).modifiers, f, result);
result = reduceNode((<GetAccessorDeclaration>node).name, f, result);
result = reduceLeft((<GetAccessorDeclaration>node).parameters, f, result);
result = reduceNode((<GetAccessorDeclaration>node).type, f, result);
result = reduceNode((<GetAccessorDeclaration>node).body, f, result);
result = reduceNodes((<GetAccessorDeclaration>node).decorators, cbNodes, result);
result = reduceNodes((<GetAccessorDeclaration>node).modifiers, cbNodes, result);
result = reduceNode((<GetAccessorDeclaration>node).name, cbNode, result);
result = reduceNodes((<GetAccessorDeclaration>node).parameters, cbNodes, result);
result = reduceNode((<GetAccessorDeclaration>node).type, cbNode, result);
result = reduceNode((<GetAccessorDeclaration>node).body, cbNode, result);
break;
case SyntaxKind.SetAccessor:
result = reduceLeft((<GetAccessorDeclaration>node).decorators, f, result);
result = reduceLeft((<GetAccessorDeclaration>node).modifiers, f, result);
result = reduceNode((<GetAccessorDeclaration>node).name, f, result);
result = reduceLeft((<GetAccessorDeclaration>node).parameters, f, result);
result = reduceNode((<GetAccessorDeclaration>node).body, f, result);
result = reduceNodes((<GetAccessorDeclaration>node).decorators, cbNodes, result);
result = reduceNodes((<GetAccessorDeclaration>node).modifiers, cbNodes, result);
result = reduceNode((<GetAccessorDeclaration>node).name, cbNode, result);
result = reduceNodes((<GetAccessorDeclaration>node).parameters, cbNodes, result);
result = reduceNode((<GetAccessorDeclaration>node).body, cbNode, result);
break;
// Binding patterns
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
result = reduceLeft((<BindingPattern>node).elements, f, result);
result = reduceNodes((<BindingPattern>node).elements, cbNodes, result);
break;
case SyntaxKind.BindingElement:
result = reduceNode((<BindingElement>node).propertyName, f, result);
result = reduceNode((<BindingElement>node).name, f, result);
result = reduceNode((<BindingElement>node).initializer, f, result);
result = reduceNode((<BindingElement>node).propertyName, cbNode, result);
result = reduceNode((<BindingElement>node).name, cbNode, result);
result = reduceNode((<BindingElement>node).initializer, cbNode, result);
break;
// Expression
case SyntaxKind.ArrayLiteralExpression:
result = reduceLeft((<ArrayLiteralExpression>node).elements, f, result);
result = reduceNodes((<ArrayLiteralExpression>node).elements, cbNodes, result);
break;
case SyntaxKind.ObjectLiteralExpression:
result = reduceLeft((<ObjectLiteralExpression>node).properties, f, result);
result = reduceNodes((<ObjectLiteralExpression>node).properties, cbNodes, result);
break;
case SyntaxKind.PropertyAccessExpression:
result = reduceNode((<PropertyAccessExpression>node).expression, f, result);
result = reduceNode((<PropertyAccessExpression>node).name, f, result);
result = reduceNode((<PropertyAccessExpression>node).expression, cbNode, result);
result = reduceNode((<PropertyAccessExpression>node).name, cbNode, result);
break;
case SyntaxKind.ElementAccessExpression:
result = reduceNode((<ElementAccessExpression>node).expression, f, result);
result = reduceNode((<ElementAccessExpression>node).argumentExpression, f, result);
result = reduceNode((<ElementAccessExpression>node).expression, cbNode, result);
result = reduceNode((<ElementAccessExpression>node).argumentExpression, cbNode, result);
break;
case SyntaxKind.CallExpression:
result = reduceNode((<CallExpression>node).expression, f, result);
result = reduceLeft((<CallExpression>node).typeArguments, f, result);
result = reduceLeft((<CallExpression>node).arguments, f, result);
result = reduceNode((<CallExpression>node).expression, cbNode, result);
result = reduceNodes((<CallExpression>node).typeArguments, cbNodes, result);
result = reduceNodes((<CallExpression>node).arguments, cbNodes, result);
break;
case SyntaxKind.NewExpression:
result = reduceNode((<NewExpression>node).expression, f, result);
result = reduceLeft((<NewExpression>node).typeArguments, f, result);
result = reduceLeft((<NewExpression>node).arguments, f, result);
result = reduceNode((<NewExpression>node).expression, cbNode, result);
result = reduceNodes((<NewExpression>node).typeArguments, cbNodes, result);
result = reduceNodes((<NewExpression>node).arguments, cbNodes, result);
break;
case SyntaxKind.TaggedTemplateExpression:
result = reduceNode((<TaggedTemplateExpression>node).tag, f, result);
result = reduceNode((<TaggedTemplateExpression>node).template, f, result);
result = reduceNode((<TaggedTemplateExpression>node).tag, cbNode, result);
result = reduceNode((<TaggedTemplateExpression>node).template, cbNode, result);
break;
case SyntaxKind.FunctionExpression:
result = reduceLeft((<FunctionExpression>node).modifiers, f, result);
result = reduceNode((<FunctionExpression>node).name, f, result);
result = reduceLeft((<FunctionExpression>node).typeParameters, f, result);
result = reduceLeft((<FunctionExpression>node).parameters, f, result);
result = reduceNode((<FunctionExpression>node).type, f, result);
result = reduceNode((<FunctionExpression>node).body, f, result);
result = reduceNodes((<FunctionExpression>node).modifiers, cbNodes, result);
result = reduceNode((<FunctionExpression>node).name, cbNode, result);
result = reduceNodes((<FunctionExpression>node).typeParameters, cbNodes, result);
result = reduceNodes((<FunctionExpression>node).parameters, cbNodes, result);
result = reduceNode((<FunctionExpression>node).type, cbNode, result);
result = reduceNode((<FunctionExpression>node).body, cbNode, result);
break;
case SyntaxKind.ArrowFunction:
result = reduceLeft((<ArrowFunction>node).modifiers, f, result);
result = reduceLeft((<ArrowFunction>node).typeParameters, f, result);
result = reduceLeft((<ArrowFunction>node).parameters, f, result);
result = reduceNode((<ArrowFunction>node).type, f, result);
result = reduceNode((<ArrowFunction>node).body, f, result);
result = reduceNodes((<ArrowFunction>node).modifiers, cbNodes, result);
result = reduceNodes((<ArrowFunction>node).typeParameters, cbNodes, result);
result = reduceNodes((<ArrowFunction>node).parameters, cbNodes, result);
result = reduceNode((<ArrowFunction>node).type, cbNode, result);
result = reduceNode((<ArrowFunction>node).body, cbNode, result);
break;
case SyntaxKind.ParenthesizedExpression:
@ -269,258 +275,258 @@ namespace ts {
case SyntaxKind.YieldExpression:
case SyntaxKind.SpreadElement:
case SyntaxKind.NonNullExpression:
result = reduceNode((<ParenthesizedExpression | DeleteExpression | TypeOfExpression | VoidExpression | AwaitExpression | YieldExpression | SpreadElement | NonNullExpression>node).expression, f, result);
result = reduceNode((<ParenthesizedExpression | DeleteExpression | TypeOfExpression | VoidExpression | AwaitExpression | YieldExpression | SpreadElement | NonNullExpression>node).expression, cbNode, result);
break;
case SyntaxKind.PrefixUnaryExpression:
case SyntaxKind.PostfixUnaryExpression:
result = reduceNode((<PrefixUnaryExpression | PostfixUnaryExpression>node).operand, f, result);
result = reduceNode((<PrefixUnaryExpression | PostfixUnaryExpression>node).operand, cbNode, result);
break;
case SyntaxKind.BinaryExpression:
result = reduceNode((<BinaryExpression>node).left, f, result);
result = reduceNode((<BinaryExpression>node).right, f, result);
result = reduceNode((<BinaryExpression>node).left, cbNode, result);
result = reduceNode((<BinaryExpression>node).right, cbNode, result);
break;
case SyntaxKind.ConditionalExpression:
result = reduceNode((<ConditionalExpression>node).condition, f, result);
result = reduceNode((<ConditionalExpression>node).whenTrue, f, result);
result = reduceNode((<ConditionalExpression>node).whenFalse, f, result);
result = reduceNode((<ConditionalExpression>node).condition, cbNode, result);
result = reduceNode((<ConditionalExpression>node).whenTrue, cbNode, result);
result = reduceNode((<ConditionalExpression>node).whenFalse, cbNode, result);
break;
case SyntaxKind.TemplateExpression:
result = reduceNode((<TemplateExpression>node).head, f, result);
result = reduceLeft((<TemplateExpression>node).templateSpans, f, result);
result = reduceNode((<TemplateExpression>node).head, cbNode, result);
result = reduceNodes((<TemplateExpression>node).templateSpans, cbNodes, result);
break;
case SyntaxKind.ClassExpression:
result = reduceLeft((<ClassExpression>node).modifiers, f, result);
result = reduceNode((<ClassExpression>node).name, f, result);
result = reduceLeft((<ClassExpression>node).typeParameters, f, result);
result = reduceLeft((<ClassExpression>node).heritageClauses, f, result);
result = reduceLeft((<ClassExpression>node).members, f, result);
result = reduceNodes((<ClassExpression>node).modifiers, cbNodes, result);
result = reduceNode((<ClassExpression>node).name, cbNode, result);
result = reduceNodes((<ClassExpression>node).typeParameters, cbNodes, result);
result = reduceNodes((<ClassExpression>node).heritageClauses, cbNodes, result);
result = reduceNodes((<ClassExpression>node).members, cbNodes, result);
break;
case SyntaxKind.ExpressionWithTypeArguments:
result = reduceNode((<ExpressionWithTypeArguments>node).expression, f, result);
result = reduceLeft((<ExpressionWithTypeArguments>node).typeArguments, f, result);
result = reduceNode((<ExpressionWithTypeArguments>node).expression, cbNode, result);
result = reduceNodes((<ExpressionWithTypeArguments>node).typeArguments, cbNodes, result);
break;
// Misc
case SyntaxKind.TemplateSpan:
result = reduceNode((<TemplateSpan>node).expression, f, result);
result = reduceNode((<TemplateSpan>node).literal, f, result);
result = reduceNode((<TemplateSpan>node).expression, cbNode, result);
result = reduceNode((<TemplateSpan>node).literal, cbNode, result);
break;
// Element
case SyntaxKind.Block:
result = reduceLeft((<Block>node).statements, f, result);
result = reduceNodes((<Block>node).statements, cbNodes, result);
break;
case SyntaxKind.VariableStatement:
result = reduceLeft((<VariableStatement>node).modifiers, f, result);
result = reduceNode((<VariableStatement>node).declarationList, f, result);
result = reduceNodes((<VariableStatement>node).modifiers, cbNodes, result);
result = reduceNode((<VariableStatement>node).declarationList, cbNode, result);
break;
case SyntaxKind.ExpressionStatement:
result = reduceNode((<ExpressionStatement>node).expression, f, result);
result = reduceNode((<ExpressionStatement>node).expression, cbNode, result);
break;
case SyntaxKind.IfStatement:
result = reduceNode((<IfStatement>node).expression, f, result);
result = reduceNode((<IfStatement>node).thenStatement, f, result);
result = reduceNode((<IfStatement>node).elseStatement, f, result);
result = reduceNode((<IfStatement>node).expression, cbNode, result);
result = reduceNode((<IfStatement>node).thenStatement, cbNode, result);
result = reduceNode((<IfStatement>node).elseStatement, cbNode, result);
break;
case SyntaxKind.DoStatement:
result = reduceNode((<DoStatement>node).statement, f, result);
result = reduceNode((<DoStatement>node).expression, f, result);
result = reduceNode((<DoStatement>node).statement, cbNode, result);
result = reduceNode((<DoStatement>node).expression, cbNode, result);
break;
case SyntaxKind.WhileStatement:
case SyntaxKind.WithStatement:
result = reduceNode((<WhileStatement | WithStatement>node).expression, f, result);
result = reduceNode((<WhileStatement | WithStatement>node).statement, f, result);
result = reduceNode((<WhileStatement | WithStatement>node).expression, cbNode, result);
result = reduceNode((<WhileStatement | WithStatement>node).statement, cbNode, result);
break;
case SyntaxKind.ForStatement:
result = reduceNode((<ForStatement>node).initializer, f, result);
result = reduceNode((<ForStatement>node).condition, f, result);
result = reduceNode((<ForStatement>node).incrementor, f, result);
result = reduceNode((<ForStatement>node).statement, f, result);
result = reduceNode((<ForStatement>node).initializer, cbNode, result);
result = reduceNode((<ForStatement>node).condition, cbNode, result);
result = reduceNode((<ForStatement>node).incrementor, cbNode, result);
result = reduceNode((<ForStatement>node).statement, cbNode, result);
break;
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
result = reduceNode((<ForInStatement | ForOfStatement>node).initializer, f, result);
result = reduceNode((<ForInStatement | ForOfStatement>node).expression, f, result);
result = reduceNode((<ForInStatement | ForOfStatement>node).statement, f, result);
result = reduceNode((<ForInStatement | ForOfStatement>node).initializer, cbNode, result);
result = reduceNode((<ForInStatement | ForOfStatement>node).expression, cbNode, result);
result = reduceNode((<ForInStatement | ForOfStatement>node).statement, cbNode, result);
break;
case SyntaxKind.ReturnStatement:
case SyntaxKind.ThrowStatement:
result = reduceNode((<ReturnStatement>node).expression, f, result);
result = reduceNode((<ReturnStatement>node).expression, cbNode, result);
break;
case SyntaxKind.SwitchStatement:
result = reduceNode((<SwitchStatement>node).expression, f, result);
result = reduceNode((<SwitchStatement>node).caseBlock, f, result);
result = reduceNode((<SwitchStatement>node).expression, cbNode, result);
result = reduceNode((<SwitchStatement>node).caseBlock, cbNode, result);
break;
case SyntaxKind.LabeledStatement:
result = reduceNode((<LabeledStatement>node).label, f, result);
result = reduceNode((<LabeledStatement>node).statement, f, result);
result = reduceNode((<LabeledStatement>node).label, cbNode, result);
result = reduceNode((<LabeledStatement>node).statement, cbNode, result);
break;
case SyntaxKind.TryStatement:
result = reduceNode((<TryStatement>node).tryBlock, f, result);
result = reduceNode((<TryStatement>node).catchClause, f, result);
result = reduceNode((<TryStatement>node).finallyBlock, f, result);
result = reduceNode((<TryStatement>node).tryBlock, cbNode, result);
result = reduceNode((<TryStatement>node).catchClause, cbNode, result);
result = reduceNode((<TryStatement>node).finallyBlock, cbNode, result);
break;
case SyntaxKind.VariableDeclaration:
result = reduceNode((<VariableDeclaration>node).name, f, result);
result = reduceNode((<VariableDeclaration>node).type, f, result);
result = reduceNode((<VariableDeclaration>node).initializer, f, result);
result = reduceNode((<VariableDeclaration>node).name, cbNode, result);
result = reduceNode((<VariableDeclaration>node).type, cbNode, result);
result = reduceNode((<VariableDeclaration>node).initializer, cbNode, result);
break;
case SyntaxKind.VariableDeclarationList:
result = reduceLeft((<VariableDeclarationList>node).declarations, f, result);
result = reduceNodes((<VariableDeclarationList>node).declarations, cbNodes, result);
break;
case SyntaxKind.FunctionDeclaration:
result = reduceLeft((<FunctionDeclaration>node).decorators, f, result);
result = reduceLeft((<FunctionDeclaration>node).modifiers, f, result);
result = reduceNode((<FunctionDeclaration>node).name, f, result);
result = reduceLeft((<FunctionDeclaration>node).typeParameters, f, result);
result = reduceLeft((<FunctionDeclaration>node).parameters, f, result);
result = reduceNode((<FunctionDeclaration>node).type, f, result);
result = reduceNode((<FunctionDeclaration>node).body, f, result);
result = reduceNodes((<FunctionDeclaration>node).decorators, cbNodes, result);
result = reduceNodes((<FunctionDeclaration>node).modifiers, cbNodes, result);
result = reduceNode((<FunctionDeclaration>node).name, cbNode, result);
result = reduceNodes((<FunctionDeclaration>node).typeParameters, cbNodes, result);
result = reduceNodes((<FunctionDeclaration>node).parameters, cbNodes, result);
result = reduceNode((<FunctionDeclaration>node).type, cbNode, result);
result = reduceNode((<FunctionDeclaration>node).body, cbNode, result);
break;
case SyntaxKind.ClassDeclaration:
result = reduceLeft((<ClassDeclaration>node).decorators, f, result);
result = reduceLeft((<ClassDeclaration>node).modifiers, f, result);
result = reduceNode((<ClassDeclaration>node).name, f, result);
result = reduceLeft((<ClassDeclaration>node).typeParameters, f, result);
result = reduceLeft((<ClassDeclaration>node).heritageClauses, f, result);
result = reduceLeft((<ClassDeclaration>node).members, f, result);
result = reduceNodes((<ClassDeclaration>node).decorators, cbNodes, result);
result = reduceNodes((<ClassDeclaration>node).modifiers, cbNodes, result);
result = reduceNode((<ClassDeclaration>node).name, cbNode, result);
result = reduceNodes((<ClassDeclaration>node).typeParameters, cbNodes, result);
result = reduceNodes((<ClassDeclaration>node).heritageClauses, cbNodes, result);
result = reduceNodes((<ClassDeclaration>node).members, cbNodes, result);
break;
case SyntaxKind.CaseBlock:
result = reduceLeft((<CaseBlock>node).clauses, f, result);
result = reduceNodes((<CaseBlock>node).clauses, cbNodes, result);
break;
case SyntaxKind.ImportDeclaration:
result = reduceLeft((<ImportDeclaration>node).decorators, f, result);
result = reduceLeft((<ImportDeclaration>node).modifiers, f, result);
result = reduceNode((<ImportDeclaration>node).importClause, f, result);
result = reduceNode((<ImportDeclaration>node).moduleSpecifier, f, result);
result = reduceNodes((<ImportDeclaration>node).decorators, cbNodes, result);
result = reduceNodes((<ImportDeclaration>node).modifiers, cbNodes, result);
result = reduceNode((<ImportDeclaration>node).importClause, cbNode, result);
result = reduceNode((<ImportDeclaration>node).moduleSpecifier, cbNode, result);
break;
case SyntaxKind.ImportClause:
result = reduceNode((<ImportClause>node).name, f, result);
result = reduceNode((<ImportClause>node).namedBindings, f, result);
result = reduceNode((<ImportClause>node).name, cbNode, result);
result = reduceNode((<ImportClause>node).namedBindings, cbNode, result);
break;
case SyntaxKind.NamespaceImport:
result = reduceNode((<NamespaceImport>node).name, f, result);
result = reduceNode((<NamespaceImport>node).name, cbNode, result);
break;
case SyntaxKind.NamedImports:
case SyntaxKind.NamedExports:
result = reduceLeft((<NamedImports | NamedExports>node).elements, f, result);
result = reduceNodes((<NamedImports | NamedExports>node).elements, cbNodes, result);
break;
case SyntaxKind.ImportSpecifier:
case SyntaxKind.ExportSpecifier:
result = reduceNode((<ImportSpecifier | ExportSpecifier>node).propertyName, f, result);
result = reduceNode((<ImportSpecifier | ExportSpecifier>node).name, f, result);
result = reduceNode((<ImportSpecifier | ExportSpecifier>node).propertyName, cbNode, result);
result = reduceNode((<ImportSpecifier | ExportSpecifier>node).name, cbNode, result);
break;
case SyntaxKind.ExportAssignment:
result = reduceLeft((<ExportAssignment>node).decorators, f, result);
result = reduceLeft((<ExportAssignment>node).modifiers, f, result);
result = reduceNode((<ExportAssignment>node).expression, f, result);
result = reduceLeft((<ExportAssignment>node).decorators, cbNode, result);
result = reduceLeft((<ExportAssignment>node).modifiers, cbNode, result);
result = reduceNode((<ExportAssignment>node).expression, cbNode, result);
break;
case SyntaxKind.ExportDeclaration:
result = reduceLeft((<ExportDeclaration>node).decorators, f, result);
result = reduceLeft((<ExportDeclaration>node).modifiers, f, result);
result = reduceNode((<ExportDeclaration>node).exportClause, f, result);
result = reduceNode((<ExportDeclaration>node).moduleSpecifier, f, result);
result = reduceLeft((<ExportDeclaration>node).decorators, cbNode, result);
result = reduceLeft((<ExportDeclaration>node).modifiers, cbNode, result);
result = reduceNode((<ExportDeclaration>node).exportClause, cbNode, result);
result = reduceNode((<ExportDeclaration>node).moduleSpecifier, cbNode, result);
break;
// JSX
case SyntaxKind.JsxElement:
result = reduceNode((<JsxElement>node).openingElement, f, result);
result = reduceLeft((<JsxElement>node).children, f, result);
result = reduceNode((<JsxElement>node).closingElement, f, result);
result = reduceNode((<JsxElement>node).openingElement, cbNode, result);
result = reduceLeft((<JsxElement>node).children, cbNode, result);
result = reduceNode((<JsxElement>node).closingElement, cbNode, result);
break;
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxOpeningElement:
result = reduceNode((<JsxSelfClosingElement | JsxOpeningElement>node).tagName, f, result);
result = reduceLeft((<JsxSelfClosingElement | JsxOpeningElement>node).attributes, f, result);
result = reduceNode((<JsxSelfClosingElement | JsxOpeningElement>node).tagName, cbNode, result);
result = reduceNodes((<JsxSelfClosingElement | JsxOpeningElement>node).attributes, cbNodes, result);
break;
case SyntaxKind.JsxClosingElement:
result = reduceNode((<JsxClosingElement>node).tagName, f, result);
result = reduceNode((<JsxClosingElement>node).tagName, cbNode, result);
break;
case SyntaxKind.JsxAttribute:
result = reduceNode((<JsxAttribute>node).name, f, result);
result = reduceNode((<JsxAttribute>node).initializer, f, result);
result = reduceNode((<JsxAttribute>node).name, cbNode, result);
result = reduceNode((<JsxAttribute>node).initializer, cbNode, result);
break;
case SyntaxKind.JsxSpreadAttribute:
result = reduceNode((<JsxSpreadAttribute>node).expression, f, result);
result = reduceNode((<JsxSpreadAttribute>node).expression, cbNode, result);
break;
case SyntaxKind.JsxExpression:
result = reduceNode((<JsxExpression>node).expression, f, result);
result = reduceNode((<JsxExpression>node).expression, cbNode, result);
break;
// Clauses
case SyntaxKind.CaseClause:
result = reduceNode((<CaseClause>node).expression, f, result);
result = reduceNode((<CaseClause>node).expression, cbNode, result);
// fall-through
case SyntaxKind.DefaultClause:
result = reduceLeft((<CaseClause | DefaultClause>node).statements, f, result);
result = reduceNodes((<CaseClause | DefaultClause>node).statements, cbNodes, result);
break;
case SyntaxKind.HeritageClause:
result = reduceLeft((<HeritageClause>node).types, f, result);
result = reduceNodes((<HeritageClause>node).types, cbNodes, result);
break;
case SyntaxKind.CatchClause:
result = reduceNode((<CatchClause>node).variableDeclaration, f, result);
result = reduceNode((<CatchClause>node).block, f, result);
result = reduceNode((<CatchClause>node).variableDeclaration, cbNode, result);
result = reduceNode((<CatchClause>node).block, cbNode, result);
break;
// Property assignments
case SyntaxKind.PropertyAssignment:
result = reduceNode((<PropertyAssignment>node).name, f, result);
result = reduceNode((<PropertyAssignment>node).initializer, f, result);
result = reduceNode((<PropertyAssignment>node).name, cbNode, result);
result = reduceNode((<PropertyAssignment>node).initializer, cbNode, result);
break;
case SyntaxKind.ShorthandPropertyAssignment:
result = reduceNode((<ShorthandPropertyAssignment>node).name, f, result);
result = reduceNode((<ShorthandPropertyAssignment>node).objectAssignmentInitializer, f, result);
result = reduceNode((<ShorthandPropertyAssignment>node).name, cbNode, result);
result = reduceNode((<ShorthandPropertyAssignment>node).objectAssignmentInitializer, cbNode, result);
break;
case SyntaxKind.SpreadAssignment:
result = reduceNode((node as SpreadAssignment).expression, f, result);
result = reduceNode((node as SpreadAssignment).expression, cbNode, result);
break;
// Top-level nodes
case SyntaxKind.SourceFile:
result = reduceLeft((<SourceFile>node).statements, f, result);
result = reduceNodes((<SourceFile>node).statements, cbNodes, result);
break;
case SyntaxKind.PartiallyEmittedExpression:
result = reduceNode((<PartiallyEmittedExpression>node).expression, f, result);
result = reduceNode((<PartiallyEmittedExpression>node).expression, cbNode, result);
break;
default:
@ -530,8 +536,8 @@ namespace ts {
const value = (<MapLike<any>>node)[edge.name];
if (value !== undefined) {
result = isArray(value)
? reduceLeft(<NodeArray<Node>>value, f, result)
: f(result, <Node>value);
? reduceNodes(<NodeArray<Node>>value, cbNodes, result)
: cbNode(result, <Node>value);
}
}
}
@ -553,8 +559,8 @@ namespace ts {
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray<Node>) => T): T;
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional: boolean, lift: (node: NodeArray<Node>) => T, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): T;
export function visitNode(node: Node, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional?: boolean, lift?: (node: Node[]) => Node, parenthesize?: (node: Node, parentNode: Node) => Node, parentNode?: Node): Node {
if (node === undefined) {
return undefined;
if (node === undefined || visitor === undefined) {
return node;
}
aggregateTransformFlags(node);
@ -659,6 +665,30 @@ namespace ts {
return updated || nodes;
}
export function visitLexicalEnvironment(nodes: NodeArray<Statement>, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment, start?: number) {
context.startLexicalEnvironment();
const updated = visitNodes(nodes, visitor, isStatement, start);
const declarations = context.endLexicalEnvironment();
return createNodeArray(concatenate(updated, declarations), updated);
}
export function visitParameterList(nodes: NodeArray<ParameterDeclaration>, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment) {
context.startLexicalEnvironment();
return visitNodes(nodes, visitor, isParameter);
}
export function visitFunctionBody(node: FunctionBody, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment): FunctionBody;
export function visitFunctionBody(node: ConciseBody, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment): ConciseBody;
export function visitFunctionBody(node: ConciseBody, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment) {
const visited = visitNode(node, visitor, isConciseBody);
const declarations = context.endLexicalEnvironment();
if (some(declarations)) {
const block = convertToFunctionBody(visited);
return updateBlock(block, createNodeArray(concatenate(block.statements, declarations), block.statements));
}
return visited;
}
/**
* Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place.
*
@ -721,41 +751,33 @@ namespace ts {
visitNodes((<MethodDeclaration>node).modifiers, visitor, isModifier),
visitNode((<MethodDeclaration>node).name, visitor, isPropertyName),
visitNodes((<MethodDeclaration>node).typeParameters, visitor, isTypeParameter),
(context.startLexicalEnvironment(), visitNodes((<MethodDeclaration>node).parameters, visitor, isParameter)),
visitParameterList((<MethodDeclaration>node).parameters, visitor, context),
visitNode((<MethodDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
mergeFunctionBodyLexicalEnvironment(
visitNode((<MethodDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
context.endLexicalEnvironment()));
visitFunctionBody((<MethodDeclaration>node).body, visitor, context));
case SyntaxKind.Constructor:
return updateConstructor(<ConstructorDeclaration>node,
visitNodes((<ConstructorDeclaration>node).decorators, visitor, isDecorator),
visitNodes((<ConstructorDeclaration>node).modifiers, visitor, isModifier),
(context.startLexicalEnvironment(), visitNodes((<ConstructorDeclaration>node).parameters, visitor, isParameter)),
mergeFunctionBodyLexicalEnvironment(
visitNode((<ConstructorDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
context.endLexicalEnvironment()));
visitParameterList((<ConstructorDeclaration>node).parameters, visitor, context),
visitFunctionBody((<ConstructorDeclaration>node).body, visitor, context));
case SyntaxKind.GetAccessor:
return updateGetAccessor(<GetAccessorDeclaration>node,
visitNodes((<GetAccessorDeclaration>node).decorators, visitor, isDecorator),
visitNodes((<GetAccessorDeclaration>node).modifiers, visitor, isModifier),
visitNode((<GetAccessorDeclaration>node).name, visitor, isPropertyName),
(context.startLexicalEnvironment(), visitNodes((<GetAccessorDeclaration>node).parameters, visitor, isParameter)),
visitParameterList((<GetAccessorDeclaration>node).parameters, visitor, context),
visitNode((<GetAccessorDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
mergeFunctionBodyLexicalEnvironment(
visitNode((<GetAccessorDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
context.endLexicalEnvironment()));
visitFunctionBody((<GetAccessorDeclaration>node).body, visitor, context));
case SyntaxKind.SetAccessor:
return updateSetAccessor(<SetAccessorDeclaration>node,
visitNodes((<SetAccessorDeclaration>node).decorators, visitor, isDecorator),
visitNodes((<SetAccessorDeclaration>node).modifiers, visitor, isModifier),
visitNode((<SetAccessorDeclaration>node).name, visitor, isPropertyName),
(context.startLexicalEnvironment(), visitNodes((<SetAccessorDeclaration>node).parameters, visitor, isParameter)),
mergeFunctionBodyLexicalEnvironment(
visitNode((<SetAccessorDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
context.endLexicalEnvironment()));
visitParameterList((<SetAccessorDeclaration>node).parameters, visitor, context),
visitFunctionBody((<SetAccessorDeclaration>node).body, visitor, context));
// Binding patterns
case SyntaxKind.ObjectBindingPattern:
@ -818,21 +840,17 @@ namespace ts {
visitNodes((<FunctionExpression>node).modifiers, visitor, isModifier),
visitNode((<FunctionExpression>node).name, visitor, isPropertyName),
visitNodes((<FunctionExpression>node).typeParameters, visitor, isTypeParameter),
(context.startLexicalEnvironment(), visitNodes((<FunctionExpression>node).parameters, visitor, isParameter)),
visitParameterList((<FunctionExpression>node).parameters, visitor, context),
visitNode((<FunctionExpression>node).type, visitor, isTypeNode, /*optional*/ true),
mergeFunctionBodyLexicalEnvironment(
visitNode((<FunctionExpression>node).body, visitor, isFunctionBody, /*optional*/ true),
context.endLexicalEnvironment()));
visitFunctionBody((<FunctionExpression>node).body, visitor, context));
case SyntaxKind.ArrowFunction:
return updateArrowFunction(<ArrowFunction>node,
visitNodes((<ArrowFunction>node).modifiers, visitor, isModifier),
visitNodes((<ArrowFunction>node).typeParameters, visitor, isTypeParameter),
(context.startLexicalEnvironment(), visitNodes((<ArrowFunction>node).parameters, visitor, isParameter)),
visitParameterList((<ArrowFunction>node).parameters, visitor, context),
visitNode((<ArrowFunction>node).type, visitor, isTypeNode, /*optional*/ true),
mergeFunctionBodyLexicalEnvironment(
visitNode((<ArrowFunction>node).body, visitor, isConciseBody, /*optional*/ true),
context.endLexicalEnvironment()));
visitFunctionBody((<ArrowFunction>node).body, visitor, context));
case SyntaxKind.DeleteExpression:
return updateDelete(<DeleteExpression>node,
@ -1003,11 +1021,9 @@ namespace ts {
visitNodes((<FunctionDeclaration>node).modifiers, visitor, isModifier),
visitNode((<FunctionDeclaration>node).name, visitor, isPropertyName),
visitNodes((<FunctionDeclaration>node).typeParameters, visitor, isTypeParameter),
(context.startLexicalEnvironment(), visitNodes((<FunctionDeclaration>node).parameters, visitor, isParameter)),
visitParameterList((<FunctionDeclaration>node).parameters, visitor, context),
visitNode((<FunctionDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
mergeFunctionBodyLexicalEnvironment(
visitNode((<FunctionDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
context.endLexicalEnvironment()));
visitFunctionBody((<FunctionDeclaration>node).body, visitor, context));
case SyntaxKind.ClassDeclaration:
return updateClassDeclaration(<ClassDeclaration>node,
@ -1139,13 +1155,8 @@ namespace ts {
// Top-level nodes
case SyntaxKind.SourceFile:
context.startLexicalEnvironment();
return updateSourceFileNode(<SourceFile>node,
createNodeArray(
concatenate(
visitNodes((<SourceFile>node).statements, visitor, isStatement),
context.endLexicalEnvironment()),
(<SourceFile>node).statements));
visitLexicalEnvironment((<SourceFile>node).statements, visitor, context));
// Transformation nodes
case SyntaxKind.PartiallyEmittedExpression:
@ -1249,13 +1260,25 @@ namespace ts {
if (node === undefined) {
return TransformFlags.None;
}
else if (node.transformFlags & TransformFlags.HasComputedFlags) {
if (node.transformFlags & TransformFlags.HasComputedFlags) {
return node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind);
}
else {
const subtreeFlags = aggregateTransformFlagsForSubtree(node);
return computeTransformFlagsForNode(node, subtreeFlags);
const subtreeFlags = aggregateTransformFlagsForSubtree(node);
return computeTransformFlagsForNode(node, subtreeFlags);
}
function aggregateTransformFlagsForNodeArray(nodes: NodeArray<Node>): TransformFlags {
if (nodes === undefined) {
return TransformFlags.None;
}
let subtreeFlags = TransformFlags.None;
let nodeArrayFlags = TransformFlags.None;
for (const node of nodes) {
subtreeFlags |= aggregateTransformFlagsForNode(node);
nodeArrayFlags |= node.transformFlags & ~TransformFlags.HasComputedFlags;
}
nodes.transformFlags = nodeArrayFlags | TransformFlags.HasComputedFlags;
return subtreeFlags;
}
/**
@ -1269,15 +1292,19 @@ namespace ts {
}
// Aggregate the transform flags of each child.
return reduceEachChild(node, aggregateTransformFlagsForChildNode, TransformFlags.None);
return reduceEachChild(node, TransformFlags.None, aggregateTransformFlagsForChildNode, aggregateTransformFlagsForChildNodes);
}
/**
* Aggregates the TransformFlags of a child node with the TransformFlags of its
* siblings.
*/
function aggregateTransformFlagsForChildNode(transformFlags: TransformFlags, child: Node): TransformFlags {
return transformFlags | aggregateTransformFlagsForNode(child);
function aggregateTransformFlagsForChildNode(transformFlags: TransformFlags, node: Node): TransformFlags {
return transformFlags | aggregateTransformFlagsForNode(node);
}
function aggregateTransformFlagsForChildNodes(transformFlags: TransformFlags, nodes: NodeArray<Node>): TransformFlags {
return transformFlags | aggregateTransformFlagsForNodeArray(nodes);
}
export namespace Debug {

View File

@ -37,17 +37,17 @@ x = [true][0];
x; // boolean
_a = [1][0], x = _a === void 0 ? "" : _a;
x; // string | number
(_b = { x: true }, x = _b.x, _b);
(x = { x: true }.x);
x; // boolean
(_c = { y: 1 }, x = _c.y, _c);
(x = { y: 1 }.y);
x; // number
(_d = { x: true }, _e = _d.x, x = _e === void 0 ? "" : _e, _d);
(_b = { x: true }.x, x = _b === void 0 ? "" : _b);
x; // string | boolean
(_f = { y: 1 }, _g = _f.y, x = _g === void 0 ? /a/ : _g, _f);
(_c = { y: 1 }.y, x = _c === void 0 ? /a/ : _c);
x; // number | RegExp
var a;
for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
x = a_1[_i];
x; // string
}
var _a, _b, _c, _d, _e, _f, _g;
var _a, _b, _c;

View File

@ -81,8 +81,8 @@ var B = (function (_super) {
// async method with assignment/destructuring on 'super' requires a binding
B.prototype.advanced = function () {
return __awaiter(this, void 0, void 0, function () {
var f, a, b, _a, _b;
return __generator(this, function (_c) {
var f, a, b;
return __generator(this, function (_a) {
f = function () { };
// call with property access
_super.prototype.x.call(this);
@ -95,9 +95,9 @@ var B = (function (_super) {
// element access (assign)
_super.prototype["x"] = f;
// destructuring assign with property access
(_a = { f: f }, super.x = _a.f, _a);
(_super.prototype.x = { f: f }.f);
// destructuring assign with element access
(_b = { f: f }, super["x"] = _b.f, _b);
(_super.prototype["x"] = { f: f }.f);
return [2 /*return*/];
});
});

View File

@ -65,11 +65,11 @@ function f5(_a) {
var _f = foo(), bar6 = [{ bar: "bar" }][0][_f];
var _g = foo.toExponential(), bar7 = [{ bar: "bar" }][0][_g];
// destructuring assignment
(_h = { bar: "bar" }, _j = foo, bar = _h[_j], _h);
(_k = { bar: "bar" }, _l = "bar", bar2 = _k[_l], _k);
(_m = { bar: "bar" }, _o = foo2(), bar3 = _m[_o], _m);
_p = foo, bar4 = [{ bar: "bar" }][0][_p];
_q = foo2(), bar5 = [{ bar: "bar" }][0][_q];
_r = foo(), bar4 = [{ bar: "bar" }][0][_r];
_s = (1 + {}), bar4 = [{ bar: "bar" }][0][_s];
var _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
(_h = foo, bar = { bar: "bar" }[_h]);
(_j = "bar", bar2 = { bar: "bar" }[_j]);
(_k = foo2(), bar3 = { bar: "bar" }[_k]);
_l = foo, bar4 = [{ bar: "bar" }][0][_l];
_m = foo2(), bar5 = [{ bar: "bar" }][0][_m];
_o = foo(), bar4 = [{ bar: "bar" }][0][_o];
_p = (1 + {}), bar4 = [{ bar: "bar" }][0][_p];
var _h, _j, _k, _l, _m, _o, _p;

View File

@ -300,8 +300,8 @@ function f18() {
var a;
var b;
var aa;
(_a = { a: a, b: b }, a = _a.a, b = _a.b, _a);
(_b = { b: b, a: a }, a = _b.a, b = _b.b, _b);
(_a = { a: a, b: b }, a = _a.a, b = _a.b);
(_b = { b: b, a: a }, a = _b.a, b = _b.b);
_c = [a, b], aa[0] = _c[0], b = _c[1];
_d = [b, a], a = _d[0], b = _d[1]; // Error
_e = [2, "def"], _f = _e[0], a = _f === void 0 ? 1 : _f, _g = _e[1], b = _g === void 0 ? "abc" : _g;
@ -311,7 +311,7 @@ function f19() {
var a, b;
_a = [1, 2], a = _a[0], b = _a[1];
_b = [b, a], a = _b[0], b = _b[1];
(_c = { b: b, a: a }, a = _c.a, b = _c.b, _c);
(_c = { b: b, a: a }, a = _c.a, b = _c.b);
_d = [[2, 3]][0], _e = _d === void 0 ? [1, 2] : _d, a = _e[0], b = _e[1];
var x = (_f = [1, 2], a = _f[0], b = _f[1], _f);
var _a, _b, _c, _d, _e, _f;

View File

@ -7,5 +7,5 @@ let x = 0;
//// [destructuringAssignmentWithDefault.js]
var a = {};
var x = 0;
(_a = a.x, x = _a === void 0 ? 1 : _a, a);
(_a = a.x, x = _a === void 0 ? 1 : _a);
var _a;

View File

@ -9,8 +9,8 @@ let x, y, z, a1, a2, a3;
//// [emptyAssignmentPatterns02_ES5.js]
var a;
var x, y, z, a1, a2, a3;
(x = a.x, y = a.y, z = a.z, a);
(a1 = a[0], a2 = a[1], a3 = a[2], a);
(x = a.x, y = a.y, z = a.z);
(a1 = a[0], a2 = a[1], a3 = a[2]);
//// [emptyAssignmentPatterns02_ES5.d.ts]

View File

@ -9,9 +9,8 @@ let x, y, z, a1, a2, a3;
//// [emptyAssignmentPatterns04_ES5.js]
var a;
var x, y, z, a1, a2, a3;
(_a = a, x = _a.x, y = _a.y, z = _a.z, _a);
(_b = a, a1 = _b[0], a2 = _b[1], a3 = _b[2], _b);
var _a, _b;
(x = a.x, y = a.y, z = a.z);
(a1 = a[0], a2 = a[1], a3 = a[2]);
//// [emptyAssignmentPatterns04_ES5.d.ts]

View File

@ -28,7 +28,6 @@ if (true) {
var x_1 = { x: 0 }.x;
var y_1 = { y: 0 }.y;
var z_1;
(_a = { z: 0 }, z_1 = _a.z, _a);
(_b = { z: 0 }, z_1 = _b.z, _b);
(z_1 = { z: 0 }.z);
(z_1 = { z: 0 }.z);
}
var _a, _b;

View File

@ -45,10 +45,10 @@ function f1() {
// Missing properties
function f2() {
var x, y;
(_a = {}, x = _a.x, y = _a.y, _a);
(_b = {}, _c = _b.x, x = _c === void 0 ? 1 : _c, y = _b.y, _b);
(_d = {}, x = _d.x, _e = _d.y, y = _e === void 0 ? 1 : _e, _d);
(_f = {}, _g = _f.x, x = _g === void 0 ? 1 : _g, _h = _f.y, y = _h === void 0 ? 1 : _h, _f);
(_a = {}, x = _a.x, y = _a.y);
(_b = {}, _c = _b.x, x = _c === void 0 ? 1 : _c, y = _b.y);
(_d = {}, x = _d.x, _e = _d.y, y = _e === void 0 ? 1 : _e);
(_f = {}, _g = _f.x, x = _g === void 0 ? 1 : _g, _h = _f.y, y = _h === void 0 ? 1 : _h);
var _a, _b, _c, _d, _e, _f, _g, _h;
}
// Excess properties
@ -62,8 +62,8 @@ function f3() {
function f4() {
var x, y;
({ x: 0, y: 0 });
(_a = { x: 0, y: 0 }, x = _a.x, _a);
(_b = { x: 0, y: 0 }, y = _b.y, _b);
(_c = { x: 0, y: 0 }, x = _c.x, y = _c.y, _c);
var _a, _b, _c;
(x = { x: 0, y: 0 }.x);
(y = { x: 0, y: 0 }.y);
(_a = { x: 0, y: 0 }, x = _a.x, y = _a.y);
var _a;
}

View File

@ -53,9 +53,9 @@ let nestedrest;
var { x } = nestedrest, _a = nestedrest.n1, { y } = _a, _b = _a.n2, { z } = _b, nr = __rest(_b.n3, []), restrest = __rest(nestedrest, ["x", "n1"]);
let complex;
var _c = complex.x, { ka } = _c, nested = __rest(_c, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]);
(_d = complex.x, { ka } = _d, nested = __rest(_d, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]), complex);
(_d = complex.x, { ka } = _d, nested = __rest(_d, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]));
var _e = { x: 1, y: 2 }, { x } = _e, fresh = __rest(_e, ["x"]);
(_f = { x: 1, y: 2 }, { x } = _f, fresh = __rest(_f, ["x"]), _f);
(_f = { x: 1, y: 2 }, { x } = _f, fresh = __rest(_f, ["x"]));
class Removable {
set z(value) { }
get both() { return 12; }

View File

@ -26,10 +26,10 @@ let nested;
let other;
let rest;
let complex;
(_a = complex.x, { ka } = _a, nested = __rest(_a, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]), complex);
(_a = complex.x, { ka } = _a, nested = __rest(_a, ["ka"]), { y: other } = complex, rest = __rest(complex, ["x", "y"]));
// should be:
let overEmit;
// var _g = overEmit.a, [_h, ...y] = _g, nested2 = __rest(_h, []), _j = overEmit.b, { z } = _j, c = __rest(_j, ["z"]), rest2 = __rest(overEmit, ["a", "b"]);
var _b = overEmit.a, [_c, ...y] = _b, nested2 = __rest(_c, []), _d = overEmit.b, { z } = _d, c = __rest(_d, ["z"]), rest2 = __rest(overEmit, ["a", "b"]);
(_e = overEmit.a, [_f, ...y] = _e, nested2 = __rest(_f, []), _g = overEmit.b, { z } = _g, c = __rest(_g, ["z"]), rest2 = __rest(overEmit, ["a", "b"]), overEmit);
var _a, _e, _f, _g;
(_e = overEmit.a, [_f, ...y] = _e, nested2 = __rest(_f, []), _g = overEmit.b, { z } = _g, c = __rest(_g, ["z"]), rest2 = __rest(overEmit, ["a", "b"]));
var _a, _e, _g;

View File

@ -17,9 +17,9 @@ var __rest = (this && this.__rest) || function (s, e) {
return t;
};
var o = { a: 1, b: 'no' };
var mustBeLast = o.mustBeLast, a = o.a;
var a = o.a;
function stillMustBeLast(_a) {
var mustBeLast = _a.mustBeLast, a = _a.a;
var a = _a.a;
}
function generic(t) {
var x = t.x, rest = __rest(t, ["x"]);

View File

@ -176,63 +176,63 @@ function foo({a = 4, b = { x: 5 }}) {
});
(function () {
var y;
(_a = { y: 1 }, _b = _a.y, y = _b === void 0 ? 5 : _b, _a);
var _a, _b;
(_a = { y: 1 }.y, y = _a === void 0 ? 5 : _a);
var _a;
});
(function () {
var y;
(_a = { y: 1 }, _b = _a.y, y = _b === void 0 ? 5 : _b, _a);
var _a, _b;
(_a = { y: 1 }.y, y = _a === void 0 ? 5 : _a);
var _a;
});
(function () {
var y0;
(_a = { y0: 1 }, _b = _a.y0, y0 = _b === void 0 ? 5 : _b, _a);
var _a, _b;
(_a = { y0: 1 }.y0, y0 = _a === void 0 ? 5 : _a);
var _a;
});
(function () {
var y0;
(_a = { y0: 1 }, _b = _a.y0, y0 = _b === void 0 ? 5 : _b, _a);
var _a, _b;
(_a = { y0: 1 }.y0, y0 = _a === void 0 ? 5 : _a);
var _a;
});
(function () {
var y1;
(_a = {}, _b = _a.y1, y1 = _b === void 0 ? 5 : _b, _a);
var _a, _b;
(_a = {}.y1, y1 = _a === void 0 ? 5 : _a);
var _a;
});
(function () {
var y1;
(_a = {}, _b = _a.y1, y1 = _b === void 0 ? 5 : _b, _a);
var _a, _b;
(_a = {}.y1, y1 = _a === void 0 ? 5 : _a);
var _a;
});
(function () {
var y2, y3;
(_a = {}, _b = _a.y2, y2 = _b === void 0 ? 5 : _b, _c = _a.y3, y3 = _c === void 0 ? { x: 1 } : _c, _a);
(_a = {}, _b = _a.y2, y2 = _b === void 0 ? 5 : _b, _c = _a.y3, y3 = _c === void 0 ? { x: 1 } : _c);
var _a, _b, _c;
});
(function () {
var y2, y3;
(_a = {}, _b = _a.y2, y2 = _b === void 0 ? 5 : _b, _c = _a.y3, y3 = _c === void 0 ? { x: 1 } : _c, _a);
(_a = {}, _b = _a.y2, y2 = _b === void 0 ? 5 : _b, _c = _a.y3, y3 = _c === void 0 ? { x: 1 } : _c);
var _a, _b, _c;
});
(function () {
var y4, y5;
(_a = {}, _b = _a.y4, y4 = _b === void 0 ? 5 : _b, _c = _a.y5, y5 = _c === void 0 ? { x: 1 } : _c, _a);
(_a = {}, _b = _a.y4, y4 = _b === void 0 ? 5 : _b, _c = _a.y5, y5 = _c === void 0 ? { x: 1 } : _c);
var _a, _b, _c;
});
(function () {
var y4, y5;
(_a = {}, _b = _a.y4, y4 = _b === void 0 ? 5 : _b, _c = _a.y5, y5 = _c === void 0 ? { x: 1 } : _c, _a);
(_a = {}, _b = _a.y4, y4 = _b === void 0 ? 5 : _b, _c = _a.y5, y5 = _c === void 0 ? { x: 1 } : _c);
var _a, _b, _c;
});
(function () {
var z;
(_a = { z: { x: 1 } }, _b = _a.z, z = _b === void 0 ? { x: 5 } : _b, _a);
var _a, _b;
(_a = { z: { x: 1 } }.z, z = _a === void 0 ? { x: 5 } : _a);
var _a;
});
(function () {
var z;
(_a = { z: { x: 1 } }, _b = _a.z, z = _b === void 0 ? { x: 5 } : _b, _a);
var _a, _b;
(_a = { z: { x: 1 } }.z, z = _a === void 0 ? { x: 5 } : _a);
var _a;
});
(function () {
var a = { s: s };