Fix crash when checking invalid object rest (#31530)

This commit is contained in:
Ron Buckton
2019-05-22 11:20:57 -07:00
committed by GitHub
parent 3d2af9ff33
commit 6a559e37ee
6 changed files with 136 additions and 14 deletions

View File

@@ -23370,14 +23370,16 @@ namespace ts {
if (strictNullChecks && properties.length === 0) {
return checkNonNullType(sourceType, node);
}
for (const p of properties) {
checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties, rightIsThis);
for (let i = 0; i < properties.length; i++) {
checkObjectLiteralDestructuringPropertyAssignment(node, sourceType, i, properties, rightIsThis);
}
return sourceType;
}
/** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: NodeArray<ObjectLiteralElementLike>, rightIsThis = false) {
function checkObjectLiteralDestructuringPropertyAssignment(node: ObjectLiteralExpression, objectLiteralType: Type, propertyIndex: number, allProperties?: NodeArray<ObjectLiteralElementLike>, rightIsThis = false) {
const properties = node.properties;
const property = properties[propertyIndex];
if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) {
const name = property.name;
const exprType = getLiteralTypeFromPropertyName(name);
@@ -23394,18 +23396,25 @@ namespace ts {
return checkDestructuringAssignment(property.kind === SyntaxKind.ShorthandPropertyAssignment ? property : property.initializer, type);
}
else if (property.kind === SyntaxKind.SpreadAssignment) {
if (languageVersion < ScriptTarget.ESNext) {
checkExternalEmitHelpers(property, ExternalEmitHelpers.Rest);
if (propertyIndex < properties.length - 1) {
error(property, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
}
const nonRestNames: PropertyName[] = [];
if (allProperties) {
for (let i = 0; i < allProperties.length - 1; i++) {
nonRestNames.push(allProperties[i].name!);
else {
if (languageVersion < ScriptTarget.ESNext) {
checkExternalEmitHelpers(property, ExternalEmitHelpers.Rest);
}
const nonRestNames: PropertyName[] = [];
if (allProperties) {
for (const otherProperty of allProperties) {
if (!isSpreadAssignment(otherProperty)) {
nonRestNames.push(otherProperty.name);
}
}
}
const type = getRestType(objectLiteralType, nonRestNames, objectLiteralType.symbol);
checkGrammarForDisallowedTrailingComma(allProperties, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
return checkDestructuringAssignment(property.expression, type);
}
const type = getRestType(objectLiteralType, nonRestNames, objectLiteralType.symbol);
checkGrammarForDisallowedTrailingComma(allProperties, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
return checkDestructuringAssignment(property.expression, type);
}
else {
error(property, Diagnostics.Property_assignment_expected);
@@ -29964,8 +29973,10 @@ namespace ts {
// If this is from nested object binding pattern
// for ({ skills: { primary, secondary } } = multiRobot, i = 0; i < 1; i++) {
if (expr.parent.kind === SyntaxKind.PropertyAssignment) {
const typeOfParentObjectLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(<Expression>expr.parent.parent);
return checkObjectLiteralDestructuringPropertyAssignment(typeOfParentObjectLiteral || errorType, <ObjectLiteralElementLike>expr.parent)!; // TODO: GH#18217
const node = cast(expr.parent.parent, isObjectLiteralExpression);
const typeOfParentObjectLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(node);
const propertyIndex = indexOfNode(node.properties, expr.parent);
return checkObjectLiteralDestructuringPropertyAssignment(node, typeOfParentObjectLiteral || errorType, propertyIndex)!; // TODO: GH#18217
}
// Array literal assignment - array destructuring pattern
Debug.assert(expr.parent.kind === SyntaxKind.ArrayLiteralExpression);