Clean up naming, add documentation, flatten (some) nested commas

This commit is contained in:
Ron Buckton
2017-05-12 09:57:39 -07:00
parent f45f7579fc
commit 22cf036ed9
7 changed files with 65 additions and 19 deletions
+29
View File
@@ -490,6 +490,35 @@ namespace ts {
return result;
}
/**
* Maps an array. If the mapped value is an array, it is spread into the result.
* Avoids allocation if all elements map to themselves.
*
* @param array The array to map.
* @param mapfn The callback used to map the result into one or more values.
*/
export function sameFlatMap<T>(array: T[], mapfn: (x: T, i: number) => T | T[]): T[] {
let result: T[];
if (array) {
for (let i = 0; i < array.length; i++) {
const item = array[i];
const mapped = mapfn(item, i);
if (result || item !== mapped || isArray(mapped)) {
if (!result) {
result = array.slice(0, i);
}
if (isArray(mapped)) {
addRange(result, mapped);
}
else {
result.push(mapped);
}
}
}
}
return result || array;
}
/**
* Computes the first matching span of elements and returns a tuple of the first span
* and the remaining elements.
+3 -3
View File
@@ -734,8 +734,8 @@ namespace ts {
case SyntaxKind.PartiallyEmittedExpression:
return emitPartiallyEmittedExpression(<PartiallyEmittedExpression>node);
case SyntaxKind.CommaList:
return emitCommaList(<CommaList>node);
case SyntaxKind.CommaListExpression:
return emitCommaList(<CommaListExpression>node);
}
}
@@ -2104,7 +2104,7 @@ namespace ts {
emitExpression(node.expression);
}
function emitCommaList(node: CommaList) {
function emitCommaList(node: CommaListExpression) {
emitExpressionList(node, node.elements, ListFormat.CommaListElements);
}
+18 -4
View File
@@ -2077,13 +2077,25 @@ namespace ts {
return node;
}
export function createCommaList(elements: Expression[]) {
const node = <CommaList>createSynthesizedNode(SyntaxKind.CommaList);
node.elements = createNodeArray(elements);
function flattenCommaElements(node: Expression): Expression | Expression[] {
if (nodeIsSynthesized(node) && !isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) {
if (node.kind === SyntaxKind.CommaListExpression) {
return (<CommaListExpression>node).elements;
}
if (isBinaryExpression(node) && node.operatorToken.kind === SyntaxKind.CommaToken) {
return [node.left, node.right];
}
}
return node;
}
export function updateCommaList(node: CommaList, elements: Expression[]) {
export function createCommaList(elements: Expression[]) {
const node = <CommaListExpression>createSynthesizedNode(SyntaxKind.CommaListExpression);
node.elements = createNodeArray(sameFlatMap(elements, flattenCommaElements));
return node;
}
export function updateCommaList(node: CommaListExpression, elements: Expression[]) {
return node.elements !== elements
? updateNode(createCommaList(elements), node)
: node;
@@ -2877,6 +2889,8 @@ namespace ts {
}
export function inlineExpressions(expressions: Expression[]) {
// Avoid deeply nested comma expressions as traversing them during emit can result in "Maximum call
// stack size exceeded" errors.
return expressions.length > 10
? createCommaList(expressions)
: reduceLeft(expressions, createComma);
+2 -2
View File
@@ -362,8 +362,8 @@ namespace ts {
return visitNode(cbNode, (<ExternalModuleReference>node).expression);
case SyntaxKind.MissingDeclaration:
return visitNodes(cbNodes, node.decorators);
case SyntaxKind.CommaList:
return visitNodes(cbNodes, (<CommaList>node).elements);
case SyntaxKind.CommaListExpression:
return visitNodes(cbNodes, (<CommaListExpression>node).elements);
case SyntaxKind.JsxElement:
return visitNode(cbNode, (<JsxElement>node).openingElement) ||
+6 -3
View File
@@ -389,9 +389,9 @@ namespace ts {
// Transformation nodes
NotEmittedStatement,
PartiallyEmittedExpression,
CommaListExpression,
MergeDeclarationMarker,
EndOfDeclarationMarker,
CommaList,
// Enum value count
Count,
@@ -1604,8 +1604,11 @@ namespace ts {
kind: SyntaxKind.EndOfDeclarationMarker;
}
export interface CommaList extends Expression {
kind: SyntaxKind.CommaList;
/**
* A list of comma-seperated expressions. This node is only created by transformations.
*/
export interface CommaListExpression extends Expression {
kind: SyntaxKind.CommaListExpression;
elements: NodeArray<Expression>;
}
+2 -2
View File
@@ -2327,7 +2327,7 @@ namespace ts {
case SyntaxKind.SpreadElement:
return 1;
case SyntaxKind.CommaList:
case SyntaxKind.CommaListExpression:
return 0;
default:
@@ -3918,7 +3918,7 @@ namespace ts {
|| kind === SyntaxKind.SpreadElement
|| kind === SyntaxKind.AsExpression
|| kind === SyntaxKind.OmittedExpression
|| kind === SyntaxKind.CommaList
|| kind === SyntaxKind.CommaListExpression
|| isUnaryExpressionKind(kind);
}
+5 -5
View File
@@ -876,9 +876,9 @@ namespace ts {
return updatePartiallyEmittedExpression(<PartiallyEmittedExpression>node,
visitNode((<PartiallyEmittedExpression>node).expression, visitor, isExpression));
case SyntaxKind.CommaList:
return updateCommaList(<CommaList>node,
nodesVisitor((<CommaList>node).elements, visitor, isExpression));
case SyntaxKind.CommaListExpression:
return updateCommaList(<CommaListExpression>node,
nodesVisitor((<CommaListExpression>node).elements, visitor, isExpression));
default:
// No need to visit nodes with no children.
@@ -1393,8 +1393,8 @@ namespace ts {
result = reduceNode((<PartiallyEmittedExpression>node).expression, cbNode, result);
break;
case SyntaxKind.CommaList:
result = reduceNodes((<CommaList>node).elements, cbNodes, result);
case SyntaxKind.CommaListExpression:
result = reduceNodes((<CommaListExpression>node).elements, cbNodes, result);
break;
default: