Merged some changes from other branches.
This commit is contained in:
parent
387b30c296
commit
ad64877dee
6 changed files with 155 additions and 61 deletions
|
@ -130,11 +130,12 @@ namespace ts {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function countWhere<T>(array: T[], predicate: (x: T) => boolean): number {
|
export function countWhere<T>(array: T[], predicate: (x: T, i: number) => boolean): number {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
if (array) {
|
if (array) {
|
||||||
for (const v of array) {
|
for (let i = 0; i < array.length; i++) {
|
||||||
if (predicate(v)) {
|
const v = array[i];
|
||||||
|
if (predicate(v, i)) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,25 +143,49 @@ namespace ts {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function filter<T>(array: T[], f: (x: T) => boolean): T[] {
|
export function filter<T, U extends T>(array: T[], f: (x: T, i: number) => x is U): U[];
|
||||||
|
export function filter<T>(array: T[], f: (x: T, i: number) => boolean): T[];
|
||||||
|
export function filter<T>(array: T[], f: (x: T, i: number) => boolean): T[] {
|
||||||
let result: T[];
|
let result: T[];
|
||||||
if (array) {
|
if (array) {
|
||||||
result = [];
|
result = [];
|
||||||
for (const item of array) {
|
for (let i = 0; i < array.length; i++) {
|
||||||
if (f(item)) {
|
const v = array[i];
|
||||||
result.push(item);
|
if (f(v, i)) {
|
||||||
|
result.push(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function map<T, U>(array: T[], f: (x: T) => U): U[] {
|
export function map<T, U>(array: T[], f: (x: T, i: number) => U): U[] {
|
||||||
let result: U[];
|
let result: U[];
|
||||||
if (array) {
|
if (array) {
|
||||||
result = [];
|
result = [];
|
||||||
for (const v of array) {
|
for (let i = 0; i < array.length; i++) {
|
||||||
result.push(f(v));
|
const v = array[i];
|
||||||
|
result.push(f(v, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps an array. If the mapped value is an array, it is spread into the result.
|
||||||
|
*/
|
||||||
|
export function flatMap<T, U>(array: T[], f: (x: T, i: number) => U | U[]): U[] {
|
||||||
|
let result: U[];
|
||||||
|
if (array) {
|
||||||
|
result = [];
|
||||||
|
for (let i = 0; i < array.length; i++) {
|
||||||
|
const v = array[i];
|
||||||
|
const ar = f(v, i);
|
||||||
|
if (ar) {
|
||||||
|
// We cast to <U> here to leverage the behavior of Array#concat
|
||||||
|
// which will append a single value here.
|
||||||
|
result = result.concat(<U[]>ar);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -170,7 +195,7 @@ namespace ts {
|
||||||
if (!array2 || !array2.length) return array1;
|
if (!array2 || !array2.length) return array1;
|
||||||
if (!array1 || !array1.length) return array2;
|
if (!array1 || !array1.length) return array2;
|
||||||
|
|
||||||
return array1.concat(array2);
|
return [...array1, ...array2];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deduplicate<T>(array: T[]): T[] {
|
export function deduplicate<T>(array: T[]): T[] {
|
||||||
|
@ -186,6 +211,27 @@ namespace ts {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compacts an array, removing any falsey elements.
|
||||||
|
*/
|
||||||
|
export function compact<T>(array: T[]): T[] {
|
||||||
|
let result: T[];
|
||||||
|
if (array) {
|
||||||
|
for (let i = 0; i < array.length; i++) {
|
||||||
|
const v = array[i];
|
||||||
|
if (result || !v) {
|
||||||
|
if (!result) {
|
||||||
|
result = array.slice(0, i);
|
||||||
|
}
|
||||||
|
if (v) {
|
||||||
|
result.push(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result || array;
|
||||||
|
}
|
||||||
|
|
||||||
export function sum(array: any[], prop: string): number {
|
export function sum(array: any[], prop: string): number {
|
||||||
let result = 0;
|
let result = 0;
|
||||||
for (const v of array) {
|
for (const v of array) {
|
||||||
|
@ -212,15 +258,25 @@ namespace ts {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function firstOrUndefined<T>(array: T[]): T {
|
||||||
|
return array && array.length > 0
|
||||||
|
? array[0]
|
||||||
|
: undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function singleOrUndefined<T>(array: T[]): T {
|
||||||
|
return array && array.length === 1
|
||||||
|
? array[0]
|
||||||
|
: undefined;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the last element of an array if non-empty, undefined otherwise.
|
* Returns the last element of an array if non-empty, undefined otherwise.
|
||||||
*/
|
*/
|
||||||
export function lastOrUndefined<T>(array: T[]): T {
|
export function lastOrUndefined<T>(array: T[]): T {
|
||||||
if (array.length === 0) {
|
return array && array.length > 0
|
||||||
return undefined;
|
? array[array.length - 1]
|
||||||
}
|
: undefined;
|
||||||
|
|
||||||
return array[array.length - 1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -252,9 +308,9 @@ namespace ts {
|
||||||
return ~low;
|
return ~low;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function reduceLeft<T, U>(array: T[], f: (memo: U, value: T) => U, initial: U): U;
|
export function reduceLeft<T, U>(array: T[], f: (memo: U, value: T, i: number) => U, initial: U): U;
|
||||||
export function reduceLeft<T>(array: T[], f: (memo: T, value: T) => T): T;
|
export function reduceLeft<T>(array: T[], f: (memo: T, value: T, i: number) => T): T;
|
||||||
export function reduceLeft<T>(array: T[], f: (memo: T, value: T) => T, initial?: T): T {
|
export function reduceLeft<T>(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T): T {
|
||||||
if (array) {
|
if (array) {
|
||||||
const count = array.length;
|
const count = array.length;
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
|
@ -268,7 +324,7 @@ namespace ts {
|
||||||
result = initial;
|
result = initial;
|
||||||
}
|
}
|
||||||
while (pos < count) {
|
while (pos < count) {
|
||||||
result = f(result, array[pos]);
|
result = f(result, array[pos], pos);
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -277,9 +333,9 @@ namespace ts {
|
||||||
return initial;
|
return initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function reduceRight<T, U>(array: T[], f: (memo: U, value: T) => U, initial: U): U;
|
export function reduceRight<T, U>(array: T[], f: (memo: U, value: T, i: number) => U, initial: U): U;
|
||||||
export function reduceRight<T>(array: T[], f: (memo: T, value: T) => T): T;
|
export function reduceRight<T>(array: T[], f: (memo: T, value: T, i: number) => T): T;
|
||||||
export function reduceRight<T>(array: T[], f: (memo: T, value: T) => T, initial?: T): T {
|
export function reduceRight<T>(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T): T {
|
||||||
if (array) {
|
if (array) {
|
||||||
let pos = array.length - 1;
|
let pos = array.length - 1;
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
|
@ -292,7 +348,7 @@ namespace ts {
|
||||||
result = initial;
|
result = initial;
|
||||||
}
|
}
|
||||||
while (pos >= 0) {
|
while (pos >= 0) {
|
||||||
result = f(result, array[pos]);
|
result = f(result, array[pos], pos);
|
||||||
pos--;
|
pos--;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -2728,7 +2728,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||||
}
|
}
|
||||||
|
|
||||||
function synthesizedNodeStartsOnNewLine(node: Node) {
|
function synthesizedNodeStartsOnNewLine(node: Node) {
|
||||||
return nodeIsSynthesized(node) && (<SynthesizedNode>node).startsOnNewLine;
|
return nodeIsSynthesized(node) && node.startsOnNewLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitConditionalExpression(node: ConditionalExpression) {
|
function emitConditionalExpression(node: ConditionalExpression) {
|
||||||
|
|
|
@ -22,8 +22,8 @@ namespace ts {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createNodeArray<T extends Node>(elements?: T[], location?: TextRange): NodeArray<T> {
|
export function createNodeArray<T extends Node>(elements?: T[], location?: TextRange, hasTrailingComma?: boolean): NodeArray<T> {
|
||||||
if (elements !== undefined) {
|
if (elements) {
|
||||||
if (isNodeArray(elements)) {
|
if (isNodeArray(elements)) {
|
||||||
return elements;
|
return elements;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
const array = <NodeArray<T>>elements;
|
const array = <NodeArray<T>>elements;
|
||||||
if (location !== undefined) {
|
if (location) {
|
||||||
array.pos = location.pos;
|
array.pos = location.pos;
|
||||||
array.end = location.end;
|
array.end = location.end;
|
||||||
}
|
}
|
||||||
|
@ -42,13 +42,17 @@ namespace ts {
|
||||||
array.end = -1;
|
array.end = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasTrailingComma) {
|
||||||
|
array.hasTrailingComma = true;
|
||||||
|
}
|
||||||
|
|
||||||
array.arrayKind = ArrayKind.NodeArray;
|
array.arrayKind = ArrayKind.NodeArray;
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createModifiersArray(elements?: Modifier[], location?: TextRange): ModifiersArray {
|
export function createModifiersArray(elements?: Modifier[], location?: TextRange): ModifiersArray {
|
||||||
let flags: NodeFlags;
|
let flags: NodeFlags;
|
||||||
if (elements !== undefined) {
|
if (elements) {
|
||||||
if (isModifiersArray(elements)) {
|
if (isModifiersArray(elements)) {
|
||||||
return elements;
|
return elements;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +68,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
const array = <ModifiersArray>elements;
|
const array = <ModifiersArray>elements;
|
||||||
if (location !== undefined) {
|
if (location) {
|
||||||
array.pos = location.pos;
|
array.pos = location.pos;
|
||||||
array.end = location.end;
|
array.end = location.end;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +83,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setModifiers<T extends Node>(node: T, modifiers: Modifier[]) {
|
export function setModifiers<T extends Node>(node: T, modifiers: Modifier[]) {
|
||||||
if (modifiers !== undefined) {
|
if (modifiers) {
|
||||||
const array = createModifiersArray(modifiers);
|
const array = createModifiersArray(modifiers);
|
||||||
node.modifiers = array;
|
node.modifiers = array;
|
||||||
node.flags |= array.flags;
|
node.flags |= array.flags;
|
||||||
|
@ -92,7 +96,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSynthesizedNode(kind: SyntaxKind, startsOnNewLine?: boolean): Node {
|
export function createSynthesizedNode(kind: SyntaxKind, startsOnNewLine?: boolean): Node {
|
||||||
const node = <SynthesizedNode>createNode(kind, /*location*/ undefined);
|
const node = createNode(kind, /*location*/ undefined);
|
||||||
node.startsOnNewLine = startsOnNewLine;
|
node.startsOnNewLine = startsOnNewLine;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -145,6 +149,15 @@ namespace ts {
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a shallow, memberwise clone of a node for mutation.
|
||||||
|
*
|
||||||
|
* @param node The node to clone.
|
||||||
|
*/
|
||||||
|
export function getMutableNode<T extends Node>(node: T): T {
|
||||||
|
return cloneNode<T>(node, node, node.flags, node.parent, node);
|
||||||
|
}
|
||||||
|
|
||||||
export function createNodeArrayNode<T extends Node>(elements: T[]): NodeArrayNode<T> {
|
export function createNodeArrayNode<T extends Node>(elements: T[]): NodeArrayNode<T> {
|
||||||
const node = <NodeArrayNode<T>>createSynthesizedNode(SyntaxKind.NodeArrayNode);
|
const node = <NodeArrayNode<T>>createSynthesizedNode(SyntaxKind.NodeArrayNode);
|
||||||
node.nodes = createNodeArray(elements);
|
node.nodes = createNodeArray(elements);
|
||||||
|
|
|
@ -447,6 +447,7 @@ namespace ts {
|
||||||
/* @internal */ id?: number; // Unique id (used to look up NodeLinks)
|
/* @internal */ id?: number; // Unique id (used to look up NodeLinks)
|
||||||
parent?: Node; // Parent node (initialized by binding)
|
parent?: Node; // Parent node (initialized by binding)
|
||||||
/* @internal */ original?: Node; // The original node if this is an updated node.
|
/* @internal */ original?: Node; // The original node if this is an updated node.
|
||||||
|
/* @internal */ startsOnNewLine?: boolean; // Whether a synthesized node should start on a new line (used by transforms).
|
||||||
/* @internal */ jsDocComment?: JSDocComment; // JSDoc for the node, if it has any. Only for .js files.
|
/* @internal */ jsDocComment?: JSDocComment; // JSDoc for the node, if it has any. Only for .js files.
|
||||||
/* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding)
|
/* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding)
|
||||||
/* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding)
|
/* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding)
|
||||||
|
|
|
@ -8,12 +8,6 @@ namespace ts {
|
||||||
isNoDefaultLib?: boolean;
|
isNoDefaultLib?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SynthesizedNode extends Node {
|
|
||||||
leadingCommentRanges?: CommentRange[];
|
|
||||||
trailingCommentRanges?: CommentRange[];
|
|
||||||
startsOnNewLine: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getDeclarationOfKind(symbol: Symbol, kind: SyntaxKind): Declaration {
|
export function getDeclarationOfKind(symbol: Symbol, kind: SyntaxKind): Declaration {
|
||||||
const declarations = symbol.declarations;
|
const declarations = symbol.declarations;
|
||||||
if (declarations) {
|
if (declarations) {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
/* @internal */
|
/* @internal */
|
||||||
namespace ts {
|
namespace ts {
|
||||||
export type OneOrMore<T extends Node> = T | NodeArrayNode<T>;
|
export type OneOrMany<T extends Node> = T | NodeArrayNode<T>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes an edge of a Node, used when traversing a syntax tree.
|
* Describes an edge of a Node, used when traversing a syntax tree.
|
||||||
|
@ -528,21 +528,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 && <OneOrMore<T>>visitor(node);
|
const visited = node && <OneOrMany<T>>visitor(node);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
addNode(updated, visited, test);
|
addNodeWorker(updated, visited, /*addOnNewLine*/ undefined, test);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updated !== undefined) {
|
if (updated !== undefined) {
|
||||||
return <TArray>(isModifiersArray(nodes)
|
return <TArray>(isModifiersArray(nodes)
|
||||||
? createModifiersArray(updated, nodes)
|
? createModifiersArray(updated, nodes)
|
||||||
: createNodeArray(updated, nodes));
|
: createNodeArray(updated, nodes, nodes.hasTrailingComma));
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodes;
|
return nodes;
|
||||||
|
@ -571,21 +571,28 @@ namespace ts {
|
||||||
|
|
||||||
const edgeTraversalPath = nodeEdgeTraversalMap[node.kind];
|
const edgeTraversalPath = nodeEdgeTraversalMap[node.kind];
|
||||||
if (edgeTraversalPath) {
|
if (edgeTraversalPath) {
|
||||||
|
let modifiers: NodeFlags;
|
||||||
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);
|
const visited = visitEdge(edge, value, visitor);
|
||||||
|
if (visited && isArray(visited) && isModifiersArray(visited)) {
|
||||||
|
modifiers = visited.flags;
|
||||||
|
}
|
||||||
|
|
||||||
if (updated !== undefined || visited !== value) {
|
if (updated !== undefined || visited !== value) {
|
||||||
if (updated === undefined) {
|
if (updated === undefined) {
|
||||||
updated = cloneNode(node, /*location*/ node, node.flags & ~NodeFlags.Modifier, /*parent*/ undefined, /*original*/ node);
|
updated = getMutableNode(node);
|
||||||
|
updated.flags &= ~NodeFlags.Modifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (visited && isArray(visited) && isModifiersArray(visited)) {
|
if (modifiers) {
|
||||||
updated[edge.name] = visited;
|
updated.flags |= modifiers;
|
||||||
updated.flags |= visited.flags;
|
modifiers = undefined;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
updated[edge.name] = visited;
|
if (visited !== value) {
|
||||||
|
setEdgeValue(updated, edge, visited);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -603,9 +610,20 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (updated !== node) {
|
||||||
|
updated.original = node;
|
||||||
|
}
|
||||||
|
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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>) {
|
||||||
|
parentNode[edge.name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visits a node edge.
|
* Visits a node edge.
|
||||||
*
|
*
|
||||||
|
@ -626,16 +644,8 @@ namespace ts {
|
||||||
* @param from The source Node or NodeArrayNode.
|
* @param from The source Node or NodeArrayNode.
|
||||||
* @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: OneOrMore<T>, test?: (node: Node) => boolean) {
|
export function addNode<T extends Node>(to: T[], from: OneOrMany<T>, startOnNewLine?: boolean) {
|
||||||
if (to !== undefined && from !== undefined) {
|
addNodeWorker(to, from, startOnNewLine, /*test*/ undefined);
|
||||||
if (isNodeArrayNode(from)) {
|
|
||||||
addNodes(to, from.nodes, test);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Debug.assert(test === undefined || test(from), "Wrong node type after visit.");
|
|
||||||
to.push(from);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -645,10 +655,30 @@ namespace ts {
|
||||||
* @param from The source array of Node or NodeArrayNode.
|
* @param from The source array of Node or NodeArrayNode.
|
||||||
* @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: OneOrMore<T>[], test?: (node: Node) => boolean) {
|
export function addNodes<T extends Node>(to: T[], from: OneOrMany<T>[], startOnNewLine?: boolean) {
|
||||||
if (to !== undefined && from !== undefined) {
|
addNodesWorker(to, from, startOnNewLine, /*test*/ undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addNodeWorker<T extends Node>(to: T[], from: OneOrMany<T>, startOnNewLine: boolean, test: (node: Node) => boolean) {
|
||||||
|
if (to && from) {
|
||||||
|
if (isNodeArrayNode(from)) {
|
||||||
|
addNodesWorker(to, from.nodes, startOnNewLine, test);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Debug.assert(test === undefined || test(from), "Wrong node type after visit.");
|
||||||
|
if (startOnNewLine) {
|
||||||
|
from.startsOnNewLine = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
to.push(from);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addNodesWorker<T extends Node>(to: T[], from: OneOrMany<T>[], startOnNewLine: boolean, test: (node: Node) => boolean) {
|
||||||
|
if (to && from) {
|
||||||
for (const node of from) {
|
for (const node of from) {
|
||||||
addNode(to, node, test);
|
addNodeWorker(to, node, startOnNewLine, test);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue