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

Commit 97a7525

Browse files
authored
Merge pull request glayzzle#226 from glayzzle/issue-220
Issue 220 - impl static & instanceof
2 parents f3c737b + 26e433c commit 97a7525

File tree

6 files changed

+105
-8
lines changed

6 files changed

+105
-8
lines changed

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/namespace.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

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__/bin.test.js.snap

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,31 @@ Program {
818818
}
819819
`;
820820

821+
exports[`bin instanceof static 1`] = `
822+
Program {
823+
"children": Array [
824+
ExpressionStatement {
825+
"expression": Bin {
826+
"kind": "bin",
827+
"left": Variable {
828+
"byref": false,
829+
"curly": false,
830+
"kind": "variable",
831+
"name": "foo",
832+
},
833+
"right": StaticReference {
834+
"kind": "staticreference",
835+
},
836+
"type": "instanceof",
837+
},
838+
"kind": "expressionstatement",
839+
},
840+
],
841+
"errors": Array [],
842+
"kind": "program",
843+
}
844+
`;
845+
821846
exports[`bin instanceof variable 1`] = `
822847
Program {
823848
"children": Array [
@@ -894,6 +919,48 @@ Program {
894919
}
895920
`;
896921

922+
exports[`bin multiple instanceof static 1`] = `
923+
Program {
924+
"children": Array [
925+
ExpressionStatement {
926+
"expression": Bin {
927+
"kind": "bin",
928+
"left": Bin {
929+
"kind": "bin",
930+
"left": Variable {
931+
"byref": false,
932+
"curly": false,
933+
"kind": "variable",
934+
"name": "foo",
935+
},
936+
"right": StaticReference {
937+
"kind": "staticreference",
938+
},
939+
"type": "instanceof",
940+
},
941+
"right": Bin {
942+
"kind": "bin",
943+
"left": Variable {
944+
"byref": false,
945+
"curly": false,
946+
"kind": "variable",
947+
"name": "bar",
948+
},
949+
"right": SelfReference {
950+
"kind": "selfreference",
951+
},
952+
"type": "instanceof",
953+
},
954+
"type": "&&",
955+
},
956+
"kind": "expressionstatement",
957+
},
958+
],
959+
"errors": Array [],
960+
"kind": "program",
961+
}
962+
`;
963+
897964
exports[`bin or 1`] = `
898965
Program {
899966
"children": Array [

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ exports[`encapsed variable curly (simple syntax) 1`] = `
296296
Program {
297297
"children": Array [
298298
Echo {
299-
"arguments": Array [
299+
"expressions": Array [
300300
Encapsed {
301301
"kind": "encapsed",
302302
"raw": "\\"string \${var} string\\"",

test/snapshot/bin.test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ describe('bin', () => {
9191
it('instanceof self', () => {
9292
expect(parser.parseEval('$foo instanceof self;')).toMatchSnapshot();
9393
});
94+
it('instanceof static', () => {
95+
expect(parser.parseEval('$foo instanceof static;')).toMatchSnapshot();
96+
});
97+
it('multiple instanceof static', () => {
98+
expect(parser.parseEval('$foo instanceof static && $bar instanceof self;')).toMatchSnapshot();
99+
});
100+
94101
it('??', () => {
95102
expect(parser.parseEval('$foo ?? $bar;')).toMatchSnapshot();
96103
});

0 commit comments

Comments
 (0)