Skip to content

Commit 69a44a6

Browse files
authored
Fix crash when trying to assign to an optional chain (#1045)
1 parent 987899c commit 69a44a6

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

src/transformation/utils/diagnostics.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,7 @@ export const annotationDeprecated = createWarningDiagnosticFactory(
143143
`'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` +
144144
`See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.`
145145
);
146+
147+
export const notAllowedOptionalAssignment = createErrorDiagnosticFactory(
148+
"The left-hand side of an assignment expression may not be an optional property access."
149+
);

src/transformation/visitors/binary-expression/assignments.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
ImmediatelyInvokedFunctionParameters,
1717
transformToImmediatelyInvokedFunctionExpression,
1818
} from "../../utils/transform";
19+
import { notAllowedOptionalAssignment } from "../../utils/diagnostics";
1920

2021
export function transformAssignmentLeftHandSideExpression(
2122
context: TransformationContext,
@@ -36,6 +37,11 @@ export function transformAssignment(
3637
right: lua.Expression,
3738
parent?: ts.Expression
3839
): lua.Statement[] {
40+
if (ts.isOptionalChain(lhs)) {
41+
context.diagnostics.push(notAllowedOptionalAssignment(lhs));
42+
return [];
43+
}
44+
3945
if (isArrayLength(context, lhs)) {
4046
const arrayLengthAssignment = lua.createExpressionStatement(
4147
transformLuaLibFunction(

test/unit/optionalChaining.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { notAllowedOptionalAssignment } from "../../src/transformation/utils/diagnostics";
12
import * as util from "../util";
23

34
test.each(["null", "undefined", '{ foo: "foo" }'])("optional chaining (%p)", value => {
@@ -97,6 +98,15 @@ test("no side effects", () => {
9798
`.expectToMatchJsResult();
9899
});
99100

101+
// Test for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1044
102+
test("does not crash when incorrectly used in assignment (#1044)", () => {
103+
const { diagnostics } = util.testFunction`
104+
foo?.bar = "foo";
105+
`.getLuaResult();
106+
107+
expect(diagnostics.find(d => d.code === notAllowedOptionalAssignment.code)).toBeDefined();
108+
});
109+
100110
describe("optional chaining function calls", () => {
101111
test.each(["() => 4", "undefined"])("stand-alone optional function (%p)", value => {
102112
util.testFunction`

0 commit comments

Comments
 (0)