diff --git a/src/compiler/core.ts b/src/compiler/core.ts
index 48abb6ae3e3..14d49604f67 100644
--- a/src/compiler/core.ts
+++ b/src/compiler/core.ts
@@ -866,6 +866,7 @@ namespace ts {
this.end = end;
this.flags = NodeFlags.None;
this.parent = undefined;
+ this.original = undefined;
}
export let objectAllocator: ObjectAllocator = {
diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts
index 06eb4b98b9c..d838288ef25 100644
--- a/src/compiler/factory.ts
+++ b/src/compiler/factory.ts
@@ -1,53 +1,134 @@
-///
+///
///
-/* @internal */
+
namespace ts {
- export function createNodeArray(elements?: T[], location?: TextRange): NodeArray;
- export function createNodeArray>(elements: TArray, location?: TextRange): TArray;
- export function createNodeArray>(elements?: T[], location?: TextRange): TArray {
- const array = (elements || []);
- if (location) {
- array.pos = location.pos;
- array.end = location.end;
- }
- else if (array.pos === undefined || array.end === undefined) {
- array.pos = -1;
- array.end = -1;
- }
+ let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
+ let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
+ export function createNode(kind: SyntaxKind, pos?: number, end?: number): Node {
+ if (kind === SyntaxKind.SourceFile) {
+ return new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, pos, end);
+ }
+ else {
+ return new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, pos, end);
+ }
+ }
+
+ /* @internal */
+ export function createNodeArray(elements?: T[], pos?: number, end?: number): NodeArray {
+ const array = >(elements || []);
+ array.pos = pos;
+ array.end = end;
+ array.arrayKind = ArrayKind.NodeArray;
return array;
}
- export function createNodeArrayNode(elements?: (T | NodeArrayNode)[]): NodeArrayNode {
- const array = >createNodeArray(elements);
- array.kind = SyntaxKind.NodeArrayNode;
+ /* @internal */
+ export function createModifiersArray(elements?: Modifier[], pos?: number, end?: number): ModifiersArray {
+ const array = (elements || []);
+ array.pos = pos;
+ array.end = end;
+ array.arrayKind = ArrayKind.ModifiersArray;
+ array.flags = 0;
return array;
}
+ /* @internal */
+ export function createSynthesizedNode(kind: SyntaxKind, startsOnNewLine?: boolean): Node {
+ const node = createNode(kind, /*pos*/ -1, /*end*/ -1);
+ node.startsOnNewLine = startsOnNewLine;
+ return node;
+ }
+
+ /* @internal */
+ export function createSynthesizedNodeArray(elements?: T[]): NodeArray {
+ return createNodeArray(elements, /*pos*/ -1, /*end*/ -1);
+ }
+
+ /* @internal */
+ export function createSynthesizedModifiersArray(elements?: Modifier[]): ModifiersArray {
+ return createModifiersArray(elements, /*pos*/ -1, /*end*/ -1);
+ }
+
+ /**
+ * Creates a shallow, memberwise clone of a node. The "kind", "pos", "end", "flags", and "parent"
+ * properties are excluded by default, and can be provided via the "location", "flags", and
+ * "parent" parameters.
+ *
+ * @param node The node to clone.
+ * @param location An optional TextRange to use to supply the new position.
+ * @param flags The NodeFlags to use for the cloned node.
+ * @param parent The parent for the new node.
+ * @param original An optional pointer to the original source tree node.
+ */
+ /* @internal */
+ export function cloneNode(node: T, location?: TextRange, flags?: NodeFlags, parent?: Node, original?: Node): T {
+ // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
+ // the original node. We also need to exclude specific properties and only include own-
+ // properties (to skip members already defined on the shared prototype).
+ const clone = location !== undefined
+ ? createNode(node.kind, location.pos, location.end)
+ : createSynthesizedNode(node.kind);
+
+ for (const key in node) {
+ if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) {
+ continue;
+ }
+
+ (clone)[key] = (node)[key];
+ }
+
+ if (flags !== undefined) {
+ clone.flags = flags;
+ }
+
+ if (parent !== undefined) {
+ clone.parent = parent;
+ }
+
+ if (original !== undefined) {
+ clone.original = original;
+ }
+
+ return clone;
+ }
+
+ /* @internal */
+ export function createNodeArrayNode(elements: T[]): NodeArrayNode {
+ const node = >createSynthesizedNode(SyntaxKind.NodeArrayNode);
+ node.nodes = createNodeArray(elements);
+ return node;
+ }
+
+ /* @internal */
export function createReturn(expression?: Expression): ReturnStatement {
const node = createSynthesizedNode(SyntaxKind.ReturnStatement);
node.expression = expression;
return node;
}
+ /* @internal */
export function createStatement(expression: Expression): ExpressionStatement {
const node = createSynthesizedNode(SyntaxKind.ExpressionStatement);
node.expression = expression;
return node;
}
+ /* @internal */
export function createVariableStatement(declarationList: VariableDeclarationList): VariableStatement {
const node = createSynthesizedNode(SyntaxKind.VariableStatement);
node.declarationList = declarationList;
return node;
}
+ /* @internal */
export function createVariableDeclarationList(declarations: VariableDeclaration[]): VariableDeclarationList {
const node = createSynthesizedNode(SyntaxKind.VariableDeclarationList);
node.declarations = createNodeArray(declarations);
return node;
}
+ /* @internal */
export function createBlock(statements: Statement[]): Block {
const block = createSynthesizedNode(SyntaxKind.Block);
block.statements = createNodeArray(statements);
diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts
index f866b86fca2..1d9f9fe2305 100644
--- a/src/compiler/parser.ts
+++ b/src/compiler/parser.ts
@@ -1,21 +1,10 @@
///
///
+///
namespace ts {
/* @internal */ export let parseTime = 0;
- let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
- let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
-
- export function createNode(kind: SyntaxKind, pos?: number, end?: number): Node {
- if (kind === SyntaxKind.SourceFile) {
- return new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, pos, end);
- }
- else {
- return new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, pos, end);
- }
- }
-
function visitNode(cbNode: (node: Node) => T, node: Node): T {
if (node) {
return cbNode(node);
@@ -875,7 +864,7 @@ namespace ts {
/** Invokes the provided callback then unconditionally restores the parser to the state it
* was in immediately prior to invoking the callback. The result of invoking the callback
- * is returned from this function.
+ * is returned from this function.
*/
function lookAhead(callback: () => T): T {
return speculationHelper(callback, /*isLookAhead*/ true);
@@ -989,6 +978,29 @@ namespace ts {
return new NodeConstructor(kind, pos, pos);
}
+ function createNodeArray(elements?: T[], pos?: number): NodeArray {
+ const array = >(elements || []);
+ if (!(pos >= 0)) {
+ pos = getNodePos();
+ }
+ array.pos = pos;
+ array.end = pos;
+ array.arrayKind = ArrayKind.NodeArray;
+ return array;
+ }
+
+ function createModifiersArray(elements?: Modifier[], pos?: number): ModifiersArray {
+ const array = (elements || []);
+ if (!(pos >= 0)) {
+ pos = getNodePos();
+ }
+ array.pos = pos;
+ array.end = pos;
+ array.arrayKind = ArrayKind.ModifiersArray;
+ array.flags = 0;
+ return array;
+ }
+
function finishNode(node: T, end?: number): T {
node.end = end === undefined ? scanner.getStartPos() : end;
@@ -1374,8 +1386,7 @@ namespace ts {
function parseList(kind: ParsingContext, parseElement: () => T): NodeArray {
const saveParsingContext = parsingContext;
parsingContext |= 1 << kind;
- const result = >[];
- result.pos = getNodePos();
+ const result = createNodeArray();
while (!isListTerminator(kind)) {
if (isListElement(kind, /*inErrorRecovery*/ false)) {
@@ -1722,8 +1733,7 @@ namespace ts {
function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimeter?: boolean): NodeArray {
const saveParsingContext = parsingContext;
parsingContext |= 1 << kind;
- const result = >[];
- result.pos = getNodePos();
+ const result = createNodeArray();
let commaStart = -1; // Meaning the previous token was not a comma
while (true) {
@@ -1778,12 +1788,8 @@ namespace ts {
return result;
}
- function createMissingList(): NodeArray {
- const pos = getNodePos();
- const result = >[];
- result.pos = pos;
- result.end = pos;
- return result;
+ function createMissingList(): NodeArray {
+ return createNodeArray();
}
function parseBracketedList(kind: ParsingContext, parseElement: () => T, open: SyntaxKind, close: SyntaxKind): NodeArray {
@@ -1848,8 +1854,7 @@ namespace ts {
template.head = parseTemplateLiteralFragment();
Debug.assert(template.head.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
- const templateSpans = >[];
- templateSpans.pos = getNodePos();
+ const templateSpans = createNodeArray();
do {
templateSpans.push(parseTemplateSpan());
@@ -2425,8 +2430,7 @@ namespace ts {
function parseUnionOrIntersectionType(kind: SyntaxKind, parseConstituentType: () => TypeNode, operator: SyntaxKind): TypeNode {
let type = parseConstituentType();
if (token === operator) {
- const types = >[type];
- types.pos = type.pos;
+ const types = createNodeArray([type], type.pos);
while (parseOptional(operator)) {
types.push(parseConstituentType());
}
@@ -2781,8 +2785,7 @@ namespace ts {
parameter.name = identifier;
finishNode(parameter);
- node.parameters = >[parameter];
- node.parameters.pos = parameter.pos;
+ node.parameters = createNodeArray([parameter], parameter.pos);
node.parameters.end = parameter.end;
node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, "=>");
@@ -3557,8 +3560,7 @@ namespace ts {
}
function parseJsxChildren(openingTagName: EntityName): NodeArray {
- const result = >[];
- result.pos = scanner.getStartPos();
+ const result = createNodeArray();
const saveParsingContext = parsingContext;
parsingContext |= 1 << ParsingContext.JsxChildren;
@@ -4922,14 +4924,15 @@ namespace ts {
break;
}
- if (!decorators) {
- decorators = >[];
- decorators.pos = decoratorStart;
- }
-
const decorator = createNode(SyntaxKind.Decorator, decoratorStart);
decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
- decorators.push(finishNode(decorator));
+ finishNode(decorator);
+ if (!decorators) {
+ decorators = createNodeArray([decorator], decoratorStart);
+ }
+ else {
+ decorators.push(decorator);
+ }
}
if (decorators) {
decorators.end = getNodeEnd();
@@ -4953,7 +4956,7 @@ namespace ts {
if (token === SyntaxKind.ConstKeyword && permitInvalidConstAsModifier) {
// We need to ensure that any subsequent modifiers appear on the same line
- // so that when 'const' is a standalone declaration, we don't issue an error.
+ // so that when 'const' is a standalone declaration, we don't issue an error.
if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) {
break;
}
@@ -4964,13 +4967,14 @@ namespace ts {
}
}
- if (!modifiers) {
- modifiers = [];
- modifiers.pos = modifierStart;
- }
-
flags |= modifierToFlag(modifierKind);
- modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
+ const modifier = finishNode(createNode(modifierKind, modifierStart));
+ if (!modifiers) {
+ modifiers = createModifiersArray([modifier], modifierStart);
+ }
+ else {
+ modifiers.push(modifier);
+ }
}
if (modifiers) {
modifiers.flags = flags;
@@ -4980,17 +4984,14 @@ namespace ts {
}
function parseModifiersForArrowFunction(): ModifiersArray {
- let flags = 0;
let modifiers: ModifiersArray;
if (token === SyntaxKind.AsyncKeyword) {
const modifierStart = scanner.getStartPos();
const modifierKind = token;
nextToken();
- modifiers = [];
- modifiers.pos = modifierStart;
- flags |= modifierToFlag(modifierKind);
- modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
- modifiers.flags = flags;
+ const modifier = finishNode(createNode(modifierKind, modifierStart));
+ modifiers = createModifiersArray([modifier], modifierStart);
+ modifiers.flags = modifierToFlag(modifierKind);
modifiers.end = scanner.getStartPos();
}
@@ -5216,7 +5217,7 @@ namespace ts {
node.decorators = decorators;
setModifiers(node, modifiers);
if (token === SyntaxKind.GlobalKeyword) {
- // parse 'global' as name of global scope augmentation
+ // parse 'global' as name of global scope augmentation
node.name = parseIdentifier();
node.flags |= NodeFlags.GlobalAugmentation;
}
@@ -5848,10 +5849,8 @@ namespace ts {
function parseJSDocTypeList(firstType: JSDocType) {
Debug.assert(!!firstType);
- const types = >[];
- types.pos = firstType.pos;
+ const types = createNodeArray([firstType], firstType.pos);
- types.push(firstType);
while (parseOptional(SyntaxKind.BarToken)) {
types.push(parseJSDocType());
}
@@ -6059,11 +6058,11 @@ namespace ts {
function addTag(tag: JSDocTag): void {
if (tag) {
if (!tags) {
- tags = >[];
- tags.pos = tag.pos;
+ tags = createNodeArray([tag], tag.pos);
+ }
+ else {
+ tags.push(tag);
}
-
- tags.push(tag);
tags.end = tag.end;
}
}
@@ -6156,8 +6155,7 @@ namespace ts {
}
// Type parameter list looks like '@template T,U,V'
- const typeParameters = >[];
- typeParameters.pos = scanner.getStartPos();
+ const typeParameters = createNodeArray();
while (true) {
const name = parseJSDocIdentifier();
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index d2d436f545f..177934fc13b 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -454,12 +454,27 @@ namespace ts {
/* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
}
- export interface NodeArray extends Array, TextRange {
+ export const enum ArrayKind {
+ NodeArray = 1,
+ ModifiersArray = 2,
+ }
+
+ export interface NodeArray extends Array, TextRange {
+ arrayKind: ArrayKind;
hasTrailingComma?: boolean;
}
+ /**
+ * A NodeArrayNode is a transient node used during transformations to indicate that more than
+ * one node will substitute a single node in the source. When the source is a NodeArray (as
+ * part of a call to `visitNodes`), the nodes of a NodeArrayNode will be spread into the
+ * result array. When the source is a Node (as part of a call to `visitNode`), the NodeArrayNode
+ * must be converted into a compatible node via the `lift` callback.
+ */
+ /* @internal */
// @kind(SyntaxKind.NodeArrayNode)
- export interface NodeArrayNode extends Node, NodeArray> {
+ export interface NodeArrayNode extends Node {
+ nodes: NodeArray;
}
export interface ModifiersArray extends NodeArray {
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index 9fe32c89a69..a6df27bc3b9 100644
--- a/src/compiler/utilities.ts
+++ b/src/compiler/utilities.ts
@@ -1647,47 +1647,6 @@ namespace ts {
return isFunctionLike(n) || n.kind === SyntaxKind.ModuleDeclaration || n.kind === SyntaxKind.SourceFile;
}
- /**
- * Creates a shallow, memberwise clone of a node. The "kind", "pos", "end", "flags", and "parent"
- * properties are excluded by default, and can be provided via the "location", "flags", and
- * "parent" parameters.
- * @param node The node to clone.
- * @param location An optional TextRange to use to supply the new position.
- * @param flags The NodeFlags to use for the cloned node.
- * @param parent The parent for the new node.
- * @param original An optional pointer to the original node.
- */
- export function cloneNode(node: T, location?: TextRange, flags?: NodeFlags, parent?: Node, original?: Node): T {
- // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
- // the original node. We also need to exclude specific properties and only include own-
- // properties (to skip members already defined on the shared prototype).
- const clone = location !== undefined
- ? createNode(node.kind, location.pos, location.end)
- : createSynthesizedNode(node.kind);
-
- for (const key in node) {
- if (key === "parent" || key === "flags" || clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) {
- continue;
- }
-
- (clone)[key] = (node)[key];
- }
-
- if (flags !== undefined) {
- clone.flags = flags;
- }
-
- if (parent !== undefined) {
- clone.parent = parent;
- }
-
- if (original !== undefined) {
- clone.original = original;
- }
-
- return clone;
- }
-
/**
* Creates a deep clone of an EntityName, with new parent pointers.
* @param node The EntityName to clone.
@@ -1719,19 +1678,6 @@ namespace ts {
return !(pos >= 0);
}
- export function createSynthesizedNode(kind: SyntaxKind, startsOnNewLine?: boolean): Node {
- const node = createNode(kind, /* pos */ -1, /* end */ -1);
- node.startsOnNewLine = startsOnNewLine;
- return node;
- }
-
- export function createSynthesizedNodeArray(): NodeArray {
- const array = >[];
- array.pos = -1;
- array.end = -1;
- return array;
- }
-
export function getOriginalNode(node: Node): Node {
while (node.original !== undefined) {
node = node.original;
@@ -2728,12 +2674,12 @@ namespace ts {
return false;
}
- export function isModifiersArray(nodes: NodeArray): nodes is ModifiersArray {
- return !isNodeArrayNode(nodes) && typeof (nodes).flags === "number";
+ export function isModifiersArray(array: NodeArray): array is ModifiersArray {
+ return array.arrayKind === ArrayKind.ModifiersArray;
}
- export function isNodeArrayNode(value: Node | NodeArray>): value is NodeArrayNode {
- return (value).kind === SyntaxKind.NodeArrayNode;
+ export function isNodeArrayNode(node: Node): node is NodeArrayNode {
+ return node.kind === SyntaxKind.NodeArrayNode;
}
export function getLocalSymbolForExportDefault(symbol: Symbol) {
diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts
index 30717578eb8..a75e79565c5 100644
--- a/src/compiler/visitor.ts
+++ b/src/compiler/visitor.ts
@@ -1,5 +1,5 @@
///
-///
+
/* @internal */
namespace ts {
/** Additional context provided to `visitEachChild` */
@@ -15,9 +15,6 @@ namespace ts {
* Describes an edge of a Node, used when traversing a syntax tree.
*/
interface NodeEdge {
- /** Indicates that the edge is a NodeArray. */
- array?: boolean;
-
/** Indicates that the result is optional. */
optional?: boolean;
@@ -25,7 +22,7 @@ namespace ts {
test?: (node: Node) => node is Node;
/** A callback used to lift a NodeArrayNode into a valid node. */
- lift?: (nodes: NodeArrayNode) => Node;
+ lift?: (nodes: NodeArray) => Node;
};
/**
@@ -55,8 +52,8 @@ namespace ts {
expression: { test: isExpressionNode },
},
[SyntaxKind.Parameter]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
name: { test: isBindingPatternOrIdentifier },
type: { test: isTypeNodeNode, optional: true },
initializer: { test: isExpressionNode, optional: true },
@@ -65,52 +62,52 @@ namespace ts {
expression: { test: isLeftHandSideExpression },
},
[SyntaxKind.PropertyDeclaration]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
name: { test: isPropertyName },
type: { test: isTypeNodeNode, optional: true },
initializer: { test: isExpressionNode, optional: true },
},
[SyntaxKind.MethodDeclaration]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
name: { test: isPropertyName },
- typeParameters: { test: isTypeParameter, array: true },
- parameters: { test: isParameter, array: true },
+ typeParameters: { test: isTypeParameter },
+ parameters: { test: isParameter },
type: { test: isTypeNodeNode, optional: true },
body: { test: isBlock, optional: true },
},
[SyntaxKind.Constructor]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
- typeParameters: { test: isTypeParameter, array: true },
- parameters: { test: isParameter, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
+ typeParameters: { test: isTypeParameter },
+ parameters: { test: isParameter },
type: { test: isTypeNodeNode, optional: true },
body: { test: isBlock, optional: true },
},
[SyntaxKind.GetAccessor]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
name: { test: isPropertyName },
- typeParameters: { test: isTypeParameter, array: true },
- parameters: { test: isParameter, array: true },
+ typeParameters: { test: isTypeParameter },
+ parameters: { test: isParameter },
type: { test: isTypeNodeNode, optional: true },
body: { test: isBlock, optional: true },
},
[SyntaxKind.SetAccessor]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
name: { test: isPropertyName },
- typeParameters: { test: isTypeParameter, array: true },
- parameters: { test: isParameter, array: true },
+ typeParameters: { test: isTypeParameter },
+ parameters: { test: isParameter },
type: { test: isTypeNodeNode, optional: true },
body: { test: isBlock, optional: true },
},
[SyntaxKind.ObjectBindingPattern]: {
- elements: { test: isBindingElement, array: true },
+ elements: { test: isBindingElement },
},
[SyntaxKind.ArrayBindingPattern]: {
- elements: { test: isBindingElement, array: true },
+ elements: { test: isBindingElement },
},
[SyntaxKind.BindingElement]: {
propertyName: { test: isPropertyName, optional: true },
@@ -118,10 +115,10 @@ namespace ts {
initializer: { test: isExpressionNode, optional: true },
},
[SyntaxKind.ArrayLiteralExpression]: {
- elements: { test: isExpressionNode, array: true },
+ elements: { test: isExpressionNode },
},
[SyntaxKind.ObjectLiteralExpression]: {
- properties: { test: isObjectLiteralElement, array: true },
+ properties: { test: isObjectLiteralElement },
},
[SyntaxKind.PropertyAccessExpression]: {
expression: { test: isLeftHandSideExpression },
@@ -133,13 +130,13 @@ namespace ts {
},
[SyntaxKind.CallExpression]: {
expression: { test: isLeftHandSideExpression },
- typeArguments: { test: isTypeNodeNode, array: true },
- arguments: { test: isExpressionNode, array: true },
+ typeArguments: { test: isTypeNodeNode },
+ arguments: { test: isExpressionNode },
},
[SyntaxKind.NewExpression]: {
expression: { test: isLeftHandSideExpression },
- typeArguments: { test: isTypeNodeNode, array: true },
- arguments: { test: isExpressionNode, array: true },
+ typeArguments: { test: isTypeNodeNode },
+ arguments: { test: isExpressionNode },
},
[SyntaxKind.TaggedTemplateExpression]: {
tag: { test: isLeftHandSideExpression },
@@ -153,19 +150,19 @@ namespace ts {
expression: { test: isExpressionNode },
},
[SyntaxKind.FunctionExpression]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
name: { test: isIdentifierNode, optional: true },
- typeParameters: { test: isTypeParameter, array: true },
- parameters: { test: isParameter, array: true },
+ typeParameters: { test: isTypeParameter },
+ parameters: { test: isParameter },
type: { test: isTypeNodeNode, optional: true },
body: { test: isBlock, optional: true },
},
[SyntaxKind.ArrowFunction]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
- typeParameters: { test: isTypeParameter, array: true },
- parameters: { test: isParameter, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
+ typeParameters: { test: isTypeParameter },
+ parameters: { test: isParameter },
type: { test: isTypeNodeNode, optional: true },
body: { test: isConciseBody, lift: liftToBlock },
},
@@ -198,7 +195,7 @@ namespace ts {
},
[SyntaxKind.TemplateExpression]: {
head: { test: isTemplateLiteralFragment },
- templateSpans: { test: isTemplateSpan, array: true },
+ templateSpans: { test: isTemplateSpan },
},
[SyntaxKind.YieldExpression]: {
expression: { test: isExpressionNode, optional: true },
@@ -207,16 +204,16 @@ namespace ts {
expression: { test: isExpressionNode },
},
[SyntaxKind.ClassExpression]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
name: { test: isIdentifierNode, optional: true },
- typeParameters: { test: isTypeParameter, array: true },
- heritageClauses: { test: isHeritageClause, array: true },
- members: { test: isClassElement, array: true },
+ typeParameters: { test: isTypeParameter },
+ heritageClauses: { test: isHeritageClause },
+ members: { test: isClassElement },
},
[SyntaxKind.ExpressionWithTypeArguments]: {
expression: { test: isLeftHandSideExpression },
- typeArguments: { test: isTypeNodeNode, array: true },
+ typeArguments: { test: isTypeNodeNode },
},
[SyntaxKind.AsExpression]: {
expression: { test: isExpressionNode },
@@ -227,11 +224,11 @@ namespace ts {
literal: { test: isTemplateLiteralFragment },
},
[SyntaxKind.Block]: {
- statements: { test: isStatementNode, array: true },
+ statements: { test: isStatementNode },
},
[SyntaxKind.VariableStatement]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
declarationList: { test: isVariableDeclarationList },
},
[SyntaxKind.ExpressionStatement]: {
@@ -301,52 +298,52 @@ namespace ts {
initializer: { test: isExpressionNode, optional: true },
},
[SyntaxKind.VariableDeclarationList]: {
- declarations: { test: isVariableDeclaration, array: true },
+ declarations: { test: isVariableDeclaration },
},
[SyntaxKind.FunctionDeclaration]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
name: { test: isIdentifierNode, optional: true },
- typeParameters: { test: isTypeParameter, array: true },
- parameters: { test: isParameter, array: true },
+ typeParameters: { test: isTypeParameter },
+ parameters: { test: isParameter },
type: { test: isTypeNodeNode, optional: true },
body: { test: isBlock, optional: true },
},
[SyntaxKind.ClassDeclaration]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
name: { test: isIdentifierNode, optional: true },
- typeParameters: { test: isTypeParameter, array: true },
- heritageClauses: { test: isHeritageClause, array: true },
- members: { test: isClassElement, array: true },
+ typeParameters: { test: isTypeParameter },
+ heritageClauses: { test: isHeritageClause },
+ members: { test: isClassElement },
},
[SyntaxKind.EnumDeclaration]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
name: { test: isIdentifierNode },
- members: { test: isEnumMember, array: true },
+ members: { test: isEnumMember },
},
[SyntaxKind.ModuleDeclaration]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
name: { test: isModuleName },
body: { test: isModuleBody },
},
[SyntaxKind.ModuleBlock]: {
- statements: { test: isStatementNode, array: true },
+ statements: { test: isStatementNode },
},
[SyntaxKind.CaseBlock]: {
- clauses: { test: isCaseOrDefaultClause, array: true },
+ clauses: { test: isCaseOrDefaultClause },
},
[SyntaxKind.ImportEqualsDeclaration]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
name: { test: isIdentifierNode },
moduleReference: { test: isModuleReference },
},
[SyntaxKind.ImportDeclaration]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
importClause: { test: isImportClause, optional: true },
moduleSpecifier: { test: isExpressionNode },
},
@@ -358,25 +355,25 @@ namespace ts {
name: { test: isIdentifierNode },
},
[SyntaxKind.NamedImports]: {
- elements: { test: isImportSpecifier, array: true },
+ elements: { test: isImportSpecifier },
},
[SyntaxKind.ImportSpecifier]: {
propertyName: { test: isIdentifierNode, optional: true },
name: { test: isIdentifierNode },
},
[SyntaxKind.ExportAssignment]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
expression: { test: isExpressionNode },
},
[SyntaxKind.ExportDeclaration]: {
- decorators: { test: isDecorator, array: true },
- modifiers: { test: isModifier, array: true },
+ decorators: { test: isDecorator },
+ modifiers: { test: isModifier },
exportClause: { test: isNamedExports, optional: true },
moduleSpecifier: { test: isExpressionNode, optional: true },
},
[SyntaxKind.NamedExports]: {
- elements: { test: isExportSpecifier, array: true },
+ elements: { test: isExportSpecifier },
},
[SyntaxKind.ExportSpecifier]: {
propertyName: { test: isIdentifierNode, optional: true },
@@ -387,16 +384,16 @@ namespace ts {
},
[SyntaxKind.JsxElement]: {
openingElement: { test: isJsxOpeningElement },
- children: { test: isJsxChild, array: true },
+ children: { test: isJsxChild },
closingElement: { test: isJsxClosingElement },
},
[SyntaxKind.JsxSelfClosingElement]: {
tagName: { test: isEntityName },
- attributes: { test: isJsxAttributeOrJsxSpreadAttribute, array: true },
+ attributes: { test: isJsxAttributeOrJsxSpreadAttribute },
},
[SyntaxKind.JsxOpeningElement]: {
tagName: { test: isEntityName },
- attributes: { test: isJsxAttributeOrJsxSpreadAttribute, array: true },
+ attributes: { test: isJsxAttributeOrJsxSpreadAttribute },
},
[SyntaxKind.JsxClosingElement]: {
tagName: { test: isEntityName },
@@ -413,13 +410,13 @@ namespace ts {
},
[SyntaxKind.CaseClause]: {
expression: { test: isExpressionNode },
- statements: { test: isStatementNode, array: true },
+ statements: { test: isStatementNode },
},
[SyntaxKind.DefaultClause]: {
- statements: { test: isStatementNode, array: true },
+ statements: { test: isStatementNode },
},
[SyntaxKind.HeritageClause]: {
- types: { test: isExpressionWithTypeArguments, array: true },
+ types: { test: isExpressionWithTypeArguments },
},
[SyntaxKind.CatchClause]: {
variableDeclaration: { test: isVariableDeclaration },
@@ -438,7 +435,7 @@ namespace ts {
initializer: { test: isExpressionNode, optional: true },
},
[SyntaxKind.SourceFile]: {
- statements: { test: isStatementNode, array: true },
+ statements: { test: isStatementNode },
},
};
@@ -462,13 +459,9 @@ namespace ts {
for (const propertyName in edgeTraversalPath) {
const value = (