Rest element support in array literal destructuring assignment

This commit is contained in:
Anders Hejlsberg 2014-12-11 17:41:24 -08:00
parent afa3111955
commit 6babef417f
4 changed files with 49 additions and 18 deletions

View File

@ -6689,15 +6689,25 @@ module ts {
for (var i = 0; i < elements.length; i++) {
var e = elements[i];
if (e.kind !== SyntaxKind.OmittedExpression) {
var propName = "" + i;
var type = sourceType.flags & TypeFlags.Any ? sourceType :
isTupleLikeType(sourceType) ? getTypeOfPropertyOfType(sourceType, propName) :
getIndexTypeOfType(sourceType, IndexKind.Number);
if (type) {
checkDestructuringAssignment(e, type, contextualMapper);
if (e.kind !== SyntaxKind.SpreadElementExpression) {
var propName = "" + i;
var type = sourceType.flags & TypeFlags.Any ? sourceType :
isTupleLikeType(sourceType) ? getTypeOfPropertyOfType(sourceType, propName) :
getIndexTypeOfType(sourceType, IndexKind.Number);
if (type) {
checkDestructuringAssignment(e, type, contextualMapper);
}
else {
error(e, Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName);
}
}
else {
error(e, Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName);
if (i === elements.length - 1) {
checkReferenceAssignment((<SpreadElementExpression>e).expression, sourceType, contextualMapper);
}
else {
error(e, Diagnostics.A_rest_element_must_be_last_in_an_array_destructuring_pattern);
}
}
}
}
@ -6715,6 +6725,10 @@ module ts {
if (target.kind === SyntaxKind.ArrayLiteralExpression) {
return checkArrayLiteralAssignment(<ArrayLiteralExpression>target, sourceType, contextualMapper);
}
return checkReferenceAssignment(target, sourceType, contextualMapper);
}
function checkReferenceAssignment(target: Expression, sourceType: Type, contextualMapper?: TypeMapper): Type {
var targetType = checkExpression(target, contextualMapper);
if (checkReferenceExpression(target, Diagnostics.Invalid_left_hand_side_of_assignment_expression, Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant)) {
checkTypeAssignableTo(sourceType, targetType, target, /*headMessage*/ undefined);

View File

@ -294,6 +294,7 @@ module ts {
Type_0_has_no_property_1_and_no_string_index_signature: { code: 2459, category: DiagnosticCategory.Error, key: "Type '{0}' has no property '{1}' and no string index signature." },
Type_0_has_no_property_1: { code: 2460, category: DiagnosticCategory.Error, key: "Type '{0}' has no property '{1}'." },
Type_0_is_not_an_array_type: { code: 2461, category: DiagnosticCategory.Error, key: "Type '{0}' is not an array type." },
A_rest_element_must_be_last_in_an_array_destructuring_pattern: { code: 2462, category: DiagnosticCategory.Error, key: "A rest element must be last in an array destructuring pattern" },
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },

View File

@ -1173,6 +1173,10 @@
"category": "Error",
"code": 2461
},
"A rest element must be last in an array destructuring pattern": {
"category": "Error",
"code": 2462
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",

View File

@ -2947,7 +2947,16 @@ module ts {
for (var i = 0; i < elements.length; i++) {
var e = elements[i];
if (e.kind !== SyntaxKind.OmittedExpression) {
emitDestructuringAssignment(e, createElementAccess(value, createNumericLiteral(i)));
if (e.kind !== SyntaxKind.SpreadElementExpression) {
emitDestructuringAssignment(e, createElementAccess(value, createNumericLiteral(i)));
}
else {
if (i === elements.length - 1) {
value = ensureIdentifier(value);
emitAssignment(<Identifier>(<SpreadElementExpression>e).expression, value);
write(".slice(" + i + ")");
}
}
}
}
}
@ -3772,17 +3781,18 @@ module ts {
increaseIndent();
emitCaptureThisForNodeIfNecessary(node);
emitLinesStartingAt(node.statements, startIndex);
emitTempDeclarations(/*newLine*/ true);
var exportName = resolver.getExportAssignmentName(node);
if (exportName) {
writeLine();
var exportAssignement = getFirstExportAssignment(node);
emitStart(exportAssignement);
var exportAssignment = getFirstExportAssignment(node);
emitStart(exportAssignment);
write("return ");
emitStart(exportAssignement.exportName);
emitStart(exportAssignment.exportName);
write(exportName);
emitEnd(exportAssignement.exportName);
emitEnd(exportAssignment.exportName);
write(";");
emitEnd(exportAssignement);
emitEnd(exportAssignment);
}
decreaseIndent();
writeLine();
@ -3792,17 +3802,18 @@ module ts {
function emitCommonJSModule(node: SourceFile, startIndex: number) {
emitCaptureThisForNodeIfNecessary(node);
emitLinesStartingAt(node.statements, startIndex);
emitTempDeclarations(/*newLine*/ true);
var exportName = resolver.getExportAssignmentName(node);
if (exportName) {
writeLine();
var exportAssignement = getFirstExportAssignment(node);
emitStart(exportAssignement);
var exportAssignment = getFirstExportAssignment(node);
emitStart(exportAssignment);
write("module.exports = ");
emitStart(exportAssignement.exportName);
emitStart(exportAssignment.exportName);
write(exportName);
emitEnd(exportAssignement.exportName);
emitEnd(exportAssignment.exportName);
write(";");
emitEnd(exportAssignement);
emitEnd(exportAssignment);
}
}
@ -3858,6 +3869,7 @@ module ts {
else {
emitCaptureThisForNodeIfNecessary(node);
emitLinesStartingAt(node.statements, startIndex);
emitTempDeclarations(/*newLine*/ true);
}
emitLeadingComments(node.endOfFileToken);