diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 12c83b71697b1..e86f79b360ab9 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -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 { diff --git a/tests/baselines/reference/mixedPropertyElementAccessAssignmentDeclaration.js b/tests/baselines/reference/mixedPropertyElementAccessAssignmentDeclaration.js new file mode 100644 index 0000000000000..ee5b3d9e89596 --- /dev/null +++ b/tests/baselines/reference/mixedPropertyElementAccessAssignmentDeclaration.js @@ -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] = {}; diff --git a/tests/baselines/reference/mixedPropertyElementAccessAssignmentDeclaration.symbols b/tests/baselines/reference/mixedPropertyElementAccessAssignmentDeclaration.symbols new file mode 100644 index 0000000000000..d414e979f178b --- /dev/null +++ b/tests/baselines/reference/mixedPropertyElementAccessAssignmentDeclaration.symbols @@ -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)) + diff --git a/tests/baselines/reference/mixedPropertyElementAccessAssignmentDeclaration.types b/tests/baselines/reference/mixedPropertyElementAccessAssignmentDeclaration.types new file mode 100644 index 0000000000000..18d20dfd936bf --- /dev/null +++ b/tests/baselines/reference/mixedPropertyElementAccessAssignmentDeclaration.types @@ -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 +>{} : {} + diff --git a/tests/cases/conformance/salsa/mixedPropertyElementAccessAssignmentDeclaration.ts b/tests/cases/conformance/salsa/mixedPropertyElementAccessAssignmentDeclaration.ts new file mode 100644 index 0000000000000..8dd13383df00c --- /dev/null +++ b/tests/cases/conformance/salsa/mixedPropertyElementAccessAssignmentDeclaration.ts @@ -0,0 +1,3 @@ +// Should not crash: #34642 +var arr = []; +arr[0].prop[2] = {};