Skip to content

Commit 1534eca

Browse files
authored
Merge pull request glayzzle#142 from czosel/array-destructuring
Add support for array destructuring
2 parents 49b11f7 + 607708c commit 1534eca

File tree

2 files changed

+48
-38
lines changed

2 files changed

+48
-38
lines changed

src/parser/expr.js

+27-25
Original file line numberDiff line numberDiff line change
@@ -121,18 +121,7 @@ module.exports = {
121121
const node = this.node("parenthesis");
122122
expr = this.next().read_expr();
123123
this.expect(")") && this.next();
124-
expr = node(expr);
125-
// handle dereferencable
126-
if (this.token === this.tok.T_OBJECT_OPERATOR) {
127-
return this.recursive_variable_chain_scan(expr, false);
128-
} else if (this.token === this.tok.T_CURLY_OPEN || this.token === "[") {
129-
return this.read_dereferencable(expr);
130-
} else if (this.token === "(") {
131-
// https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1118
132-
return this.node("call")(expr, this.read_function_argument_list());
133-
} else {
134-
return expr;
135-
}
124+
return this.handleDereferencable(node(expr));
136125
}
137126

138127
if (this.token === "`") {
@@ -185,6 +174,15 @@ module.exports = {
185174
}
186175
}
187176

177+
if (this.token === "[") {
178+
expr = this.read_array();
179+
if (this.token === "=") {
180+
return this.node("assign")(expr, this.next().read_expr(), "=");
181+
} else {
182+
return this.handleDereferencable(expr);
183+
}
184+
}
185+
188186
if (this.token === this.tok.T_CLONE)
189187
return this.node("clone")(this.next().read_expr());
190188

@@ -417,19 +415,7 @@ module.exports = {
417415
}
418416
} else if (this.is("SCALAR")) {
419417
expr = this.read_scalar();
420-
// handle dereferencable
421-
while (this.token !== this.EOF) {
422-
if (this.token === this.tok.T_OBJECT_OPERATOR) {
423-
expr = this.recursive_variable_chain_scan(expr, false);
424-
} else if (this.token === this.tok.T_CURLY_OPEN || this.token === "[") {
425-
expr = this.read_dereferencable(expr);
426-
} else if (this.token === "(") {
427-
// https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1118
428-
expr = this.node("call")(expr, this.read_function_argument_list());
429-
} else {
430-
return expr;
431-
}
432-
}
418+
return this.handleDereferencable(expr);
433419
} else {
434420
this.error("EXPR");
435421
this.next();
@@ -521,5 +507,21 @@ module.exports = {
521507
result = ["key", result, this.next().read_expr_item()];
522508
}
523509
return result;
510+
},
511+
512+
handleDereferencable: function(expr) {
513+
while (this.token !== this.EOF) {
514+
if (this.token === this.tok.T_OBJECT_OPERATOR) {
515+
expr = this.recursive_variable_chain_scan(expr, false);
516+
} else if (this.token === this.tok.T_CURLY_OPEN || this.token === "[") {
517+
expr = this.read_dereferencable(expr);
518+
} else if (this.token === "(") {
519+
// https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1118
520+
expr = this.node("call")(expr, this.read_function_argument_list());
521+
} else {
522+
return expr;
523+
}
524+
}
525+
return expr;
524526
}
525527
};

test/variableTests.js

+21-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
var parser = require("./main");
22

33
describe("Test variables", function() {
4+
describe("array destructuring", function() {
5+
// Get result from parser
6+
var ast = parser.parseEval("[$id1, $name1] = $data[0];");
7+
it("should be assign with array", function() {
8+
ast.children[0].kind.should.be.exactly("assign");
9+
ast.children[0].left.kind.should.be.exactly("array");
10+
ast.children[0].operator.should.be.exactly("=");
11+
});
12+
});
13+
414
describe("Default variables", function() {
515
var ast = parser.parseEval(
616
['$a = "foo";', "$b = &$c;", "$a->b = true;"].join("\n")
@@ -197,11 +207,9 @@ describe("Test variables", function() {
197207
astErr.errors[0].line.should.be.exactly(1);
198208
astErr.errors[0].message.should.be.exactly(msg);
199209
});
200-
210+
201211
it("should fail on property lookup on static lookup", function() {
202-
var astErr = parser.parseEval([
203-
"$this->foo::bar->baz;"
204-
].join('\n'), {
212+
var astErr = parser.parseEval(["$this->foo::bar->baz;"].join("\n"), {
205213
parser: {
206214
suppressErrors: true
207215
}
@@ -213,27 +221,27 @@ describe("Test variables", function() {
213221
astErr.errors[0].line.should.be.exactly(1);
214222
astErr.errors[0].message.should.be.exactly(msg);
215223
});
216-
217-
it('should fail $foo->bar::!', function() {
218-
var errAst = parser.parseEval('$foo->bar::!', {
224+
225+
it("should fail $foo->bar::!", function() {
226+
var errAst = parser.parseEval("$foo->bar::!", {
219227
parser: {
220228
suppressErrors: true
221229
}
222230
});
223231
errAst.errors.length.should.be.exactly(1);
224-
errAst.errors[0].token.should.be.exactly('\'!\'');
225-
errAst.children[0].kind.should.be.exactly('staticlookup');
226-
errAst.children[0].offset.name.should.be.exactly('!');
232+
errAst.errors[0].token.should.be.exactly("'!'");
233+
errAst.children[0].kind.should.be.exactly("staticlookup");
234+
errAst.children[0].offset.name.should.be.exactly("!");
227235
});
228236

229-
it('should fail foo::bar::baz', function() {
230-
var errAst = parser.parseEval('foo::bar::baz', {
237+
it("should fail foo::bar::baz", function() {
238+
var errAst = parser.parseEval("foo::bar::baz", {
231239
parser: {
232240
suppressErrors: true
233241
}
234242
});
235243
errAst.errors.length.should.be.exactly(1);
236-
errAst.children[0].kind.should.be.exactly('staticlookup');
244+
errAst.children[0].kind.should.be.exactly("staticlookup");
237245
});
238246
});
239247
});

0 commit comments

Comments
 (0)