Merge branch 'transforms-transformer' into transforms-printer
This commit is contained in:
commit
98ab964688
2 changed files with 132 additions and 79 deletions
|
@ -250,7 +250,7 @@ namespace ts {
|
||||||
node.decorators = undefined;
|
node.decorators = undefined;
|
||||||
node.modifiers = undefined;
|
node.modifiers = undefined;
|
||||||
node.typeParameters = undefined;
|
node.typeParameters = undefined;
|
||||||
node.parameters = createSynthesizedNodeArray(parameters);
|
node.parameters = createNodeArray(parameters);
|
||||||
node.type = undefined;
|
node.type = undefined;
|
||||||
node.body = body;
|
node.body = body;
|
||||||
return node;
|
return node;
|
||||||
|
@ -286,7 +286,7 @@ namespace ts {
|
||||||
node.name = typeof name === "string" ? createIdentifier(name) : name;
|
node.name = typeof name === "string" ? createIdentifier(name) : name;
|
||||||
node.questionToken = undefined;
|
node.questionToken = undefined;
|
||||||
node.type = undefined;
|
node.type = undefined;
|
||||||
node.initializer = initializer;
|
node.initializer = initializer ? parenthesizeExpressionForList(initializer) : undefined;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ namespace ts {
|
||||||
|
|
||||||
export function createArrayLiteral(elements?: Expression[]) {
|
export function createArrayLiteral(elements?: Expression[]) {
|
||||||
const node = <ArrayLiteralExpression>createNode(SyntaxKind.ArrayLiteralExpression);
|
const node = <ArrayLiteralExpression>createNode(SyntaxKind.ArrayLiteralExpression);
|
||||||
node.elements = createNodeArray(elements);
|
node.elements = parenthesizeListElements(createNodeArray(elements));
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,14 +322,16 @@ namespace ts {
|
||||||
export function createCall(expression: Expression, argumentsArray: Expression[], location?: TextRange) {
|
export function createCall(expression: Expression, argumentsArray: Expression[], location?: TextRange) {
|
||||||
const node = <CallExpression>createNode(SyntaxKind.CallExpression, location);
|
const node = <CallExpression>createNode(SyntaxKind.CallExpression, location);
|
||||||
node.expression = parenthesizeForAccess(expression);
|
node.expression = parenthesizeForAccess(expression);
|
||||||
node.arguments = createNodeArray(argumentsArray);
|
node.arguments = parenthesizeListElements(createNodeArray(argumentsArray));
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createNew(expression: Expression, argumentsArray: Expression[], location?: TextRange) {
|
export function createNew(expression: Expression, argumentsArray: Expression[], location?: TextRange) {
|
||||||
const node = <NewExpression>createNode(SyntaxKind.NewExpression, location);
|
const node = <NewExpression>createNode(SyntaxKind.NewExpression, location);
|
||||||
node.expression = parenthesizeForAccess(expression);
|
node.expression = parenthesizeForAccess(expression);
|
||||||
node.arguments = argumentsArray ? createNodeArray(argumentsArray) : undefined;
|
node.arguments = argumentsArray
|
||||||
|
? parenthesizeListElements(createNodeArray(argumentsArray))
|
||||||
|
: undefined;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +360,7 @@ namespace ts {
|
||||||
node.parameters = createNodeArray(parameters);
|
node.parameters = createNodeArray(parameters);
|
||||||
node.type = undefined;
|
node.type = undefined;
|
||||||
node.equalsGreaterThanToken = createNode(SyntaxKind.EqualsGreaterThanToken);
|
node.equalsGreaterThanToken = createNode(SyntaxKind.EqualsGreaterThanToken);
|
||||||
node.body = body;
|
node.body = parenthesizeConciseBody(body);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,7 +416,7 @@ namespace ts {
|
||||||
|
|
||||||
export function createSpread(expression: Expression) {
|
export function createSpread(expression: Expression) {
|
||||||
const node = <SpreadElementExpression>createNode(SyntaxKind.SpreadElementExpression);
|
const node = <SpreadElementExpression>createNode(SyntaxKind.SpreadElementExpression);
|
||||||
node.expression = expression;
|
node.expression = parenthesizeExpressionForList(expression);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,8 +426,8 @@ namespace ts {
|
||||||
node.modifiers = undefined;
|
node.modifiers = undefined;
|
||||||
node.name = name;
|
node.name = name;
|
||||||
node.typeParameters = undefined;
|
node.typeParameters = undefined;
|
||||||
node.heritageClauses = createSynthesizedNodeArray(heritageClauses);
|
node.heritageClauses = createNodeArray(heritageClauses);
|
||||||
node.members = createSynthesizedNodeArray(members);
|
node.members = createNodeArray(members);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,7 +471,7 @@ namespace ts {
|
||||||
export function createVariableDeclaration(name: string | BindingPattern | Identifier, initializer?: Expression, location?: TextRange): VariableDeclaration {
|
export function createVariableDeclaration(name: string | BindingPattern | Identifier, initializer?: Expression, location?: TextRange): VariableDeclaration {
|
||||||
const node = <VariableDeclaration>createNode(SyntaxKind.VariableDeclaration, location);
|
const node = <VariableDeclaration>createNode(SyntaxKind.VariableDeclaration, location);
|
||||||
node.name = typeof name === "string" ? createIdentifier(name) : name;
|
node.name = typeof name === "string" ? createIdentifier(name) : name;
|
||||||
node.initializer = initializer;
|
node.initializer = initializer !== undefined ? parenthesizeExpressionForList(initializer) : undefined;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +481,7 @@ namespace ts {
|
||||||
|
|
||||||
export function createStatement(expression: Expression, location?: TextRange): ExpressionStatement {
|
export function createStatement(expression: Expression, location?: TextRange): ExpressionStatement {
|
||||||
const node = <ExpressionStatement>createNode(SyntaxKind.ExpressionStatement, location);
|
const node = <ExpressionStatement>createNode(SyntaxKind.ExpressionStatement, location);
|
||||||
node.expression = expression;
|
node.expression = parenthesizeExpressionForExpressionStatement(expression);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,8 +564,8 @@ namespace ts {
|
||||||
setModifiers(node, modifiers);
|
setModifiers(node, modifiers);
|
||||||
node.name = name;
|
node.name = name;
|
||||||
node.typeParameters = undefined;
|
node.typeParameters = undefined;
|
||||||
node.heritageClauses = createSynthesizedNodeArray(heritageClauses);
|
node.heritageClauses = createNodeArray(heritageClauses);
|
||||||
node.members = createSynthesizedNodeArray(members);
|
node.members = createNodeArray(members);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,7 +601,14 @@ namespace ts {
|
||||||
export function createHeritageClause(token: SyntaxKind, types: ExpressionWithTypeArguments[], location?: TextRange) {
|
export function createHeritageClause(token: SyntaxKind, types: ExpressionWithTypeArguments[], location?: TextRange) {
|
||||||
const node = <HeritageClause>createNode(SyntaxKind.HeritageClause, location);
|
const node = <HeritageClause>createNode(SyntaxKind.HeritageClause, location);
|
||||||
node.token = token;
|
node.token = token;
|
||||||
node.types = createSynthesizedNodeArray(types);
|
node.types = createNodeArray(types);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createCaseClause(expression: Expression, statements: Statement[], location?: TextRange) {
|
||||||
|
const node = <CaseClause>createNode(SyntaxKind.CaseClause, location);
|
||||||
|
node.expression = parenthesizeExpressionForList(expression);
|
||||||
|
node.statements = createNodeArray(statements);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,7 +618,7 @@ namespace ts {
|
||||||
const node = <PropertyAssignment>createNode(SyntaxKind.PropertyAssignment, location);
|
const node = <PropertyAssignment>createNode(SyntaxKind.PropertyAssignment, location);
|
||||||
node.name = typeof name === "string" ? createIdentifier(name) : name;
|
node.name = typeof name === "string" ? createIdentifier(name) : name;
|
||||||
node.questionToken = undefined;
|
node.questionToken = undefined;
|
||||||
node.initializer = initializer;
|
node.initializer = initializer !== undefined ? parenthesizeExpressionForList(initializer) : undefined;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1206,6 +1215,26 @@ namespace ts {
|
||||||
: createParen(operand, /*location*/ operand);
|
: createParen(operand, /*location*/ operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parenthesizeListElements(elements: NodeArray<Expression>) {
|
||||||
|
let result: Expression[];
|
||||||
|
for (let i = 0; i < elements.length; i++) {
|
||||||
|
const element = parenthesizeExpressionForList(elements[i]);
|
||||||
|
if (result !== undefined || element !== elements[i]) {
|
||||||
|
if (result === undefined) {
|
||||||
|
result = elements.slice(0, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result !== undefined) {
|
||||||
|
return createNodeArray(result, elements, elements.hasTrailingComma);
|
||||||
|
}
|
||||||
|
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
export function parenthesizeExpressionForList(expression: Expression) {
|
export function parenthesizeExpressionForList(expression: Expression) {
|
||||||
const expressionPrecedence = getExpressionPrecedence(expression);
|
const expressionPrecedence = getExpressionPrecedence(expression);
|
||||||
const commaPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, SyntaxKind.CommaToken);
|
const commaPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, SyntaxKind.CommaToken);
|
||||||
|
@ -1231,6 +1260,14 @@ namespace ts {
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function parenthesizeConciseBody(body: ConciseBody): ConciseBody {
|
||||||
|
if (body.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||||
|
return createParen(<Expression>body, /*location*/ body);
|
||||||
|
}
|
||||||
|
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
function getLeftmostExpression(node: Expression): Expression {
|
function getLeftmostExpression(node: Expression): Expression {
|
||||||
while (true) {
|
while (true) {
|
||||||
switch (node.kind) {
|
switch (node.kind) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/// <reference path="checker.ts" />
|
/// <reference path="checker.ts" />
|
||||||
|
/// <reference path="factory.ts" />
|
||||||
|
|
||||||
/* @internal */
|
/* @internal */
|
||||||
namespace ts {
|
namespace ts {
|
||||||
|
@ -162,7 +163,7 @@ namespace ts {
|
||||||
{ name: "typeParameters", test: isTypeParameter },
|
{ name: "typeParameters", test: isTypeParameter },
|
||||||
{ name: "parameters", test: isParameter },
|
{ name: "parameters", test: isParameter },
|
||||||
{ name: "type", test: isTypeNode, optional: true },
|
{ name: "type", test: isTypeNode, optional: true },
|
||||||
{ name: "body", test: isConciseBody, lift: liftToBlock },
|
{ name: "body", test: isConciseBody, lift: liftToBlock, parenthesize: parenthesizeConciseBody },
|
||||||
],
|
],
|
||||||
[SyntaxKind.DeleteExpression]: [
|
[SyntaxKind.DeleteExpression]: [
|
||||||
{ name: "expression", test: isUnaryExpression, parenthesize: parenthesizePrefixOperand },
|
{ name: "expression", test: isUnaryExpression, parenthesize: parenthesizePrefixOperand },
|
||||||
|
@ -407,7 +408,7 @@ namespace ts {
|
||||||
{ name: "expression", test: isExpression, optional: true },
|
{ name: "expression", test: isExpression, optional: true },
|
||||||
],
|
],
|
||||||
[SyntaxKind.CaseClause]: [
|
[SyntaxKind.CaseClause]: [
|
||||||
{ name: "expression", test: isExpression },
|
{ name: "expression", test: isExpression, parenthesize: parenthesizeExpressionForList },
|
||||||
{ name: "statements", test: isStatement },
|
{ name: "statements", test: isStatement },
|
||||||
],
|
],
|
||||||
[SyntaxKind.DefaultClause]: [
|
[SyntaxKind.DefaultClause]: [
|
||||||
|
@ -477,24 +478,46 @@ namespace ts {
|
||||||
* @param lift An optional callback to execute to lift a NodeArrayNode into a valid Node.
|
* @param lift An optional callback to execute to lift a NodeArrayNode into a valid Node.
|
||||||
*/
|
*/
|
||||||
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => Node, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray<Node>) => T): T {
|
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => Node, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray<Node>) => T): T {
|
||||||
|
return <T>visitNodeWorker(node, visitor, test, optional, lift, /*parenthesize*/ undefined, /*parentNode*/ undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits a Node using the supplied visitor, possibly returning a new Node in its place.
|
||||||
|
*
|
||||||
|
* @param node The Node to visit.
|
||||||
|
* @param visitor The callback used to visit the Node.
|
||||||
|
* @param test A callback to execute to verify the Node is valid.
|
||||||
|
* @param optional A value indicating whether the Node is itself optional.
|
||||||
|
* @param lift A callback to execute to lift a NodeArrayNode into a valid Node.
|
||||||
|
* @param parenthesize A callback used to parenthesize the node if needed.
|
||||||
|
* @param parentNode A parentNode for the node.
|
||||||
|
*/
|
||||||
|
function visitNodeWorker(node: Node, visitor: (node: Node) => Node, test: (node: Node) => boolean, optional: boolean, lift: (node: NodeArray<Node>) => Node, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): Node {
|
||||||
if (node === undefined) {
|
if (node === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const visited = visitor(node);
|
let visited = visitor(node);
|
||||||
if (visited === node) {
|
if (visited === node) {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lifted = liftNode(visited, lift);
|
if (lift !== undefined && visited !== undefined && isNodeArrayNode(visited)) {
|
||||||
if (lifted === undefined) {
|
visited = lift((<NodeArrayNode<Node>>visited).nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parenthesize !== undefined && visited !== undefined) {
|
||||||
|
visited = parenthesize(visited, parentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visited === undefined) {
|
||||||
Debug.assert(optional, "Node not optional.");
|
Debug.assert(optional, "Node not optional.");
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.assert(test === undefined || test(visited), "Wrong node type after visit.");
|
Debug.assert(test === undefined || test(visited), "Wrong node type after visit.");
|
||||||
aggregateTransformFlags(visited);
|
aggregateTransformFlags(visited);
|
||||||
return <T>visited;
|
return visited;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -507,11 +530,24 @@ namespace ts {
|
||||||
* @param count An optional value indicating the maximum number of nodes to visit.
|
* @param count An optional value indicating the maximum number of nodes to visit.
|
||||||
*/
|
*/
|
||||||
export function visitNodes<T extends Node, TArray extends NodeArray<T>>(nodes: TArray, visitor: (node: Node) => Node, test: (node: Node) => boolean, start?: number, count?: number): TArray {
|
export function visitNodes<T extends Node, TArray extends NodeArray<T>>(nodes: TArray, visitor: (node: Node) => Node, test: (node: Node) => boolean, start?: number, count?: number): TArray {
|
||||||
|
return <TArray>visitNodesWorker(nodes, visitor, test, /*parenthesize*/ undefined, /*parentNode*/ undefined, start, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
|
||||||
|
*
|
||||||
|
* @param nodes The NodeArray to visit.
|
||||||
|
* @param visitor The callback used to visit a Node.
|
||||||
|
* @param test A node test to execute for each node.
|
||||||
|
* @param start An optional value indicating the starting offset at which to start visiting.
|
||||||
|
* @param count An optional value indicating the maximum number of nodes to visit.
|
||||||
|
*/
|
||||||
|
function visitNodesWorker(nodes: NodeArray<Node>, visitor: (node: Node) => Node, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, start: number, count: number): NodeArray<Node> {
|
||||||
if (nodes === undefined) {
|
if (nodes === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
let updated: T[];
|
let updated: Node[];
|
||||||
|
|
||||||
// Ensure start and count have valid values
|
// Ensure start and count have valid values
|
||||||
const length = nodes.length;
|
const length = nodes.length;
|
||||||
|
@ -531,25 +567,21 @@ namespace ts {
|
||||||
// Visit each original node.
|
// Visit each original node.
|
||||||
for (let i = 0; i < count; i++) {
|
for (let i = 0; i < count; i++) {
|
||||||
const node = nodes[i + start];
|
const node = nodes[i + start];
|
||||||
const visited = node && <OneOrMany<T>>visitor(node);
|
const visited = node !== undefined ? visitor(node) : undefined;
|
||||||
if (updated !== undefined || visited === undefined || visited !== node) {
|
if (updated !== undefined || visited === undefined || visited !== node) {
|
||||||
if (updated === undefined) {
|
if (updated === undefined) {
|
||||||
// Ensure we have a copy of `nodes`, up to the current index.
|
// Ensure we have a copy of `nodes`, up to the current index.
|
||||||
updated = nodes.slice(0, i);
|
updated = nodes.slice(0, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (visited !== node) {
|
addNodeWorker(updated, visited, /*addOnNewLine*/ undefined, test, parenthesize, parentNode, /*isVisiting*/ visited !== node);
|
||||||
aggregateTransformFlags(visited);
|
|
||||||
}
|
|
||||||
|
|
||||||
addNodeWorker(updated, visited, /*addOnNewLine*/ undefined, test);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updated !== undefined) {
|
if (updated !== undefined) {
|
||||||
return <TArray>(isModifiersArray(nodes)
|
return isModifiersArray(nodes)
|
||||||
? createModifiersArray(updated, nodes)
|
? createModifiersArray(updated, nodes)
|
||||||
: createNodeArray(updated, nodes, nodes.hasTrailingComma));
|
: createNodeArray(updated, nodes, nodes.hasTrailingComma);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodes;
|
return nodes;
|
||||||
|
@ -582,9 +614,17 @@ namespace ts {
|
||||||
for (const edge of edgeTraversalPath) {
|
for (const edge of edgeTraversalPath) {
|
||||||
const value = <Node | NodeArray<Node>>node[edge.name];
|
const value = <Node | NodeArray<Node>>node[edge.name];
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
const visited = visitEdge(edge, value, visitor);
|
let visited: Node | NodeArray<Node>;
|
||||||
if (visited && isArray(visited) && isModifiersArray(visited)) {
|
if (isArray(value)) {
|
||||||
modifiers = visited.flags;
|
const visitedArray = visitNodesWorker(value, visitor, edge.test, edge.parenthesize, node, 0, value.length);
|
||||||
|
if (isModifiersArray(visitedArray)) {
|
||||||
|
modifiers = visitedArray.flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
visited = visitedArray;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
visited = visitNodeWorker(<Node>value, visitor, edge.test, edge.optional, edge.lift, edge.parenthesize, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updated !== undefined || visited !== value) {
|
if (updated !== undefined || visited !== value) {
|
||||||
|
@ -599,7 +639,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (visited !== value) {
|
if (visited !== value) {
|
||||||
setEdgeValue(updated, edge, visited);
|
updated[edge.name] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -625,39 +665,6 @@ namespace ts {
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Visits a node edge.
|
|
||||||
*
|
|
||||||
* @param edge The edge of the Node.
|
|
||||||
* @param value The Node or NodeArray value for the edge.
|
|
||||||
* @param visitor A callback used to visit the node.
|
|
||||||
*/
|
|
||||||
function visitEdge(edge: NodeEdge, value: Node | NodeArray<Node>, visitor: (node: Node) => Node) {
|
|
||||||
return isArray(value)
|
|
||||||
? visitNodes(<NodeArray<Node>>value, visitor, edge.test, /*start*/ undefined, /*count*/ undefined)
|
|
||||||
: visitNode(<Node>value, visitor, edge.test, edge.optional, edge.lift);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of an edge, adjusting the value as necessary for cases such as expression precedence.
|
|
||||||
*/
|
|
||||||
function setEdgeValue(parentNode: Node & Map<any>, edge: NodeEdge, value: Node | NodeArray<Node>) {
|
|
||||||
if (value && edge.parenthesize && !isArray(value)) {
|
|
||||||
value = parenthesizeEdge(<Node>value, parentNode, edge.parenthesize, edge.test);
|
|
||||||
}
|
|
||||||
|
|
||||||
parentNode[edge.name] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies parentheses to a node to ensure the correct precedence.
|
|
||||||
*/
|
|
||||||
function parenthesizeEdge(node: Node, parentNode: Node, parenthesize: (node: Node, parentNode: Node) => Node, test: (node: Node) => boolean) {
|
|
||||||
node = parenthesize(node, parentNode);
|
|
||||||
Debug.assert(test === undefined || test(node), "Unexpected node kind after visit.");
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends a node to an array.
|
* Appends a node to an array.
|
||||||
*
|
*
|
||||||
|
@ -666,7 +673,7 @@ namespace ts {
|
||||||
* @param test The node test used to validate each node.
|
* @param test The node test used to validate each node.
|
||||||
*/
|
*/
|
||||||
export function addNode<T extends Node>(to: T[], from: OneOrMany<T>, startOnNewLine?: boolean) {
|
export function addNode<T extends Node>(to: T[], from: OneOrMany<T>, startOnNewLine?: boolean) {
|
||||||
addNodeWorker(to, from, startOnNewLine, /*test*/ undefined);
|
addNodeWorker(to, from, startOnNewLine, /*test*/ undefined, /*parenthesize*/ undefined, /*parentNode*/ undefined, /*isVisiting*/ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -677,29 +684,38 @@ namespace ts {
|
||||||
* @param test The node test used to validate each node.
|
* @param test The node test used to validate each node.
|
||||||
*/
|
*/
|
||||||
export function addNodes<T extends Node>(to: T[], from: OneOrMany<T>[], startOnNewLine?: boolean) {
|
export function addNodes<T extends Node>(to: T[], from: OneOrMany<T>[], startOnNewLine?: boolean) {
|
||||||
addNodesWorker(to, from, startOnNewLine, /*test*/ undefined);
|
addNodesWorker(to, from, startOnNewLine, /*test*/ undefined, /*parenthesize*/ undefined, /*parentNode*/ undefined, /*isVisiting*/ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addNodeWorker<T extends Node>(to: T[], from: OneOrMany<T>, startOnNewLine: boolean, test: (node: Node) => boolean) {
|
function addNodeWorker(to: Node[], from: OneOrMany<Node>, startOnNewLine: boolean, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, isVisiting: boolean) {
|
||||||
if (to && from) {
|
if (to && from) {
|
||||||
if (isNodeArrayNode(from)) {
|
if (isNodeArrayNode(from)) {
|
||||||
addNodesWorker(to, from.nodes, startOnNewLine, test);
|
addNodesWorker(to, from.nodes, startOnNewLine, test, parenthesize, parentNode, isVisiting);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
Debug.assert(test === undefined || test(from), "Wrong node type after visit.");
|
|
||||||
if (startOnNewLine) {
|
|
||||||
from.startsOnNewLine = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
to.push(from);
|
if (parenthesize !== undefined) {
|
||||||
|
from = parenthesize(from, parentNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug.assert(test === undefined || test(from), "Wrong node type after visit.");
|
||||||
|
|
||||||
|
if (startOnNewLine) {
|
||||||
|
from.startsOnNewLine = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isVisiting) {
|
||||||
|
aggregateTransformFlags(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
to.push(from);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addNodesWorker<T extends Node>(to: T[], from: OneOrMany<T>[], startOnNewLine: boolean, test: (node: Node) => boolean) {
|
function addNodesWorker(to: Node[], from: OneOrMany<Node>[], startOnNewLine: boolean, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, isVisiting: boolean) {
|
||||||
if (to && from) {
|
if (to && from) {
|
||||||
for (const node of from) {
|
for (const node of from) {
|
||||||
addNodeWorker(to, node, startOnNewLine, test);
|
addNodeWorker(to, node, startOnNewLine, test, parenthesize, parentNode, isVisiting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue