Fix unnecessary parens for omitted expressions and trailing commas in spread arrays

This commit is contained in:
Ron Buckton
2016-03-22 16:15:26 -07:00
parent 1b24d470bb
commit 1ecbc51873
3 changed files with 28 additions and 7 deletions

View File

@@ -244,7 +244,7 @@ namespace ts {
* @param keyfn A callback used to select the key for an element.
* @param mapfn A callback used to map a contiguous chunk of values to a single value.
*/
export function spanMap<T, K, U>(array: T[], keyfn: (x: T, i: number) => K, mapfn: (chunk: T[], key: K) => U): U[] {
export function spanMap<T, K, U>(array: T[], keyfn: (x: T, i: number) => K, mapfn: (chunk: T[], key: K, start: number, end: number) => U): U[] {
let result: U[];
if (array) {
result = [];
@@ -268,7 +268,7 @@ namespace ts {
}
if (start < pos) {
const v = mapfn(array.slice(start, pos), previousKey);
const v = mapfn(array.slice(start, pos), previousKey, start, pos);
if (v) {
result.push(v);
}

View File

@@ -1436,7 +1436,7 @@ namespace ts {
*/
function visitArrayLiteralExpression(node: ArrayLiteralExpression): Expression {
// We are here because we contain a SpreadElementExpression.
return transformAndSpreadElements(node.elements, /*needsUniqueCopy*/ true, node.multiLine);
return transformAndSpreadElements(node.elements, /*needsUniqueCopy*/ true, node.multiLine, /*hasTrailingComma*/ node.elements.hasTrailingComma);
}
/**
@@ -1523,7 +1523,7 @@ namespace ts {
* @param needsUniqueCopy A value indicating whether to ensure that the result is a fresh array.
* @param multiLine A value indicating whether the result should be emitted on multiple lines.
*/
function transformAndSpreadElements(elements: NodeArray<Expression>, needsUniqueCopy: boolean, multiLine: boolean): Expression {
function transformAndSpreadElements(elements: NodeArray<Expression>, needsUniqueCopy: boolean, multiLine: boolean, hasTrailingComma?: boolean): Expression {
// [source]
// [a, ...b, c]
//
@@ -1532,10 +1532,12 @@ namespace ts {
// Map spans of spread expressions into their expressions and spans of other
// expressions into an array literal.
const numElements = elements.length;
const segments = flatten(
spanMap(elements, isSpreadElementExpression, (chunk: Expression[], isSpread: boolean) => isSpread
? map(chunk, visitExpressionOfSpreadElement)
: createArrayLiteral(visitNodes(createNodeArray(chunk), visitor, isExpression), /*location*/ undefined, multiLine)));
spanMap(elements, partitionSpreadElement, (partition, visitPartition, start, end) =>
visitPartition(partition, multiLine, hasTrailingComma && end === numElements)
)
);
if (segments.length === 1) {
return needsUniqueCopy && isSpreadElementExpression(elements[0])
@@ -1547,6 +1549,24 @@ namespace ts {
return createArrayConcat(segments.shift(), segments);
}
function partitionSpreadElement(node: Expression) {
return isSpreadElementExpression(node)
? visitSpanOfSpreadElements
: visitSpanOfNonSpreadElements;
}
function visitSpanOfSpreadElements(chunk: Expression[], multiLine: boolean, hasTrailingComma: boolean): VisitResult<Expression> {
return map(chunk, visitExpressionOfSpreadElement);
}
function visitSpanOfNonSpreadElements(chunk: Expression[], multiLine: boolean, hasTrailingComma: boolean): VisitResult<Expression> {
return createArrayLiteral(
visitNodes(createNodeArray(chunk, /*location*/ undefined, hasTrailingComma), visitor, isExpression),
/*location*/ undefined,
multiLine
);
}
/**
* Transforms the expression of a SpreadElementExpression node.
*

View File

@@ -1825,6 +1825,7 @@ namespace ts {
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.TemplateExpression:
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.OmittedExpression:
return 19;
case SyntaxKind.TaggedTemplateExpression: