Skip to content

Commit 5858dc8

Browse files
authored
Merge pull request glayzzle#74 from glayzzle/2.1.0
2.0.4
2 parents ba172a8 + 737ded3 commit 5858dc8

21 files changed

+371
-121
lines changed

RELEASE.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Releases
22

3+
## 2.0.4 : (2017-07-09)
4+
5+
- Fix AST errors on suppressErrors
6+
- Add curly boolean on variable node (for `${bar}` syntax)
7+
- Implement the static closure flag, ex: `$c = static function() {};`
8+
39
## 2.0.0 : (2017-03-04)
410

511
- Update AST for operators, unify bin/bool/coalesce nodes

dist/php-parser.js

+90-34
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*! php-parser - BSD3 License - 2017-03-04 */
1+
/*! php-parser - BSD3 License - 2017-07-10 */
22

33
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
44
// shim for using process in browser
@@ -366,7 +366,7 @@ AST.prototype.prepare = function(kind, parser) {
366366
if (out) { // shift with precedence
367367
result = out;
368368
}
369-
} else if (result.kind === 'unary') {
369+
} else if (result.kind === 'unary' && result.what) {
370370
var out = result.precedence(result.what);
371371
if (out) { // shift with precedence
372372
result = out;
@@ -485,9 +485,31 @@ var KIND = 'array';
485485
/**
486486
* Defines an array structure
487487
* @constructor Array
488+
* @example
489+
* // PHP code :
490+
* [1, 'foo' => 'bar', 3]
491+
*
492+
* // AST structure :
493+
* {
494+
* "kind": "array",
495+
* "shortForm": true
496+
* "items": [{
497+
* "kind": "entry",
498+
* "key": null,
499+
* "value": {"kind": "number", "value": "1"}
500+
* }, {
501+
* "kind": "entry",
502+
* "key": {"kind": "string", "value": "foo", "isDoubleQuote": false},
503+
* "value": {"kind": "string", "value": "bar", "isDoubleQuote": false}
504+
* }, {
505+
* "kind": "entry",
506+
* "key": null,
507+
* "value": {"kind": "number", "value": "3"}
508+
* }]
509+
* }
488510
* @extends {Expression}
489-
* @property {Entry[]} items
490-
* @property {boolean} shortForm
511+
* @property {Entry[]} items List of array items
512+
* @property {boolean} shortForm Indicate if the short array syntax is used, ex `[]` instead `array()`
491513
*/
492514
var Array = Expr.extends(function Array(shortForm, items, location) {
493515
Expr.apply(this, [KIND, location]);
@@ -875,14 +897,16 @@ var KIND = 'closure';
875897
* @property {boolean} byref
876898
* @property {boolean} nullable
877899
* @property {Block|null} body
900+
* @property {boolean} isStatic
878901
*/
879-
var Closure = Statement.extends(function Closure(args, byref, uses, type, nullable, location) {
902+
var Closure = Statement.extends(function Closure(args, byref, uses, type, nullable, isStatic, location) {
880903
Statement.apply(this, [KIND, location]);
881904
this.uses = uses;
882905
this.arguments = args;
883906
this.byref = byref;
884907
this.type = type;
885908
this.nullable = nullable;
909+
this.isStatic = isStatic || false;
886910
this.body = null;
887911
});
888912

@@ -1243,11 +1267,11 @@ var Node = require('./node');
12431267
var KIND = 'entry';
12441268

12451269
/**
1246-
* An array entry
1270+
* An array entry - see [Array](#array)
12471271
* @constructor Entry
12481272
* @extends {Node}
1249-
* @property {Node|null} key
1250-
* @property {Node} value
1273+
* @property {Node|null} key The entry key/offset
1274+
* @property {Node} value The entry value
12511275
*/
12521276
var Entry = Node.extends(function Entry(key, value, location) {
12531277
Node.apply(this, [KIND, location]);
@@ -2816,13 +2840,25 @@ var KIND = 'variable';
28162840
* be any expression in general, an expression can also be a pattern.
28172841
* @constructor Variable
28182842
* @extends {Expression}
2819-
* @property {String|Node} name
2820-
* @property {boolean} byref
2843+
* @example
2844+
* // PHP code :
2845+
* &$foo
2846+
* // AST output
2847+
* {
2848+
* "kind": "variable",
2849+
* "name": "foo",
2850+
* "byref": true,
2851+
* "curly": false
2852+
* }
2853+
* @property {String|Node} name The variable name (can be a complex expression when the name is resolved dynamically)
2854+
* @property {boolean} byref Indicate if the variable reference is used, ex `&$foo`
2855+
* @property {boolean} curly Indicate if the name is defined between curlies, ex `${foo}`
28212856
*/
2822-
var Variable = Expr.extends(function Variable(name, byref, location) {
2857+
var Variable = Expr.extends(function Variable(name, byref, curly, location) {
28232858
Expr.apply(this, [KIND, location]);
28242859
this.name = name;
28252860
this.byref = byref || false;
2861+
this.curly = curly || false;
28262862
});
28272863

28282864
module.exports = Variable;
@@ -5883,9 +5919,20 @@ module.exports = {
58835919
return result(expr);
58845920

58855921
case this.tok.T_FUNCTION:
5886-
// @fixme later - removed static lambda function declarations (colides with static keyword usage)
58875922
return this.read_function(true);
58885923

5924+
case this.tok.T_STATIC:
5925+
var backup = [this.token, this.lexer.getState()];
5926+
if (this.next().token === this.tok.T_FUNCTION) {
5927+
// handles static function
5928+
return this.read_function(true, [0, 1, 0]);
5929+
} else {
5930+
// rollback
5931+
this.lexer.tokens.push(backup);
5932+
this.next();
5933+
}
5934+
5935+
58895936
}
58905937

58915938
// SCALAR | VARIABLE
@@ -6108,7 +6155,8 @@ module.exports = {
61086155
*/
61096156
,read_function: function(closure, flag) {
61106157
var result = this.read_function_declaration(
6111-
closure ? 1 : (flag ? 2 : 0)
6158+
closure ? 1 : (flag ? 2 : 0),
6159+
flag && flag[1] === 1
61126160
);
61136161
if (flag && flag[2] == 1) {
61146162
// abstract function :
@@ -6123,7 +6171,7 @@ module.exports = {
61236171
result.loc.end = result.body.loc.end;
61246172
}
61256173
}
6126-
if (flag) {
6174+
if (!closure && flag) {
61276175
result.parseFlags(flag);
61286176
}
61296177
}
@@ -6135,14 +6183,15 @@ module.exports = {
61356183
* function_declaration ::= T_FUNCTION '&'? T_STRING '(' parameter_list ')'
61366184
* ```
61376185
*/
6138-
,read_function_declaration: function(type) {
6186+
,read_function_declaration: function(type, isStatic) {
61396187
var nodeName = 'function';
61406188
if (type === 1) {
61416189
nodeName = 'closure';
61426190
} else if (type === 2) {
61436191
nodeName = 'method';
61446192
}
61456193
var result = this.node(nodeName);
6194+
61466195
if (this.expect(this.tok.T_FUNCTION)) {
61476196
this.next();
61486197
}
@@ -6171,7 +6220,7 @@ module.exports = {
61716220
}
61726221
if (type === 1) {
61736222
// closure
6174-
return result(params, isRef, use, returnType, nullable);
6223+
return result(params, isRef, use, returnType, nullable, isStatic);
61756224
}
61766225
return result(name, params, isRef, returnType, nullable);
61776226
}
@@ -6190,7 +6239,7 @@ module.exports = {
61906239
this.expect(this.tok.T_VARIABLE);
61916240
var name = this.text().substring(1);
61926241
this.next();
6193-
return result(name, isRef);
6242+
return result(name, isRef, false);
61946243
}
61956244
/**
61966245
* reads a list of parameters
@@ -6259,11 +6308,13 @@ module.exports = {
62596308
if (this.token !== ')') {
62606309
while(this.token != this.EOF) {
62616310
var argument = this.read_argument_list();
6262-
result.push(argument);
6263-
if (argument.kind === 'variadic') {
6264-
wasVariadic = true;
6265-
} else if (wasVariadic) {
6266-
this.raiseError('Unexpected argument after a variadic argument');
6311+
if (argument) {
6312+
result.push(argument);
6313+
if (argument.kind === 'variadic') {
6314+
wasVariadic = true;
6315+
} else if (wasVariadic) {
6316+
this.raiseError('Unexpected argument after a variadic argument');
6317+
}
62676318
}
62686319
if (this.token === ',') {
62696320
this.next();
@@ -6693,7 +6744,7 @@ module.exports = {
66936744
if (this.token === ',') {
66946745
items = items.concat(this.next().read_use_declarations(false));
66956746
} else if (this.token === '{') {
6696-
name = items[0].name.name;
6747+
name = items[0].name;
66976748
items = this.next().read_use_declarations(type === null);
66986749
this.expect('}') && this.next();
66996750
}
@@ -6940,20 +6991,22 @@ module.exports = {
69406991
var varName = this.text();
69416992
name = this.node('variable');
69426993
this.next();
6943-
name = name(varName, false);
69446994
// check if lookup an offset
69456995
// https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1243
69466996
if (this.token === '[') {
6997+
name = name(varName, false);
69476998
var node = this.node('offsetlookup');
69486999
var offset = this.next().read_expr();
69497000
this.expect(']') && this.next();
69507001
name = node(name, offset);
7002+
} else {
7003+
name = varName;
69517004
}
69527005
} else {
69537006
name = this.read_expr();
69547007
}
69557008
this.expect('}') && this.next();
6956-
result = result('variable', name, false);
7009+
result = result('variable', name, false, true);
69577010
}
69587011

69597012
// expression
@@ -7282,6 +7335,9 @@ module.exports = {
72827335
this.expect(';') && this.nextWithComments();
72837336
return expr;
72847337
}
7338+
if (this.token === this.tok.T_FUNCTION) {
7339+
return this.read_function(true, [0, 1, 0]);
7340+
}
72857341
var items = this.read_variable_declarations();
72867342
this.expectEndOfStatement();
72877343
return result(items);
@@ -7650,9 +7706,9 @@ module.exports = {
76507706
if (this.expect(this.tok.T_VARIABLE)) {
76517707
var name = this.text().substring(1);
76527708
this.next();
7653-
variable = variable(name, false);
7709+
variable = variable(name, false, false);
76547710
} else {
7655-
variable = variable('#ERR', false);
7711+
variable = variable('#ERR', false, false);
76567712
}
76577713
if (this.token === '=') {
76587714
return node(variable, this.next().read_expr());
@@ -7807,7 +7863,7 @@ module.exports = {
78077863
name = this.text().substring(1);
78087864
this.next();
78097865
what = this.node('encapsed')(
7810-
[what, inner(name, false)],
7866+
[what, inner(name, false, false)],
78117867
'offset'
78127868
);
78137869
if (what.loc && what.value[0].loc) {
@@ -7829,7 +7885,7 @@ module.exports = {
78297885
what = this.node('variable');
78307886
var name = this.text().substring(1);
78317887
this.next();
7832-
what = what(name, false);
7888+
what = what(name, false, false);
78337889
break;
78347890
case '$':
78357891
this.next().expect(['{', this.tok.T_VARIABLE]);
@@ -7883,7 +7939,7 @@ module.exports = {
78837939
} else if (this.token === this.tok.T_VARIABLE) {
78847940
var name = this.text().substring(1);
78857941
this.next();
7886-
offset = offset('variable', name, false);
7942+
offset = offset('variable', name, false, false);
78877943
} else {
78887944
this.expect([
78897945
this.tok.T_STRING,
@@ -7940,15 +7996,15 @@ module.exports = {
79407996
// plain variable name
79417997
var name = this.text().substring(1);
79427998
this.next();
7943-
result = result(name, byref);
7999+
result = result(name, byref, false);
79448000
} else {
79458001
if (this.token === '$') this.next();
79468002
// dynamic variable name
79478003
switch(this.token) {
79488004
case '{':
79498005
var expr = this.next().read_expr();
79508006
this.expect('}') && this.next();
7951-
result = result(expr, byref);
8007+
result = result(expr, byref, true);
79528008
break;
79538009
case '$': // $$$var
79548010
result = result(this.read_simple_variable(false), byref);
@@ -7957,14 +8013,14 @@ module.exports = {
79578013
var name = this.text().substring(1);
79588014
var node = this.node('variable');
79598015
this.next();
7960-
result = result(node(name, false), byref);
8016+
result = result(node(name, false, false), byref, false);
79618017
break;
79628018
default:
79638019
this.error(['{', '$', this.tok.T_VARIABLE]);
79648020
// graceful mode
79658021
var name = this.text();
79668022
this.next();
7967-
result = result(name, byref);
8023+
result = result(name, byref, false);
79688024
}
79698025
}
79708026
return result;

0 commit comments

Comments
 (0)