From 21de90b81db38a641c34e3b334018fd494b5ce7a Mon Sep 17 00:00:00 2001 From: Brandon Thompson Date: Sat, 7 Oct 2017 19:38:05 -0400 Subject: [PATCH 1/3] Added support for static lookup on property --- src/parser/variable.js | 3 +++ test/variableTests.js | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/parser/variable.js b/src/parser/variable.js index 30506cad8..3fb116b80 100644 --- a/src/parser/variable.js +++ b/src/parser/variable.js @@ -126,6 +126,9 @@ module.exports = { } result = node(result, offset); break; + case this.tok.T_DOUBLE_COLON: + result = this.read_static_getter(result, encapsed); + break; case this.tok.T_OBJECT_OPERATOR: var node = this.node('propertylookup'); var what = null; diff --git a/test/variableTests.js b/test/variableTests.js index 48a009eb6..779633f83 100644 --- a/test/variableTests.js +++ b/test/variableTests.js @@ -48,7 +48,8 @@ describe('Test variables', function() { 'parent::foo();', 'foo::class;', '$this->foo();', - 'foo::$bar;' + 'foo::$bar;', + '$this->foo::bar' ].join('\n'), { parser: { // debug: true @@ -104,6 +105,15 @@ describe('Test variables', function() { expr.offset.kind.should.be.exactly('variable'); expr.offset.name.should.be.exactly('bar'); }); + it('should be $this->foo::bar', function() { + var expr = ast.children[6]; + expr.kind.should.be.exactly('staticlookup'); + expr.what.kind.should.be.exactly('propertylookup'); + expr.what.what.kind.should.be.exactly('variable'); + expr.what.what.name.should.be.exactly('this'); + expr.what.offset.name.should.be.exactly('foo'); + expr.offset.name.should.be.exactly('bar'); + }); }); From 195e9374e45d08e0f5709e55e4158a31673fa1cf Mon Sep 17 00:00:00 2001 From: Brandon Thompson Date: Sun, 8 Oct 2017 15:52:05 -0400 Subject: [PATCH 2/3] Made static lookup on property more robust --- src/parser/variable.js | 18 +++++++++++++++++- test/variableTests.js | 31 +++++++++++++++++++++++-------- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/parser/variable.js b/src/parser/variable.js index 8bacf49ad..668d742ac 100644 --- a/src/parser/variable.js +++ b/src/parser/variable.js @@ -127,7 +127,23 @@ module.exports = { result = node(result, offset); break; case this.tok.T_DOUBLE_COLON: - result = this.read_static_getter(result, encapsed); + var node = this.node('staticlookup'), offset; + this.next(); + + if(this.is('IDENTIFIER') || this.token === this.tok.T_STRING + || this.token === this.tok.T_CLASS + ) { + offset = this.node('constref'); + var name = this.text(); + this.next(); + offset = offset(name); + + if(this.token === this.tok.T_OBJECT_OPERATOR || this.token === this.tok.T_DOUBLE_COLON) { + this.error(); + } + } + + result = node(result, offset); break; case this.tok.T_OBJECT_OPERATOR: var node = this.node('propertylookup'); diff --git a/test/variableTests.js b/test/variableTests.js index 779633f83..2ccd9b9c4 100644 --- a/test/variableTests.js +++ b/test/variableTests.js @@ -49,7 +49,7 @@ describe('Test variables', function() { 'foo::class;', '$this->foo();', 'foo::$bar;', - '$this->foo::bar' + '$this->foo::bar["baz"]::qux();' ].join('\n'), { parser: { // debug: true @@ -105,14 +105,29 @@ describe('Test variables', function() { expr.offset.kind.should.be.exactly('variable'); expr.offset.name.should.be.exactly('bar'); }); - it('should be $this->foo::bar', function() { + it('should be $this->foo::bar["baz"]::qux();', function() { var expr = ast.children[6]; - expr.kind.should.be.exactly('staticlookup'); - expr.what.kind.should.be.exactly('propertylookup'); - expr.what.what.kind.should.be.exactly('variable'); - expr.what.what.name.should.be.exactly('this'); - expr.what.offset.name.should.be.exactly('foo'); - expr.offset.name.should.be.exactly('bar'); + + expr.kind.should.be.exactly("call"); + expr.arguments.length.should.be.exactly(0); + + expr.what.kind.should.be.exactly("staticlookup"); + expr.what.offset.kind.should.be.exactly("constref"); + expr.what.offset.name.should.be.exactly("qux"); + + expr.what.what.kind.should.be.exactly("offsetlookup"); + expr.what.what.offset.kind.should.be.exactly("string"); + expr.what.what.offset.value.should.be.exactly("baz"); + + expr.what.what.what.kind.should.be.exactly("staticlookup"); + expr.what.what.what.offset.kind.should.be.exactly("constref"); + expr.what.what.what.offset.name.should.be.exactly("bar"); + + expr.what.what.what.what.kind.should.be.exactly("propertylookup"); + expr.what.what.what.what.what.kind.should.be.exactly("variable"); + expr.what.what.what.what.what.name.should.be.exactly("this"); + expr.what.what.what.what.offset.kind.should.be.exactly("constref"); + expr.what.what.what.what.offset.name.should.be.exactly("foo"); }); }); From 13687512f2beb9d1f5de5706e43a9c3b19df54a1 Mon Sep 17 00:00:00 2001 From: Brandon Thompson Date: Sun, 8 Oct 2017 16:05:22 -0400 Subject: [PATCH 3/3] Added two tests for static property lookup --- test/variableTests.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/test/variableTests.js b/test/variableTests.js index 2ccd9b9c4..2165a08cd 100644 --- a/test/variableTests.js +++ b/test/variableTests.js @@ -188,5 +188,36 @@ describe('Test variables', function() { ast.children[0].left.kind.should.be.exactly('variable'); ast.children[0].left.name.should.be.exactly('?'); }); + + it('should fail on double static lookup', function() { + var astErr = parser.parseEval([ + 'this->foo::bar::baz;' + ].join('\n'), { + parser: { + suppressErrors: true + } + }); + + var msg = 'Parse Error : syntax error, unexpected \'::\' (T_DOUBLE_COLON) on line 1'; + astErr.errors.length.should.be.exactly(1); + astErr.errors[0].line.should.be.exactly(1); + astErr.errors[0].message.should.be.exactly(msg); + }); + + it('should fail on property lookup on static lookup', function() { + var astErr = parser.parseEval([ + 'this->foo::bar->baz;' + ].join('\n'), { + parser: { + suppressErrors: true + } + }); + + var msg = 'Parse Error : syntax error, unexpected \'->\' (T_OBJECT_OPERATOR) on line 1'; + astErr.errors.length.should.be.exactly(1); + astErr.errors[0].line.should.be.exactly(1); + astErr.errors[0].message.should.be.exactly(msg); + }); + }); });