Cherry-pick PR #34649 into release-3.7 (#34657)

Component commits:
b6744812a0 Treat any mix of element/prop access as declaration in JS
Fixes #34642 but, notably, doesn't actually make the assignment into a
working declaration. It just fixes the crash.
This commit is contained in:
Nathan Shively-Sanders 2019-10-22 15:22:40 -07:00 committed by GitHub
commit f21e9312e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 8 deletions

View File

@ -2061,26 +2061,30 @@ namespace ts {
isBindableStaticNameExpression(expr.arguments[0], /*excludeThisKeyword*/ true);
}
export function isBindableStaticElementAccessExpression(node: Node, excludeThisKeyword?: boolean): node is BindableStaticElementAccessExpression {
return isLiteralLikeElementAccess(node)
&& ((!excludeThisKeyword && node.expression.kind === SyntaxKind.ThisKeyword) ||
isEntityNameExpression(node.expression) ||
isBindableStaticElementAccessExpression(node.expression, /*excludeThisKeyword*/ true));
}
/** x.y OR x[0] */
export function isLiteralLikeAccess(node: Node): node is LiteralLikeElementAccessExpression | PropertyAccessExpression {
return isPropertyAccessExpression(node) || isLiteralLikeElementAccess(node);
}
/** x[0] OR x['a'] OR x[Symbol.y] */
export function isLiteralLikeElementAccess(node: Node): node is LiteralLikeElementAccessExpression {
return isElementAccessExpression(node) && (
isStringOrNumericLiteralLike(node.argumentExpression) ||
isWellKnownSymbolSyntactically(node.argumentExpression));
}
/** Any series of property and element accesses. */
export function isBindableStaticAccessExpression(node: Node, excludeThisKeyword?: boolean): node is BindableStaticAccessExpression {
return isPropertyAccessExpression(node) && (!excludeThisKeyword && node.expression.kind === SyntaxKind.ThisKeyword || isBindableStaticNameExpression(node.expression, /*excludeThisKeyword*/ true))
|| isBindableStaticElementAccessExpression(node, excludeThisKeyword);
|| isBindableStaticElementAccessExpression(node, excludeThisKeyword);
}
/** Any series of property and element accesses, ending in a literal element access */
export function isBindableStaticElementAccessExpression(node: Node, excludeThisKeyword?: boolean): node is BindableStaticElementAccessExpression {
return isLiteralLikeElementAccess(node)
&& ((!excludeThisKeyword && node.expression.kind === SyntaxKind.ThisKeyword) ||
isEntityNameExpression(node.expression) ||
isBindableStaticAccessExpression(node.expression, /*excludeThisKeyword*/ true));
}
export function isBindableStaticNameExpression(node: Node, excludeThisKeyword?: boolean): node is BindableStaticNameExpression {

View File

@ -0,0 +1,10 @@
//// [mixedPropertyElementAccessAssignmentDeclaration.ts]
// Should not crash: #34642
var arr = [];
arr[0].prop[2] = {};
//// [mixedPropertyElementAccessAssignmentDeclaration.js]
// Should not crash: #34642
var arr = [];
arr[0].prop[2] = {};

View File

@ -0,0 +1,8 @@
=== tests/cases/conformance/salsa/mixedPropertyElementAccessAssignmentDeclaration.ts ===
// Should not crash: #34642
var arr = [];
>arr : Symbol(arr, Decl(mixedPropertyElementAccessAssignmentDeclaration.ts, 1, 3))
arr[0].prop[2] = {};
>arr : Symbol(arr, Decl(mixedPropertyElementAccessAssignmentDeclaration.ts, 1, 3))

View File

@ -0,0 +1,17 @@
=== tests/cases/conformance/salsa/mixedPropertyElementAccessAssignmentDeclaration.ts ===
// Should not crash: #34642
var arr = [];
>arr : any[]
>[] : undefined[]
arr[0].prop[2] = {};
>arr[0].prop[2] = {} : {}
>arr[0].prop[2] : any
>arr[0].prop : any
>arr[0] : any
>arr : any[]
>0 : 0
>prop : any
>2 : 2
>{} : {}

View File

@ -0,0 +1,3 @@
// Should not crash: #34642
var arr = [];
arr[0].prop[2] = {};