Skip to content

Commit 41bec41

Browse files
authored
Merge pull request glayzzle#384 from glayzzle/fix-support-negative-offset-in-ecapsed
fix: support negative offset in encapsed
2 parents e3c0cbb + e487690 commit 41bec41

File tree

3 files changed

+219
-20
lines changed

3 files changed

+219
-20
lines changed

src/parser/variable.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,11 @@ module.exports = {
250250
const num = this.text();
251251
this.next();
252252
offset = offset("number", num, null);
253+
} else if (this.token === "-") {
254+
this.next();
255+
const num = -1 * this.text();
256+
this.expect(this.tok.T_NUM_STRING) && this.next();
257+
offset = offset("number", num, null);
253258
} else if (this.token === this.tok.T_VARIABLE) {
254259
const name = this.text().substring(1);
255260
this.next();
@@ -258,6 +263,7 @@ module.exports = {
258263
this.expect([
259264
this.tok.T_STRING,
260265
this.tok.T_NUM_STRING,
266+
"-",
261267
this.tok.T_VARIABLE
262268
]);
263269
// fallback : consider as identifier

test/snapshot/__snapshots__/encapsed.test.js.snap

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,41 @@ Program {
6464
}
6565
`;
6666

67+
exports[`encapsed negative offset in encapsed var offset 1`] = `
68+
Program {
69+
"children": Array [
70+
ExpressionStatement {
71+
"expression": Encapsed {
72+
"kind": "encapsed",
73+
"raw": "\\"$var[-1]\\"",
74+
"type": "string",
75+
"value": Array [
76+
EncapsedPart {
77+
"curly": false,
78+
"expression": OffsetLookup {
79+
"kind": "offsetlookup",
80+
"offset": Number {
81+
"kind": "number",
82+
"value": -1,
83+
},
84+
"what": Variable {
85+
"curly": false,
86+
"kind": "variable",
87+
"name": "var",
88+
},
89+
},
90+
"kind": "encapsedpart",
91+
},
92+
],
93+
},
94+
"kind": "expressionstatement",
95+
},
96+
],
97+
"errors": Array [],
98+
"kind": "program",
99+
}
100+
`;
101+
67102
exports[`encapsed newline before closing curly (complex syntax) 1`] = `
68103
Program {
69104
"children": Array [
@@ -542,6 +577,41 @@ Program {
542577
}
543578
`;
544579

580+
exports[`encapsed positive offset in encapsed var offset 1`] = `
581+
Program {
582+
"children": Array [
583+
ExpressionStatement {
584+
"expression": Encapsed {
585+
"kind": "encapsed",
586+
"raw": "\\"$var[1]\\"",
587+
"type": "string",
588+
"value": Array [
589+
EncapsedPart {
590+
"curly": false,
591+
"expression": OffsetLookup {
592+
"kind": "offsetlookup",
593+
"offset": Number {
594+
"kind": "number",
595+
"value": "1",
596+
},
597+
"what": Variable {
598+
"curly": false,
599+
"kind": "variable",
600+
"name": "var",
601+
},
602+
},
603+
"kind": "encapsedpart",
604+
},
605+
],
606+
},
607+
"kind": "expressionstatement",
608+
},
609+
],
610+
"errors": Array [],
611+
"kind": "program",
612+
}
613+
`;
614+
545615
exports[`encapsed propertylookup (complex syntax) 1`] = `
546616
Program {
547617
"children": Array [
@@ -1313,6 +1383,77 @@ Program {
13131383
}
13141384
`;
13151385

1386+
exports[`encapsed string offset in encapsed var offset 1`] = `
1387+
Program {
1388+
"children": Array [
1389+
ExpressionStatement {
1390+
"expression": Encapsed {
1391+
"kind": "encapsed",
1392+
"raw": "\\"$var[var]\\"",
1393+
"type": "string",
1394+
"value": Array [
1395+
EncapsedPart {
1396+
"curly": false,
1397+
"expression": OffsetLookup {
1398+
"kind": "offsetlookup",
1399+
"offset": Identifier {
1400+
"kind": "identifier",
1401+
"name": "var",
1402+
},
1403+
"what": Variable {
1404+
"curly": false,
1405+
"kind": "variable",
1406+
"name": "var",
1407+
},
1408+
},
1409+
"kind": "encapsedpart",
1410+
},
1411+
],
1412+
},
1413+
"kind": "expressionstatement",
1414+
},
1415+
],
1416+
"errors": Array [],
1417+
"kind": "program",
1418+
}
1419+
`;
1420+
1421+
exports[`encapsed string offset in encapsed var offset 2`] = `
1422+
Program {
1423+
"children": Array [
1424+
ExpressionStatement {
1425+
"expression": Encapsed {
1426+
"kind": "encapsed",
1427+
"raw": "\\"$var[$var]\\"",
1428+
"type": "string",
1429+
"value": Array [
1430+
EncapsedPart {
1431+
"curly": false,
1432+
"expression": OffsetLookup {
1433+
"kind": "offsetlookup",
1434+
"offset": Variable {
1435+
"curly": false,
1436+
"kind": "variable",
1437+
"name": "var",
1438+
},
1439+
"what": Variable {
1440+
"curly": false,
1441+
"kind": "variable",
1442+
"name": "var",
1443+
},
1444+
},
1445+
"kind": "encapsedpart",
1446+
},
1447+
],
1448+
},
1449+
"kind": "expressionstatement",
1450+
},
1451+
],
1452+
"errors": Array [],
1453+
"kind": "program",
1454+
}
1455+
`;
1456+
13161457
exports[`encapsed two variable (simple syntax) 1`] = `
13171458
Program {
13181459
"children": Array [

test/snapshot/encapsed.test.js

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const parser = require('../main');
1+
const parser = require("../main");
22

33
describe("encapsed", function() {
44
it("variable (simple syntax)", function() {
@@ -14,13 +14,17 @@ describe("encapsed", function() {
1414
expect(parser.parseEval('"string $array[0] string";')).toMatchSnapshot();
1515
});
1616
it("offsetlookup (2) (simple syntax)", function() {
17-
expect(parser.parseEval('"string $array[koolaid1] string";')).toMatchSnapshot();
17+
expect(
18+
parser.parseEval('"string $array[koolaid1] string";')
19+
).toMatchSnapshot();
1820
});
1921
it("offsetlookup (3) (simple syntax)", function() {
2022
expect(parser.parseEval('"string $array[0][0] string";')).toMatchSnapshot();
2123
});
2224
it("propertylookup (simple syntax)", function() {
23-
expect(parser.parseEval('"string $obj->property string";')).toMatchSnapshot();
25+
expect(
26+
parser.parseEval('"string $obj->property string";')
27+
).toMatchSnapshot();
2428
});
2529
it("variable with space opening before curly", function() {
2630
expect(parser.parseEval('"string { $var} string";')).toMatchSnapshot();
@@ -32,22 +36,34 @@ describe("encapsed", function() {
3236
expect(parser.parseEval('"string {$var} string";')).toMatchSnapshot();
3337
});
3438
it("propertylookup (complex syntax)", function() {
35-
expect(parser.parseEval('"string {$obj->property} string";')).toMatchSnapshot();
39+
expect(
40+
parser.parseEval('"string {$obj->property} string";')
41+
).toMatchSnapshot();
3642
});
3743
it("offsetlookup (complex syntax)", function() {
38-
expect(parser.parseEval('"string {$array["key"]} string";')).toMatchSnapshot();
44+
expect(
45+
parser.parseEval('"string {$array["key"]} string";')
46+
).toMatchSnapshot();
3947
});
4048
it("offsetlookup 2 (complex syntax)", function() {
41-
expect(parser.parseEval('"string {$array[4][3]} string";')).toMatchSnapshot();
49+
expect(
50+
parser.parseEval('"string {$array[4][3]} string";')
51+
).toMatchSnapshot();
4252
});
4353
it("offsetlookup 3 (complex syntax)", function() {
44-
expect(parser.parseEval('"string {$arr[foo][3]} string";')).toMatchSnapshot();
54+
expect(
55+
parser.parseEval('"string {$arr[foo][3]} string";')
56+
).toMatchSnapshot();
4557
});
4658
it("offsetlookup 4 (complex syntax)", function() {
47-
expect(parser.parseEval('"string {$arr["foo"][3]} string";')).toMatchSnapshot();
59+
expect(
60+
parser.parseEval('"string {$arr["foo"][3]} string";')
61+
).toMatchSnapshot();
4862
});
4963
it("propertylookup and offsetlookup (complex syntax)", function() {
50-
expect(parser.parseEval('"string {$obj->values[3]->name} string";')).toMatchSnapshot();
64+
expect(
65+
parser.parseEval('"string {$obj->values[3]->name} string";')
66+
).toMatchSnapshot();
5167
});
5268
it("value of the var (complex syntax)", function() {
5369
expect(parser.parseEval('"string {${$name}} string";')).toMatchSnapshot();
@@ -59,31 +75,47 @@ describe("encapsed", function() {
5975
expect(parser.parseEval('"string {${call()}} string";')).toMatchSnapshot();
6076
});
6177
it("value of the var named by the return value (3) (complex syntax)", function() {
62-
expect(parser.parseEval('"string {${$obj->property}} string";')).toMatchSnapshot();
78+
expect(
79+
parser.parseEval('"string {${$obj->property}} string";')
80+
).toMatchSnapshot();
6381
});
6482
it("value of the var named by the return value (4) (complex syntax)", function() {
65-
expect(parser.parseEval('"string {${$obj->call()}} string";')).toMatchSnapshot();
83+
expect(
84+
parser.parseEval('"string {${$obj->call()}} string";')
85+
).toMatchSnapshot();
6686
});
6787
it("value of the var named by the return value (5) (complex syntax)", function() {
68-
expect(parser.parseEval('"string {${$obj::$var}} string";')).toMatchSnapshot();
88+
expect(
89+
parser.parseEval('"string {${$obj::$var}} string";')
90+
).toMatchSnapshot();
6991
});
7092
it("value of the var named by the return value (6) (complex syntax)", function() {
71-
expect(parser.parseEval('"string {${$obj::call()}} string";')).toMatchSnapshot();
93+
expect(
94+
parser.parseEval('"string {${$obj::call()}} string";')
95+
).toMatchSnapshot();
7296
});
7397
it("propertylookup by variable (complex syntax)", function() {
7498
expect(parser.parseEval('"string {$obj->$var} string";')).toMatchSnapshot();
7599
});
76100
it("propertylookup by variable (2) (complex syntax)", function() {
77-
expect(parser.parseEval('"string {$obj->{$array[1]}} string";')).toMatchSnapshot();
101+
expect(
102+
parser.parseEval('"string {$obj->{$array[1]}} string";')
103+
).toMatchSnapshot();
78104
});
79105
it("propertylookup with multiple call (complex syntax)", function() {
80-
expect(parser.parseEval('"string {$obj->call()->call()} string";')).toMatchSnapshot();
106+
expect(
107+
parser.parseEval('"string {$obj->call()->call()} string";')
108+
).toMatchSnapshot();
81109
});
82110
it("multiple propertylookup (complex syntax)", function() {
83-
expect(parser.parseEval('"string {$obj->property->property} string";')).toMatchSnapshot();
111+
expect(
112+
parser.parseEval('"string {$obj->property->property} string";')
113+
).toMatchSnapshot();
84114
});
85115
it("propertylookup with comments (complex syntax)", function() {
86-
expect(parser.parseEval('"string {$var->foo->bar /* Comment */ } string";')).toMatchSnapshot();
116+
expect(
117+
parser.parseEval('"string {$var->foo->bar /* Comment */ } string";')
118+
).toMatchSnapshot();
87119
});
88120
it("newline before closing curly (complex syntax)", function() {
89121
expect(parser.parseEval('"string {$var\n} string";')).toMatchSnapshot();
@@ -92,12 +124,32 @@ describe("encapsed", function() {
92124
expect(parser.parseEval('"string {$obj::$var} string";')).toMatchSnapshot();
93125
});
94126
it("staticlookup (2) (complex syntax)", function() {
95-
expect(parser.parseEval('"string {$obj::call()} string";')).toMatchSnapshot();
127+
expect(
128+
parser.parseEval('"string {$obj::call()} string";')
129+
).toMatchSnapshot();
96130
});
97131
it("staticlookup (3) (complex syntax)", function() {
98-
expect(parser.parseEval('"string {$obj::$var::$var} string";')).toMatchSnapshot();
132+
expect(
133+
parser.parseEval('"string {$obj::$var::$var} string";')
134+
).toMatchSnapshot();
99135
});
100136
it("staticlookup (4) (complex syntax)", function() {
101-
expect(parser.parseEval('"string {$var::$target::$resource::$binary::$foo::$bar::$foobar::$bar::$foo::$foobar::$bar::$foo} string";')).toMatchSnapshot();
137+
expect(
138+
parser.parseEval(
139+
'"string {$var::$target::$resource::$binary::$foo::$bar::$foobar::$bar::$foo::$foobar::$bar::$foo} string";'
140+
)
141+
).toMatchSnapshot();
142+
});
143+
it("string offset in encapsed var offset", () => {
144+
expect(parser.parseEval(`"$var[var]";`)).toMatchSnapshot();
145+
});
146+
it("positive offset in encapsed var offset", () => {
147+
expect(parser.parseEval(`"$var[1]";`)).toMatchSnapshot();
148+
});
149+
it("negative offset in encapsed var offset", () => {
150+
expect(parser.parseEval(`"$var[-1]";`)).toMatchSnapshot();
151+
});
152+
it("string offset in encapsed var offset", () => {
153+
expect(parser.parseEval(`"$var[$var]";`)).toMatchSnapshot();
102154
});
103155
});

0 commit comments

Comments
 (0)