Skip to content
This repository was archived by the owner on Mar 29, 2023. It is now read-only.

Commit dccd8f8

Browse files
authored
Merge branch 'master' into fix-broken-code
2 parents 8e9a3b6 + 7c53a16 commit dccd8f8

29 files changed

+3149
-17
lines changed

src/ast/parentreference.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ const KIND = "parentreference";
1414
* @extends {Reference}
1515
*/
1616
const ParentReference = Reference.extends(KIND, function ParentReference(
17+
raw,
1718
docs,
1819
location
1920
) {
2021
Reference.apply(this, [KIND, docs, location]);
22+
this.raw = raw;
2123
});
2224
module.exports = ParentReference;

src/ast/selfreference.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ const KIND = "selfreference";
1414
* @extends {Reference}
1515
*/
1616
const SelfReference = Reference.extends(KIND, function SelfReference(
17+
raw,
1718
docs,
1819
location
1920
) {
2021
Reference.apply(this, [KIND, docs, location]);
22+
this.raw = raw;
2123
});
2224
module.exports = SelfReference;

src/ast/staticreference.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ const KIND = "staticreference";
1414
* @extends {Reference}
1515
*/
1616
const StaticReference = Reference.extends(KIND, function StaticReference(
17+
raw,
1718
docs,
1819
location
1920
) {
2021
Reference.apply(this, [KIND, docs, location]);
22+
this.raw = raw;
2123
});
2224
module.exports = StaticReference;

src/ast/typereference.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,24 @@ const KIND = "typereference";
1616
*/
1717
const TypeReference = Reference.extends(KIND, function TypeReference(
1818
name,
19+
raw,
1920
docs,
2021
location
2122
) {
2223
Reference.apply(this, [KIND, docs, location]);
2324
this.name = name;
25+
this.raw = raw;
2426
});
2527

26-
TypeReference.types = ["int", "float", "string", "bool", "object", "array"];
28+
TypeReference.types = [
29+
"int",
30+
"float",
31+
"string",
32+
"bool",
33+
"object",
34+
"array",
35+
"callable",
36+
"iterable"
37+
];
2738

2839
module.exports = TypeReference;

src/parser/expr.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
"use strict";
77

88
module.exports = {
9-
read_expr: function() {
9+
read_expr: function(expr) {
1010
const result = this.node();
11-
const expr = this.read_expr_item();
11+
if (!expr) {
12+
expr = this.read_expr_item();
13+
}
1214
// binary operations
1315
if (this.token === "|")
1416
return result("bin", "|", expr, this.next().read_expr());
@@ -63,8 +65,21 @@ module.exports = {
6365
return result("bin", ">=", expr, this.next().read_expr());
6466
if (this.token === this.tok.T_SPACESHIP)
6567
return result("bin", "<=>", expr, this.next().read_expr());
66-
if (this.token === this.tok.T_INSTANCEOF)
67-
return result("bin", "instanceof", expr, this.next().read_expr());
68+
if (this.token === this.tok.T_INSTANCEOF) {
69+
expr = result(
70+
"bin",
71+
"instanceof",
72+
expr,
73+
this.next().read_class_name_reference()
74+
);
75+
if (
76+
this.token !== ";" &&
77+
this.token !== this.tok.T_INLINE_HTML &&
78+
this.token !== this.EOF
79+
) {
80+
expr = this.read_expr(expr);
81+
}
82+
}
6883

6984
// extra operations :
7085
// $username = $_GET['user'] ?? 'nobody';

src/parser/function.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,11 @@ module.exports = {
240240
* ```
241241
*/
242242
read_type: function() {
243-
const result = this.node("typereference");
243+
const result = this.node();
244244
if (this.token === this.tok.T_ARRAY || this.token === this.tok.T_CALLABLE) {
245245
const type = this.text();
246246
this.next();
247-
return result(type);
247+
return result("typereference", type.toLowerCase(), type);
248248
} else if (this.token === this.tok.T_STRING) {
249249
const type = this.text();
250250
const backup = [this.token, this.lexer.getState()];
@@ -253,7 +253,7 @@ module.exports = {
253253
this.token !== this.tok.T_NS_SEPARATOR &&
254254
this.ast.typereference.types.indexOf(type.toLowerCase()) > -1
255255
) {
256-
return result(type);
256+
return result("typereference", type.toLowerCase(), type);
257257
} else {
258258
// rollback a classic namespace
259259
this.lexer.tokens.push(backup);

src/parser/namespace.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ module.exports = {
7474
true
7575
);
7676
if (!relative && names.length === 1) {
77-
if (names[0] === "parent") {
78-
return result("parentreference");
79-
} else if (names[0] === "self") {
80-
return result("selfreference");
77+
if (names[0].toLowerCase() === "parent") {
78+
return result("parentreference", names[0]);
79+
} else if (names[0].toLowerCase() === "self") {
80+
return result("selfreference", names[0]);
8181
}
8282
}
8383
return result("classreference", names, relative);
@@ -112,6 +112,14 @@ module.exports = {
112112
this.expect(";") && this.next();
113113
return result;
114114
},
115+
/**
116+
*
117+
* @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1045
118+
*/
119+
read_class_name_reference: function() {
120+
// resolved as the same
121+
return this.read_variable(true, false, false);
122+
},
115123
/**
116124
* Reads a use declaration
117125
* ```ebnf

src/parser/variable.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ module.exports = {
4343
) {
4444
result = this.node();
4545
const name = this.read_namespace_name();
46-
if (this.token != this.tok.T_DOUBLE_COLON && this.token != "(") {
46+
if (
47+
this.token != this.tok.T_DOUBLE_COLON &&
48+
this.token != "(" &&
49+
["parentreference", "selfreference"].indexOf(name.kind) === -1
50+
) {
4751
// @see parser.js line 130 : resolves a conflict with scalar
4852
const literal = name.name.toLowerCase();
4953
if (literal === "true") {
@@ -60,8 +64,9 @@ module.exports = {
6064
}
6165
} else if (this.token === this.tok.T_STATIC) {
6266
result = this.node("staticreference");
67+
const raw = this.text();
6368
this.next();
64-
result = result();
69+
result = result(raw);
6570
} else {
6671
this.expect("VARIABLE");
6772
}

test/precedence.test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ describe("Test precedence", function() {
4848
shouldBeSame("5 % 3 . 2", "(5 % 3) . 2");
4949
});
5050
it("test instanceof", function() {
51-
shouldBeSame("3 instanceof 2 * 5", "(3 instanceof 2) * 5");
51+
shouldBeSame("$a instanceof $b && $c", "($a instanceof $b) && $c");
5252
});
5353
it("test <<", function() {
5454
shouldBeSame("1 + 3 << 5", "(1 + 3) << 5");
@@ -95,8 +95,8 @@ describe("Test precedence", function() {
9595
shouldBeSame("5 AND 4 + 3", "5 AND (4 + 3)");
9696
});
9797
it("test unary : !", function() {
98-
shouldBeSame("!4 instanceof 3", "(!4) instanceof 3");
99-
shouldBeSame("!4 + 5 instanceof 3", "(!4) + (5 instanceof 3)");
98+
shouldBeSame("!$a instanceof $b", "(!$a) instanceof $b");
99+
shouldBeSame("!$a + $b instanceof $c", "(!$a) + ($b instanceof $c)");
100100
shouldBeSame("6 + !4 + 5", "6 + (!4) + 5");
101101
shouldBeSame("if($a && !$b) {}", "if($a && (!$b)) {}");
102102
});

test/snapshot/__snapshots__/acid.test.js.snap

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,7 @@ Program {
14481448
},
14491449
},
14501450
"name": "bool",
1451+
"raw": "bool",
14511452
},
14521453
"visibility": "public",
14531454
},
@@ -1506,6 +1507,7 @@ Program {
15061507
},
15071508
},
15081509
"name": "bool",
1510+
"raw": "bool",
15091511
},
15101512
"visibility": "protected",
15111513
},
@@ -1564,6 +1566,7 @@ Program {
15641566
},
15651567
},
15661568
"name": "bool",
1569+
"raw": "bool",
15671570
},
15681571
"visibility": "protected",
15691572
},
@@ -1860,6 +1863,7 @@ Program {
18601863
},
18611864
},
18621865
"name": "bool",
1866+
"raw": "bool",
18631867
},
18641868
"value": Boolean {
18651869
"kind": "boolean",
@@ -2504,6 +2508,7 @@ Program {
25042508
},
25052509
},
25062510
"name": "string",
2511+
"raw": "string",
25072512
},
25082513
"visibility": "public",
25092514
},
@@ -3637,6 +3642,7 @@ next:
36373642
},
36383643
},
36393644
"name": "int",
3645+
"raw": "int",
36403646
},
36413647
},
36423648
ExpressionStatement {
@@ -3747,6 +3753,7 @@ next:
37473753
},
37483754
},
37493755
"name": "int",
3756+
"raw": "int",
37503757
},
37513758
"value": Number {
37523759
"kind": "number",
@@ -6316,6 +6323,7 @@ next:
63166323
},
63176324
},
63186325
"name": "bool",
6326+
"raw": "bool",
63196327
},
63206328
"uses": Array [
63216329
Variable {

0 commit comments

Comments
 (0)