1- /*! php-parser - BSD3 License - 2017-03-21 */
1+ /*! php-parser - BSD3 License - 2017-07-10 */
22
33require = ( 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
@@ -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 */
492514var 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');
12431267var 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 */
12521276var 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
28282864module . 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
@@ -6942,20 +6991,22 @@ module.exports = {
69426991 var varName = this . text ( ) ;
69436992 name = this . node ( 'variable' ) ;
69446993 this . next ( ) ;
6945- name = name ( varName , false ) ;
69466994 // check if lookup an offset
69476995 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1243
69486996 if ( this . token === '[' ) {
6997+ name = name ( varName , false ) ;
69496998 var node = this . node ( 'offsetlookup' ) ;
69506999 var offset = this . next ( ) . read_expr ( ) ;
69517000 this . expect ( ']' ) && this . next ( ) ;
69527001 name = node ( name , offset ) ;
7002+ } else {
7003+ name = varName ;
69537004 }
69547005 } else {
69557006 name = this . read_expr ( ) ;
69567007 }
69577008 this . expect ( '}' ) && this . next ( ) ;
6958- result = result ( 'variable' , name , false ) ;
7009+ result = result ( 'variable' , name , false , true ) ;
69597010 }
69607011
69617012 // expression
@@ -7284,6 +7335,9 @@ module.exports = {
72847335 this . expect ( ';' ) && this . nextWithComments ( ) ;
72857336 return expr ;
72867337 }
7338+ if ( this . token === this . tok . T_FUNCTION ) {
7339+ return this . read_function ( true , [ 0 , 1 , 0 ] ) ;
7340+ }
72877341 var items = this . read_variable_declarations ( ) ;
72887342 this . expectEndOfStatement ( ) ;
72897343 return result ( items ) ;
@@ -7652,9 +7706,9 @@ module.exports = {
76527706 if ( this . expect ( this . tok . T_VARIABLE ) ) {
76537707 var name = this . text ( ) . substring ( 1 ) ;
76547708 this . next ( ) ;
7655- variable = variable ( name , false ) ;
7709+ variable = variable ( name , false , false ) ;
76567710 } else {
7657- variable = variable ( '#ERR' , false ) ;
7711+ variable = variable ( '#ERR' , false , false ) ;
76587712 }
76597713 if ( this . token === '=' ) {
76607714 return node ( variable , this . next ( ) . read_expr ( ) ) ;
@@ -7809,7 +7863,7 @@ module.exports = {
78097863 name = this . text ( ) . substring ( 1 ) ;
78107864 this . next ( ) ;
78117865 what = this . node ( 'encapsed' ) (
7812- [ what , inner ( name , false ) ] ,
7866+ [ what , inner ( name , false , false ) ] ,
78137867 'offset'
78147868 ) ;
78157869 if ( what . loc && what . value [ 0 ] . loc ) {
@@ -7831,7 +7885,7 @@ module.exports = {
78317885 what = this . node ( 'variable' ) ;
78327886 var name = this . text ( ) . substring ( 1 ) ;
78337887 this . next ( ) ;
7834- what = what ( name , false ) ;
7888+ what = what ( name , false , false ) ;
78357889 break ;
78367890 case '$' :
78377891 this . next ( ) . expect ( [ '{' , this . tok . T_VARIABLE ] ) ;
@@ -7885,7 +7939,7 @@ module.exports = {
78857939 } else if ( this . token === this . tok . T_VARIABLE ) {
78867940 var name = this . text ( ) . substring ( 1 ) ;
78877941 this . next ( ) ;
7888- offset = offset ( 'variable' , name , false ) ;
7942+ offset = offset ( 'variable' , name , false , false ) ;
78897943 } else {
78907944 this . expect ( [
78917945 this . tok . T_STRING ,
@@ -7942,15 +7996,15 @@ module.exports = {
79427996 // plain variable name
79437997 var name = this . text ( ) . substring ( 1 ) ;
79447998 this . next ( ) ;
7945- result = result ( name , byref ) ;
7999+ result = result ( name , byref , false ) ;
79468000 } else {
79478001 if ( this . token === '$' ) this . next ( ) ;
79488002 // dynamic variable name
79498003 switch ( this . token ) {
79508004 case '{' :
79518005 var expr = this . next ( ) . read_expr ( ) ;
79528006 this . expect ( '}' ) && this . next ( ) ;
7953- result = result ( expr , byref ) ;
8007+ result = result ( expr , byref , true ) ;
79548008 break ;
79558009 case '$' : // $$$var
79568010 result = result ( this . read_simple_variable ( false ) , byref ) ;
@@ -7959,14 +8013,14 @@ module.exports = {
79598013 var name = this . text ( ) . substring ( 1 ) ;
79608014 var node = this . node ( 'variable' ) ;
79618015 this . next ( ) ;
7962- result = result ( node ( name , false ) , byref ) ;
8016+ result = result ( node ( name , false , false ) , byref , false ) ;
79638017 break ;
79648018 default :
79658019 this . error ( [ '{' , '$' , this . tok . T_VARIABLE ] ) ;
79668020 // graceful mode
79678021 var name = this . text ( ) ;
79688022 this . next ( ) ;
7969- result = result ( name , byref ) ;
8023+ result = result ( name , byref , false ) ;
79708024 }
79718025 }
79728026 return result ;
0 commit comments