Add more commonly used nodes, reduce less frequently used nodes.

This commit is contained in:
Ron Buckton
2016-07-20 17:36:18 -07:00
parent ec9c4d26f9
commit d119167653
8 changed files with 646 additions and 403 deletions
+242 -89
View File
@@ -210,20 +210,6 @@ namespace ts {
// Names
export function createQualifiedName(left: EntityName, right: Identifier, location?: TextRange) {
const node = <QualifiedName>createNode(SyntaxKind.QualifiedName, location);
node.left = left;
node.right = right;
return node;
}
export function updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier) {
if (node.left !== left || node.right !== right) {
return updateNode(createQualifiedName(left, right, node), node);
}
return node;
}
export function createComputedPropertyName(expression: Expression, location?: TextRange) {
const node = <ComputedPropertyName>createNode(SyntaxKind.ComputedPropertyName, location);
node.expression = expression;
@@ -272,19 +258,6 @@ namespace ts {
return node;
}
export function createDecorator(expression: LeftHandSideExpression, location?: TextRange) {
const node = <Decorator>createNode(SyntaxKind.Decorator, location);
node.expression = expression;
return node;
}
export function updateDecorator(node: Decorator, expression: LeftHandSideExpression) {
if (node.expression !== expression) {
return updateNode(createDecorator(expression, node), node);
}
return node;
}
// Type members
export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: Node, type: TypeNode, initializer: Expression, location?: TextRange) {
@@ -506,7 +479,6 @@ namespace ts {
if (expression !== node.expression || typeArguments !== node.typeArguments || argumentsArray !== node.arguments) {
return updateNode(createCall(expression, typeArguments, argumentsArray, /*location*/ node, node.flags), node);
}
return node;
}
@@ -628,6 +600,19 @@ namespace ts {
return node;
}
export function createAwait(expression: Expression, location?: TextRange) {
const node = <AwaitExpression>createNode(SyntaxKind.AwaitExpression, location);
node.expression = parenthesizePrefixOperand(expression);
return node;
}
export function updateAwait(node: AwaitExpression, expression: Expression) {
if (node.expression !== expression) {
return updateNode(createAwait(expression, node), node);
}
return node;
}
export function createPrefix(operator: SyntaxKind, operand: Expression, location?: TextRange) {
const node = <PrefixUnaryExpression>createNode(SyntaxKind.PrefixUnaryExpression, location);
node.operator = operator;
@@ -768,6 +753,7 @@ namespace ts {
return node;
}
// Misc
export function createTemplateSpan(expression: Expression, literal: TemplateLiteralFragment, location?: TextRange) {
@@ -831,14 +817,6 @@ namespace ts {
return node;
}
export function createLetDeclarationList(declarations: VariableDeclaration[], location?: TextRange) {
return createVariableDeclarationList(declarations, location, NodeFlags.Let);
}
export function createConstDeclarationList(declarations: VariableDeclaration[], location?: TextRange) {
return createVariableDeclarationList(declarations, location, NodeFlags.Const);
}
export function createVariableDeclaration(name: string | BindingPattern | Identifier, type?: TypeNode, initializer?: Expression, location?: TextRange, flags?: NodeFlags): VariableDeclaration {
const node = <VariableDeclaration>createNode(SyntaxKind.VariableDeclaration, location, flags);
node.name = typeof name === "string" ? createIdentifier(name) : name;
@@ -997,22 +975,6 @@ namespace ts {
return node;
}
export function createTryCatchFinally(tryBlock: Block, catchClause: CatchClause, finallyBlock: Block, location?: TextRange) {
const node = <TryStatement>createNode(SyntaxKind.TryStatement, location);
node.tryBlock = tryBlock;
node.catchClause = catchClause;
node.finallyBlock = finallyBlock;
return node;
}
export function createTryCatch(tryBlock: Block, catchClause: CatchClause, location?: TextRange) {
return createTryCatchFinally(tryBlock, catchClause, /*finallyBlock*/ undefined, location);
}
export function createTryFinally(tryBlock: Block, finallyBlock: Block, location?: TextRange) {
return createTryCatchFinally(tryBlock, /*catchClause*/ undefined, finallyBlock, location);
}
export function updateReturn(node: ReturnStatement, expression: Expression) {
if (node.expression !== expression) {
return updateNode(createReturn(expression, /*location*/ node), node);
@@ -1075,6 +1037,21 @@ namespace ts {
return node;
}
export function createTry(tryBlock: Block, catchClause: CatchClause, finallyBlock: Block, location?: TextRange) {
const node = <TryStatement>createNode(SyntaxKind.TryStatement, location);
node.tryBlock = tryBlock;
node.catchClause = catchClause;
node.finallyBlock = finallyBlock;
return node;
}
export function updateTry(node: TryStatement, tryBlock: Block, catchClause: CatchClause, finallyBlock: Block) {
if (node.tryBlock !== tryBlock || node.catchClause !== catchClause || node.finallyBlock !== finallyBlock) {
return updateNode(createTry(tryBlock, catchClause, finallyBlock, node), node);
}
return node;
}
export function createCaseBlock(clauses: CaseOrDefaultClause[], location?: TextRange): CaseBlock {
const node = <CaseBlock>createNode(SyntaxKind.CaseBlock, location);
node.clauses = createNodeArray(clauses);
@@ -1126,30 +1103,104 @@ namespace ts {
return node;
}
export function createExportAssignment(isExportEquals: boolean, expression: Expression, location?: TextRange) {
export function createImportDeclaration(decorators: Decorator[], modifiers: Modifier[], importClause: ImportClause, moduleSpecifier?: Expression, location?: TextRange): ImportDeclaration {
const node = <ImportDeclaration>createNode(SyntaxKind.ImportDeclaration, location);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.importClause = importClause;
node.moduleSpecifier = moduleSpecifier;
return node;
}
export function updateImportDeclaration(node: ImportDeclaration, decorators: Decorator[], modifiers: Modifier[], importClause: ImportClause, moduleSpecifier: Expression) {
if (node.decorators !== decorators || node.modifiers !== modifiers || node.importClause !== importClause || node.moduleSpecifier !== moduleSpecifier) {
return updateNode(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier, node), node);
}
return node;
}
export function createImportClause(name: Identifier, namedBindings: NamedImportBindings, location?: TextRange): ImportClause {
const node = <ImportClause>createNode(SyntaxKind.ImportClause, location);
node.name = name;
node.namedBindings = namedBindings;
return node;
}
export function updateImportClause(node: ImportClause, name: Identifier, namedBindings: NamedImportBindings) {
if (node.name !== name || node.namedBindings !== namedBindings) {
return updateNode(createImportClause(name, namedBindings, node), node);
}
return node;
}
export function createNamespaceImport(name: Identifier, location?: TextRange): NamespaceImport {
const node = <NamespaceImport>createNode(SyntaxKind.NamespaceImport, location);
node.name = name;
return node;
}
export function updateNamespaceImport(node: NamespaceImport, name: Identifier) {
if (node.name !== name) {
return updateNode(createNamespaceImport(name, node), node);
}
return node;
}
export function createNamedImports(elements: ImportSpecifier[], location?: TextRange): NamedImports {
const node = <NamedImports>createNode(SyntaxKind.NamedImports, location);
node.elements = createNodeArray(elements);
return node;
}
export function updateNamedImports(node: NamedImports, elements: ImportSpecifier[]) {
if (node.elements !== elements) {
return updateNode(createNamedImports(elements, node), node);
}
return node;
}
export function createImportSpecifier(propertyName: Identifier, name: Identifier, location?: TextRange) {
const node = <ImportSpecifier>createNode(SyntaxKind.ImportSpecifier, location);
node.propertyName = propertyName;
node.name = name;
return node;
}
export function updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier, name: Identifier) {
if (node.propertyName !== propertyName || node.name !== name) {
return updateNode(createImportSpecifier(propertyName, name, node), node);
}
return node;
}
export function createExportAssignment(decorators: Decorator[], modifiers: Modifier[], isExportEquals: boolean, expression: Expression, location?: TextRange) {
const node = <ExportAssignment>createNode(SyntaxKind.ExportAssignment, location);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.isExportEquals = isExportEquals;
node.expression = expression;
return node;
}
export function updateExportAssignment(node: ExportAssignment, expression: Expression) {
if (node.expression !== expression) {
return updateNode(createExportAssignment(node.isExportEquals, expression, node), node);
export function updateExportAssignment(node: ExportAssignment, decorators: Decorator[], modifiers: Modifier[], expression: Expression) {
if (node.decorators !== decorators || node.modifiers !== modifiers || node.expression !== expression) {
return updateNode(createExportAssignment(decorators, modifiers, node.isExportEquals, expression, node), node);
}
return node;
}
export function createExportDeclaration(exportClause: NamedExports, moduleSpecifier?: Expression, location?: TextRange) {
export function createExportDeclaration(decorators: Decorator[], modifiers: Modifier[], exportClause: NamedExports, moduleSpecifier?: Expression, location?: TextRange) {
const node = <ExportDeclaration>createNode(SyntaxKind.ExportDeclaration, location);
node.decorators = decorators ? createNodeArray(decorators) : undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.exportClause = exportClause;
node.moduleSpecifier = moduleSpecifier;
return node;
}
export function updateExportDeclaration(node: ExportDeclaration, exportClause: NamedExports, moduleSpecifier: Expression) {
if (node.exportClause !== exportClause || node.moduleSpecifier !== moduleSpecifier) {
return updateNode(createExportDeclaration(exportClause, moduleSpecifier, node), node);
export function updateExportDeclaration(node: ExportDeclaration, decorators: Decorator[], modifiers: Modifier[], exportClause: NamedExports, moduleSpecifier: Expression) {
if (node.decorators !== decorators || node.modifiers !== modifiers || node.exportClause !== exportClause || node.moduleSpecifier !== moduleSpecifier) {
return updateNode(createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier, node), node);
}
return node;
}
@@ -1181,6 +1232,104 @@ namespace ts {
return node;
}
// JSX
export function createJsxElement(openingElement: JsxOpeningElement, children: JsxChild[], closingElement: JsxClosingElement, location?: TextRange) {
const node = <JsxElement>createNode(SyntaxKind.JsxElement, location);
node.openingElement = openingElement;
node.children = createNodeArray(children);
node.closingElement = closingElement;
return node;
}
export function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: JsxChild[], closingElement: JsxClosingElement) {
if (node.openingElement !== openingElement || node.children !== children || node.closingElement !== closingElement) {
return updateNode(createJsxElement(openingElement, children, closingElement, node), node);
}
return node;
}
export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) {
const node = <JsxSelfClosingElement>createNode(SyntaxKind.JsxSelfClosingElement, location);
node.tagName = tagName;
node.attributes = createNodeArray(attributes);
return node;
}
export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) {
if (node.tagName !== tagName || node.attributes !== attributes) {
return updateNode(createJsxSelfClosingElement(tagName, attributes, node), node);
}
return node;
}
export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) {
const node = <JsxOpeningElement>createNode(SyntaxKind.JsxOpeningElement, location);
node.tagName = tagName;
node.attributes = createNodeArray(attributes);
return node;
}
export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) {
if (node.tagName !== tagName || node.attributes !== attributes) {
return updateNode(createJsxOpeningElement(tagName, attributes, node), node);
}
return node;
}
export function createJsxClosingElement(tagName: JsxTagNameExpression, location?: TextRange) {
const node = <JsxClosingElement>createNode(SyntaxKind.JsxClosingElement, location);
node.tagName = tagName;
return node;
}
export function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression) {
if (node.tagName !== tagName) {
return updateNode(createJsxClosingElement(tagName, node), node);
}
return node;
}
export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression, location?: TextRange) {
const node = <JsxAttribute>createNode(SyntaxKind.JsxAttribute, location);
node.name = name;
node.initializer = initializer;
return node;
}
export function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression) {
if (node.name !== name || node.initializer !== initializer) {
return updateNode(createJsxAttribute(name, initializer, node), node);
}
return node;
}
export function createJsxSpreadAttribute(expression: Expression, location?: TextRange) {
const node = <JsxSpreadAttribute>createNode(SyntaxKind.JsxSpreadAttribute, location);
node.expression = expression;
return node;
}
export function updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression) {
if (node.expression !== expression) {
return updateNode(createJsxSpreadAttribute(expression, node), node);
}
return node;
}
export function createJsxExpression(expression: Expression, location?: TextRange) {
const node = <JsxExpression>createNode(SyntaxKind.JsxExpression, location);
node.expression = expression;
return node;
}
export function updateJsxExpression(node: JsxExpression, expression: Expression) {
if (node.expression !== expression) {
return updateNode(createJsxExpression(expression, node), node);
}
return node;
}
// Clauses
export function createHeritageClause(token: SyntaxKind, types: ExpressionWithTypeArguments[], location?: TextRange) {
@@ -1224,6 +1373,20 @@ namespace ts {
return node;
}
export function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block, location?: TextRange) {
const node = <CatchClause>createNode(SyntaxKind.CatchClause, location);
node.variableDeclaration = typeof variableDeclaration === "string" ? createVariableDeclaration(variableDeclaration) : variableDeclaration;
node.block = block;
return node;
}
export function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration, block: Block) {
if (node.variableDeclaration !== variableDeclaration || node.block !== block) {
return updateNode(createCatchClause(variableDeclaration, block, node), node);
}
return node;
}
// Property assignments
export function createPropertyAssignment(name: string | PropertyName, initializer: Expression, location?: TextRange) {
@@ -1382,32 +1545,6 @@ namespace ts {
return createVoid(createLiteral(0));
}
export function createImportDeclaration(importClause: ImportClause, moduleSpecifier?: Expression, location?: TextRange): ImportDeclaration {
const node = <ImportDeclaration>createNode(SyntaxKind.ImportDeclaration, location);
node.importClause = importClause;
node.moduleSpecifier = moduleSpecifier;
return node;
}
export function createImportClause(name: Identifier, namedBindings: NamedImportBindings, location?: TextRange): ImportClause {
const node = <ImportClause>createNode(SyntaxKind.ImportClause, location);
node.name = name;
node.namedBindings = namedBindings;
return node;
}
export function createNamespaceImport(name: Identifier): NamespaceImport {
const node = <NamespaceImport>createNode(SyntaxKind.NamespaceImport);
node.name = name;
return node;
}
export function createNamedImports(elements: NodeArray<ImportSpecifier>, location?: TextRange): NamedImports {
const node = <NamedImports>createNode(SyntaxKind.NamedImports, location);
node.elements = elements;
return node;
}
export function createMemberAccessForPropertyName(target: Expression, memberName: PropertyName, location?: TextRange): MemberExpression {
if (isComputedPropertyName(memberName)) {
return createElementAccess(target, memberName.expression, location);
@@ -1502,7 +1639,15 @@ namespace ts {
argumentsList.push(createNull());
}
addNodes(argumentsList, children, /*startOnNewLine*/ children.length > 1);
if (children.length > 1) {
for (const child of children) {
child.startsOnNewLine = true;
argumentsList.push(child);
}
}
else {
argumentsList.push(children[0]);
}
}
return createCall(
@@ -1516,6 +1661,14 @@ namespace ts {
);
}
export function createLetDeclarationList(declarations: VariableDeclaration[], location?: TextRange) {
return createVariableDeclarationList(declarations, location, NodeFlags.Let);
}
export function createConstDeclarationList(declarations: VariableDeclaration[], location?: TextRange) {
return createVariableDeclarationList(declarations, location, NodeFlags.Const);
}
// Helpers
export function createHelperName(externalHelpersModuleName: Identifier | undefined, name: string) {
@@ -2482,8 +2635,8 @@ namespace ts {
return node;
}
export function startOnNewLine<T extends Node>(node: T): T {
node.startsOnNewLine = true;
export function startOnNewLine<T extends Node>(node: T, startsOnNewLine?: boolean): T {
node.startsOnNewLine = startsOnNewLine !== false;
return node;
}
+45 -27
View File
@@ -1196,7 +1196,7 @@ namespace ts {
*/
function transformAccessorsToStatement(receiver: LeftHandSideExpression, accessors: AllAccessorDeclarations): Statement {
const statement = createStatement(
transformAccessorsToExpression(receiver, accessors),
transformAccessorsToExpression(receiver, accessors, /*startsOnNewLine*/ false),
/*location*/ getSourceMapRange(accessors.firstAccessor)
);
@@ -1213,7 +1213,7 @@ namespace ts {
*
* @param receiver The receiver for the member.
*/
function transformAccessorsToExpression(receiver: LeftHandSideExpression, { firstAccessor, getAccessor, setAccessor }: AllAccessorDeclarations): Expression {
function transformAccessorsToExpression(receiver: LeftHandSideExpression, { firstAccessor, getAccessor, setAccessor }: AllAccessorDeclarations, startsOnNewLine: boolean): Expression {
// To align with source maps in the old emitter, the receiver and property name
// arguments are both mapped contiguously to the accessor name.
const target = getMutableClone(receiver);
@@ -1246,7 +1246,7 @@ namespace ts {
createPropertyAssignment("configurable", createLiteral(true))
);
return createCall(
const call = createCall(
createPropertyAccess(createIdentifier("Object"), "defineProperty"),
/*typeArguments*/ undefined,
[
@@ -1255,6 +1255,10 @@ namespace ts {
createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true)
]
);
if (startsOnNewLine) {
call.startsOnNewLine = true;
}
return call;
}
/**
@@ -1895,26 +1899,28 @@ namespace ts {
// Write out the first non-computed properties, then emit the rest through indexing on the temp variable.
const expressions: Expression[] = [];
addNode(expressions,
createAssignment(
temp,
setNodeEmitFlags(
createObjectLiteral(
visitNodes(properties, visitor, isObjectLiteralElement, 0, numInitialProperties),
/*location*/ undefined,
node.multiLine
),
NodeEmitFlags.Indented
)
),
node.multiLine
expressions.push(
startOnNewLine(
createAssignment(
temp,
setNodeEmitFlags(
createObjectLiteral(
visitNodes(properties, visitor, isObjectLiteralElement, 0, numInitialProperties),
/*location*/ undefined,
node.multiLine
),
NodeEmitFlags.Indented
)
),
node.multiLine
)
);
addObjectLiteralMembers(expressions, node, temp, numInitialProperties);
// We need to clone the temporary identifier so that we can write it on a
// new line
addNode(expressions, getMutableClone(temp), node.multiLine);
expressions.push(startOnNewLine(getMutableClone(temp), node.multiLine));
return inlineExpressions(expressions);
}
@@ -2313,21 +2319,21 @@ namespace ts {
case SyntaxKind.SetAccessor:
const accessors = getAllAccessorDeclarations(node.properties, <AccessorDeclaration>property);
if (property === accessors.firstAccessor) {
addNode(expressions, transformAccessorsToExpression(receiver, accessors), node.multiLine);
expressions.push(transformAccessorsToExpression(receiver, accessors, node.multiLine));
}
break;
case SyntaxKind.PropertyAssignment:
addNode(expressions, transformPropertyAssignmentToExpression(node, <PropertyAssignment>property, receiver), node.multiLine);
expressions.push(transformPropertyAssignmentToExpression(node, <PropertyAssignment>property, receiver, node.multiLine));
break;
case SyntaxKind.ShorthandPropertyAssignment:
addNode(expressions, transformShorthandPropertyAssignmentToExpression(node, <ShorthandPropertyAssignment>property, receiver), node.multiLine);
expressions.push(transformShorthandPropertyAssignmentToExpression(node, <ShorthandPropertyAssignment>property, receiver, node.multiLine));
break;
case SyntaxKind.MethodDeclaration:
addNode(expressions, transformObjectLiteralMethodDeclarationToExpression(node, <MethodDeclaration>property, receiver), node.multiLine);
expressions.push(transformObjectLiteralMethodDeclarationToExpression(node, <MethodDeclaration>property, receiver, node.multiLine));
break;
default:
@@ -2344,8 +2350,8 @@ namespace ts {
* @param property The PropertyAssignment node.
* @param receiver The receiver for the assignment.
*/
function transformPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: PropertyAssignment, receiver: Expression) {
return createAssignment(
function transformPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: PropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
const expression = createAssignment(
createMemberAccessForPropertyName(
receiver,
visitNode(property.name, visitor, isPropertyName)
@@ -2353,6 +2359,10 @@ namespace ts {
visitNode(property.initializer, visitor, isExpression),
/*location*/ property
);
if (startsOnNewLine) {
expression.startsOnNewLine = true;
}
return expression;
}
/**
@@ -2362,8 +2372,8 @@ namespace ts {
* @param property The ShorthandPropertyAssignment node.
* @param receiver The receiver for the assignment.
*/
function transformShorthandPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: ShorthandPropertyAssignment, receiver: Expression) {
return createAssignment(
function transformShorthandPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: ShorthandPropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
const expression = createAssignment(
createMemberAccessForPropertyName(
receiver,
visitNode(property.name, visitor, isPropertyName)
@@ -2371,6 +2381,10 @@ namespace ts {
getSynthesizedClone(property.name),
/*location*/ property
);
if (startsOnNewLine) {
expression.startsOnNewLine = true;
}
return expression;
}
/**
@@ -2380,8 +2394,8 @@ namespace ts {
* @param method The MethodDeclaration node.
* @param receiver The receiver for the assignment.
*/
function transformObjectLiteralMethodDeclarationToExpression(node: ObjectLiteralExpression, method: MethodDeclaration, receiver: Expression) {
return createAssignment(
function transformObjectLiteralMethodDeclarationToExpression(node: ObjectLiteralExpression, method: MethodDeclaration, receiver: Expression, startsOnNewLine: boolean) {
const expression = createAssignment(
createMemberAccessForPropertyName(
receiver,
visitNode(method.name, visitor, isPropertyName)
@@ -2389,6 +2403,10 @@ namespace ts {
transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined),
/*location*/ method
);
if (startsOnNewLine) {
expression.startsOnNewLine = true;
}
return expression;
}
/**
+10 -4
View File
@@ -580,8 +580,8 @@ namespace ts {
transformAndEmitStatements(body.statements, statementOffset);
const buildResult = build();
addNodes(statements, endLexicalEnvironment());
addNode(statements, createReturn(buildResult));
addRange(statements, endLexicalEnvironment());
statements.push(createReturn(buildResult));
// Restore previous generator state
inGeneratorFunctionBody = savedInGeneratorFunctionBody;
@@ -1019,7 +1019,7 @@ namespace ts {
);
const expressions = reduceLeft(properties, reduceProperty, <Expression[]>[], numInitialProperties);
addNode(expressions, getMutableClone(temp), multiLine);
expressions.push(multiLine ? startOnNewLine(getMutableClone(temp)) : temp);
return inlineExpressions(expressions);
function reduceProperty(expressions: Expression[], property: ObjectLiteralElement) {
@@ -1029,7 +1029,13 @@ namespace ts {
}
const expression = createExpressionForObjectLiteralElement(node, property, temp);
addNode(expressions, visitNode(expression, visitor, isExpression), multiLine);
const visited = visitNode(expression, visitor, isExpression);
if (visited) {
if (multiLine) {
visited.startsOnNewLine = true;
}
expressions.push(visited);
}
return expressions;
}
}
+10 -2
View File
@@ -65,7 +65,11 @@ namespace ts {
return node;
}
return newExportClause
? createExportDeclaration(newExportClause, node.moduleSpecifier)
? createExportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
newExportClause,
node.moduleSpecifier)
: undefined;
}
@@ -92,7 +96,11 @@ namespace ts {
return undefined;
}
else if (newImportClause !== node.importClause) {
return createImportDeclaration(newImportClause, node.moduleSpecifier);
return createImportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
newImportClause,
node.moduleSpecifier);
}
}
return node;
+23 -17
View File
@@ -197,7 +197,7 @@ namespace ts {
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, visitSourceElement);
// var __moduleName = context_1 && context_1.id;
addNode(statements,
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
@@ -226,14 +226,14 @@ namespace ts {
// - Temporary variables will appear at the top rather than at the bottom of the file
// - Calls to the exporter for exported function declarations are grouped after
// the declarations.
addNodes(statements, endLexicalEnvironment());
addRange(statements, endLexicalEnvironment());
// Emit early exports for function declarations.
addNodes(statements, exportedFunctionDeclarations);
addRange(statements, exportedFunctionDeclarations);
const exportStarFunction = addExportStarIfNeeded(statements);
addNode(statements,
statements.push(
createReturn(
setMultiLine(
createObjectLiteral([
@@ -292,7 +292,7 @@ namespace ts {
if (exportedLocalNames) {
for (const exportedLocalName of exportedLocalNames) {
// write name of exported declaration, i.e 'export var x...'
addNode(exportedNames,
exportedNames.push(
createPropertyAssignment(
createLiteral(exportedLocalName.text),
createLiteral(true)
@@ -314,7 +314,7 @@ namespace ts {
for (const element of exportDecl.exportClause.elements) {
// write name of indirectly exported entry, i.e. 'export {x} from ...'
addNode(exportedNames,
exportedNames.push(
createPropertyAssignment(
createLiteral((element.name || element.propertyName).text),
createLiteral(true)
@@ -324,7 +324,7 @@ namespace ts {
}
const exportedNamesStorageRef = createUniqueName("exportedNames");
addNode(statements,
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
@@ -365,7 +365,7 @@ namespace ts {
case SyntaxKind.ImportEqualsDeclaration:
Debug.assert(importVariableName !== undefined);
// save import into the local
addNode(statements,
statements.push(
createStatement(
createAssignment(importVariableName, parameterName)
)
@@ -396,7 +396,7 @@ namespace ts {
);
}
addNode(statements,
statements.push(
createStatement(
createCall(
exportFunctionForFile,
@@ -412,7 +412,7 @@ namespace ts {
// emit as:
//
// exportStar(foo_1_1);
addNode(statements,
statements.push(
createStatement(
createCall(
exportStarFunction,
@@ -426,7 +426,7 @@ namespace ts {
}
}
addNode(setters,
setters.push(
createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
@@ -563,7 +563,7 @@ namespace ts {
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement> {
if (!node.moduleSpecifier) {
const statements: Statement[] = [];
addNodes(statements, map(node.exportClause.elements, visitExportSpecifier));
addRange(statements, map(node.exportClause.elements, visitExportSpecifier));
return statements;
}
@@ -612,7 +612,10 @@ namespace ts {
const isExported = hasModifier(node, ModifierFlags.Export);
const expressions: Expression[] = [];
for (const variable of node.declarationList.declarations) {
addNode(expressions, <Expression>transformVariable(variable, isExported));
const visited = <Expression>transformVariable(variable, isExported);
if (visited) {
expressions.push(visited);
}
}
if (expressions.length) {
@@ -715,7 +718,7 @@ namespace ts {
const statements: Statement[] = [];
// Rewrite the class declaration into an assignment of a class expression.
addNode(statements,
statements.push(
createStatement(
createAssignment(
name,
@@ -738,7 +741,7 @@ namespace ts {
recordExportName(name);
}
addNode(statements, createDeclarationExport(node));
statements.push(createDeclarationExport(node));
}
return statements;
@@ -758,7 +761,10 @@ namespace ts {
if (shouldHoistLoopInitializer(initializer)) {
const expressions: Expression[] = [];
for (const variable of (<VariableDeclarationList>initializer).declarations) {
addNode(expressions, <Expression>transformVariable(variable, /*isExported*/ false));
const visited = <Expression>transformVariable(variable, /*isExported*/ false);
if (visited) {
expressions.push(visited);
}
};
return createFor(
@@ -1209,7 +1215,7 @@ namespace ts {
);
}
addNode(statements,
statements.push(
createFunctionDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
+43 -21
View File
@@ -428,6 +428,8 @@ namespace ts {
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ false, visitor);
const externalHelpersModuleName = createUniqueName(externalHelpersModuleNameText);
const externalHelpersModuleImport = createImportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
createLiteral(externalHelpersModuleNameText)
);
@@ -550,7 +552,11 @@ namespace ts {
}
else if (isDecoratedClass) {
if (isDefaultExternalModuleExport(node)) {
statements.push(createExportAssignment(/*isExportEquals*/ false, getLocalName(node)));
statements.push(createExportAssignment(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*isExportEquals*/ false,
getLocalName(node)));
}
else if (isNamedExternalModuleExport(node)) {
statements.push(createExternalModuleExport(name));
@@ -688,7 +694,7 @@ namespace ts {
// let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference
// or decoratedClassAlias if the class contain self-reference.
addNode(statements,
statements.push(
setOriginalNode(
createVariableStatement(
/*modifiers*/ undefined,
@@ -710,7 +716,7 @@ namespace ts {
// TDZ as the class.
// let ${declaredName} = ${decoratedClassAlias}
addNode(statements,
statements.push(
setOriginalNode(
createVariableStatement(
/*modifiers*/ undefined,
@@ -763,15 +769,15 @@ namespace ts {
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) {
// record an alias as the class name is not in scope for statics.
enableSubstitutionForClassAliases();
classAliases[getOriginalNodeId(node)] = temp;
classAliases[getOriginalNodeId(node)] = getSynthesizedClone(temp);
}
// To preserve the behavior of the old emitter, we explicitly indent
// the body of a class with static initializers.
setNodeEmitFlags(classExpression, NodeEmitFlags.Indented | getNodeEmitFlags(classExpression));
addNode(expressions, createAssignment(temp, classExpression), true);
addNodes(expressions, generateInitializedPropertyExpressions(node, staticProperties, temp), true);
addNode(expressions, temp, true);
expressions.push(startOnNewLine(createAssignment(temp, classExpression)));
addRange(expressions, generateInitializedPropertyExpressions(node, staticProperties, temp));
expressions.push(startOnNewLine(temp));
return inlineExpressions(expressions);
}
@@ -786,8 +792,12 @@ namespace ts {
*/
function transformClassMembers(node: ClassDeclaration | ClassExpression, hasExtendsClause: boolean) {
const members: ClassElement[] = [];
addNode(members, transformConstructor(node, hasExtendsClause));
addNodes(members, visitNodes(node.members, classElementVisitor, isClassElement));
const constructor = transformConstructor(node, hasExtendsClause);
if (constructor) {
members.push(constructor);
}
addRange(members, visitNodes(node.members, classElementVisitor, isClassElement));
return createNodeArray(members, /*location*/ node.members);
}
@@ -876,7 +886,7 @@ namespace ts {
// }
//
const propertyAssignments = getParametersWithPropertyAssignments(constructor);
addNodes(statements, map(propertyAssignments, transformParameterWithPropertyAssignment));
addRange(statements, map(propertyAssignments, transformParameterWithPropertyAssignment));
}
else if (hasExtendsClause) {
Debug.assert(parameters.length === 1 && isIdentifier(parameters[0].name));
@@ -885,7 +895,7 @@ namespace ts {
//
// super(...args);
//
addNode(statements,
statements.push(
createStatement(
createCall(
createSuper(),
@@ -911,11 +921,11 @@ namespace ts {
if (constructor) {
// The class already had a constructor, so we should add the existing statements, skipping the initial super call.
addNodes(statements, visitNodes(constructor.body.statements, visitor, isStatement, indexOfFirstStatement));
addRange(statements, visitNodes(constructor.body.statements, visitor, isStatement, indexOfFirstStatement));
}
// End the lexical environment.
addNodes(statements, endLexicalEnvironment());
addRange(statements, endLexicalEnvironment());
return setMultiLine(
createBlock(
createNodeArray(
@@ -1071,6 +1081,7 @@ namespace ts {
const expressions: Expression[] = [];
for (const property of properties) {
const expression = transformInitializedProperty(node, property, receiver);
expression.startsOnNewLine = true;
setSourceMapRange(expression, moveRangePastModifiers(property));
setCommentRange(expression, property);
expressions.push(expression);
@@ -1283,8 +1294,8 @@ namespace ts {
}
const decoratorExpressions: Expression[] = [];
addNodes(decoratorExpressions, map(allDecorators.decorators, transformDecorator));
addNodes(decoratorExpressions, flatMap(allDecorators.parameters, transformDecoratorsOfParameter));
addRange(decoratorExpressions, map(allDecorators.decorators, transformDecorator));
addRange(decoratorExpressions, flatMap(allDecorators.parameters, transformDecoratorsOfParameter));
addTypeMetadata(node, decoratorExpressions);
return decoratorExpressions;
}
@@ -2217,7 +2228,7 @@ namespace ts {
startLexicalEnvironment();
const visited: Expression | Block = visitNode(body, visitor, isConciseBody);
const declarations = endLexicalEnvironment();
const merged = mergeConciseBodyLexicalEnvironment(visited, declarations);
const merged = mergeFunctionBodyLexicalEnvironment(visited, declarations);
if (forceBlockFunctionBody && !isBlock(merged)) {
return createBlock([
createReturn(<Expression>merged)
@@ -2556,8 +2567,8 @@ namespace ts {
const statements: Statement[] = [];
startLexicalEnvironment();
addNodes(statements, map(node.members, transformEnumMember));
addNodes(statements, endLexicalEnvironment());
addRange(statements, map(node.members, transformEnumMember));
addRange(statements, endLexicalEnvironment());
currentNamespaceContainerName = savedCurrentNamespaceLocalName;
return createBlock(
@@ -2794,17 +2805,26 @@ namespace ts {
let blockLocation: TextRange;
const body = node.body;
if (body.kind === SyntaxKind.ModuleBlock) {
addNodes(statements, visitNodes((<ModuleBlock>body).statements, namespaceElementVisitor, isStatement));
addRange(statements, visitNodes((<ModuleBlock>body).statements, namespaceElementVisitor, isStatement));
statementsLocation = (<ModuleBlock>body).statements;
blockLocation = body;
}
else {
addNode(statements, visitModuleDeclaration(<ModuleDeclaration>body));
const result = visitModuleDeclaration(<ModuleDeclaration>body);
if (result) {
if (isArray(result)) {
addRange(statements, result);
}
else {
statements.push(result);
}
}
const moduleBlock = <ModuleBlock>getInnerMostModuleDeclarationFromDottedModule(node).body;
statementsLocation = moveRangePos(moduleBlock.statements, -1);
}
addNodes(statements, endLexicalEnvironment());
addRange(statements, endLexicalEnvironment());
currentNamespaceContainerName = savedCurrentNamespaceContainerName;
currentNamespace = savedCurrentNamespace;
@@ -2965,6 +2985,8 @@ namespace ts {
function createExternalModuleExport(exportName: Identifier) {
return createExportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createNamedExports([
createExportSpecifier(exportName)
])
+7
View File
@@ -4057,6 +4057,13 @@ namespace ts {
return node.kind === SyntaxKind.JsxClosingElement;
}
export function isJsxTagNameExpression(node: Node): node is JsxTagNameExpression {
const kind = node.kind;
return kind === SyntaxKind.ThisKeyword
|| kind === SyntaxKind.Identifier
|| kind === SyntaxKind.PropertyAccessExpression;
}
export function isJsxChild(node: Node): node is JsxChild {
const kind = node.kind;
return kind === SyntaxKind.JsxElement
+266 -243
View File
@@ -38,6 +38,8 @@ namespace ts {
* Each edge corresponds to a property in a Node subtype that should be traversed when visiting
* each child. The properties are assigned in the order in which traversal should occur.
*
* We only add entries for nodes that do not have a create/update pair defined in factory.ts
*
* NOTE: This needs to be kept up to date with changes to nodes in "types.ts". Currently, this
* map is not comprehensive. Only node edges relevant to tree transformation are
* currently defined. We may extend this to be more comprehensive, and eventually
@@ -45,13 +47,17 @@ namespace ts {
* significantly impacted.
*/
const nodeEdgeTraversalMap: Map<NodeTraversalPath> = {
[SyntaxKind.QualifiedName]: [
{ name: "left", test: isEntityName },
{ name: "right", test: isIdentifier }
],
[SyntaxKind.Decorator]: [
{ name: "expression", test: isLeftHandSideExpression }
],
[SyntaxKind.TypeAssertionExpression]: [
{ name: "type", test: isTypeNode },
{ name: "expression", test: isUnaryExpression }
],
[SyntaxKind.AwaitExpression]: [
{ name: "expression", test: isUnaryExpression, parenthesize: parenthesizePrefixOperand }
],
[SyntaxKind.AsExpression]: [
{ name: "expression", test: isExpression },
{ name: "type", test: isTypeNode }
@@ -59,11 +65,6 @@ namespace ts {
[SyntaxKind.NonNullExpression]: [
{ name: "expression", test: isLeftHandSideExpression }
],
[SyntaxKind.TryStatement]: [
{ name: "tryBlock", test: isBlock },
{ name: "catchClause", test: isCatchClause, optional: true },
{ name: "finallyBlock", test: isBlock, optional: true }
],
[SyntaxKind.EnumDeclaration]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
@@ -85,77 +86,9 @@ namespace ts {
{ name: "name", test: isIdentifier },
{ name: "moduleReference", test: isModuleReference }
],
[SyntaxKind.ImportDeclaration]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "importClause", test: isImportClause, optional: true },
{ name: "moduleSpecifier", test: isExpression }
],
[SyntaxKind.ImportClause]: [
{ name: "name", test: isIdentifier, optional: true },
{ name: "namedBindings", test: isNamedImportBindings, optional: true }
],
[SyntaxKind.NamespaceImport]: [
{ name: "name", test: isIdentifier }
],
[SyntaxKind.NamedImports]: [
{ name: "elements", test: isImportSpecifier }
],
[SyntaxKind.ImportSpecifier]: [
{ name: "propertyName", test: isIdentifier, optional: true },
{ name: "name", test: isIdentifier }
],
[SyntaxKind.ExportAssignment]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "expression", test: isExpression }
],
[SyntaxKind.ExportDeclaration]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "exportClause", test: isNamedExports, optional: true },
{ name: "moduleSpecifier", test: isExpression, optional: true }
],
[SyntaxKind.NamedExports]: [
{ name: "elements", test: isExportSpecifier }
],
[SyntaxKind.ExportSpecifier]: [
{ name: "propertyName", test: isIdentifier, optional: true },
{ name: "name", test: isIdentifier }
],
[SyntaxKind.ExternalModuleReference]: [
{ name: "expression", test: isExpression, optional: true }
],
[SyntaxKind.JsxElement]: [
{ name: "openingElement", test: isJsxOpeningElement },
{ name: "children", test: isJsxChild },
{ name: "closingElement", test: isJsxClosingElement }
],
[SyntaxKind.JsxSelfClosingElement]: [
{ name: "tagName", test: isEntityName },
{ name: "attributes", test: isJsxAttributeLike }
],
[SyntaxKind.JsxOpeningElement]: [
{ name: "tagName", test: isEntityName },
{ name: "attributes", test: isJsxAttributeLike }
],
[SyntaxKind.JsxClosingElement]: [
{ name: "tagName", test: isEntityName }
],
[SyntaxKind.JsxAttribute]: [
{ name: "name", test: isIdentifier },
{ name: "initializer", test: isStringLiteralOrJsxExpression, optional: true }
],
[SyntaxKind.JsxSpreadAttribute]: [
{ name: "expression", test: isExpression }
],
[SyntaxKind.JsxExpression]: [
{ name: "expression", test: isExpression, optional: true }
],
[SyntaxKind.CatchClause]: [
{ name: "variableDeclaration", test: isVariableDeclaration },
{ name: "block", test: isBlock }
],
[SyntaxKind.EnumMember]: [
{ name: "name", test: isPropertyName },
{ name: "initializer", test: isExpression, optional: true, parenthesize: parenthesizeExpressionForList }
@@ -187,24 +120,23 @@ namespace ts {
return initial;
}
// We do not yet support types.
if ((kind >= SyntaxKind.TypePredicate && kind <= SyntaxKind.StringLiteralType)) {
return initial;
}
let result = initial;
switch (kind) {
switch (node.kind) {
// Leaf nodes
case SyntaxKind.ThisType:
case SyntaxKind.StringLiteralType:
case SyntaxKind.SemicolonClassElement:
case SyntaxKind.EmptyStatement:
case SyntaxKind.OmittedExpression:
case SyntaxKind.DebuggerStatement:
case SyntaxKind.NotEmittedStatement:
// No need to visit nodes with no children.
break;
// Names
case SyntaxKind.QualifiedName:
result = reduceNode((<QualifiedName>node).left, f, result);
result = reduceNode((<QualifiedName>node).right, f, result);
break;
case SyntaxKind.ComputedPropertyName:
result = reduceNode((<ComputedPropertyName>node).expression, f, result);
break;
@@ -290,6 +222,11 @@ namespace ts {
result = reduceNode((<PropertyAccessExpression>node).name, f, result);
break;
case SyntaxKind.ElementAccessExpression:
result = reduceNode((<ElementAccessExpression>node).expression, f, result);
result = reduceNode((<ElementAccessExpression>node).argumentExpression, f, result);
break;
case SyntaxKind.CallExpression:
result = reduceNode((<CallExpression>node).expression, f, result);
result = reduceLeft((<CallExpression>node).typeArguments, f, result);
@@ -331,7 +268,8 @@ namespace ts {
case SyntaxKind.AwaitExpression:
case SyntaxKind.YieldExpression:
case SyntaxKind.SpreadElementExpression:
result = reduceNode((<ParenthesizedExpression | DeleteExpression | TypeOfExpression | VoidExpression | AwaitExpression | YieldExpression | SpreadElementExpression>node).expression, f, result);
case SyntaxKind.NonNullExpression:
result = reduceNode((<ParenthesizedExpression | DeleteExpression | TypeOfExpression | VoidExpression | AwaitExpression | YieldExpression | SpreadElementExpression | NonNullExpression>node).expression, f, result);
break;
case SyntaxKind.PrefixUnaryExpression:
@@ -375,7 +313,6 @@ namespace ts {
break;
// Element
case SyntaxKind.Block:
result = reduceLeft((<Block>node).statements, f, result);
break;
@@ -474,10 +411,81 @@ namespace ts {
result = reduceLeft((<CaseBlock>node).clauses, f, 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);
break;
case SyntaxKind.ImportClause:
result = reduceNode((<ImportClause>node).name, f, result);
result = reduceNode((<ImportClause>node).namedBindings, f, result);
break;
case SyntaxKind.NamespaceImport:
result = reduceNode((<NamespaceImport>node).name, f, result);
break;
case SyntaxKind.NamedImports:
case SyntaxKind.NamedExports:
result = reduceLeft((<NamedImports | NamedExports>node).elements, f, result);
break;
case SyntaxKind.ImportSpecifier:
case SyntaxKind.ExportSpecifier:
result = reduceNode((<ImportSpecifier | ExportSpecifier>node).propertyName, f, result);
result = reduceNode((<ImportSpecifier | ExportSpecifier>node).name, f, 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);
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);
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);
break;
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxOpeningElement:
result = reduceNode((<JsxSelfClosingElement | JsxOpeningElement>node).tagName, f, result);
result = reduceLeft((<JsxSelfClosingElement | JsxOpeningElement>node).attributes, f, result);
break;
case SyntaxKind.JsxClosingElement:
result = reduceNode((<JsxClosingElement>node).tagName, f, result);
break;
case SyntaxKind.JsxAttribute:
result = reduceNode((<JsxAttribute>node).name, f, result);
result = reduceNode((<JsxAttribute>node).initializer, f, result);
break;
case SyntaxKind.JsxSpreadAttribute:
result = reduceNode((<JsxSpreadAttribute>node).expression, f, result);
break;
case SyntaxKind.JsxExpression:
result = reduceNode((<JsxExpression>node).expression, f, result);
break;
// Clauses
case SyntaxKind.CaseClause:
result = reduceNode((<CaseClause>node).expression, f, result);
// fall-through
case SyntaxKind.DefaultClause:
result = reduceLeft((<CaseClause | DefaultClause>node).statements, f, result);
break;
@@ -507,6 +515,10 @@ namespace ts {
result = reduceLeft((<SourceFile>node).statements, f, result);
break;
case SyntaxKind.PartiallyEmittedExpression:
result = reduceNode((<PartiallyEmittedExpression>node).expression, f, result);
break;
default:
const edgeTraversalPath = nodeEdgeTraversalMap[kind];
if (edgeTraversalPath) {
@@ -523,7 +535,6 @@ namespace ts {
}
return result;
}
/**
@@ -616,8 +627,26 @@ namespace ts {
// Ensure we have a copy of `nodes`, up to the current index.
updated = createNodeArray(nodes.slice(0, i), /*location*/ nodes, nodes.hasTrailingComma);
}
addNode(updated, visited, /*addOnNewLine*/ undefined, test, parenthesize, parentNode, /*isVisiting*/ visited !== node);
if (visited) {
if (isArray(visited)) {
for (let visitedNode of visited) {
visitedNode = parenthesize
? parenthesize(visitedNode, parentNode)
: visitedNode;
Debug.assertNode(visitedNode, test);
aggregateTransformFlags(visitedNode);
updated.push(visitedNode);
}
}
else {
const visitedNode = parenthesize
? parenthesize(visited, parentNode)
: visited;
Debug.assertNode(visitedNode, test);
aggregateTransformFlags(visitedNode);
updated.push(visitedNode);
}
}
}
}
@@ -643,10 +672,12 @@ namespace ts {
return node;
}
// Special cases for frequent visitors to improve performance.
switch (kind) {
case SyntaxKind.ThisType:
case SyntaxKind.StringLiteralType:
// We do not yet support types.
if ((kind >= SyntaxKind.TypePredicate && kind <= SyntaxKind.StringLiteralType)) {
return node;
}
switch (node.kind) {
case SyntaxKind.SemicolonClassElement:
case SyntaxKind.EmptyStatement:
case SyntaxKind.OmittedExpression:
@@ -655,28 +686,19 @@ namespace ts {
return node;
// Names
case SyntaxKind.QualifiedName:
return updateQualifiedName(<QualifiedName>node,
visitNode((<QualifiedName>node).left, visitor, isEntityName),
visitNode((<QualifiedName>node).right, visitor, isIdentifier));
case SyntaxKind.ComputedPropertyName:
return updateComputedPropertyName(<ComputedPropertyName>node,
visitNode((<ComputedPropertyName>node).expression, visitor, isExpression));
// Signature elements
case SyntaxKind.Parameter:
return updateParameterDeclaration((<ParameterDeclaration>node),
return updateParameterDeclaration(<ParameterDeclaration>node,
visitNodes((<ParameterDeclaration>node).decorators, visitor, isDecorator),
visitNodes((<ParameterDeclaration>node).modifiers, visitor, isModifier),
visitNode((<ParameterDeclaration>node).name, visitor, isBindingName),
visitNode((<ParameterDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
visitNode((<ParameterDeclaration>node).initializer, visitor, isExpression, /*optional*/ true));
case SyntaxKind.Decorator:
return updateDecorator(<Decorator>node,
visitNode((<Decorator>node).expression, visitor, isLeftHandSideExpression));
// Type member
case SyntaxKind.PropertyDeclaration:
return updateProperty(<PropertyDeclaration>node,
@@ -692,41 +714,41 @@ namespace ts {
visitNodes((<MethodDeclaration>node).modifiers, visitor, isModifier),
visitNode((<MethodDeclaration>node).name, visitor, isPropertyName),
visitNodes((<MethodDeclaration>node).typeParameters, visitor, isTypeParameter),
startLexicalEnvironmentAndVisitParameters((<MethodDeclaration>node).parameters, visitor, context),
(context.startLexicalEnvironment(), visitNodes((<MethodDeclaration>node).parameters, visitor, isParameter)),
visitNode((<MethodDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
endLexicalEnvironmentAndUpdateBody(
mergeFunctionBodyLexicalEnvironment(
visitNode((<MethodDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
context));
context.endLexicalEnvironment()));
case SyntaxKind.Constructor:
return updateConstructor(<ConstructorDeclaration>node,
visitNodes((<ConstructorDeclaration>node).decorators, visitor, isDecorator),
visitNodes((<ConstructorDeclaration>node).modifiers, visitor, isModifier),
startLexicalEnvironmentAndVisitParameters((<ConstructorDeclaration>node).parameters, visitor, context),
endLexicalEnvironmentAndUpdateBody(
(context.startLexicalEnvironment(), visitNodes((<ConstructorDeclaration>node).parameters, visitor, isParameter)),
mergeFunctionBodyLexicalEnvironment(
visitNode((<ConstructorDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
context));
context.endLexicalEnvironment()));
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),
startLexicalEnvironmentAndVisitParameters((<GetAccessorDeclaration>node).parameters, visitor, context),
(context.startLexicalEnvironment(), visitNodes((<GetAccessorDeclaration>node).parameters, visitor, isParameter)),
visitNode((<GetAccessorDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
endLexicalEnvironmentAndUpdateBody(
mergeFunctionBodyLexicalEnvironment(
visitNode((<GetAccessorDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
context));
context.endLexicalEnvironment()));
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),
startLexicalEnvironmentAndVisitParameters((<SetAccessorDeclaration>node).parameters, visitor, context),
endLexicalEnvironmentAndUpdateBody(
(context.startLexicalEnvironment(), visitNodes((<SetAccessorDeclaration>node).parameters, visitor, isParameter)),
mergeFunctionBodyLexicalEnvironment(
visitNode((<SetAccessorDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
context));
context.endLexicalEnvironment()));
// Binding patterns
case SyntaxKind.ObjectBindingPattern:
@@ -750,10 +772,10 @@ namespace ts {
case SyntaxKind.ObjectLiteralExpression:
return updateObjectLiteral(<ObjectLiteralExpression>node,
visitNodes((<ObjectLiteralExpression>node).properties, visitor, isExpression));
visitNodes((<ObjectLiteralExpression>node).properties, visitor, isObjectLiteralElement));
case SyntaxKind.PropertyAccessExpression:
return updatePropertyAccess((<PropertyAccessExpression>node),
return updatePropertyAccess(<PropertyAccessExpression>node,
visitNode((<PropertyAccessExpression>node).expression, visitor, isExpression),
visitNode((<PropertyAccessExpression>node).name, visitor, isIdentifier));
@@ -763,13 +785,13 @@ namespace ts {
visitNode((<ElementAccessExpression>node).argumentExpression, visitor, isExpression));
case SyntaxKind.CallExpression:
return updateCall((<CallExpression>node),
return updateCall(<CallExpression>node,
visitNode((<CallExpression>node).expression, visitor, isExpression),
visitNodes((<CallExpression>node).typeArguments, visitor, isTypeNode),
visitNodes((<CallExpression>node).arguments, visitor, isExpression));
case SyntaxKind.NewExpression:
return updateNew((<NewExpression>node),
return updateNew(<NewExpression>node,
visitNode((<NewExpression>node).expression, visitor, isExpression),
visitNodes((<NewExpression>node).typeArguments, visitor, isTypeNode),
visitNodes((<NewExpression>node).arguments, visitor, isExpression));
@@ -780,28 +802,28 @@ namespace ts {
visitNode((<TaggedTemplateExpression>node).template, visitor, isTemplate));
case SyntaxKind.ParenthesizedExpression:
return updateParen((<ParenthesizedExpression>node),
return updateParen(<ParenthesizedExpression>node,
visitNode((<ParenthesizedExpression>node).expression, visitor, isExpression));
case SyntaxKind.FunctionExpression:
return updateFunctionExpression(<FunctionExpression>node,
visitNode((<FunctionExpression>node).name, visitor, isPropertyName),
visitNodes((<FunctionExpression>node).typeParameters, visitor, isTypeParameter),
startLexicalEnvironmentAndVisitParameters((<FunctionExpression>node).parameters, visitor, context),
(context.startLexicalEnvironment(), visitNodes((<FunctionExpression>node).parameters, visitor, isParameter)),
visitNode((<FunctionExpression>node).type, visitor, isTypeNode, /*optional*/ true),
endLexicalEnvironmentAndUpdateBody(
mergeFunctionBodyLexicalEnvironment(
visitNode((<FunctionExpression>node).body, visitor, isFunctionBody, /*optional*/ true),
context));
context.endLexicalEnvironment()));
case SyntaxKind.ArrowFunction:
return updateArrowFunction(<ArrowFunction>node,
visitNodes((<ArrowFunction>node).modifiers, visitor, isModifier),
visitNodes((<ArrowFunction>node).typeParameters, visitor, isTypeParameter),
startLexicalEnvironmentAndVisitParameters((<ArrowFunction>node).parameters, visitor, context),
(context.startLexicalEnvironment(), visitNodes((<ArrowFunction>node).parameters, visitor, isParameter)),
visitNode((<ArrowFunction>node).type, visitor, isTypeNode, /*optional*/ true),
endLexicalEnvironmentAndUpdateBody(
mergeFunctionBodyLexicalEnvironment(
visitNode((<ArrowFunction>node).body, visitor, isConciseBody, /*optional*/ true),
context));
context.endLexicalEnvironment()));
case SyntaxKind.DeleteExpression:
return updateDelete(<DeleteExpression>node,
@@ -815,8 +837,12 @@ namespace ts {
return updateVoid(<VoidExpression>node,
visitNode((<VoidExpression>node).expression, visitor, isUnaryExpression));
case SyntaxKind.AwaitExpression:
return updateAwait(<AwaitExpression>node,
visitNode((<AwaitExpression>node).expression, visitor, isUnaryExpression));
case SyntaxKind.BinaryExpression:
return updateBinary((<BinaryExpression>node),
return updateBinary(<BinaryExpression>node,
visitNode((<BinaryExpression>node).left, visitor, isExpression),
visitNode((<BinaryExpression>node).right, visitor, isExpression));
@@ -868,20 +894,20 @@ namespace ts {
// Element
case SyntaxKind.Block:
return updateBlock((<Block>node),
return updateBlock(<Block>node,
visitNodes((<Block>node).statements, visitor, isStatement));
case SyntaxKind.VariableStatement:
return updateVariableStatement((<VariableStatement>node),
return updateVariableStatement(<VariableStatement>node,
visitNodes((<VariableStatement>node).modifiers, visitor, isModifier),
visitNode((<VariableStatement>node).declarationList, visitor, isVariableDeclarationList));
case SyntaxKind.ExpressionStatement:
return updateStatement((<ExpressionStatement>node),
return updateStatement(<ExpressionStatement>node,
visitNode((<ExpressionStatement>node).expression, visitor, isExpression));
case SyntaxKind.IfStatement:
return updateIf((<IfStatement>node),
return updateIf(<IfStatement>node,
visitNode((<IfStatement>node).expression, visitor, isExpression),
visitNode((<IfStatement>node).thenStatement, visitor, isStatement, /*optional*/ false, liftToBlock),
visitNode((<IfStatement>node).elseStatement, visitor, isStatement, /*optional*/ true, liftToBlock));
@@ -946,14 +972,20 @@ namespace ts {
return updateThrow(<ThrowStatement>node,
visitNode((<ThrowStatement>node).expression, visitor, isExpression));
case SyntaxKind.TryStatement:
return updateTry(<TryStatement>node,
visitNode((<TryStatement>node).tryBlock, visitor, isBlock),
visitNode((<TryStatement>node).catchClause, visitor, isCatchClause, /*optional*/ true),
visitNode((<TryStatement>node).finallyBlock, visitor, isBlock, /*optional*/ true));
case SyntaxKind.VariableDeclaration:
return updateVariableDeclaration((<VariableDeclaration>node),
return updateVariableDeclaration(<VariableDeclaration>node,
visitNode((<VariableDeclaration>node).name, visitor, isBindingName),
visitNode((<VariableDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
visitNode((<VariableDeclaration>node).initializer, visitor, isExpression, /*optional*/ true));
case SyntaxKind.VariableDeclarationList:
return updateVariableDeclarationList((<VariableDeclarationList>node),
return updateVariableDeclarationList(<VariableDeclarationList>node,
visitNodes((<VariableDeclarationList>node).declarations, visitor, isVariableDeclaration));
case SyntaxKind.FunctionDeclaration:
@@ -962,11 +994,11 @@ namespace ts {
visitNodes((<FunctionDeclaration>node).modifiers, visitor, isModifier),
visitNode((<FunctionDeclaration>node).name, visitor, isPropertyName),
visitNodes((<FunctionDeclaration>node).typeParameters, visitor, isTypeParameter),
startLexicalEnvironmentAndVisitParameters((<FunctionDeclaration>node).parameters, visitor, context),
(context.startLexicalEnvironment(), visitNodes((<FunctionDeclaration>node).parameters, visitor, isParameter)),
visitNode((<FunctionDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
endLexicalEnvironmentAndUpdateBody(
mergeFunctionBodyLexicalEnvironment(
visitNode((<FunctionDeclaration>node).body, visitor, isFunctionBody, /*optional*/ true),
context));
context.endLexicalEnvironment()));
case SyntaxKind.ClassDeclaration:
return updateClassDeclaration(<ClassDeclaration>node,
@@ -981,6 +1013,87 @@ namespace ts {
return updateCaseBlock(<CaseBlock>node,
visitNodes((<CaseBlock>node).clauses, visitor, isCaseOrDefaultClause));
case SyntaxKind.ImportDeclaration:
return updateImportDeclaration(<ImportDeclaration>node,
visitNodes((<ImportDeclaration>node).decorators, visitor, isDecorator),
visitNodes((<ImportDeclaration>node).modifiers, visitor, isModifier),
visitNode((<ImportDeclaration>node).importClause, visitor, isImportClause, /*optional*/ true),
visitNode((<ImportDeclaration>node).moduleSpecifier, visitor, isExpression));
case SyntaxKind.ImportClause:
return updateImportClause(<ImportClause>node,
visitNode((<ImportClause>node).name, visitor, isIdentifier, /*optional*/ true),
visitNode((<ImportClause>node).namedBindings, visitor, isNamedImportBindings, /*optional*/ true));
case SyntaxKind.NamespaceImport:
return updateNamespaceImport(<NamespaceImport>node,
visitNode((<NamespaceImport>node).name, visitor, isIdentifier));
case SyntaxKind.NamedImports:
return updateNamedImports(<NamedImports>node,
visitNodes((<NamedImports>node).elements, visitor, isImportSpecifier));
case SyntaxKind.ImportSpecifier:
return updateImportSpecifier(<ImportSpecifier>node,
visitNode((<ImportSpecifier>node).propertyName, visitor, isIdentifier, /*optional*/ true),
visitNode((<ImportSpecifier>node).name, visitor, isIdentifier));
case SyntaxKind.ExportAssignment:
return updateExportAssignment(<ExportAssignment>node,
visitNodes((<ExportAssignment>node).decorators, visitor, isDecorator),
visitNodes((<ExportAssignment>node).modifiers, visitor, isModifier),
visitNode((<ExportAssignment>node).expression, visitor, isExpression));
case SyntaxKind.ExportDeclaration:
return updateExportDeclaration(<ExportDeclaration>node,
visitNodes((<ExportDeclaration>node).decorators, visitor, isDecorator),
visitNodes((<ExportDeclaration>node).modifiers, visitor, isModifier),
visitNode((<ExportDeclaration>node).exportClause, visitor, isNamedExports, /*optional*/ true),
visitNode((<ExportDeclaration>node).moduleSpecifier, visitor, isExpression, /*optional*/ true));
case SyntaxKind.NamedExports:
return updateNamedExports(<NamedExports>node,
visitNodes((<NamedExports>node).elements, visitor, isExportSpecifier));
case SyntaxKind.ExportSpecifier:
return updateExportSpecifier(<ExportSpecifier>node,
visitNode((<ExportSpecifier>node).propertyName, visitor, isIdentifier, /*optional*/ true),
visitNode((<ExportSpecifier>node).name, visitor, isIdentifier));
// JSX
case SyntaxKind.JsxElement:
return updateJsxElement(<JsxElement>node,
visitNode((<JsxElement>node).openingElement, visitor, isJsxOpeningElement),
visitNodes((<JsxElement>node).children, visitor, isJsxChild),
visitNode((<JsxElement>node).closingElement, visitor, isJsxClosingElement));
case SyntaxKind.JsxSelfClosingElement:
return updateJsxSelfClosingElement(<JsxSelfClosingElement>node,
visitNode((<JsxSelfClosingElement>node).tagName, visitor, isJsxTagNameExpression),
visitNodes((<JsxSelfClosingElement>node).attributes, visitor, isJsxAttributeLike));
case SyntaxKind.JsxOpeningElement:
return updateJsxOpeningElement(<JsxOpeningElement>node,
visitNode((<JsxOpeningElement>node).tagName, visitor, isJsxTagNameExpression),
visitNodes((<JsxOpeningElement>node).attributes, visitor, isJsxAttributeLike));
case SyntaxKind.JsxClosingElement:
return updateJsxClosingElement(<JsxClosingElement>node,
visitNode((<JsxClosingElement>node).tagName, visitor, isJsxTagNameExpression));
case SyntaxKind.JsxAttribute:
return updateJsxAttribute(<JsxAttribute>node,
visitNode((<JsxAttribute>node).name, visitor, isIdentifier),
visitNode((<JsxAttribute>node).initializer, visitor, isStringLiteralOrJsxExpression));
case SyntaxKind.JsxSpreadAttribute:
return updateJsxSpreadAttribute(<JsxSpreadAttribute>node,
visitNode((<JsxSpreadAttribute>node).expression, visitor, isExpression));
case SyntaxKind.JsxExpression:
return updateJsxExpression(<JsxExpression>node,
visitNode((<JsxExpression>node).expression, visitor, isExpression));
// Clauses
case SyntaxKind.CaseClause:
return updateCaseClause(<CaseClause>node,
@@ -995,6 +1108,11 @@ namespace ts {
return updateHeritageClause(<HeritageClause>node,
visitNodes((<HeritageClause>node).types, visitor, isExpressionWithTypeArguments));
case SyntaxKind.CatchClause:
return updateCatchClause(<CatchClause>node,
visitNode((<CatchClause>node).variableDeclaration, visitor, isVariableDeclaration),
visitNode((<CatchClause>node).block, visitor, isBlock));
// Property assignments
case SyntaxKind.PropertyAssignment:
return updatePropertyAssignment(<PropertyAssignment>node,
@@ -1009,7 +1127,7 @@ namespace ts {
// Top-level nodes
case SyntaxKind.SourceFile:
context.startLexicalEnvironment();
return updateSourceFileNode((<SourceFile>node),
return updateSourceFileNode(<SourceFile>node,
createNodeArray(
concatenate(
visitNodes((<SourceFile>node).statements, visitor, isStatement),
@@ -1044,76 +1162,8 @@ namespace ts {
}
return updated ? updateNode(updated, node) : node;
}
}
function startLexicalEnvironmentAndVisitParameters(nodes: NodeArray<ParameterDeclaration>, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment): NodeArray<ParameterDeclaration> {
context.startLexicalEnvironment();
return visitNodes(nodes, visitor, isParameter);
}
function endLexicalEnvironmentAndUpdateBody(body: FunctionBody, context: LexicalEnvironment): FunctionBody;
function endLexicalEnvironmentAndUpdateBody(body: ConciseBody, context: LexicalEnvironment): ConciseBody;
function endLexicalEnvironmentAndUpdateBody(body: ConciseBody, context: LexicalEnvironment) {
const declarations = context.endLexicalEnvironment();
if (body && declarations && declarations.length) {
if (isBlock(body)) {
return updateBlock(body, createNodeArray(concatenate(body.statements, declarations), body.statements));
}
return createBlock(
createNodeArray([createReturn(body, /*location*/ body), ...declarations], body),
/*location*/ body,
/*multiLine*/ true);
}
return body;
}
/**
* Appends a node to an array.
*
* @param to The destination array.
* @param from The source Node or NodeArrayNode.
*/
export function addNode<T extends Node>(to: T[], from: VisitResult<T>, startOnNewLine?: boolean): void;
export function addNode(to: Node[], from: VisitResult<Node>, startOnNewLine: boolean, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, isVisiting: boolean): void;
export function addNode(to: Node[], from: VisitResult<Node>, startOnNewLine?: boolean, test?: (node: Node) => boolean, parenthesize?: (node: Node, parentNode: Node) => Node, parentNode?: Node, isVisiting?: boolean): void {
if (to && from) {
if (isArray(from)) {
addNodes(to, from, startOnNewLine, test, parenthesize, parentNode, isVisiting);
}
else {
const node = parenthesize !== undefined
? parenthesize(from, parentNode)
: from;
Debug.assertNode(node, test);
if (startOnNewLine) {
node.startsOnNewLine = true;
}
if (isVisiting) {
aggregateTransformFlags(node);
}
to.push(node);
}
}
}
/**
* Appends an array of nodes to an array.
*
* @param to The destination NodeArray.
* @param from The source array of Node or NodeArrayNode.
*/
export function addNodes<T extends Node>(to: T[], from: VisitResult<T>[], startOnNewLine?: boolean): void;
export function addNodes(to: Node[], from: VisitResult<Node>[], startOnNewLine: boolean, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, isVisiting: boolean): void;
export function addNodes(to: Node[], from: VisitResult<Node>[], startOnNewLine?: boolean, test?: (node: Node) => boolean, parenthesize?: (node: Node, parentNode: Node) => Node, parentNode?: Node, isVisiting?: boolean): void {
if (to && from) {
for (const node of from) {
addNode(to, node, startOnNewLine, test, parenthesize, parentNode, isVisiting);
}
}
// return node;
}
/**
@@ -1122,13 +1172,7 @@ namespace ts {
* @param node The ConciseBody of an arrow function.
* @param declarations The lexical declarations to merge.
*/
export function mergeFunctionBodyLexicalEnvironment(body: FunctionBody, declarations: Statement[]): FunctionBody {
if (declarations !== undefined && declarations.length > 0) {
return mergeBlockLexicalEnvironment(body, declarations);
}
return body;
}
export function mergeFunctionBodyLexicalEnvironment(body: FunctionBody, declarations: Statement[]): FunctionBody;
/**
* Merges generated lexical declarations into the ConciseBody of an ArrowFunction.
@@ -1136,44 +1180,23 @@ namespace ts {
* @param node The ConciseBody of an arrow function.
* @param declarations The lexical declarations to merge.
*/
export function mergeConciseBodyLexicalEnvironment(body: ConciseBody, declarations: Statement[]): ConciseBody {
if (declarations !== undefined && declarations.length > 0) {
export function mergeFunctionBodyLexicalEnvironment(body: ConciseBody, declarations: Statement[]): ConciseBody;
export function mergeFunctionBodyLexicalEnvironment(body: ConciseBody, declarations: Statement[]): ConciseBody {
if (body && declarations !== undefined && declarations.length > 0) {
if (isBlock(body)) {
return mergeBlockLexicalEnvironment(body, declarations);
return updateBlock(body, createNodeArray(concatenate(body.statements, declarations), body.statements));
}
else {
return createBlock([
createReturn(body),
...declarations
]);
return createBlock(
createNodeArray([createReturn(body, /*location*/ body), ...declarations], body),
/*location*/ body,
/*multiLine*/ true);
}
}
return body;
}
/**
* Merge generated declarations of a lexical environment into a FunctionBody or ModuleBlock.
*
* @param node The block into which to merge lexical declarations.
* @param declarations The lexical declarations to merge.
*/
function mergeBlockLexicalEnvironment<T extends Block>(node: T, declarations: Statement[]): T {
const mutableNode = getMutableClone(node);
mutableNode.statements = mergeStatements(node.statements, declarations);
return mutableNode;
}
/**
* Merge generated declarations of a lexical environment into a NodeArray of Statement.
*
* @param statements The node array to concatentate with the supplied lexical declarations.
* @param declarations The lexical declarations to merge.
*/
function mergeStatements(statements: NodeArray<Statement>, declarations: Statement[]): NodeArray<Statement> {
return createNodeArray(concatenate(statements, declarations), /*location*/ statements);
}
/**
* Lifts a NodeArray containing only Statement nodes to a block.
*