1
- /*! php-parser - BSD3 License - 2017-03-21 */
1
+ /*! php-parser - BSD3 License - 2017-07-10 */
2
2
3
3
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 ) {
4
4
// shim for using process in browser
@@ -485,9 +485,31 @@ var KIND = 'array';
485
485
/**
486
486
* Defines an array structure
487
487
* @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
+ * }
488
510
* @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()`
491
513
*/
492
514
var Array = Expr . extends ( function Array ( shortForm , items , location ) {
493
515
Expr . apply ( this , [ KIND , location ] ) ;
@@ -875,14 +897,16 @@ var KIND = 'closure';
875
897
* @property {boolean } byref
876
898
* @property {boolean } nullable
877
899
* @property {Block|null } body
900
+ * @property {boolean } isStatic
878
901
*/
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 ) {
880
903
Statement . apply ( this , [ KIND , location ] ) ;
881
904
this . uses = uses ;
882
905
this . arguments = args ;
883
906
this . byref = byref ;
884
907
this . type = type ;
885
908
this . nullable = nullable ;
909
+ this . isStatic = isStatic || false ;
886
910
this . body = null ;
887
911
} ) ;
888
912
@@ -1243,11 +1267,11 @@ var Node = require('./node');
1243
1267
var KIND = 'entry' ;
1244
1268
1245
1269
/**
1246
- * An array entry
1270
+ * An array entry - see [Array](#array)
1247
1271
* @constructor Entry
1248
1272
* @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
1251
1275
*/
1252
1276
var Entry = Node . extends ( function Entry ( key , value , location ) {
1253
1277
Node . apply ( this , [ KIND , location ] ) ;
@@ -2816,13 +2840,25 @@ var KIND = 'variable';
2816
2840
* be any expression in general, an expression can also be a pattern.
2817
2841
* @constructor Variable
2818
2842
* @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}`
2821
2856
*/
2822
- var Variable = Expr . extends ( function Variable ( name , byref , location ) {
2857
+ var Variable = Expr . extends ( function Variable ( name , byref , curly , location ) {
2823
2858
Expr . apply ( this , [ KIND , location ] ) ;
2824
2859
this . name = name ;
2825
2860
this . byref = byref || false ;
2861
+ this . curly = curly || false ;
2826
2862
} ) ;
2827
2863
2828
2864
module . exports = Variable ;
@@ -5883,9 +5919,20 @@ module.exports = {
5883
5919
return result ( expr ) ;
5884
5920
5885
5921
case this . tok . T_FUNCTION :
5886
- // @fixme later - removed static lambda function declarations (colides with static keyword usage)
5887
5922
return this . read_function ( true ) ;
5888
5923
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
+
5889
5936
}
5890
5937
5891
5938
// SCALAR | VARIABLE
@@ -6108,7 +6155,8 @@ module.exports = {
6108
6155
*/
6109
6156
, read_function : function ( closure , flag ) {
6110
6157
var result = this . read_function_declaration (
6111
- closure ? 1 : ( flag ? 2 : 0 )
6158
+ closure ? 1 : ( flag ? 2 : 0 ) ,
6159
+ flag && flag [ 1 ] === 1
6112
6160
) ;
6113
6161
if ( flag && flag [ 2 ] == 1 ) {
6114
6162
// abstract function :
@@ -6123,7 +6171,7 @@ module.exports = {
6123
6171
result . loc . end = result . body . loc . end ;
6124
6172
}
6125
6173
}
6126
- if ( flag ) {
6174
+ if ( ! closure && flag ) {
6127
6175
result . parseFlags ( flag ) ;
6128
6176
}
6129
6177
}
@@ -6135,14 +6183,15 @@ module.exports = {
6135
6183
* function_declaration ::= T_FUNCTION '&'? T_STRING '(' parameter_list ')'
6136
6184
* ```
6137
6185
*/
6138
- , read_function_declaration : function ( type ) {
6186
+ , read_function_declaration : function ( type , isStatic ) {
6139
6187
var nodeName = 'function' ;
6140
6188
if ( type === 1 ) {
6141
6189
nodeName = 'closure' ;
6142
6190
} else if ( type === 2 ) {
6143
6191
nodeName = 'method' ;
6144
6192
}
6145
6193
var result = this . node ( nodeName ) ;
6194
+
6146
6195
if ( this . expect ( this . tok . T_FUNCTION ) ) {
6147
6196
this . next ( ) ;
6148
6197
}
@@ -6171,7 +6220,7 @@ module.exports = {
6171
6220
}
6172
6221
if ( type === 1 ) {
6173
6222
// closure
6174
- return result ( params , isRef , use , returnType , nullable ) ;
6223
+ return result ( params , isRef , use , returnType , nullable , isStatic ) ;
6175
6224
}
6176
6225
return result ( name , params , isRef , returnType , nullable ) ;
6177
6226
}
@@ -6190,7 +6239,7 @@ module.exports = {
6190
6239
this . expect ( this . tok . T_VARIABLE ) ;
6191
6240
var name = this . text ( ) . substring ( 1 ) ;
6192
6241
this . next ( ) ;
6193
- return result ( name , isRef ) ;
6242
+ return result ( name , isRef , false ) ;
6194
6243
}
6195
6244
/**
6196
6245
* reads a list of parameters
@@ -6942,20 +6991,22 @@ module.exports = {
6942
6991
var varName = this . text ( ) ;
6943
6992
name = this . node ( 'variable' ) ;
6944
6993
this . next ( ) ;
6945
- name = name ( varName , false ) ;
6946
6994
// check if lookup an offset
6947
6995
// https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1243
6948
6996
if ( this . token === '[' ) {
6997
+ name = name ( varName , false ) ;
6949
6998
var node = this . node ( 'offsetlookup' ) ;
6950
6999
var offset = this . next ( ) . read_expr ( ) ;
6951
7000
this . expect ( ']' ) && this . next ( ) ;
6952
7001
name = node ( name , offset ) ;
7002
+ } else {
7003
+ name = varName ;
6953
7004
}
6954
7005
} else {
6955
7006
name = this . read_expr ( ) ;
6956
7007
}
6957
7008
this . expect ( '}' ) && this . next ( ) ;
6958
- result = result ( 'variable' , name , false ) ;
7009
+ result = result ( 'variable' , name , false , true ) ;
6959
7010
}
6960
7011
6961
7012
// expression
@@ -7284,6 +7335,9 @@ module.exports = {
7284
7335
this . expect ( ';' ) && this . nextWithComments ( ) ;
7285
7336
return expr ;
7286
7337
}
7338
+ if ( this . token === this . tok . T_FUNCTION ) {
7339
+ return this . read_function ( true , [ 0 , 1 , 0 ] ) ;
7340
+ }
7287
7341
var items = this . read_variable_declarations ( ) ;
7288
7342
this . expectEndOfStatement ( ) ;
7289
7343
return result ( items ) ;
@@ -7652,9 +7706,9 @@ module.exports = {
7652
7706
if ( this . expect ( this . tok . T_VARIABLE ) ) {
7653
7707
var name = this . text ( ) . substring ( 1 ) ;
7654
7708
this . next ( ) ;
7655
- variable = variable ( name , false ) ;
7709
+ variable = variable ( name , false , false ) ;
7656
7710
} else {
7657
- variable = variable ( '#ERR' , false ) ;
7711
+ variable = variable ( '#ERR' , false , false ) ;
7658
7712
}
7659
7713
if ( this . token === '=' ) {
7660
7714
return node ( variable , this . next ( ) . read_expr ( ) ) ;
@@ -7809,7 +7863,7 @@ module.exports = {
7809
7863
name = this . text ( ) . substring ( 1 ) ;
7810
7864
this . next ( ) ;
7811
7865
what = this . node ( 'encapsed' ) (
7812
- [ what , inner ( name , false ) ] ,
7866
+ [ what , inner ( name , false , false ) ] ,
7813
7867
'offset'
7814
7868
) ;
7815
7869
if ( what . loc && what . value [ 0 ] . loc ) {
@@ -7831,7 +7885,7 @@ module.exports = {
7831
7885
what = this . node ( 'variable' ) ;
7832
7886
var name = this . text ( ) . substring ( 1 ) ;
7833
7887
this . next ( ) ;
7834
- what = what ( name , false ) ;
7888
+ what = what ( name , false , false ) ;
7835
7889
break ;
7836
7890
case '$' :
7837
7891
this . next ( ) . expect ( [ '{' , this . tok . T_VARIABLE ] ) ;
@@ -7885,7 +7939,7 @@ module.exports = {
7885
7939
} else if ( this . token === this . tok . T_VARIABLE ) {
7886
7940
var name = this . text ( ) . substring ( 1 ) ;
7887
7941
this . next ( ) ;
7888
- offset = offset ( 'variable' , name , false ) ;
7942
+ offset = offset ( 'variable' , name , false , false ) ;
7889
7943
} else {
7890
7944
this . expect ( [
7891
7945
this . tok . T_STRING ,
@@ -7942,15 +7996,15 @@ module.exports = {
7942
7996
// plain variable name
7943
7997
var name = this . text ( ) . substring ( 1 ) ;
7944
7998
this . next ( ) ;
7945
- result = result ( name , byref ) ;
7999
+ result = result ( name , byref , false ) ;
7946
8000
} else {
7947
8001
if ( this . token === '$' ) this . next ( ) ;
7948
8002
// dynamic variable name
7949
8003
switch ( this . token ) {
7950
8004
case '{' :
7951
8005
var expr = this . next ( ) . read_expr ( ) ;
7952
8006
this . expect ( '}' ) && this . next ( ) ;
7953
- result = result ( expr , byref ) ;
8007
+ result = result ( expr , byref , true ) ;
7954
8008
break ;
7955
8009
case '$' : // $$$var
7956
8010
result = result ( this . read_simple_variable ( false ) , byref ) ;
@@ -7959,14 +8013,14 @@ module.exports = {
7959
8013
var name = this . text ( ) . substring ( 1 ) ;
7960
8014
var node = this . node ( 'variable' ) ;
7961
8015
this . next ( ) ;
7962
- result = result ( node ( name , false ) , byref ) ;
8016
+ result = result ( node ( name , false , false ) , byref , false ) ;
7963
8017
break ;
7964
8018
default :
7965
8019
this . error ( [ '{' , '$' , this . tok . T_VARIABLE ] ) ;
7966
8020
// graceful mode
7967
8021
var name = this . text ( ) ;
7968
8022
this . next ( ) ;
7969
- result = result ( name , byref ) ;
8023
+ result = result ( name , byref , false ) ;
7970
8024
}
7971
8025
}
7972
8026
return result ;
0 commit comments