Skip to content

Commit 771a2d4

Browse files
authored
Merge pull request glayzzle#82 from glayzzle/2.1.0
2.1.0
2 parents 18b7ed1 + 62aaee6 commit 771a2d4

File tree

4 files changed

+60
-7
lines changed

4 files changed

+60
-7
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ Documentation
9090
Related projects
9191
----------------
9292

93+
- [babel-preset-php](https://gitlab.com/kornelski/babel-preset-php) : Babel preset for converting PHP syntax to JavaScript. It can run subset of PHP in the browser or in Node.js. .
9394
- [php-unparser](https://github.com/chris-l/php-unparser) : Produce code that uses the style format recommended by PSR-1 and PSR-2.
9495
- [php-writer](https://github.com/glayzzle/php-writer) : Update PHP scripts from their AST
9596
- [ts-php-inspections](https://github.com/DaGhostman/ts-php-inspections) : Provide PHP code inspections written in typescript

src/parser/expr.js

+25
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,20 @@ module.exports = {
353353
if (this.is('VARIABLE')) {
354354
var result = this.node();
355355
expr = this.read_variable(false, false, false);
356+
357+
// https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L877
358+
// should accept only a variable
359+
var isConst = (
360+
expr.kind === 'constref' || (
361+
expr.kind === 'staticlookup' &&
362+
expr.offset.kind === 'constref'
363+
)
364+
);
365+
356366
// VARIABLES SPECIFIC OPERATIONS
357367
switch(this.token) {
358368
case '=':
369+
if (isConst) this.error('VARIABLE');
359370
var right;
360371
if (this.next().token == '&') {
361372
if (this.next().token === this.tok.T_NEW) {
@@ -370,45 +381,59 @@ module.exports = {
370381

371382
// operations :
372383
case this.tok.T_PLUS_EQUAL:
384+
if (isConst) this.error('VARIABLE');
373385
return result('assign', expr, this.next().read_expr(), '+=');
374386

375387
case this.tok.T_MINUS_EQUAL:
388+
if (isConst) this.error('VARIABLE');
376389
return result('assign', expr, this.next().read_expr(), '-=');
377390

378391
case this.tok.T_MUL_EQUAL:
392+
if (isConst) this.error('VARIABLE');
379393
return result('assign', expr, this.next().read_expr(), '*=');
380394

381395
case this.tok.T_POW_EQUAL:
396+
if (isConst) this.error('VARIABLE');
382397
return result('assign', expr, this.next().read_expr(), '**=');
383398

384399
case this.tok.T_DIV_EQUAL:
400+
if (isConst) this.error('VARIABLE');
385401
return result('assign', expr, this.next().read_expr(), '/=');
386402

387403
case this.tok.T_CONCAT_EQUAL:
404+
if (isConst) this.error('VARIABLE');
388405
return result('assign', expr, this.next().read_expr(), '.=');
389406

390407
case this.tok.T_MOD_EQUAL:
408+
if (isConst) this.error('VARIABLE');
391409
return result('assign', expr, this.next().read_expr(), '%=');
392410

393411
case this.tok.T_AND_EQUAL:
412+
if (isConst) this.error('VARIABLE');
394413
return result('assign', expr, this.next().read_expr(), '&=');
395414

396415
case this.tok.T_OR_EQUAL:
416+
if (isConst) this.error('VARIABLE');
397417
return result('assign', expr, this.next().read_expr(), '|=');
398418

399419
case this.tok.T_XOR_EQUAL:
420+
if (isConst) this.error('VARIABLE');
400421
return result('assign', expr, this.next().read_expr(), '^=');
401422

402423
case this.tok.T_SL_EQUAL:
424+
if (isConst) this.error('VARIABLE');
403425
return result('assign', expr, this.next().read_expr(), '<<=');
404426

405427
case this.tok.T_SR_EQUAL:
428+
if (isConst) this.error('VARIABLE');
406429
return result('assign',expr, this.next().read_expr(), '>>=');
407430

408431
case this.tok.T_INC:
432+
if (isConst) this.error('VARIABLE');
409433
this.next();
410434
return result('post', '+', expr);
411435
case this.tok.T_DEC:
436+
if (isConst) this.error('VARIABLE');
412437
this.next();
413438
return result('post', '-', expr);
414439
}

src/parser/statement.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -322,18 +322,19 @@ module.exports = {
322322
case this.tok.T_STRING:
323323
var current = [this.token, this.lexer.getState()];
324324
var label = this.text();
325+
// AST : https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L457
325326
if (this.next().token === ':') {
326327
var result = this.node('label');
327328
this.next();
328329
return result(label);
329-
} else {
330-
// default fallback expr
331-
this.lexer.tokens.push(current);
332-
var expr = this.next().read_expr();
333-
this.expect([';', this.tok.T_CLOSE_TAG]) && this.nextWithComments();
334-
return expr;
335330
}
336331

332+
// default fallback expr / T_STRING '::' (etc...)
333+
this.lexer.tokens.push(current);
334+
var expr = this.next().read_expr();
335+
this.expectEndOfStatement();
336+
return expr;
337+
337338
case this.tok.T_GOTO:
338339
var result = this.node('goto'), label = null;
339340
if (this.next().expect(this.tok.T_STRING)) {

test/exprTests.js

+27-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ describe('Test expressions', function() {
8787
'$a > 5 ? true : false;',
8888
'$a ?: false;'
8989
].join('\n'));
90-
console.log(ast.children[1]);
90+
//console.log(ast.children[1]);
9191
ast.children[1].kind.should.be.exactly('retif');
9292

9393
});
@@ -209,6 +209,32 @@ describe('Test expressions', function() {
209209
ast.children[3].type.should.be.exactly('-');
210210
});
211211

212+
it('should fail to assign constants', function() {
213+
var ast = parser.parseEval('a = 1;', {
214+
parser: { debug: false, suppressErrors: true }
215+
});
216+
var msg = 'Parse Error : syntax error, unexpected \'=\' on line 1';
217+
ast.errors.length.should.be.exactly(1);
218+
ast.errors[0].message.should.be.exactly(msg);
219+
});
220+
221+
it('should fail to assign class constants', function() {
222+
var ast = parser.parseEval('foo::b = 1;', {
223+
parser: { debug: false, suppressErrors: true }
224+
});
225+
var msg = 'Parse Error : syntax error, unexpected \'=\' on line 1';
226+
ast.errors.length.should.be.exactly(1);
227+
ast.errors[0].message.should.be.exactly(msg);
228+
});
229+
230+
it('should assign class static', function() {
231+
var ast = parser.parseEval('a::$b = 1;', {
232+
parser: { debug: false, suppressErrors: true }
233+
});
234+
ast.errors.length.should.be.exactly(0);
235+
ast.children[0].kind.should.be.exactly('assign');
236+
});
237+
212238
it('test new', function() {
213239
var ast = parser.parseEval([
214240
'$a = new \\foo();',

0 commit comments

Comments
 (0)