From ca8f3a7dcdd76ca9542d10f5e8c245e787632be8 Mon Sep 17 00:00:00 2001 From: Jorg Sowa Date: Thu, 8 Jan 2026 07:52:17 +0100 Subject: [PATCH] fix: nullsafe operator parenthesized --- src/parser/expr.js | 3 +++ test/snapshot/__snapshots__/call.test.js.snap | 25 +++++++++++++++++++ test/snapshot/call.test.js | 6 +++++ 3 files changed, 34 insertions(+) diff --git a/src/parser/expr.js b/src/parser/expr.js index fd7bf1e4c..a99d22caa 100644 --- a/src/parser/expr.js +++ b/src/parser/expr.js @@ -97,6 +97,9 @@ module.exports = { if (this.token === this.tok.T_SPACESHIP) { return result("bin", "<=>", expr, this.next().read_expr()); } + if (this.token === this.tok.T_NULLSAFE_OBJECT_OPERATOR) { + return result("nullsafepropertylookup", expr, this.read_what()); + } if (this.token === this.tok.T_INSTANCEOF) { expr = result( diff --git a/test/snapshot/__snapshots__/call.test.js.snap b/test/snapshot/__snapshots__/call.test.js.snap index 14e51dcd5..ce891f381 100644 --- a/test/snapshot/__snapshots__/call.test.js.snap +++ b/test/snapshot/__snapshots__/call.test.js.snap @@ -1119,6 +1119,31 @@ Program { } `; +exports[`Test call nullsafepropertylookup (3) 1`] = ` +Program { + "children": [ + ExpressionStatement { + "expression": NullSafePropertyLookup { + "kind": "nullsafepropertylookup", + "offset": Identifier { + "kind": "identifier", + "name": "property", + }, + "what": Variable { + "curly": false, + "kind": "variable", + "name": "obj", + "parenthesizedExpression": true, + }, + }, + "kind": "expressionstatement", + }, + ], + "errors": [], + "kind": "program", +} +`; + exports[`Test call nullsafepropertylookup 1`] = ` Program { "children": [ diff --git a/test/snapshot/call.test.js b/test/snapshot/call.test.js index 0ab555383..87e4a36ee 100644 --- a/test/snapshot/call.test.js +++ b/test/snapshot/call.test.js @@ -61,6 +61,12 @@ describe("Test call", function () { }); expect(ast).toMatchSnapshot(); }); + it("nullsafepropertylookup (3)", function () { + const ast = parser.parseEval("($obj)?->property;", { + parser: { debug: false }, + }); + expect(ast).toMatchSnapshot(); + }); it("staticlookup", function () { const ast = parser.parseEval("$obj::call();", { parser: { debug: false },