diff --git a/internal/ast/utilities.go b/internal/ast/utilities.go index 5c5fd2314d..8c6f65c04b 100644 --- a/internal/ast/utilities.go +++ b/internal/ast/utilities.go @@ -1507,7 +1507,7 @@ func GetAssignmentDeclarationKind(bin *BinaryExpression) JSDeclarationKind { if IsInJSFile(bin.Left) && bin.Left.Expression().Kind == KindThisKeyword { return JSDeclarationKindThisProperty } - if bin.Left.Kind == KindPropertyAccessExpression && IsEntityNameExpressionEx(bin.Left.Expression(), IsInJSFile(bin.Left)) && IsIdentifier(bin.Left.Name()) || + if bin.Left.Kind == KindPropertyAccessExpression && IsEntityNameExpressionEx(bin.Left.Expression(), IsInJSFile(bin.Left)) && bin.Left.Name() != nil && IsIdentifier(bin.Left.Name()) || bin.Left.Kind == KindElementAccessExpression && IsEntityNameExpressionEx(bin.Left.Expression(), IsInJSFile(bin.Left)) { return JSDeclarationKindProperty } diff --git a/testdata/baselines/reference/compiler/crash-on-neo-async.js b/testdata/baselines/reference/compiler/crash-on-neo-async.js new file mode 100644 index 0000000000..55bd99f57f --- /dev/null +++ b/testdata/baselines/reference/compiler/crash-on-neo-async.js @@ -0,0 +1,46 @@ +//// [tests/cases/compiler/crash-on-neo-async.ts] //// + +//// [crash-on-neo-async.js] +// This test reproduces a crash that occurs when parsing files like webpack/node_modules/neo-async/async.js +// The crash happens in GetAssignmentDeclarationKind when checking IsIdentifier(bin.Left.Name()) +// where bin.Left.Name() returns nil for ElementAccessExpression +// Pattern that causes the crash - element access assignment +var obj = {}; +var prop = 'test'; +// This assignment with element access should not crash +// It previously crashed because ElementAccessExpression.Name() returns nil +// and IsIdentifier was called on that nil value +obj[prop] = function () { + return 42; +}; +// Property access assignment should work fine (has a valid Name()) +obj.prop2 = function () { + return 43; +}; +// Nested element access assignment +obj['nested'][prop] = function () { + return 44; +}; + + +//// [crash-on-neo-async.js] +// This test reproduces a crash that occurs when parsing files like webpack/node_modules/neo-async/async.js +// The crash happens in GetAssignmentDeclarationKind when checking IsIdentifier(bin.Left.Name()) +// where bin.Left.Name() returns nil for ElementAccessExpression +// Pattern that causes the crash - element access assignment +var obj = {}; +var prop = 'test'; +// This assignment with element access should not crash +// It previously crashed because ElementAccessExpression.Name() returns nil +// and IsIdentifier was called on that nil value +obj[prop] = function () { + return 42; +}; +// Property access assignment should work fine (has a valid Name()) +obj.prop2 = function () { + return 43; +}; +// Nested element access assignment +obj['nested'][prop] = function () { + return 44; +}; diff --git a/testdata/baselines/reference/compiler/crash-on-neo-async.symbols b/testdata/baselines/reference/compiler/crash-on-neo-async.symbols new file mode 100644 index 0000000000..de159102ef --- /dev/null +++ b/testdata/baselines/reference/compiler/crash-on-neo-async.symbols @@ -0,0 +1,38 @@ +//// [tests/cases/compiler/crash-on-neo-async.ts] //// + +=== crash-on-neo-async.js === +// This test reproduces a crash that occurs when parsing files like webpack/node_modules/neo-async/async.js +// The crash happens in GetAssignmentDeclarationKind when checking IsIdentifier(bin.Left.Name()) +// where bin.Left.Name() returns nil for ElementAccessExpression +// Pattern that causes the crash - element access assignment +var obj = {}; +>obj : Symbol(obj, Decl(crash-on-neo-async.js, 4, 3)) + +var prop = 'test'; +>prop : Symbol(prop, Decl(crash-on-neo-async.js, 5, 3)) + +// This assignment with element access should not crash +// It previously crashed because ElementAccessExpression.Name() returns nil +// and IsIdentifier was called on that nil value +obj[prop] = function () { +>obj : Symbol(obj, Decl(crash-on-neo-async.js, 4, 3)) +>prop : Symbol(prop, Decl(crash-on-neo-async.js, 5, 3)) + + return 42; +}; +// Property access assignment should work fine (has a valid Name()) +obj.prop2 = function () { +>obj.prop2 : Symbol(prop2, Decl(crash-on-neo-async.js, 11, 2)) +>obj : Symbol(obj, Decl(crash-on-neo-async.js, 4, 3)) +>prop2 : Symbol(prop2, Decl(crash-on-neo-async.js, 11, 2)) + + return 43; +}; +// Nested element access assignment +obj['nested'][prop] = function () { +>obj : Symbol(obj, Decl(crash-on-neo-async.js, 4, 3)) +>prop : Symbol(prop, Decl(crash-on-neo-async.js, 5, 3)) + + return 44; +}; + diff --git a/testdata/baselines/reference/compiler/crash-on-neo-async.types b/testdata/baselines/reference/compiler/crash-on-neo-async.types new file mode 100644 index 0000000000..6def691b25 --- /dev/null +++ b/testdata/baselines/reference/compiler/crash-on-neo-async.types @@ -0,0 +1,56 @@ +//// [tests/cases/compiler/crash-on-neo-async.ts] //// + +=== crash-on-neo-async.js === +// This test reproduces a crash that occurs when parsing files like webpack/node_modules/neo-async/async.js +// The crash happens in GetAssignmentDeclarationKind when checking IsIdentifier(bin.Left.Name()) +// where bin.Left.Name() returns nil for ElementAccessExpression +// Pattern that causes the crash - element access assignment +var obj = {}; +>obj : { prop2: () => number; } +>{} : { prop2: () => number; } + +var prop = 'test'; +>prop : string +>'test' : "test" + +// This assignment with element access should not crash +// It previously crashed because ElementAccessExpression.Name() returns nil +// and IsIdentifier was called on that nil value +obj[prop] = function () { +>obj[prop] = function () { return 42;} : () => number +>obj[prop] : any +>obj : { prop2: () => number; } +>prop : string +>function () { return 42;} : () => number + + return 42; +>42 : 42 + +}; +// Property access assignment should work fine (has a valid Name()) +obj.prop2 = function () { +>obj.prop2 = function () { return 43;} : () => number +>obj.prop2 : () => number +>obj : { prop2: () => number; } +>prop2 : () => number +>function () { return 43;} : () => number + + return 43; +>43 : 43 + +}; +// Nested element access assignment +obj['nested'][prop] = function () { +>obj['nested'][prop] = function () { return 44;} : () => number +>obj['nested'][prop] : any +>obj['nested'] : any +>obj : { prop2: () => number; } +>'nested' : "nested" +>prop : string +>function () { return 44;} : () => number + + return 44; +>44 : 44 + +}; + diff --git a/testdata/tests/cases/compiler/crash-on-neo-async.ts b/testdata/tests/cases/compiler/crash-on-neo-async.ts new file mode 100644 index 0000000000..9e30af1aa9 --- /dev/null +++ b/testdata/tests/cases/compiler/crash-on-neo-async.ts @@ -0,0 +1,22 @@ +// @checkJs: true +// @filename: crash-on-neo-async.js +// This test reproduces a crash that occurs when parsing files like webpack/node_modules/neo-async/async.js +// The crash happens in GetAssignmentDeclarationKind when checking IsIdentifier(bin.Left.Name()) +// where bin.Left.Name() returns nil for ElementAccessExpression +// Pattern that causes the crash - element access assignment +var obj = {}; +var prop = 'test'; +// This assignment with element access should not crash +// It previously crashed because ElementAccessExpression.Name() returns nil +// and IsIdentifier was called on that nil value +obj[prop] = function () { + return 42; +}; +// Property access assignment should work fine (has a valid Name()) +obj.prop2 = function () { + return 43; +}; +// Nested element access assignment +obj['nested'][prop] = function () { + return 44; +};