PluginProbe
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts / 2.7.7
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts v2.7.7
2.7.7 2.7.6 2.7.5 2.7.4 trunk 1.3 2.0.4 2.0.6 2.1.91 2.2.4 2.2.7 2.2.9 2.3.1 2.3.10 2.4.10 2.4.2 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.6.0 2.6.1 2.7.0 All 28 releases
insert-php / admin / assets / js / codemirror / php-parser.js

php-parser.js in Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts 2.7.7, at admin/assets/js/codemirror/php-parser.js

8,676 lines 233.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*! php-parser - BSD3 License - 2017-11-01 */
2
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 /*!
5 * Determine if an object is a Buffer
6 *
7 * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
8 * @license MIT
9 */
10
11 // The _isBuffer check is for Safari 5-7 support, because it's missing
12 // Object.prototype.constructor. Remove this eventually
13 module.exports = function (obj) {
14 return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
15 }
16
17 function isBuffer (obj) {
18 return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
19 }
20
21 // For Node v0.10 support. Remove this eventually.
22 function isSlowBuffer (obj) {
23 return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
24 }
25
26 },{}],2:[function(require,module,exports){
27 // shim for using process in browser
28 var process = module.exports = {};
29
30 // cached from whatever global is present so that test runners that stub it
31 // don't break things. But we need to wrap it in a try catch in case it is
32 // wrapped in strict mode code which doesn't define any globals. It's inside a
33 // function because try/catches deoptimize in certain engines.
34
35 var cachedSetTimeout;
36 var cachedClearTimeout;
37
38 function defaultSetTimout() {
39 throw new Error('setTimeout has not been defined');
40 }
41 function defaultClearTimeout () {
42 throw new Error('clearTimeout has not been defined');
43 }
44 (function () {
45 try {
46 if (typeof setTimeout === 'function') {
47 cachedSetTimeout = setTimeout;
48 } else {
49 cachedSetTimeout = defaultSetTimout;
50 }
51 } catch (e) {
52 cachedSetTimeout = defaultSetTimout;
53 }
54 try {
55 if (typeof clearTimeout === 'function') {
56 cachedClearTimeout = clearTimeout;
57 } else {
58 cachedClearTimeout = defaultClearTimeout;
59 }
60 } catch (e) {
61 cachedClearTimeout = defaultClearTimeout;
62 }
63 } ())
64 function runTimeout(fun) {
65 if (cachedSetTimeout === setTimeout) {
66 //normal enviroments in sane situations
67 return setTimeout(fun, 0);
68 }
69 // if setTimeout wasn't available but was latter defined
70 if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
71 cachedSetTimeout = setTimeout;
72 return setTimeout(fun, 0);
73 }
74 try {
75 // when when somebody has screwed with setTimeout but no I.E. maddness
76 return cachedSetTimeout(fun, 0);
77 } catch(e){
78 try {
79 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
80 return cachedSetTimeout.call(null, fun, 0);
81 } catch(e){
82 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
83 return cachedSetTimeout.call(this, fun, 0);
84 }
85 }
86
87
88 }
89 function runClearTimeout(marker) {
90 if (cachedClearTimeout === clearTimeout) {
91 //normal enviroments in sane situations
92 return clearTimeout(marker);
93 }
94 // if clearTimeout wasn't available but was latter defined
95 if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
96 cachedClearTimeout = clearTimeout;
97 return clearTimeout(marker);
98 }
99 try {
100 // when when somebody has screwed with setTimeout but no I.E. maddness
101 return cachedClearTimeout(marker);
102 } catch (e){
103 try {
104 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
105 return cachedClearTimeout.call(null, marker);
106 } catch (e){
107 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
108 // Some versions of I.E. have different rules for clearTimeout vs setTimeout
109 return cachedClearTimeout.call(this, marker);
110 }
111 }
112
113
114
115 }
116 var queue = [];
117 var draining = false;
118 var currentQueue;
119 var queueIndex = -1;
120
121 function cleanUpNextTick() {
122 if (!draining || !currentQueue) {
123 return;
124 }
125 draining = false;
126 if (currentQueue.length) {
127 queue = currentQueue.concat(queue);
128 } else {
129 queueIndex = -1;
130 }
131 if (queue.length) {
132 drainQueue();
133 }
134 }
135
136 function drainQueue() {
137 if (draining) {
138 return;
139 }
140 var timeout = runTimeout(cleanUpNextTick);
141 draining = true;
142
143 var len = queue.length;
144 while(len) {
145 currentQueue = queue;
146 queue = [];
147 while (++queueIndex < len) {
148 if (currentQueue) {
149 currentQueue[queueIndex].run();
150 }
151 }
152 queueIndex = -1;
153 len = queue.length;
154 }
155 currentQueue = null;
156 draining = false;
157 runClearTimeout(timeout);
158 }
159
160 process.nextTick = function (fun) {
161 var args = new Array(arguments.length - 1);
162 if (arguments.length > 1) {
163 for (var i = 1; i < arguments.length; i++) {
164 args[i - 1] = arguments[i];
165 }
166 }
167 queue.push(new Item(fun, args));
168 if (queue.length === 1 && !draining) {
169 runTimeout(drainQueue);
170 }
171 };
172
173 // v8 likes predictible objects
174 function Item(fun, array) {
175 this.fun = fun;
176 this.array = array;
177 }
178 Item.prototype.run = function () {
179 this.fun.apply(null, this.array);
180 };
181 process.title = 'browser';
182 process.browser = true;
183 process.env = {};
184 process.argv = [];
185 process.version = ''; // empty string to avoid regexp issues
186 process.versions = {};
187
188 function noop() {}
189
190 process.on = noop;
191 process.addListener = noop;
192 process.once = noop;
193 process.off = noop;
194 process.removeListener = noop;
195 process.removeAllListeners = noop;
196 process.emit = noop;
197
198 process.binding = function (name) {
199 throw new Error('process.binding is not supported');
200 };
201
202 process.cwd = function () { return '/' };
203 process.chdir = function (dir) {
204 throw new Error('process.chdir is not supported');
205 };
206 process.umask = function() { return 0; };
207
208 },{}],3:[function(require,module,exports){
209 /*!
210 * Copyright (C) 2017 Glayzzle (BSD3 License)
211 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
212 * @url http://gla*yzzle.com
213 */
214
215 var Location = require('./ast/location');
216 var Position = require('./ast/position');
217
218 /**
219 * ## Class hierarchy
220 *
221 * - [Location](#location)
222 * - [Position](#position)
223 * - [Node](#node)
224 * - [Identifier](#identifier)
225 * - [TraitUse](#traituse)
226 * - [TraitAlias](#traitalias)
227 * - [TraitPrecedence](#traitprecedence)
228 * - [Entry](#entry)
229 * - [Case](#case)
230 * - [Label](#label)
231 * - [Doc](#doc)
232 * - [Error](#error)
233 * - [Expression](#expression)
234 * - [Array](#array)
235 * - [Variable](#variable)
236 * - [Variadic](#variadic)
237 * - [ConstRef](#constref)
238 * - [Yield](#yield)
239 * - [YieldFrom](#yieldfrom)
240 * - [Lookup](#lookup)
241 * - [PropertyLookup](#propertylookup)
242 * - [StaticLookup](#staticlookup)
243 * - [OffsetLookup](#offsetlookup)
244 * - [Operation](#operation)
245 * - [Pre](#pre)
246 * - [Post](#post)
247 * - [Bin](#bin)
248 * - [Parenthesis](#parenthesis)
249 * - [Unary](#unary)
250 * - [Cast](#cast)
251 * - [Literal](#literal)
252 * - [Boolean](#boolean)
253 * - [String](#string)
254 * - [Number](#number)
255 * - [Inline](#inline)
256 * - [Magic](#magic)
257 * - [Nowdoc](#nowdoc)
258 * - [Encapsed](#encapsed)
259 * - [Statement](#statement)
260 * - [Eval](#eval)
261 * - [Exit](#exit)
262 * - [Halt](#halt)
263 * - [Clone](#clone)
264 * - [Declare](#declare)
265 * - [Global](#global)
266 * - [Static](#static)
267 * - [Include](#include)
268 * - [Assign](#assign)
269 * - [RetIf](#retif)
270 * - [If](#if)
271 * - [Do](#do)
272 * - [While](#while)
273 * - [For](#for)
274 * - [Foreach](#foreach)
275 * - [Switch](#switch)
276 * - [Goto](#goto)
277 * - [Silent](#silent)
278 * - [Try](#try)
279 * - [Catch](#catch)
280 * - [Throw](#throw)
281 * - [Call](#call)
282 * - [Closure](#closure)
283 * - [New](#new)
284 * - [UseGroup](#usegroup)
285 * - [UseItem](#useitem)
286 * - [Block](#block)
287 * - [Program](#program)
288 * - [Namespace](#namespace)
289 * - [Sys](#sys)
290 * - [Echo](#echo)
291 * - [List](#list)
292 * - [Print](#print)
293 * - [Isset](#isset)
294 * - [Unset](#unset)
295 * - [Empty](#empty)
296 * - [Declaration](#declaration)
297 * - [Class](#class)
298 * - [Interface](#interface)
299 * - [Trait](#trait)
300 * - [Constant](#constant)
301 * - [ClassConstant](#classconstant)
302 * - [Function](#function)
303 * - [Method](#method)
304 * - [Parameter](#parameter)
305 * - [Property](#property)
306 * ---
307 */
308
309 /**
310 * The AST builder class
311 * @constructor AST
312 * @property {Boolean} withPositions - Should locate any node (by default false)
313 * @property {Boolean} withSource - Should extract the node original code (by default false)
314 */
315 var AST = function(withPositions, withSource) {
316 this.withPositions = withPositions;
317 this.withSource = withSource;
318 };
319
320 /**
321 * Create a position node from specified parser
322 * including it's lexer current state
323 * @param {Parser}
324 * @return {Position}
325 * @private
326 */
327 AST.prototype.position = function(parser) {
328 return new Position(
329 parser.lexer.yylloc.first_line,
330 parser.lexer.yylloc.first_column,
331 parser.lexer.yylloc.first_offset
332 );
333 };
334
335
336 // operators in ascending order of precedence
337 AST.precedence = {};
338 var binOperatorsPrecedence = [
339 ['or'],
340 ['xor'],
341 ['and'],
342 ['='],
343 ['?'],
344 ['??'],
345 ['||'],
346 ['&&'],
347 ['|'],
348 ['^'],
349 ['&'],
350 ['==', '!=', '===', '!==', /* '<>', */ '<=>'],
351 ['<', '<=', '>', '>='],
352 ['<<', '>>'],
353 ['+', '-', '.'],
354 ['*', '/', '%'],
355 ['!'],
356 ['instanceof'],
357 // TODO: typecasts
358 // TODO: [ (array)
359 // TODO: clone, new
360 ].forEach(function (list, index) {
361 list.forEach(function (operator) {
362 AST.precedence[operator] = index + 1;
363 });
364 });
365
366
367 /**
368 * Check and fix precence, by default using right
369 */
370 AST.prototype.resolvePrecedence = function(result) {
371 var buffer;
372 // handling precendence
373 if (result.kind === 'bin') {
374 if (result.right) {
375 if (result.right.kind === 'bin') {
376 var lLevel = AST.precedence[result.type];
377 var rLevel = AST.precedence[result.right.type];
378 if (lLevel && rLevel && rLevel <= lLevel) {
379 // https://github.com/glayzzle/php-parser/issues/79
380 // shift precedence
381 buffer = result.right;
382 result.right = result.right.left;
383 buffer.left = this.resolvePrecedence(result);
384 result = buffer;
385 }
386 } else if (result.right.kind === 'retif') {
387 var lLevel = AST.precedence[result.type];
388 var rLevel = AST.precedence['?'];
389 if (lLevel && rLevel && rLevel <= lLevel) {
390 buffer = result.right;
391 result.right = result.right.test;
392 buffer.test = this.resolvePrecedence(result);
393 result = buffer;
394 }
395 }
396 }
397 } else if (result.kind === 'unary') {
398 // https://github.com/glayzzle/php-parser/issues/75
399 if (result.what) {
400 // unary precedence is allways lower
401 if (result.what.kind === 'bin') {
402 buffer = result.what;
403 result.what = result.what.left;
404 buffer.left = this.resolvePrecedence(result);
405 result = buffer;
406 } else if (result.what.kind === 'retif') {
407 buffer = result.what;
408 result.what = result.what.test;
409 buffer.test = this.resolvePrecedence(result);
410 result = buffer;
411 }
412 }
413 } else if (result.kind === 'retif') {
414 // https://github.com/glayzzle/php-parser/issues/77
415 if (result.falseExpr && result.falseExpr.kind === 'retif') {
416 buffer = result.falseExpr;
417 result.falseExpr = buffer.test;
418 buffer.test = this.resolvePrecedence(result);
419 result = buffer;
420 }
421 } else if (result.kind === 'assign') {
422 // https://github.com/glayzzle/php-parser/issues/81
423 if (result.right && result.right.kind === 'bin') {
424 var lLevel = AST.precedence['='];
425 var rLevel = AST.precedence[result.right.type];
426 // only shifts with and, xor, or
427 if (lLevel && rLevel && rLevel < lLevel) {
428 buffer = result.right;
429 result.right = result.right.left;
430 buffer.left = result;
431 result = buffer;
432 }
433 }
434 }
435 return result;
436 };
437
438 /**
439 * Prepares an AST node
440 * @param {String|null} kind - Defines the node type
441 * (if null, the kind must be passed at the function call)
442 * @param {Parser} parser - The parser instance (use for extracting locations)
443 * @return {Function}
444 */
445 AST.prototype.prepare = function(kind, parser) {
446 var start = null;
447 if (this.withPositions || this.withSource) {
448 start = this.position(parser);
449 }
450 var self = this;
451 // returns the node
452 return function() {
453 var location = null;
454 var args = Array.prototype.slice.call(arguments);
455 if (self.withPositions || self.withSource) {
456 var src = null;
457 if (self.withSource) {
458 src = parser.lexer._input.substring(
459 start.offset,
460 parser.lexer.yylloc.prev_offset
461 );
462 }
463 if (self.withPositions) {
464 location = new Location(src, start, new Position(
465 parser.lexer.yylloc.prev_line,
466 parser.lexer.yylloc.prev_column,
467 parser.lexer.yylloc.prev_offset
468 ));
469 } else {
470 location = new Location(src, null, null);
471 }
472 // last argument is allways the location
473 args.push(location);
474 }
475 // handle lazy kind definitions
476 if (!kind) {
477 kind = args.shift();
478 }
479 // build the object
480 var node = self[kind];
481 if (typeof node !== 'function') {
482 throw new Error('Undefined node "'+kind+'"');
483 }
484 var result = Object.create(node.prototype);
485 node.apply(result, args);
486 return self.resolvePrecedence(result);
487 };
488 };
489
490 // Define all AST nodes
491 [
492 require('./ast/array'),
493 require('./ast/assign'),
494 require('./ast/bin'),
495 require('./ast/block'),
496 require('./ast/boolean'),
497 require('./ast/break'),
498 require('./ast/call'),
499 require('./ast/case'),
500 require('./ast/cast'),
501 require('./ast/catch'),
502 require('./ast/class'),
503 require('./ast/classconstant'),
504 require('./ast/clone'),
505 require('./ast/closure'),
506 require('./ast/constant'),
507 require('./ast/constref'),
508 require('./ast/continue'),
509 require('./ast/declaration'),
510 require('./ast/declare'),
511 require('./ast/do'),
512 require('./ast/doc'),
513 require('./ast/echo'),
514 require('./ast/empty'),
515 require('./ast/encapsed'),
516 require('./ast/entry'),
517 require('./ast/error'),
518 require('./ast/eval'),
519 require('./ast/exit'),
520 require('./ast/expression'),
521 require('./ast/for'),
522 require('./ast/foreach'),
523 require('./ast/function'),
524 require('./ast/global'),
525 require('./ast/goto'),
526 require('./ast/halt'),
527 require('./ast/identifier'),
528 require('./ast/if'),
529 require('./ast/include'),
530 require('./ast/inline'),
531 require('./ast/interface'),
532 require('./ast/isset'),
533 require('./ast/label'),
534 require('./ast/list'),
535 require('./ast/literal'),
536 require('./ast/lookup'),
537 require('./ast/magic'),
538 require('./ast/method'),
539 require('./ast/namespace'),
540 require('./ast/new'),
541 require('./ast/node'),
542 require('./ast/nowdoc'),
543 require('./ast/number'),
544 require('./ast/offsetlookup'),
545 require('./ast/operation'),
546 require('./ast/parameter'),
547 require('./ast/parenthesis'),
548 require('./ast/post'),
549 require('./ast/pre'),
550 require('./ast/print'),
551 require('./ast/program'),
552 require('./ast/property'),
553 require('./ast/propertylookup'),
554 require('./ast/retif'),
555 require('./ast/return'),
556 require('./ast/silent'),
557 require('./ast/statement'),
558 require('./ast/static'),
559 require('./ast/staticlookup'),
560 require('./ast/string'),
561 require('./ast/switch'),
562 require('./ast/sys'),
563 require('./ast/throw'),
564 require('./ast/trait'),
565 require('./ast/traitalias'),
566 require('./ast/traitprecedence'),
567 require('./ast/traituse'),
568 require('./ast/try'),
569 require('./ast/unary'),
570 require('./ast/unset'),
571 require('./ast/usegroup'),
572 require('./ast/useitem'),
573 require('./ast/variable'),
574 require('./ast/variadic'),
575 require('./ast/while'),
576 require('./ast/yield'),
577 require('./ast/yieldfrom')
578 ].forEach(function (ctor) {
579 var kind = ctor.prototype.constructor.name.toLowerCase();
580 if (kind[0] === '_') kind = kind.substring(1);
581 AST.prototype[kind] = ctor;
582 });
583
584 module.exports = AST;
585
586 },{"./ast/array":4,"./ast/assign":5,"./ast/bin":6,"./ast/block":7,"./ast/boolean":8,"./ast/break":9,"./ast/call":10,"./ast/case":11,"./ast/cast":12,"./ast/catch":13,"./ast/class":14,"./ast/classconstant":15,"./ast/clone":16,"./ast/closure":17,"./ast/constant":18,"./ast/constref":19,"./ast/continue":20,"./ast/declaration":21,"./ast/declare":22,"./ast/do":23,"./ast/doc":24,"./ast/echo":25,"./ast/empty":26,"./ast/encapsed":27,"./ast/entry":28,"./ast/error":29,"./ast/eval":30,"./ast/exit":31,"./ast/expression":32,"./ast/for":33,"./ast/foreach":34,"./ast/function":35,"./ast/global":36,"./ast/goto":37,"./ast/halt":38,"./ast/identifier":39,"./ast/if":40,"./ast/include":41,"./ast/inline":42,"./ast/interface":43,"./ast/isset":44,"./ast/label":45,"./ast/list":46,"./ast/literal":47,"./ast/location":48,"./ast/lookup":49,"./ast/magic":50,"./ast/method":51,"./ast/namespace":52,"./ast/new":53,"./ast/node":54,"./ast/nowdoc":55,"./ast/number":56,"./ast/offsetlookup":57,"./ast/operation":58,"./ast/parameter":59,"./ast/parenthesis":60,"./ast/position":61,"./ast/post":62,"./ast/pre":63,"./ast/print":64,"./ast/program":65,"./ast/property":66,"./ast/propertylookup":67,"./ast/retif":68,"./ast/return":69,"./ast/silent":70,"./ast/statement":71,"./ast/static":72,"./ast/staticlookup":73,"./ast/string":74,"./ast/switch":75,"./ast/sys":76,"./ast/throw":77,"./ast/trait":78,"./ast/traitalias":79,"./ast/traitprecedence":80,"./ast/traituse":81,"./ast/try":82,"./ast/unary":83,"./ast/unset":84,"./ast/usegroup":85,"./ast/useitem":86,"./ast/variable":87,"./ast/variadic":88,"./ast/while":89,"./ast/yield":90,"./ast/yieldfrom":91}],4:[function(require,module,exports){
587 /*!
588 * Copyright (C) 2017 Glayzzle (BSD3 License)
589 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
590 * @url http://glayzzle.com
591 */
592
593 var Expr = require('./expression');
594 var KIND = 'array';
595
596 /**
597 * Defines an array structure
598 * @constructor Array
599 * @example
600 * // PHP code :
601 * [1, 'foo' => 'bar', 3]
602 *
603 * // AST structure :
604 * {
605 * "kind": "array",
606 * "shortForm": true
607 * "items": [{
608 * "kind": "entry",
609 * "key": null,
610 * "value": {"kind": "number", "value": "1"}
611 * }, {
612 * "kind": "entry",
613 * "key": {"kind": "string", "value": "foo", "isDoubleQuote": false},
614 * "value": {"kind": "string", "value": "bar", "isDoubleQuote": false}
615 * }, {
616 * "kind": "entry",
617 * "key": null,
618 * "value": {"kind": "number", "value": "3"}
619 * }]
620 * }
621 * @extends {Expression}
622 * @property {Entry[]} items List of array items
623 * @property {boolean} shortForm Indicate if the short array syntax is used, ex `[]` instead `array()`
624 */
625 var Array = Expr.extends(function Array(shortForm, items, location) {
626 Expr.apply(this, [KIND, location]);
627 this.items = items;
628 this.shortForm = shortForm;
629 });
630
631 module.exports = Array;
632
633 },{"./expression":32}],5:[function(require,module,exports){
634 /*!
635 * Copyright (C) 2017 Glayzzle (BSD3 License)
636 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
637 * @url http://glayzzle.com
638 */
639
640 var Statement = require('./statement');
641 var KIND = 'assign';
642
643 /**
644 * Assigns a value to the specified target
645 * @constructor Assign
646 * @extends {Statement}
647 * @property {Expression} left
648 * @property {Expression} right
649 * @property {String} operator
650 */
651 var Assign = Statement.extends(function Assign(left, right, operator, location) {
652 Statement.apply(this, [KIND, location]);
653 this.operator = operator;
654 this.left = left;
655 this.right = right;
656 });
657
658 module.exports = Assign;
659
660 },{"./statement":71}],6:[function(require,module,exports){
661 /*!
662 * Copyright (C) 2017 Glayzzle (BSD3 License)
663 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
664 * @url http://glayzzle.com
665 */
666 "use strict";
667
668 var Operation = require('./operation');
669 var KIND = 'bin';
670 /**
671 * Binary operations
672 * @constructor Bin
673 * @extends {Operation}
674 * @property {String} type
675 * @property {Expression} left
676 * @property {Expression} right
677 */
678 var Bin = Operation.extends(function Bin(type, left, right, location) {
679 Operation.apply(this, [KIND, location]);
680 this.type = type;
681 this.left = left;
682 this.right = right;
683 });
684
685 module.exports = Bin;
686
687 },{"./operation":58}],7:[function(require,module,exports){
688 /*!
689 * Copyright (C) 2017 Glayzzle (BSD3 License)
690 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
691 * @url http://glayzzle.com
692 */
693
694 var Statement = require('./statement');
695 var KIND = 'block';
696
697 /**
698 * A block statement, i.e., a sequence of statements surrounded by braces.
699 * @constructor Block
700 * @extends {Statement}
701 * @property {Node[]} children
702 */
703 var Block = Statement.extends(function Block(kind, children, location) {
704 Statement.apply(this, [kind || KIND, location]);
705 this.children = children.filter(Boolean);
706 });
707
708 module.exports = Block;
709
710 },{"./statement":71}],8:[function(require,module,exports){
711 /*!
712 * Copyright (C) 2017 Glayzzle (BSD3 License)
713 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
714 * @url http://glayzzle.com
715 */
716
717 var Literal = require('./literal');
718 var KIND = 'boolean';
719
720 /**
721 * Defines a boolean value (true/false)
722 * @constructor Boolean
723 * @extends {Literal}
724 */
725 var Boolean = Literal.extends(function Boolean(value, location) {
726 Literal.apply(this, [KIND, value, location]);
727 });
728
729 module.exports = Boolean;
730
731 },{"./literal":47}],9:[function(require,module,exports){
732 /*!
733 * Copyright (C) 2017 Glayzzle (BSD3 License)
734 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
735 * @url http://glayzzle.com
736 */
737 "use strict";
738 var Node = require('./node');
739 var KIND = 'break';
740
741 /**
742 * A break statement
743 * @constructor Break
744 * @extends {Node}
745 * @property {Number|Null} level
746 */
747 var Break = Node.extends(function Break(level, location) {
748 Node.apply(this, [KIND, location]);
749 this.level = level;
750 });
751
752 module.exports = Break;
753
754 },{"./node":54}],10:[function(require,module,exports){
755 /*!
756 * Copyright (C) 2017 Glayzzle (BSD3 License)
757 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
758 * @url http://glayzzle.com
759 */
760 "use strict";
761
762 var Statement = require('./statement');
763 var KIND = 'call';
764
765 /**
766 * Executes a call statement
767 * @constructor Call
768 * @extends {Statement}
769 * @property {Identifier|Variable|??} what
770 * @property {Arguments[]} arguments
771 */
772 var Call = Statement.extends(function Call(what, args, location) {
773 Statement.apply(this, [KIND, location]);
774 this.what = what;
775 this.arguments = args;
776 });
777
778 module.exports = Call;
779
780 },{"./statement":71}],11:[function(require,module,exports){
781 /*!
782 * Copyright (C) 2017 Glayzzle (BSD3 License)
783 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
784 * @url http://glayzzle.com
785 */
786 "use strict";
787 var Node = require('./node');
788 var KIND = 'case';
789
790 /**
791 * A switch case statement
792 * @constructor Case
793 * @extends {Node}
794 * @property {Expression|null} test - if null, means that the default case
795 * @property {Block|null} body
796 */
797 var Case = Node.extends(function Case(test, body, location) {
798 Node.apply(this, [KIND, location]);
799 this.test = test;
800 this.body = body;
801 });
802
803 module.exports = Case;
804
805 },{"./node":54}],12:[function(require,module,exports){
806 /*!
807 * Copyright (C) 2017 Glayzzle (BSD3 License)
808 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
809 * @url http://glayzzle.com
810 */
811 "use strict";
812
813 var Operation = require('./operation');
814 var KIND = 'cast';
815
816 /**
817 * Binary operations
818 * @constructor Cast
819 * @extends {Operation}
820 * @property {String} type
821 * @property {Expression} what
822 */
823 var Cast = Operation.extends(function Cast(type, what, location) {
824 Operation.apply(this, [KIND, location]);
825 this.type = type;
826 this.what = what;
827 });
828
829 module.exports = Cast;
830
831 },{"./operation":58}],13:[function(require,module,exports){
832 /*!
833 * Copyright (C) 2017 Glayzzle (BSD3 License)
834 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
835 * @url http://glayzzle.com
836 */
837 "use strict";
838
839 var Statement = require('./statement');
840 var KIND = 'catch';
841
842 /**
843 * Defines a catch statement
844 * @constructor Catch
845 * @extends {Statement}
846 * @property {Identifier[]} what
847 * @property {Variable} variable
848 * @property {Statement} body
849 * @see http://php.net/manual/en/language.exceptions.php
850 */
851 var Catch = Statement.extends(function Catch(body, what, variable, location) {
852 Statement.apply(this, [KIND, location]);
853 this.body = body;
854 this.what = what;
855 this.variable = variable;
856 });
857
858 module.exports = Catch;
859
860 },{"./statement":71}],14:[function(require,module,exports){
861 /*!
862 * Copyright (C) 2017 Glayzzle (BSD3 License)
863 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
864 * @url http://glayzzle.com
865 */
866
867 var Declaration = require('./declaration');
868 var KIND = 'class';
869
870
871 /**
872 * A class definition
873 * @constructor Class
874 * @extends {Declaration}
875 * @property {Identifier|null} extends
876 * @property {Identifier[]} implements
877 * @property {Declaration[]} body
878 * @property {boolean} isAnonymous
879 * @property {boolean} isAbstract
880 * @property {boolean} isFinal
881 */
882 var Class = Declaration.extends(function Class(name, ext, impl, body, flags, location) {
883 Declaration.apply(this, [KIND, name, location]);
884 this.isAnonymous = name ? false : true;
885 this.extends = ext;
886 this.implements = impl;
887 this.body = body;
888 this.parseFlags(flags);
889 });
890
891 module.exports = Class;
892
893 },{"./declaration":21}],15:[function(require,module,exports){
894 /*!
895 * Copyright (C) 2017 Glayzzle (BSD3 License)
896 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
897 * @url http://glayzzle.com
898 */
899
900 var Constant = require('./constant');
901 var KIND = 'classconstant';
902
903 /**
904 * Defines a class/interface/trait constant
905 * @constructor ClassConstant
906 * @extends {Constant}
907 * @property {boolean} isStatic
908 * @property {string} visibility
909 */
910 var ClassConstant = Constant.extends(function ClassConstant(name, value, flags, location) {
911 Constant.apply(this, [name, value, location]);
912 this.kind = KIND;
913 this.parseFlags(flags);
914 });
915
916 module.exports = ClassConstant;
917
918 },{"./constant":18}],16:[function(require,module,exports){
919 /*!
920 * Copyright (C) 2017 Glayzzle (BSD3 License)
921 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
922 * @url http://glayzzle.com
923 */
924
925 var Statement = require('./statement');
926 var KIND = 'clone';
927
928 /**
929 * Defines a clone call
930 * @constructor Clone
931 * @extends {Statement}
932 * @property {Expression} what
933 */
934 var Clone = Statement.extends(function Clone(what, location) {
935 Statement.apply(this, [KIND, location]);
936 this.what = what;
937 });
938
939 module.exports = Clone;
940
941 },{"./statement":71}],17:[function(require,module,exports){
942 /*!
943 * Copyright (C) 2017 Glayzzle (BSD3 License)
944 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
945 * @url http://glayzzle.com
946 */
947 "use strict";
948 var Statement = require('./statement');
949 var KIND = 'closure';
950
951 /**
952 * Defines a closure
953 * @constructor Closure
954 * @extends {Statement}
955 * @property {Parameter[]} arguments
956 * @property {Variable[]} uses
957 * @property {Identifier} type
958 * @property {boolean} byref
959 * @property {boolean} nullable
960 * @property {Block|null} body
961 * @property {boolean} isStatic
962 */
963 var Closure = Statement.extends(function Closure(args, byref, uses, type, nullable, isStatic, location) {
964 Statement.apply(this, [KIND, location]);
965 this.uses = uses;
966 this.arguments = args;
967 this.byref = byref;
968 this.type = type;
969 this.nullable = nullable;
970 this.isStatic = isStatic || false;
971 this.body = null;
972 });
973
974 module.exports = Closure;
975
976 },{"./statement":71}],18:[function(require,module,exports){
977 /*!
978 * Copyright (C) 2017 Glayzzle (BSD3 License)
979 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
980 * @url http://glayzzle.com
981 */
982
983 var Declaration = require('./declaration');
984 var KIND = 'constant';
985
986 /**
987 * Defines a namespace constant
988 * @constructor Constant
989 * @extends {Declaration}
990 * @property {Node|null} value
991 */
992 var Constant = Declaration.extends(function Constant(name, value, location) {
993 Declaration.apply(this, [KIND, name, location]);
994 this.value = value;
995 });
996
997 module.exports = Constant;
998
999 },{"./declaration":21}],19:[function(require,module,exports){
1000 /*!
1001 * Copyright (C) 2017 Glayzzle (BSD3 License)
1002 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1003 * @url http://glayzzle.com
1004 */
1005
1006 var Expr = require('./expression');
1007 var KIND = 'constref';
1008
1009 /**
1010 * A constant reference
1011 * @constructor ConstRef
1012 * @extends {Expression}
1013 * @property {String|Node} name
1014 */
1015 var ConstRef = Expr.extends(function ConstRef(identifier, location) {
1016 Expr.apply(this, [KIND, location]);
1017 this.name = identifier;
1018 });
1019
1020 module.exports = ConstRef;
1021
1022 },{"./expression":32}],20:[function(require,module,exports){
1023 /*!
1024 * Copyright (C) 2017 Glayzzle (BSD3 License)
1025 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1026 * @url http://glayzzle.com
1027 */
1028 "use strict";
1029 var Node = require('./node');
1030 var KIND = 'continue';
1031
1032 /**
1033 * A continue statement
1034 * @constructor Continue
1035 * @extends {Node}
1036 * @property {Number|Null} level
1037 */
1038 var Continue = Node.extends(function Continue(level, location) {
1039 Node.apply(this, [KIND, location]);
1040 this.level = level;
1041 });
1042
1043 module.exports = Continue;
1044
1045 },{"./node":54}],21:[function(require,module,exports){
1046 /*!
1047 * Copyright (C) 2017 Glayzzle (BSD3 License)
1048 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1049 * @url http://glayzzle.com
1050 */
1051
1052 var Statement = require('./statement');
1053 var KIND = 'declaration';
1054
1055 var IS_PUBLIC = 'public';
1056 var IS_PROTECTED = 'protected';
1057 var IS_PRIVATE = 'private';
1058
1059 /**
1060 * A declaration statement (function, class, interface...)
1061 * @constructor Declaration
1062 * @extends {Statement}
1063 * @property {string} name
1064 */
1065 var Declaration = Statement.extends(function Declaration(kind, name, location) {
1066 Statement.apply(this, [kind || KIND, location]);
1067 this.name = name;
1068 });
1069
1070 /**
1071 * Generic flags parser
1072 * @param {Integer[]} flags
1073 * @return {void}
1074 */
1075 Declaration.prototype.parseFlags = function(flags) {
1076 this.isAbstract = flags[2] === 1;
1077 this.isFinal = flags[2] === 2;
1078 if (this.kind !== 'class') {
1079 if (flags[0] === 0) {
1080 this.visibility = IS_PUBLIC;
1081 } else if (flags[0] === 1) {
1082 this.visibility = IS_PROTECTED;
1083 } else if (flags[0] === 2) {
1084 this.visibility = IS_PRIVATE;
1085 }
1086 this.isStatic = flags[1] === 1;
1087 }
1088 };
1089
1090 module.exports = Declaration;
1091
1092 },{"./statement":71}],22:[function(require,module,exports){
1093 /*!
1094 * Copyright (C) 2017 Glayzzle (BSD3 License)
1095 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1096 * @url http://glayzzle.com
1097 */
1098
1099 var Block = require('./block');
1100 var KIND = 'declare';
1101
1102 /**
1103 * The declare construct is used to set execution directives for a block of code
1104 * @constructor Declare
1105 * @extends {Block}
1106 * @property {Expression[]} what
1107 * @property {String} mode
1108 * @see http://php.net/manual/en/control-structures.declare.php
1109 */
1110 var Declare = Block.extends(function Declare(what, body, mode, location) {
1111 Block.apply(this, [KIND, body, location]);
1112 this.what = what;
1113 this.mode = mode;
1114 });
1115
1116
1117 /**
1118 * The node is declared as a short tag syntax :
1119 * ```php
1120 * <?php
1121 * declare(ticks=1):
1122 * // some statements
1123 * enddeclare;
1124 * ```
1125 * @constant {String} MODE_SHORT
1126 */
1127 Declare.MODE_SHORT = 'short';
1128
1129 /**
1130 * The node is declared bracket enclosed code :
1131 * ```php
1132 * <?php
1133 * declare(ticks=1) {
1134 * // some statements
1135 * }
1136 * ```
1137 * @constant {String} MODE_BLOCK
1138 */
1139 Declare.MODE_BLOCK = 'block';
1140
1141 /**
1142 * The node is declared as a simple statement. In order to make things simpler
1143 * children of the node are automatically collected until the next
1144 * declare statement.
1145 * ```php
1146 * <?php
1147 * declare(ticks=1);
1148 * // some statements
1149 * declare(ticks=2);
1150 * // some statements
1151 * ```
1152 * @constant {String} MODE_NONE
1153 */
1154 Declare.MODE_NONE = 'none';
1155
1156 module.exports = Declare;
1157
1158 },{"./block":7}],23:[function(require,module,exports){
1159 /*!
1160 * Copyright (C) 2017 Glayzzle (BSD3 License)
1161 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1162 * @url http://glayzzle.com
1163 */
1164 "use strict";
1165
1166 var Statement = require('./statement');
1167 var KIND = 'do';
1168
1169 /**
1170 * Defines a do/while statement
1171 * @constructor Do
1172 * @extends {Statement}
1173 * @property {Expression} test
1174 * @property {Statement} body
1175 */
1176 var Do = Statement.extends(function Do(test, body, location) {
1177 Statement.apply(this, [KIND, location]);
1178 this.test = test;
1179 this.body = body;
1180 });
1181
1182 module.exports = Do;
1183
1184 },{"./statement":71}],24:[function(require,module,exports){
1185 /*!
1186 * Copyright (C) 2017 Glayzzle (BSD3 License)
1187 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1188 * @url http://glayzzle.com
1189 */
1190
1191 var Node = require('./node');
1192 var KIND = 'doc';
1193
1194 /**
1195 * A comment or documentation
1196 * @constructor Documentation
1197 * @extends {Node}
1198 * @property {Boolean} isDoc
1199 * @property {String[]} lines
1200 */
1201 var Doc = Node.extends(function Doc(isDoc, lines, location) {
1202 Node.apply(this, [KIND, location]);
1203 this.isDoc = isDoc;
1204 this.lines = lines;
1205 });
1206
1207 module.exports = Doc;
1208
1209 },{"./node":54}],25:[function(require,module,exports){
1210 /*!
1211 * Copyright (C) 2017 Glayzzle (BSD3 License)
1212 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1213 * @url http://glayzzle.com
1214 */
1215
1216 var Sys = require('./sys');
1217 var KIND = 'echo';
1218
1219 /**
1220 * Defines system based call
1221 * @constructor Echo
1222 * @extends {Sys}
1223 */
1224 var Echo = Sys.extends(function Echo(args, location) {
1225 Sys.apply(this, [KIND, args, location]);
1226 });
1227
1228 module.exports = Echo;
1229
1230 },{"./sys":76}],26:[function(require,module,exports){
1231 /*!
1232 * Copyright (C) 2017 Glayzzle (BSD3 License)
1233 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1234 * @url http://glayzzle.com
1235 */
1236
1237 var Sys = require('./sys');
1238 var KIND = 'empty';
1239
1240 /**
1241 * Defines an empty check call
1242 * @constructor Empty
1243 * @extends {Sys}
1244 */
1245 var Empty = Sys.extends(function Empty(args, location) {
1246 Sys.apply(this, [KIND, args, location]);
1247 });
1248
1249 module.exports = Empty;
1250
1251 },{"./sys":76}],27:[function(require,module,exports){
1252 /*!
1253 * Copyright (C) 2017 Glayzzle (BSD3 License)
1254 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1255 * @url http://glayzzle.com
1256 */
1257
1258 var Literal = require('./literal');
1259 var KIND = 'encapsed';
1260
1261 /**
1262 * Defines an encapsed string (contains expressions)
1263 * @constructor Encapsed
1264 * @extends {Literal}
1265 * @property {String} type - Defines the type of encapsed string (shell, heredoc, string)
1266 * @property {String|Null} label - The heredoc label, defined only when the type is heredoc
1267 */
1268 var Encapsed = Literal.extends(function Encapsed(value, type, location) {
1269 Literal.apply(this, [KIND, value, location]);
1270 this.type = type;
1271 });
1272
1273
1274 /**
1275 * The node is a double quote string :
1276 * ```php
1277 * <?php
1278 * echo "hello $world";
1279 * ```
1280 * @constant {String} TYPE_STRING - `string`
1281 */
1282 Encapsed.TYPE_STRING = 'string';
1283
1284 /**
1285 * The node is a shell execute string :
1286 * ```php
1287 * <?php
1288 * echo `ls -larth $path`;
1289 * ```
1290 * @constant {String} TYPE_SHELL - `shell`
1291 */
1292 Encapsed.TYPE_SHELL = 'shell';
1293
1294 /**
1295 * The node is a shell execute string :
1296 * ```php
1297 * <?php
1298 * echo <<<STR
1299 * Hello $world
1300 * STR
1301 * ;
1302 * ```
1303 * @constant {String} TYPE_HEREDOC - `heredoc`
1304 */
1305 Encapsed.TYPE_HEREDOC = 'heredoc';
1306
1307 /**
1308 * The node contains a list of constref / variables / expr :
1309 * ```php
1310 * <?php
1311 * echo $foo->bar_$baz;
1312 * ```
1313 * @constant {String} TYPE_OFFSET - `offset`
1314 */
1315 Encapsed.TYPE_OFFSET = 'offset';
1316
1317
1318 module.exports = Encapsed;
1319
1320 },{"./literal":47}],28:[function(require,module,exports){
1321 /*!
1322 * Copyright (C) 2017 Glayzzle (BSD3 License)
1323 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1324 * @url http://glayzzle.com
1325 */
1326
1327 var Node = require('./node');
1328 var KIND = 'entry';
1329
1330 /**
1331 * An array entry - see [Array](#array)
1332 * @constructor Entry
1333 * @extends {Node}
1334 * @property {Node|null} key The entry key/offset
1335 * @property {Node} value The entry value
1336 */
1337 var Entry = Node.extends(function Entry(key, value, location) {
1338 Node.apply(this, [KIND, location]);
1339 this.key = key;
1340 this.value = value;
1341 });
1342
1343 module.exports = Entry;
1344
1345 },{"./node":54}],29:[function(require,module,exports){
1346 /*!
1347 * Copyright (C) 2017 Glayzzle (BSD3 License)
1348 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1349 * @url http://glayzzle.com
1350 */
1351
1352 var Node = require('./node');
1353 var KIND = 'error';
1354
1355
1356 /**
1357 * Defines an error node (used only on silentMode)
1358 * @constructor Error
1359 * @extends {Node}
1360 * @property {string} message
1361 * @property {number} line
1362 * @property {number|string} token
1363 * @property {string|array} expected
1364 */
1365 var Error = Node.extends(function Error(message, token, line, expected, location) {
1366 Node.apply(this, [KIND, location]);
1367 this.message = message;
1368 this.token = token;
1369 this.line = line;
1370 this.expected = expected;
1371 });
1372
1373 module.exports = Error;
1374
1375 },{"./node":54}],30:[function(require,module,exports){
1376 /*!
1377 * Copyright (C) 2017 Glayzzle (BSD3 License)
1378 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1379 * @url http://glayzzle.com
1380 */
1381
1382 var Statement = require('./statement');
1383 var KIND = 'eval';
1384
1385 /**
1386 * Defines an eval statement
1387 * @constructor Eval
1388 * @extends {Statement}
1389 * @property {Node} source
1390 */
1391 var Eval = Statement.extends(function Eval(source, location) {
1392 Statement.apply(this, [KIND, location]);
1393 this.source = source;
1394 });
1395
1396 module.exports = Eval;
1397
1398 },{"./statement":71}],31:[function(require,module,exports){
1399 /*!
1400 * Copyright (C) 2017 Glayzzle (BSD3 License)
1401 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1402 * @url http://glayzzle.com
1403 */
1404
1405 var Statement = require('./statement');
1406 var KIND = 'exit';
1407
1408 /**
1409 * Defines an exit / die call
1410 * @constructor Exit
1411 * @extends {Statement}
1412 * @property {Node|null} status
1413 */
1414 var Exit = Statement.extends(function Exit(status, location) {
1415 Statement.apply(this, [KIND, location]);
1416 this.status = status;
1417 });
1418
1419 module.exports = Exit;
1420
1421 },{"./statement":71}],32:[function(require,module,exports){
1422 /*!
1423 * Copyright (C) 2017 Glayzzle (BSD3 License)
1424 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1425 * @url http://glayzzle.com
1426 */
1427
1428 var Node = require('./node');
1429 var KIND = 'expression';
1430
1431 /**
1432 * Any expression node. Since the left-hand side of an assignment may
1433 * be any expression in general, an expression can also be a pattern.
1434 * @constructor Expression
1435 * @extends {Node}
1436 */
1437 var Expression = Node.extends(function Expression(kind, location) {
1438 Node.apply(this, [kind || KIND, location]);
1439 });
1440
1441 module.exports = Expression;
1442
1443 },{"./node":54}],33:[function(require,module,exports){
1444 /*!
1445 * Copyright (C) 2017 Glayzzle (BSD3 License)
1446 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1447 * @url http://glayzzle.com
1448 */
1449 "use strict";
1450
1451 var Statement = require('./statement');
1452 var KIND = 'for';
1453
1454 /**
1455 * Defines a for iterator
1456 * @constructor For
1457 * @extends {Statement}
1458 * @property {Expression[]} init
1459 * @property {Expression[]} test
1460 * @property {Expression[]} increment
1461 * @property {Statement} body
1462 * @property {boolean} shortForm
1463 * @see http://php.net/manual/en/control-structures.for.php
1464 */
1465 var For = Statement.extends(function For(init, test, increment, body, shortForm, location) {
1466 Statement.apply(this, [KIND, location]);
1467 this.init = init;
1468 this.test = test;
1469 this.increment = increment;
1470 this.shortForm = shortForm;
1471 this.body = body;
1472 });
1473
1474 module.exports = For;
1475
1476 },{"./statement":71}],34:[function(require,module,exports){
1477 /*!
1478 * Copyright (C) 2017 Glayzzle (BSD3 License)
1479 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1480 * @url http://glayzzle.com
1481 */
1482 "use strict";
1483
1484 var Statement = require('./statement');
1485 var KIND = 'foreach';
1486
1487 /**
1488 * Defines a foreach iterator
1489 * @constructor Foreach
1490 * @extends {Statement}
1491 * @property {Expression} source
1492 * @property {Expression|null} key
1493 * @property {Expression} value
1494 * @property {Statement} body
1495 * @property {boolean} shortForm
1496 * @see http://php.net/manual/en/control-structures.foreach.php
1497 */
1498 var Foreach = Statement.extends(function Foreach(source, key, value, body, shortForm, location) {
1499 Statement.apply(this, [KIND, location]);
1500 this.source = source;
1501 this.key = key;
1502 this.value = value;
1503 this.shortForm = shortForm;
1504 this.body = body;
1505 });
1506
1507 module.exports = Foreach;
1508
1509 },{"./statement":71}],35:[function(require,module,exports){
1510 /*!
1511 * Copyright (C) 2017 Glayzzle (BSD3 License)
1512 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1513 * @url http://glayzzle.com
1514 */
1515
1516 var Declaration = require('./declaration');
1517 var KIND = 'function';
1518
1519 /**
1520 * Defines a classic function
1521 * @constructor Function
1522 * @extends {Declaration}
1523 * @property {Parameter[]} arguments
1524 * @property {Identifier} type
1525 * @property {boolean} byref
1526 * @property {boolean} nullable
1527 * @property {Block|null} body
1528 */
1529 var fn = Declaration.extends(function _Function(name, args, byref, type, nullable, location) {
1530 Declaration.apply(this, [KIND, name, location]);
1531 this.arguments = args;
1532 this.byref = byref;
1533 this.type = type;
1534 this.nullable = nullable;
1535 this.body = null;
1536 });
1537 module.exports = fn;
1538
1539 },{"./declaration":21}],36:[function(require,module,exports){
1540 /*!
1541 * Copyright (C) 2017 Glayzzle (BSD3 License)
1542 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1543 * @url http://glayzzle.com
1544 */
1545 "use strict";
1546 var Statement = require('./statement');
1547 var KIND = 'global';
1548
1549 /**
1550 * Imports a variable from the global scope
1551 * @constructor Global
1552 * @extends {Statement}
1553 * @property {Variable[]} items
1554 */
1555 var Global = Statement.extends(function Global(items, location) {
1556 Statement.apply(this, [KIND, location]);
1557 this.items = items;
1558 });
1559
1560 module.exports = Global;
1561
1562 },{"./statement":71}],37:[function(require,module,exports){
1563 /*!
1564 * Copyright (C) 2017 Glayzzle (BSD3 License)
1565 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1566 * @url http://glayzzle.com
1567 */
1568 "use strict";
1569
1570 var Statement = require('./statement');
1571 var KIND = 'goto';
1572
1573 /**
1574 * Defines goto statement
1575 * @constructor Goto
1576 * @extends {Statement}
1577 * @property {String} label
1578 * @see {Label}
1579 */
1580 var Goto = Statement.extends(function Goto(label, location) {
1581 Statement.apply(this, [KIND, location]);
1582 this.label = label;
1583 });
1584
1585 module.exports = Goto;
1586
1587 },{"./statement":71}],38:[function(require,module,exports){
1588 /*!
1589 * Copyright (C) 2017 Glayzzle (BSD3 License)
1590 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1591 * @url http://glayzzle.com
1592 */
1593 "use strict";
1594
1595 var Statement = require('./statement');
1596 var KIND = 'halt';
1597
1598 /**
1599 * Halts the compiler execution
1600 * @constructor Halt
1601 * @extends {Statement}
1602 * @property {String} after - String after the halt statement
1603 * @see http://php.net/manual/en/function.halt-compiler.php
1604 */
1605 var Halt = Statement.extends(function Halt(after, location) {
1606 Statement.apply(this, [KIND, location]);
1607 this.after = after;
1608 });
1609
1610 module.exports = Halt;
1611
1612 },{"./statement":71}],39:[function(require,module,exports){
1613 /*!
1614 * Copyright (C) 2017 Glayzzle (BSD3 License)
1615 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1616 * @url http://glayzzle.com
1617 */
1618
1619 var Node = require('./node');
1620 var KIND = 'identifier';
1621
1622 /**
1623 * Defines an identifier node
1624 * @constructor Identifier
1625 * @extends {Node}
1626 * @property {string} name
1627 * @property {string} resolution
1628 */
1629 var Identifier = Node.extends(function Identifier(name, isRelative, location) {
1630 Node.apply(this, [KIND, location]);
1631 if (isRelative) {
1632 this.resolution = Identifier.RELATIVE_NAME;
1633 } else if (name.length === 1) {
1634 this.resolution = Identifier.UNQUALIFIED_NAME;
1635 } else if (name[0] === '') {
1636 this.resolution = Identifier.FULL_QUALIFIED_NAME;
1637 } else {
1638 this.resolution = Identifier.QUALIFIED_NAME;
1639 }
1640 this.name = name.join('\\');
1641 });
1642
1643 /**
1644 * This is an identifier without a namespace separator, such as Foo
1645 * @constant {String} UNQUALIFIED_NAME
1646 */
1647 Identifier.UNQUALIFIED_NAME = 'uqn';
1648 /**
1649 * This is an identifier with a namespace separator, such as Foo\Bar
1650 * @constant {String} QUALIFIED_NAME
1651 */
1652 Identifier.QUALIFIED_NAME = 'qn';
1653 /**
1654 * This is an identifier with a namespace separator that begins with
1655 * a namespace separator, such as \Foo\Bar. The namespace \Foo is also
1656 * a fully qualified name.
1657 * @constant {String} FULL_QUALIFIED_NAME
1658 */
1659 Identifier.FULL_QUALIFIED_NAME = 'fqn';
1660 /**
1661 * This is an identifier starting with namespace, such as namespace\Foo\Bar.
1662 * @constant {String} RELATIVE_NAME
1663 */
1664 Identifier.RELATIVE_NAME = 'rn';
1665
1666
1667 module.exports = Identifier;
1668
1669 },{"./node":54}],40:[function(require,module,exports){
1670 /*!
1671 * Copyright (C) 2017 Glayzzle (BSD3 License)
1672 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1673 * @url http://glayzzle.com
1674 */
1675 "use strict";
1676
1677 var Statement = require('./statement');
1678 var KIND = 'if';
1679
1680 /**
1681 * Defines a if statement
1682 * @constructor If
1683 * @extends {Statement}
1684 * @property {Expression} test
1685 * @property {Block} body
1686 * @property {Block|If|null} alternate
1687 * @property {boolean} shortForm
1688 */
1689 var If = Statement.extends(function If(test, body, alternate, shortForm, location) {
1690 Statement.apply(this, [KIND, location]);
1691 this.test = test;
1692 this.body = body;
1693 this.alternate = alternate;
1694 this.shortForm = shortForm;
1695 });
1696
1697 module.exports = If;
1698
1699 },{"./statement":71}],41:[function(require,module,exports){
1700 /*!
1701 * Copyright (C) 2017 Glayzzle (BSD3 License)
1702 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1703 * @url http://glayzzle.com
1704 */
1705
1706 var Statement = require('./statement');
1707 var KIND = 'include';
1708
1709 /**
1710 * Defines system include call
1711 * @constructor Include
1712 * @extends {Statement}
1713 * @property {Node} target
1714 * @property {boolean} once
1715 * @property {boolean} require
1716 */
1717 var Include = Statement.extends(function Include(once, require, target, location) {
1718 Statement.apply(this, [KIND, location]);
1719 this.once = once;
1720 this.require = require;
1721 this.target = target;
1722 });
1723
1724 module.exports = Include;
1725
1726 },{"./statement":71}],42:[function(require,module,exports){
1727 /*!
1728 * Copyright (C) 2017 Glayzzle (BSD3 License)
1729 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1730 * @url http://glayzzle.com
1731 */
1732
1733 var Literal = require('./literal');
1734 var KIND = 'inline';
1735
1736 /**
1737 * Defines inline html output (treated as echo output)
1738 * @constructor Inline
1739 * @extends {Literal}
1740 */
1741 var Inline = Literal.extends(function Inline(value, location) {
1742 Literal.apply(this, [KIND, value, location]);
1743 });
1744
1745 module.exports = Inline;
1746
1747 },{"./literal":47}],43:[function(require,module,exports){
1748 /*!
1749 * Copyright (C) 2017 Glayzzle (BSD3 License)
1750 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1751 * @url http://glayzzle.com
1752 */
1753
1754 var Declaration = require('./declaration');
1755 var KIND = 'interface';
1756
1757
1758 /**
1759 * An interface definition
1760 * @constructor Interface
1761 * @extends {Declaration}
1762 * @property {Identifier[]} extends
1763 * @property {Declaration[]} body
1764 */
1765 var Interface = Declaration.extends(function Interface(name, ext, body, location) {
1766 Declaration.apply(this, [KIND, name, location]);
1767 this.extends = ext;
1768 this.body = body;
1769 });
1770
1771 module.exports = Interface;
1772
1773 },{"./declaration":21}],44:[function(require,module,exports){
1774 /*!
1775 * Copyright (C) 2017 Glayzzle (BSD3 License)
1776 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1777 * @url http://glayzzle.com
1778 */
1779
1780 var Sys = require('./sys');
1781 var KIND = 'isset';
1782
1783 /**
1784 * Defines an isset call
1785 * @constructor Isset
1786 * @extends {Sys}
1787 */
1788 var Isset = Sys.extends(function Isset(args, location) {
1789 Sys.apply(this, [KIND, args, location]);
1790 });
1791
1792 module.exports = Isset;
1793
1794 },{"./sys":76}],45:[function(require,module,exports){
1795 /*!
1796 * Copyright (C) 2017 Glayzzle (BSD3 License)
1797 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1798 * @url http://glayzzle.com
1799 */
1800 "use strict";
1801 var Node = require('./node');
1802 var KIND = 'label';
1803
1804 /**
1805 * A label statement (referenced by goto)
1806 * @constructor Label
1807 * @extends {Node}
1808 * @property {String} name
1809 */
1810 var Label = Node.extends(function Label(name, location) {
1811 Node.apply(this, [KIND, location]);
1812 this.name = name;
1813 });
1814
1815 module.exports = Label;
1816
1817 },{"./node":54}],46:[function(require,module,exports){
1818 /*!
1819 * Copyright (C) 2017 Glayzzle (BSD3 License)
1820 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1821 * @url http://glayzzle.com
1822 */
1823
1824 var Sys = require('./sys');
1825 var KIND = 'list';
1826
1827 /**
1828 * Defines list assignment
1829 * @constructor List
1830 * @extends {Sys}
1831 */
1832 var List = Sys.extends(function List(args, location) {
1833 Sys.apply(this, [KIND, args, location]);
1834 });
1835
1836 module.exports = List;
1837
1838 },{"./sys":76}],47:[function(require,module,exports){
1839 /*!
1840 * Copyright (C) 2017 Glayzzle (BSD3 License)
1841 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1842 * @url http://glayzzle.com
1843 */
1844
1845 var Expr = require('./expression');
1846 var KIND = 'literal';
1847
1848 /**
1849 * Defines an array structure
1850 * @constructor Literal
1851 * @extends {Expression}
1852 * @property {Node|string|number|boolean|null} value
1853 */
1854 var Literal = Expr.extends(function Literal(kind, value, location) {
1855 Expr.apply(this, [kind || KIND, location]);
1856 this.value = value;
1857 });
1858
1859 module.exports = Literal;
1860
1861 },{"./expression":32}],48:[function(require,module,exports){
1862 /*!
1863 * Copyright (C) 2017 Glayzzle (BSD3 License)
1864 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1865 * @url http://glayzzle.com
1866 */
1867
1868 /**
1869 * Defines the location of the node (with it's source contents as string)
1870 * @constructor Location
1871 * @property {String|null} source
1872 * @property {Position} start
1873 * @property {Position} end
1874 */
1875 var Location = function(source, start, end) {
1876 this.source = source;
1877 this.start = start;
1878 this.end = end;
1879 };
1880
1881 module.exports = Location;
1882
1883 },{}],49:[function(require,module,exports){
1884 /*!
1885 * Copyright (C) 2017 Glayzzle (BSD3 License)
1886 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1887 * @url http://glayzzle.com
1888 */
1889
1890 var Expr = require('./expression');
1891 var KIND = 'lookup';
1892
1893 /**
1894 * Lookup on an offset in the specified object
1895 * @constructor Lookup
1896 * @extends {Expression}
1897 * @property {Expression} what
1898 * @property {Expression} offset
1899 */
1900 var Lookup = Expr.extends(function Lookup(kind, what, offset, location) {
1901 Expr.apply(this, [kind || KIND, location]);
1902 this.what = what;
1903 this.offset = offset;
1904 });
1905
1906 module.exports = Lookup;
1907
1908 },{"./expression":32}],50:[function(require,module,exports){
1909 /*!
1910 * Copyright (C) 2017 Glayzzle (BSD3 License)
1911 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1912 * @url http://glayzzle.com
1913 */
1914
1915 var Literal = require('./literal');
1916 var KIND = 'magic';
1917
1918 /**
1919 * Defines magic constant
1920 * @constructor Magic
1921 * @extends {Literal}
1922 */
1923 var Magic = Literal.extends(function Magic(value, location) {
1924 Literal.apply(this, [KIND, value, location]);
1925 });
1926
1927 module.exports = Magic;
1928
1929 },{"./literal":47}],51:[function(require,module,exports){
1930 /*!
1931 * Copyright (C) 2017 Glayzzle (BSD3 License)
1932 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1933 * @url http://glayzzle.com
1934 */
1935
1936 var fn = require('./function');
1937 var KIND = 'method';
1938
1939 /**
1940 * Defines a class/interface/trait method
1941 * @constructor Method
1942 * @extends {Function}
1943 * @property {boolean} isAbstract
1944 * @property {boolean} isFinal
1945 * @property {boolean} isStatic
1946 * @property {string} visibility
1947 */
1948 var Method = fn.extends(function Method() {
1949 fn.apply(this, arguments);
1950 this.kind = KIND;
1951 });
1952
1953 module.exports = Method;
1954
1955 },{"./function":35}],52:[function(require,module,exports){
1956 /*!
1957 * Copyright (C) 2017 Glayzzle (BSD3 License)
1958 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1959 * @url http://glayzzle.com
1960 */
1961
1962 var Block = require('./block');
1963 var Identifier = require('./identifier');
1964 var KIND = 'namespace';
1965
1966 /**
1967 * The main program node
1968 * @constructor Namespace
1969 * @extends {Block}
1970 * @property {String} name
1971 * @property {Boolean} withBrackets
1972 */
1973 var Namespace = Block.extends(function Namespace(name, children, withBrackets, location) {
1974 Block.apply(this, [KIND, children, location]);
1975 this.name = name;
1976 this.withBrackets = withBrackets || false;
1977 });
1978
1979 module.exports = Namespace;
1980
1981 },{"./block":7,"./identifier":39}],53:[function(require,module,exports){
1982 /*!
1983 * Copyright (C) 2017 Glayzzle (BSD3 License)
1984 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
1985 * @url http://glayzzle.com
1986 */
1987 "use strict";
1988
1989 var Statement = require('./statement');
1990 var KIND = 'new';
1991
1992 /**
1993 * Creates a new instance of the specified class
1994 * @constructor New
1995 * @extends {Statement}
1996 * @property {Identifier|Variable|Class} what
1997 * @property {Arguments[]} arguments
1998 */
1999 var New = Statement.extends(function New(what, args, location) {
2000 Statement.apply(this, [KIND, location]);
2001 this.what = what;
2002 this.arguments = args;
2003 });
2004
2005 module.exports = New;
2006
2007 },{"./statement":71}],54:[function(require,module,exports){
2008 /*!
2009 * Copyright (C) 2017 Glayzzle (BSD3 License)
2010 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2011 * @url http://glayzzle.com
2012 */
2013
2014 /**
2015 * A generic AST node
2016 * @constructor Node
2017 * @property {Location|null} loc
2018 * @property {String} kind
2019 */
2020 var Node = function Node(kind, location) {
2021 this.kind = kind;
2022 if(location) {
2023 this.loc = location;
2024 }
2025 };
2026
2027 /**
2028 * Helper for extending the Node class
2029 * @param {Function} constructor
2030 * @return {Function}
2031 */
2032 Node.extends = function(constructor) {
2033 constructor.prototype = Object.create(this.prototype);
2034 constructor.extends = this.extends;
2035 constructor.prototype.constructor = constructor;
2036 return constructor;
2037 };
2038
2039 module.exports = Node;
2040
2041 },{}],55:[function(require,module,exports){
2042 /*!
2043 * Copyright (C) 2017 Glayzzle (BSD3 License)
2044 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2045 * @url http://glayzzle.com
2046 */
2047
2048 var Literal = require('./literal');
2049 var KIND = 'nowdoc';
2050
2051 /**
2052 * Defines a nowdoc string
2053 * @constructor String
2054 * @extends {Literal}
2055 * @property {String} label
2056
2057 */
2058 var Nowdoc = Literal.extends(function Nowdoc(value, label, location) {
2059 Literal.apply(this, [KIND, value, location]);
2060 this.label = label;
2061 });
2062
2063 module.exports = Nowdoc;
2064
2065 },{"./literal":47}],56:[function(require,module,exports){
2066 /*!
2067 * Copyright (C) 2017 Glayzzle (BSD3 License)
2068 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2069 * @url http://glayzzle.com
2070 */
2071
2072 var Literal = require('./literal');
2073 var KIND = 'number';
2074
2075 /**
2076 * Defines a numeric value
2077 * @constructor Number
2078 * @extends {Literal}
2079 */
2080 var _Number = Literal.extends(function Number(value, location) {
2081 Literal.apply(this, [KIND, value, location]);
2082 });
2083
2084 module.exports = _Number;
2085
2086 },{"./literal":47}],57:[function(require,module,exports){
2087 /*!
2088 * Copyright (C) 2017 Glayzzle (BSD3 License)
2089 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2090 * @url http://glayzzle.com
2091 */
2092 "use strict";
2093 var Lookup = require('./lookup');
2094 var KIND = 'offsetlookup';
2095
2096 /**
2097 * Lookup on an offset in an array
2098 * @constructor OffsetLookup
2099 * @extends {Lookup}
2100 */
2101 var OffsetLookup = Lookup.extends(function OffsetLookup(what, offset, location) {
2102 Lookup.apply(this, [KIND, what, offset, location]);
2103 });
2104
2105 module.exports = OffsetLookup;
2106
2107 },{"./lookup":49}],58:[function(require,module,exports){
2108 /*!
2109 * Copyright (C) 2017 Glayzzle (BSD3 License)
2110 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2111 * @url http://glayzzle.com
2112 */
2113 "use strict";
2114
2115 var Expr = require('./expression');
2116 var KIND = 'operation';
2117
2118 /**
2119 * Defines binary operations
2120 * @constructor Operation
2121 * @extends {Expression}
2122 */
2123 var Operation = Expr.extends(function Operation(kind, location) {
2124 Expr.apply(this, [kind || KIND, location]);
2125 });
2126
2127 module.exports = Operation;
2128
2129 },{"./expression":32}],59:[function(require,module,exports){
2130 /*!
2131 * Copyright (C) 2017 Glayzzle (BSD3 License)
2132 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2133 * @url http://glayzzle.com
2134 */
2135
2136 var Declaration = require('./declaration');
2137 var KIND = 'parameter';
2138
2139 /**
2140 * Defines a function parameter
2141 * @constructor Parameter
2142 * @extends {Declaration}
2143 * @property {Identifier|null} type
2144 * @property {Node|null} value
2145 * @property {boolean} byref
2146 * @property {boolean} variadic
2147 * @property {boolean} nullable
2148 */
2149 var Parameter = Declaration.extends(function Parameter(name, type, value, isRef, isVariadic, nullable, location) {
2150 Declaration.apply(this, [KIND, name, location]);
2151 this.value = value;
2152 this.type = type;
2153 this.byref = isRef;
2154 this.variadic = isVariadic;
2155 this.nullable = nullable;
2156 });
2157
2158 module.exports = Parameter;
2159
2160 },{"./declaration":21}],60:[function(require,module,exports){
2161 /*!
2162 * Copyright (C) 2017 Glayzzle (BSD3 License)
2163 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2164 * @url http://glayzzle.com
2165 */
2166 "use strict";
2167
2168 var Operation = require('./operation');
2169 var KIND = 'parenthesis';
2170
2171 /**
2172 * Parenthesis encapsulation `(... expr ...)`
2173 * @constructor Parenthesis
2174 * @extends {Operation}
2175 * @property {Expression} inner
2176 */
2177 var Parenthesis = Operation.extends(function Parenthesis(inner, location) {
2178 Operation.apply(this, [KIND, location]);
2179 this.inner = inner;
2180 });
2181
2182 module.exports = Parenthesis;
2183
2184 },{"./operation":58}],61:[function(require,module,exports){
2185 /*!
2186 * Copyright (C) 2017 Glayzzle (BSD3 License)
2187 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2188 * @url http://glayzzle.com
2189 */
2190
2191 /**
2192 * Each Position object consists of a line number (1-indexed) and a column number (0-indexed):
2193 * @constructor Position
2194 * @property {Number} line
2195 * @property {Number} column
2196 * @property {Number} offset
2197 */
2198 var Position = function(line, column, offset) {
2199 this.line = line;
2200 this.column = column;
2201 this.offset = offset;
2202 };
2203
2204 module.exports = Position;
2205
2206 },{}],62:[function(require,module,exports){
2207 /*!
2208 * Copyright (C) 2017 Glayzzle (BSD3 License)
2209 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2210 * @url http://glayzzle.com
2211 */
2212 "use strict";
2213
2214 var Operation = require('./operation');
2215 var KIND = 'post';
2216
2217 /**
2218 * Defines a post operation `$i++` or `$i--`
2219 * @constructor Post
2220 * @extends {Operation}
2221 * @property {String} type
2222 * @property {Variable} what
2223 */
2224 var Post = Operation.extends(function Post(type, what, location) {
2225 Operation.apply(this, [KIND, location]);
2226 this.type = type;
2227 this.what = what;
2228 });
2229
2230 module.exports = Post;
2231
2232 },{"./operation":58}],63:[function(require,module,exports){
2233 /*!
2234 * Copyright (C) 2017 Glayzzle (BSD3 License)
2235 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2236 * @url http://glayzzle.com
2237 */
2238 "use strict";
2239
2240 var Operation = require('./operation');
2241 var KIND = 'pre';
2242
2243 /**
2244 * Defines a pre operation `++$i` or `--$i`
2245 * @constructor Pre
2246 * @extends {Operation}
2247 * @property {String} type
2248 * @property {Variable} what
2249 */
2250 var Pre = Operation.extends(function Pre(type, what, location) {
2251 Operation.apply(this, [KIND, location]);
2252 this.type = type;
2253 this.what = what;
2254 });
2255
2256 module.exports = Pre;
2257
2258 },{"./operation":58}],64:[function(require,module,exports){
2259 /*!
2260 * Copyright (C) 2017 Glayzzle (BSD3 License)
2261 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2262 * @url http://glayzzle.com
2263 */
2264
2265 var Sys = require('./sys');
2266 var KIND = 'print';
2267
2268 /**
2269 * Outputs
2270 * @constructor Print
2271 * @extends {Sys}
2272 */
2273 var Print = Sys.extends(function Print(args, location) {
2274 Sys.apply(this, [KIND, args, location]);
2275 });
2276
2277 module.exports = Print;
2278
2279 },{"./sys":76}],65:[function(require,module,exports){
2280 /*!
2281 * Copyright (C) 2017 Glayzzle (BSD3 License)
2282 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2283 * @url http://glayzzle.com
2284 */
2285
2286 var Block = require('./block');
2287 var KIND = 'program';
2288
2289 /**
2290 * The main program node
2291 * @constructor Program
2292 * @extends {Block}
2293 * @property {Error[]} errors
2294 */
2295 var Program = Block.extends(function Program(children, errors, location) {
2296 Block.apply(this, [KIND, children, location]);
2297 this.errors = errors;
2298 });
2299
2300 module.exports = Program;
2301
2302 },{"./block":7}],66:[function(require,module,exports){
2303 /*!
2304 * Copyright (C) 2017 Glayzzle (BSD3 License)
2305 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2306 * @url http://glayzzle.com
2307 */
2308
2309 var Declaration = require('./declaration');
2310 var KIND = 'property';
2311
2312 /**
2313 * Defines a class property
2314 * @constructor Property
2315 * @extends {Declaration}
2316 * @property {boolean} isFinal
2317 * @property {boolean} isStatic
2318 * @property {string} visibility
2319 * @property {Node|null} value
2320 */
2321 var Property = Declaration.extends(function Property(name, value, flags, location) {
2322 Declaration.apply(this, [KIND, name, location]);
2323 this.value = value;
2324 this.parseFlags(flags);
2325 });
2326
2327 module.exports = Property;
2328
2329 },{"./declaration":21}],67:[function(require,module,exports){
2330 /*!
2331 * Copyright (C) 2017 Glayzzle (BSD3 License)
2332 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2333 * @url http://glayzzle.com
2334 */
2335 "use strict";
2336 var Lookup = require('./lookup');
2337 var KIND = 'propertylookup';
2338
2339 /**
2340 * Lookup to an object property
2341 * @constructor PropertyLookup
2342 * @extends {Lookup}
2343 */
2344 var PropertyLookup = Lookup.extends(function PropertyLookup(what, offset, location) {
2345 Lookup.apply(this, [KIND, what, offset, location]);
2346 });
2347
2348 module.exports = PropertyLookup;
2349
2350 },{"./lookup":49}],68:[function(require,module,exports){
2351 /*!
2352 * Copyright (C) 2017 Glayzzle (BSD3 License)
2353 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2354 * @url http://glayzzle.com
2355 */
2356 "use strict";
2357
2358 var Statement = require('./statement');
2359 var KIND = 'retif';
2360
2361 /**
2362 * Defines a short if statement that returns a value
2363 * @constructor RetIf
2364 * @extends {Statement}
2365 * @property {Expression} test
2366 * @property {Expression} trueExpr
2367 * @property {Expression} falseExpr
2368 */
2369 var RetIf = Statement.extends(function RetIf(test, trueExpr, falseExpr, location) {
2370 Statement.apply(this, [KIND, location]);
2371 this.test = test;
2372 this.trueExpr = trueExpr;
2373 this.falseExpr = falseExpr;
2374 });
2375
2376 module.exports = RetIf;
2377
2378 },{"./statement":71}],69:[function(require,module,exports){
2379 /*!
2380 * Copyright (C) 2017 Glayzzle (BSD3 License)
2381 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2382 * @url http://glayzzle.com
2383 */
2384 "use strict";
2385 var Node = require('./node');
2386 var KIND = 'return';
2387
2388 /**
2389 * A continue statement
2390 * @constructor Return
2391 * @extends {Node}
2392 * @property {Expression|null} expr
2393 */
2394 var Return = Node.extends(function Return(expr, location) {
2395 Node.apply(this, [KIND, location]);
2396 this.expr = expr;
2397 });
2398
2399 module.exports = Return;
2400
2401 },{"./node":54}],70:[function(require,module,exports){
2402 /*!
2403 * Copyright (C) 2017 Glayzzle (BSD3 License)
2404 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2405 * @url http://glayzzle.com
2406 */
2407 "use strict";
2408
2409 var Statement = require('./statement');
2410 var KIND = 'silent';
2411
2412 /**
2413 * Avoids to show/log warnings & notices from the inner expression
2414 * @constructor Silent
2415 * @extends {Statement}
2416 * @property {Expression} expr
2417 */
2418 var Silent = Statement.extends(function Silent(expr, location) {
2419 Statement.apply(this, [KIND, location]);
2420 this.expr = expr;
2421 });
2422
2423 module.exports = Silent;
2424
2425 },{"./statement":71}],71:[function(require,module,exports){
2426 /*!
2427 * Copyright (C) 2017 Glayzzle (BSD3 License)
2428 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2429 * @url http://glayzzle.com
2430 */
2431
2432 var Node = require('./node');
2433 var KIND = 'statement';
2434
2435 /**
2436 * Any statement.
2437 * @constructor Statement
2438 * @extends {Node}
2439 */
2440 var Statement = Node.extends(function Statement(kind, location) {
2441 Node.apply(this, [kind || KIND, location]);
2442 });
2443
2444 module.exports = Statement;
2445
2446 },{"./node":54}],72:[function(require,module,exports){
2447 /*!
2448 * Copyright (C) 2017 Glayzzle (BSD3 License)
2449 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2450 * @url http://glayzzle.com
2451 */
2452 "use strict";
2453 var Statement = require('./statement');
2454 var KIND = 'static';
2455
2456 /**
2457 * Declares a static variable into the current scope
2458 * @constructor Static
2459 * @extends {Statement}
2460 * @property {Variable[]|Assign[]} items
2461 */
2462 var Static = Statement.extends(function Static(items, location) {
2463 Statement.apply(this, [KIND, location]);
2464 this.items = items;
2465 });
2466
2467 module.exports = Static;
2468
2469 },{"./statement":71}],73:[function(require,module,exports){
2470 /*!
2471 * Copyright (C) 2017 Glayzzle (BSD3 License)
2472 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2473 * @url http://glayzzle.com
2474 */
2475 "use strict";
2476 var Lookup = require('./lookup');
2477 var KIND = 'staticlookup';
2478
2479 /**
2480 * Lookup to a static property
2481 * @constructor StaticLookup
2482 * @extends {Lookup}
2483 */
2484 var StaticLookup = Lookup.extends(function StaticLookup(what, offset, location) {
2485 Lookup.apply(this, [KIND, what, offset, location]);
2486 });
2487
2488 module.exports = StaticLookup;
2489
2490 },{"./lookup":49}],74:[function(require,module,exports){
2491 /*!
2492 * Copyright (C) 2017 Glayzzle (BSD3 License)
2493 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2494 * @url http://glayzzle.com
2495 */
2496
2497 var Literal = require('./literal');
2498 var KIND = 'string';
2499
2500 /**
2501 * Defines a string (simple ou double quoted) - chars are already escaped
2502 * @constructor String
2503 * @extends {Literal}
2504 * @property {boolean} isDoubleQuote
2505 * @see {Encapsed}
2506 */
2507 var String = Literal.extends(function String(isDoubleQuote, value, location) {
2508 Literal.apply(this, [KIND, value, location]);
2509 this.isDoubleQuote = isDoubleQuote;
2510 });
2511
2512 module.exports = String;
2513
2514 },{"./literal":47}],75:[function(require,module,exports){
2515 /*!
2516 * Copyright (C) 2017 Glayzzle (BSD3 License)
2517 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2518 * @url http://glayzzle.com
2519 */
2520 "use strict";
2521
2522 var Statement = require('./statement');
2523 var KIND = 'switch';
2524
2525 /**
2526 * Defines a switch statement
2527 * @constructor Switch
2528 * @extends {Statement}
2529 * @property {Expression} test
2530 * @property {Block} body
2531 * @property {boolean} shortForm
2532 */
2533 var Switch = Statement.extends(function Switch(test, body, shortForm, location) {
2534 Statement.apply(this, [KIND, location]);
2535 this.test = test;
2536 this.body = body;
2537 this.shortForm = shortForm;
2538 });
2539
2540 module.exports = Switch;
2541
2542 },{"./statement":71}],76:[function(require,module,exports){
2543 /*!
2544 * Copyright (C) 2017 Glayzzle (BSD3 License)
2545 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2546 * @url http://glayzzle.com
2547 */
2548
2549 var Statement = require('./statement');
2550 var KIND = 'sys';
2551
2552 /**
2553 * Defines system based call
2554 * @constructor Sys
2555 * @extends {Statement}
2556 * @property {Node[]} arguments
2557 */
2558 var Sys = Statement.extends(function Sys(kind, args, location) {
2559 Statement.apply(this, [kind || KIND, location]);
2560 this.arguments = args;
2561 });
2562
2563 module.exports = Sys;
2564
2565 },{"./statement":71}],77:[function(require,module,exports){
2566 /*!
2567 * Copyright (C) 2017 Glayzzle (BSD3 License)
2568 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2569 * @url http://glayzzle.com
2570 */
2571 "use strict";
2572
2573 var Statement = require('./statement');
2574 var KIND = 'throw';
2575
2576 /**
2577 * Defines a throw statement
2578 * @constructor Throw
2579 * @extends {Statement}
2580 * @property {Expression} what
2581 */
2582 var Throw = Statement.extends(function Throw(what, location) {
2583 Statement.apply(this, [KIND, location]);
2584 this.what = what;
2585 });
2586
2587 module.exports = Throw;
2588
2589 },{"./statement":71}],78:[function(require,module,exports){
2590 /*!
2591 * Copyright (C) 2017 Glayzzle (BSD3 License)
2592 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2593 * @url http://glayzzle.com
2594 */
2595
2596 var Declaration = require('./declaration');
2597 var KIND = 'trait';
2598
2599
2600 /**
2601 * A trait definition
2602 * @constructor Trait
2603 * @extends {Declaration}
2604 * @property {Identifier|null} extends
2605 * @property {Identifier[]} implements
2606 * @property {Declaration[]} body
2607 */
2608 var Trait = Declaration.extends(function Trait(name, ext, impl, body, location) {
2609 Declaration.apply(this, [KIND, name, location]);
2610 this.extends = ext;
2611 this.implements = impl;
2612 this.body = body;
2613 });
2614
2615 module.exports = Trait;
2616
2617 },{"./declaration":21}],79:[function(require,module,exports){
2618 /*!
2619 * Copyright (C) 2017 Glayzzle (BSD3 License)
2620 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2621 * @url http://glayzzle.com
2622 */
2623
2624 var Node = require('./node');
2625 var KIND = 'traitalias';
2626
2627 var IS_PUBLIC = 'public';
2628 var IS_PROTECTED = 'protected';
2629 var IS_PRIVATE = 'private';
2630
2631 /**
2632 * Defines a trait alias
2633 * @constructor TraitAlias
2634 * @extends {Node}
2635 * @property {Identifier|null} trait
2636 * @property {string} method
2637 * @property {string|null} as
2638 * @property {string|null} visibility
2639 */
2640 var TraitAlias = Node.extends(function TraitAlias(trait, method, as, flags, location) {
2641 Node.apply(this, [KIND, location]);
2642 this.trait = trait;
2643 this.method = method;
2644 this.as = as;
2645 if (flags) {
2646 if (flags[0] === 0) {
2647 this.visibility = IS_PUBLIC;
2648 } else if (flags[0] === 1) {
2649 this.visibility = IS_PROTECTED;
2650 } else {
2651 this.visibility = IS_PRIVATE;
2652 }
2653 } else {
2654 this.visibility = null;
2655 }
2656 });
2657
2658 module.exports = TraitAlias;
2659
2660 },{"./node":54}],80:[function(require,module,exports){
2661 /*!
2662 * Copyright (C) 2017 Glayzzle (BSD3 License)
2663 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2664 * @url http://glayzzle.com
2665 */
2666
2667 var Node = require('./node');
2668 var KIND = 'traitprecedence';
2669
2670 /**
2671 * Defines a trait alias
2672 * @constructor TraitPrecedence
2673 * @extends {Node}
2674 * @property {Identifier|null} trait
2675 * @property {string} method
2676 * @property {Identifier[]} instead
2677 */
2678 var TraitPrecedence = Node.extends(function TraitPrecedence(trait, method, instead, location) {
2679 Node.apply(this, [KIND, location]);
2680 this.trait = trait;
2681 this.method = method;
2682 this.instead = instead;
2683 });
2684
2685 module.exports = TraitPrecedence;
2686
2687 },{"./node":54}],81:[function(require,module,exports){
2688 /*!
2689 * Copyright (C) 2017 Glayzzle (BSD3 License)
2690 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2691 * @url http://glayzzle.com
2692 */
2693
2694 var Node = require('./node');
2695 var KIND = 'traituse';
2696
2697 /**
2698 * Defines a trait usage
2699 * @constructor TraitUse
2700 * @extends {Node}
2701 * @property {Identifier[]} traits
2702 * @property {Node[]|null} adaptations
2703 */
2704 var TraitUse = Node.extends(function TraitUse(traits, adaptations, location) {
2705 Node.apply(this, [KIND, location]);
2706 this.traits = traits;
2707 this.adaptations = adaptations;
2708 });
2709
2710 module.exports = TraitUse;
2711
2712 },{"./node":54}],82:[function(require,module,exports){
2713 /*!
2714 * Copyright (C) 2017 Glayzzle (BSD3 License)
2715 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2716 * @url http://glayzzle.com
2717 */
2718 "use strict";
2719
2720 var Statement = require('./statement');
2721 var KIND = 'try';
2722
2723 /**
2724 * Defines a try statement
2725 * @constructor Try
2726 * @extends {Statement}
2727 * @property {Block} body
2728 * @property {Catch[]} catches
2729 * @property {Block} allways
2730 */
2731 var Try = Statement.extends(function Try(body, catches, always, location) {
2732 Statement.apply(this, [KIND, location]);
2733 this.body = body;
2734 this.catches = catches;
2735 this.always = always;
2736 });
2737
2738 module.exports = Try;
2739
2740 },{"./statement":71}],83:[function(require,module,exports){
2741 /*!
2742 * Copyright (C) 2017 Glayzzle (BSD3 License)
2743 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2744 * @url http://glayzzle.com
2745 */
2746 "use strict";
2747
2748 var Operation = require('./operation');
2749 var KIND = 'unary';
2750
2751 /**
2752 * Unary operations
2753 * @constructor Unary
2754 * @extends {Operation}
2755 * @property {String} type
2756 * @property {Expression} what
2757 */
2758 var Unary = Operation.extends(function Unary(type, what, location) {
2759 Operation.apply(this, [KIND, location]);
2760 this.type = type;
2761 this.what = what;
2762 });
2763
2764 module.exports = Unary;
2765
2766 },{"./operation":58}],84:[function(require,module,exports){
2767 /*!
2768 * Copyright (C) 2017 Glayzzle (BSD3 License)
2769 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2770 * @url http://glayzzle.com
2771 */
2772
2773 var Sys = require('./sys');
2774 var KIND = 'unset';
2775
2776 /**
2777 * Deletes references to a list of variables
2778 * @constructor Unset
2779 * @extends {Sys}
2780 */
2781 var Unset = Sys.extends(function Unset(args, location) {
2782 Sys.apply(this, [KIND, args, location]);
2783 });
2784
2785 module.exports = Unset;
2786
2787 },{"./sys":76}],85:[function(require,module,exports){
2788 /*!
2789 * Copyright (C) 2017 Glayzzle (BSD3 License)
2790 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2791 * @url http://glayzzle.com
2792 */
2793 "use strict";
2794 var Statement = require('./statement');
2795 var KIND = 'usegroup';
2796
2797 /**
2798 * Defines a use statement (with a list of use items)
2799 * @constructor UseGroup
2800 * @extends {Statement}
2801 * @property {String|null} name
2802 * @property {String|null} type - Possible value : function, const
2803 * @property {UseItem[]} item
2804 * @see {Namespace}
2805 * @see http://php.net/manual/en/language.namespaces.importing.php
2806 */
2807 var UseGroup = Statement.extends(function UseGroup(name, type, items, location) {
2808 Statement.apply(this, [KIND, location]);
2809 this.name = name;
2810 this.type = type;
2811 this.items = items;
2812 });
2813
2814 module.exports = UseGroup;
2815
2816 },{"./statement":71}],86:[function(require,module,exports){
2817 /*!
2818 * Copyright (C) 2017 Glayzzle (BSD3 License)
2819 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2820 * @url http://glayzzle.com
2821 */
2822 "use strict";
2823 var Statement = require('./statement');
2824 var KIND = 'useitem';
2825
2826 /**
2827 * Defines a use statement (from namespace)
2828 * @constructor UseItem
2829 * @extends {Statement}
2830 * @property {String} name
2831 * @property {String|null} type - Possible value : function, const
2832 * @property {String|null} alias
2833 * @see {Namespace}
2834 * @see http://php.net/manual/en/language.namespaces.importing.php
2835 */
2836 var UseItem = Statement.extends(function UseItem(name, alias, type, location) {
2837 Statement.apply(this, [KIND, location]);
2838 this.name = name;
2839 this.alias = alias;
2840 this.type = type;
2841 });
2842
2843
2844 /**
2845 * Importing a constant
2846 * @constant {String} TYPE_CONST
2847 */
2848 UseItem.TYPE_CONST = 'const';
2849 /**
2850 * Importing a function
2851 * @constant {String} TYPE_FUNC
2852 */
2853 UseItem.TYPE_FUNCTION = 'function';
2854
2855
2856 module.exports = UseItem;
2857
2858 },{"./statement":71}],87:[function(require,module,exports){
2859 /*!
2860 * Copyright (C) 2017 Glayzzle (BSD3 License)
2861 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2862 * @url http://glayzzle.com
2863 */
2864 "use strict";
2865 var Expr = require('./expression');
2866 var KIND = 'variable';
2867
2868 /**
2869 * Any expression node. Since the left-hand side of an assignment may
2870 * be any expression in general, an expression can also be a pattern.
2871 * @constructor Variable
2872 * @extends {Expression}
2873 * @example
2874 * // PHP code :
2875 * &$foo
2876 * // AST output
2877 * {
2878 * "kind": "variable",
2879 * "name": "foo",
2880 * "byref": true,
2881 * "curly": false
2882 * }
2883 * @property {String|Node} name The variable name (can be a complex expression when the name is resolved dynamically)
2884 * @property {boolean} byref Indicate if the variable reference is used, ex `&$foo`
2885 * @property {boolean} curly Indicate if the name is defined between curlies, ex `${foo}`
2886 */
2887 var Variable = Expr.extends(function Variable(name, byref, curly, location) {
2888 Expr.apply(this, [KIND, location]);
2889 this.name = name;
2890 this.byref = byref || false;
2891 this.curly = curly || false;
2892 });
2893
2894 module.exports = Variable;
2895
2896 },{"./expression":32}],88:[function(require,module,exports){
2897 /*!
2898 * Copyright (C) 2017 Glayzzle (BSD3 License)
2899 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2900 * @url http://glayzzle.com
2901 */
2902 "use strict";
2903 var Expr = require('./expression');
2904 var KIND = 'variadic';
2905
2906 /**
2907 * Introduce a list of items into the arguments of the call
2908 * @constructor Variadic
2909 * @extends {Expression}
2910 * @property {Array|Expression} what
2911 * @see https://wiki.php.net/rfc/argument_unpacking
2912 */
2913 var Variadic = Expr.extends(function Variadic(what, location) {
2914 Expr.apply(this, [KIND, location]);
2915 this.what = what;
2916 });
2917
2918 module.exports = Variadic;
2919
2920 },{"./expression":32}],89:[function(require,module,exports){
2921 /*!
2922 * Copyright (C) 2017 Glayzzle (BSD3 License)
2923 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2924 * @url http://glayzzle.com
2925 */
2926 "use strict";
2927
2928 var Statement = require('./statement');
2929 var KIND = 'while';
2930
2931 /**
2932 * Defines a while statement
2933 * @constructor While
2934 * @extends {Statement}
2935 * @property {Expression} test
2936 * @property {Statement} body
2937 * @property {boolean} shortForm
2938 */
2939 var While = Statement.extends(function While(test, body, shortForm, location) {
2940 Statement.apply(this, [KIND, location]);
2941 this.test = test;
2942 this.body = body;
2943 this.shortForm = shortForm;
2944 });
2945
2946 module.exports = While;
2947
2948 },{"./statement":71}],90:[function(require,module,exports){
2949 /*!
2950 * Copyright (C) 2017 Glayzzle (BSD3 License)
2951 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2952 * @url http://glayzzle.com
2953 */
2954 "use strict";
2955
2956 var Expression = require('./expression');
2957 var KIND = 'yield';
2958
2959 /**
2960 * Defines a yield generator statement
2961 * @constructor Yield
2962 * @extends {Expression}
2963 * @property {Expression|Null} value
2964 * @property {Expression|Null} key
2965 * @see http://php.net/manual/en/language.generators.syntax.php
2966 */
2967 var Yield = Expression.extends(function Yield(value, key, location) {
2968 Expression.apply(this, [KIND, location]);
2969 this.value = value;
2970 this.key = key;
2971 });
2972
2973 module.exports = Yield;
2974
2975 },{"./expression":32}],91:[function(require,module,exports){
2976 /*!
2977 * Copyright (C) 2017 Glayzzle (BSD3 License)
2978 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
2979 * @url http://glayzzle.com
2980 */
2981 "use strict";
2982
2983 var Expression = require('./expression');
2984 var KIND = 'yieldfrom';
2985
2986 /**
2987 * Defines a yield from generator statement
2988 * @constructor YieldFrom
2989 * @extends {Expression}
2990 * @property {Expression} value
2991 * @see http://php.net/manual/en/language.generators.syntax.php
2992 */
2993 var YieldFrom = Expression.extends(function YieldFrom(value, location) {
2994 Expression.apply(this, [KIND, location]);
2995 this.value = value;
2996 });
2997
2998 module.exports = YieldFrom;
2999
3000 },{"./expression":32}],92:[function(require,module,exports){
3001 /*!
3002 * Copyright (C) 2017 Glayzzle (BSD3 License)
3003 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
3004 * @url http://glayzzle.com
3005 */
3006 "use strict";
3007 /**
3008 * This is the php lexer. It will tokenize the string for helping the
3009 * parser to build the AST from its grammar.
3010 *
3011 * @public @constructor {Lexer}
3012 * @property {Integer} EOF
3013 * @property {Boolean} all_tokens defines if all tokens must be retrieved (used by token_get_all only)
3014 * @property {Boolean} comment_tokens extracts comments tokens
3015 * @property {Boolean} mode_eval enables the evald mode (ignore opening tags)
3016 * @property {Boolean} asp_tags disables by default asp tags mode
3017 * @property {Boolean} short_tags enables by default short tags mode
3018 * @property {Object} keywords List of php keyword
3019 * @property {Object} castKeywords List of php keywords for type casting
3020 */
3021 var lexer = function(engine) {
3022 this.engine = engine;
3023 this.tok = this.engine.tokens.names;
3024 this.EOF = 1;
3025 this.debug = false;
3026 this.all_tokens = true;
3027 this.comment_tokens = false;
3028 this.mode_eval = false;
3029 this.asp_tags = false;
3030 this.short_tags = true;
3031 this.yyprevcol = 0;
3032 this.keywords = {
3033 "__class__": this.tok.T_CLASS_C,
3034 "__trait__": this.tok.T_TRAIT_C,
3035 "__function__": this.tok.T_FUNC_C,
3036 "__method__": this.tok.T_METHOD_C,
3037 "__line__": this.tok.T_LINE,
3038 "__file__": this.tok.T_FILE,
3039 "__dir__": this.tok.T_DIR,
3040 "__namespace__": this.tok.T_NS_C,
3041 'exit': this.tok.T_EXIT,
3042 'die': this.tok.T_EXIT,
3043 'function': this.tok.T_FUNCTION,
3044 "const": this.tok.T_CONST,
3045 "return": this.tok.T_RETURN,
3046 "try": this.tok.T_TRY,
3047 "catch": this.tok.T_CATCH,
3048 "finally": this.tok.T_FINALLY,
3049 "throw": this.tok.T_THROW,
3050 "if": this.tok.T_IF,
3051 "elseif": this.tok.T_ELSEIF,
3052 "endif": this.tok.T_ENDIF,
3053 "else": this.tok.T_ELSE,
3054 "while": this.tok.T_WHILE,
3055 "endwhile": this.tok.T_ENDWHILE,
3056 "do": this.tok.T_DO,
3057 "for": this.tok.T_FOR,
3058 "endfor": this.tok.T_ENDFOR,
3059 "foreach": this.tok.T_FOREACH,
3060 "endforeach": this.tok.T_ENDFOREACH,
3061 "declare": this.tok.T_DECLARE,
3062 "enddeclare": this.tok.T_ENDDECLARE,
3063 "instanceof": this.tok.T_INSTANCEOF,
3064 "as": this.tok.T_AS,
3065 "switch": this.tok.T_SWITCH,
3066 "endswitch": this.tok.T_ENDSWITCH,
3067 "case": this.tok.T_CASE,
3068 "default": this.tok.T_DEFAULT,
3069 "break": this.tok.T_BREAK,
3070 "continue": this.tok.T_CONTINUE,
3071 "goto": this.tok.T_GOTO,
3072 "echo": this.tok.T_ECHO,
3073 "print": this.tok.T_PRINT,
3074 "class": this.tok.T_CLASS,
3075 "interface": this.tok.T_INTERFACE,
3076 "trait": this.tok.T_TRAIT,
3077 "extends": this.tok.T_EXTENDS,
3078 "implements": this.tok.T_IMPLEMENTS,
3079 "new": this.tok.T_NEW,
3080 "clone": this.tok.T_CLONE,
3081 "var": this.tok.T_VAR,
3082 "eval": this.tok.T_EVAL,
3083 "include": this.tok.T_INCLUDE,
3084 "include_once": this.tok.T_INCLUDE_ONCE,
3085 "require": this.tok.T_REQUIRE,
3086 "require_once": this.tok.T_REQUIRE_ONCE,
3087 "namespace": this.tok.T_NAMESPACE,
3088 "use": this.tok.T_USE,
3089 "insteadof": this.tok.T_INSTEADOF,
3090 "global": this.tok.T_GLOBAL,
3091 "isset": this.tok.T_ISSET,
3092 "empty": this.tok.T_EMPTY,
3093 "__halt_compiler": this.tok.T_HALT_COMPILER,
3094 "static": this.tok.T_STATIC,
3095 "abstract": this.tok.T_ABSTRACT,
3096 "final": this.tok.T_FINAL,
3097 "private": this.tok.T_PRIVATE,
3098 "protected": this.tok.T_PROTECTED,
3099 "public": this.tok.T_PUBLIC,
3100 "unset": this.tok.T_UNSET,
3101 "list": this.tok.T_LIST,
3102 "array": this.tok.T_ARRAY,
3103 "callable": this.tok.T_CALLABLE,
3104 "or": this.tok.T_LOGICAL_OR,
3105 "and": this.tok.T_LOGICAL_AND,
3106 "xor": this.tok.T_LOGICAL_XOR
3107 };
3108 this.castKeywords = {
3109 'int': this.tok.T_INT_CAST,
3110 'integer': this.tok.T_INT_CAST,
3111 "real": this.tok.T_DOUBLE_CAST,
3112 "double": this.tok.T_DOUBLE_CAST,
3113 "float": this.tok.T_DOUBLE_CAST,
3114 "string": this.tok.T_STRING_CAST,
3115 "binary": this.tok.T_STRING_CAST,
3116 "array": this.tok.T_ARRAY_CAST,
3117 "object": this.tok.T_OBJECT_CAST,
3118 "bool": this.tok.T_BOOL_CAST,
3119 "boolean": this.tok.T_BOOL_CAST,
3120 "unset": this.tok.T_UNSET_CAST
3121 };
3122 };
3123
3124 /**
3125 * Initialize the lexer with the specified input
3126 */
3127 lexer.prototype.setInput = function(input) {
3128 this._input = input;
3129 this.size = input.length;
3130 this.yylineno = 1;
3131 this.offset = 0;
3132 this.yyprevcol = 0;
3133 this.yytext = '';
3134 this.yylloc = {
3135 first_offset: 0,
3136 first_line: 1,
3137 first_column: 0,
3138 prev_offset: 0,
3139 prev_line: 1,
3140 prev_column: 0,
3141 last_line: 1,
3142 last_column: 0
3143 };
3144 this.tokens = [];
3145 this.conditionStack = [];
3146 this.done = this.offset >= this.size;
3147 if (!this.all_tokens && this.mode_eval) {
3148 this.begin('ST_IN_SCRIPTING');
3149 } else {
3150 this.begin('INITIAL');
3151 }
3152 return this;
3153 };
3154
3155
3156 /**
3157 * consumes and returns one char from the input
3158 */
3159 lexer.prototype.input = function(size) {
3160 var ch = this._input[this.offset];
3161 if (!ch) return '';
3162 this.yytext += ch;
3163 this.offset ++;
3164 if ( ch === '\r' && this._input[this.offset] === '\n' ) {
3165 this.yytext += '\n';
3166 this.offset++;
3167 }
3168 if (ch === '\n' || ch === '\r') {
3169 this.yylloc.last_line = ++this.yylineno;
3170 this.yyprevcol = this.yylloc.last_column;
3171 this.yylloc.last_column = 0;
3172 } else {
3173 this.yylloc.last_column++;
3174 }
3175 return ch;
3176 };
3177
3178 /**
3179 * revert eating specified size
3180 */
3181 lexer.prototype.unput = function(size) {
3182 if (size === 1) {
3183 // 1 char unput (most cases)
3184 this.offset --;
3185 if (this._input[this.offset] === '\n' && this._input[this.offset - 1] === '\r') {
3186 this.offset --;
3187 size ++;
3188 }
3189 if (this._input[this.offset] === '\r' || this._input[this.offset] === '\n') {
3190 this.yylloc.last_line --;
3191 this.yylineno --;
3192 this.yylloc.last_column = this.yyprevcol;
3193 } else {
3194 this.yylloc.last_column --;
3195 }
3196 this.yytext = this.yytext.substring(0, this.yytext.length - size);
3197 } else if (size > 0) {
3198 this.offset -= size;
3199 if (size < this.yytext.length) {
3200 this.yytext = this.yytext.substring(0, this.yytext.length - size);
3201 // re-calculate position
3202 this.yylloc.last_line = this.yylloc.first_line;
3203 this.yylloc.last_column = this.yyprevcol = this.yylloc.first_column;
3204 for(var i = 0; i < this.yytext.length; i++) {
3205 var c = this.yytext[i];
3206 if (c === '\r') {
3207 c = this.yytext[++i];
3208 this.yyprevcol = this.yylloc.last_column;
3209 this.yylloc.last_line ++;
3210 this.yylloc.last_column = 0;
3211 if (c !== '\n') {
3212 if (c === '\r') {
3213 this.yylloc.last_line ++;
3214 } else {
3215 this.yylloc.last_column ++;
3216 }
3217 }
3218 } else if (c === '\n') {
3219 this.yyprevcol = this.yylloc.last_column;
3220 this.yylloc.last_line ++;
3221 this.yylloc.last_column = 0;
3222 } else {
3223 this.yylloc.last_column ++;
3224 }
3225 }
3226 this.yylineno = this.yylloc.last_line;
3227 } else {
3228 // reset full text
3229 this.yytext = "";
3230 this.yylloc.last_line = this.yylineno = this.yylloc.first_line;
3231 this.yylloc.last_column = this.yylloc.first_column;
3232 }
3233 }
3234
3235 return this;
3236 };
3237
3238 // check if the text matches
3239 lexer.prototype.tryMatch = function(text) {
3240 return text === this.ahead(text.length);
3241 };
3242
3243 // check if the text matches
3244 lexer.prototype.tryMatchCaseless = function(text) {
3245 return text === this.ahead(text.length).toLowerCase();
3246 };
3247
3248 // look ahead
3249 lexer.prototype.ahead = function(size) {
3250 var text = this._input.substring(this.offset, this.offset + size);
3251 if (text[text.length - 1] === '\r' && this._input[this.offset + size + 1] === '\n') {
3252 text += '\n';
3253 }
3254 return text;
3255 };
3256
3257 // consume the specified size
3258 lexer.prototype.consume = function(size) {
3259 for(var i = 0; i < size; i++) {
3260 var ch = this._input[this.offset];
3261 if (!ch) break;
3262 this.yytext += ch;
3263 this.offset ++;
3264 if ( ch === '\r' && this._input[this.offset] === '\n' ) {
3265 this.yytext += '\n';
3266 this.offset++;
3267 i++;
3268 }
3269 if (ch === '\n' || ch === '\r') {
3270 this.yylloc.last_line = ++this.yylineno;
3271 this.yyprevcol = this.yylloc.last_column;
3272 this.yylloc.last_column = 0;
3273 } else {
3274 this.yylloc.last_column++;
3275 }
3276 }
3277 return this;
3278 };
3279
3280 /**
3281 * Gets the current state
3282 */
3283 lexer.prototype.getState = function() {
3284 return {
3285 yytext: this.yytext,
3286 offset: this.offset,
3287 yylineno: this.yylineno,
3288 yyprevcol: this.yyprevcol,
3289 yylloc: {
3290 first_offset: this.yylloc.first_offset,
3291 first_line: this.yylloc.first_line,
3292 first_column: this.yylloc.first_column,
3293 last_line: this.yylloc.last_line,
3294 last_column: this.yylloc.last_column
3295 }
3296 };
3297 };
3298
3299 /**
3300 * Sets the current lexer state
3301 */
3302 lexer.prototype.setState = function(state) {
3303 this.yytext = state.yytext;
3304 this.offset = state.offset;
3305 this.yylineno = state.yylineno;
3306 this.yyprevcol = state.yyprevcol;
3307 this.yylloc = state.yylloc;
3308 return this;
3309 };
3310
3311 // prepend next token
3312 lexer.prototype.appendToken = function(value, ahead) {
3313 this.tokens.push([value, ahead]);
3314 return this;
3315 };
3316
3317 // return next match that has a token
3318 lexer.prototype.lex = function() {
3319 this.yylloc.prev_offset = this.offset;
3320 this.yylloc.prev_line = this.yylloc.last_line;
3321 this.yylloc.prev_column = this.yylloc.last_column;
3322 var token = this.next() || this.lex();
3323 if (!this.all_tokens) {
3324 while(
3325 token === this.tok.T_WHITESPACE // ignore white space
3326 || (
3327 !this.comment_tokens && (
3328 token === this.tok.T_COMMENT // ignore single lines comments
3329 || token === this.tok.T_DOC_COMMENT // ignore doc comments
3330 )
3331 )
3332 || (
3333 // ignore open tags
3334 token === this.tok.T_OPEN_TAG
3335 )
3336 ) {
3337 token = this.next() || this.lex();
3338 }
3339 if (!this.mode_eval && token == this.tok.T_OPEN_TAG_WITH_ECHO) {
3340 // open tag with echo statement
3341 return this.tok.T_ECHO;
3342 }
3343 }
3344 if (!this.yylloc.prev_offset) {
3345 this.yylloc.prev_offset = this.yylloc.first_offset;
3346 this.yylloc.prev_line = this.yylloc.first_line;
3347 this.yylloc.prev_column = this.yylloc.first_column;
3348 }
3349 /*else if (this.yylloc.prev_offset === this.offset && this.offset !== this.size) {
3350 throw new Error('Infinite loop @ ' + this.offset + ' / ' + this.size);
3351 }*/
3352 return token;
3353 };
3354
3355 // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
3356 lexer.prototype.begin = function(condition) {
3357 this.conditionStack.push(condition);
3358 this.curCondition = condition;
3359 this.stateCb = this['match' + condition];
3360 if (typeof this.stateCb !== 'function') {
3361 throw new Error('Undefined condition state "'+condition+'"');
3362 }
3363 return this;
3364 };
3365
3366 // pop the previously active lexer condition state off the condition stack
3367 lexer.prototype.popState = function() {
3368 var n = this.conditionStack.length - 1;
3369 var condition = (n > 0) ? this.conditionStack.pop() : this.conditionStack[0];
3370 this.curCondition = this.conditionStack[this.conditionStack.length - 1];
3371 this.stateCb = this['match' + this.curCondition];
3372 if (typeof this.stateCb !== 'function') {
3373 throw new Error('Undefined condition state "'+this.curCondition+'"');
3374 }
3375 return condition;
3376 };
3377
3378 // return next match in input
3379 lexer.prototype.next = function () {
3380 var token;
3381 if (!this._input) {
3382 this.done = true;
3383 }
3384 this.yylloc.first_offset = this.offset;
3385 this.yylloc.first_line = this.yylloc.last_line;
3386 this.yylloc.first_column = this.yylloc.last_column;
3387 this.yytext = '';
3388 if (this.done) {
3389 this.yylloc.prev_offset = this.yylloc.first_offset;
3390 this.yylloc.prev_line = this.yylloc.first_line;
3391 this.yylloc.prev_column = this.yylloc.first_column;
3392 return this.EOF;
3393 }
3394 if (this.tokens.length > 0) {
3395 token = this.tokens.shift();
3396 if (typeof token[1] === 'object') {
3397 this.setState(token[1]);
3398 } else {
3399 this.consume(token[1]);
3400 }
3401 token = token[0];
3402 } else {
3403 token = this.stateCb.apply(this, []);
3404 }
3405 if (this.offset >= this.size && this.tokens.length === 0) {
3406 this.done = true;
3407 }
3408 if (this.debug) {
3409 var tName = token;
3410 if (typeof tName === 'number') {
3411 tName = this.engine.tokens.values[tName];
3412 } else {
3413 tName = '"'+tName+'"';
3414 }
3415 var e = new Error(
3416 tName +
3417 '\tfrom ' + this.yylloc.first_line + ',' + this.yylloc.first_column +
3418 '\t - to ' + this.yylloc.last_line + ',' + this.yylloc.last_column +
3419 '\t"'+this.yytext+'"'
3420 );
3421 console.log(e.stack);
3422 }
3423 return token;
3424 };
3425
3426
3427 // extends the lexer with states
3428 [
3429 require('./lexer/comments.js'),
3430 require('./lexer/initial.js'),
3431 require('./lexer/numbers.js'),
3432 require('./lexer/property.js'),
3433 require('./lexer/scripting.js'),
3434 require('./lexer/strings.js'),
3435 require('./lexer/tokens.js'),
3436 require('./lexer/utils.js')
3437 ].forEach(function (ext) {
3438 for(var k in ext) {
3439 lexer.prototype[k] = ext[k];
3440 }
3441 });
3442
3443 module.exports = lexer;
3444
3445 },{"./lexer/comments.js":93,"./lexer/initial.js":94,"./lexer/numbers.js":95,"./lexer/property.js":96,"./lexer/scripting.js":97,"./lexer/strings.js":98,"./lexer/tokens.js":99,"./lexer/utils.js":100}],93:[function(require,module,exports){
3446 /*!
3447 * Copyright (C) 2017 Glayzzle (BSD3 License)
3448 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
3449 * @url http://glayzzle.com
3450 */
3451
3452 "use strict";
3453
3454 module.exports = {
3455 /**
3456 * Reads a single line comment
3457 * @see
3458 */
3459 T_COMMENT: function() {
3460 while(this.offset < this.size) {
3461 var ch = this.input();
3462 if (ch === '\n' || ch === '\r') {
3463 return this.tok.T_COMMENT;
3464 } else if (ch === '?' && !this.aspTagMode && this._input[this.offset] === '>') {
3465 this.unput(1);
3466 return this.tok.T_COMMENT;
3467 } else if (ch === '%' && this.aspTagMode && this._input[this.offset] === '>') {
3468 this.unput(1);
3469 return this.tok.T_COMMENT;
3470 }
3471 }
3472 return this.tok.T_COMMENT;
3473 },
3474 /**
3475 * Behaviour : https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1927
3476 */
3477 T_DOC_COMMENT: function() {
3478 var ch = this.input();
3479 var token = this.tok.T_COMMENT;
3480 if (ch === '*') { // started with '/*' , check is next is '*'
3481 ch = this.input();
3482 if (this.is_WHITESPACE()) { // check if next is WHITESPACE
3483 token = this.tok.T_DOC_COMMENT;
3484 }
3485 if (ch === '/') {
3486 return token;
3487 } else {
3488 this.unput(1); // reset
3489 }
3490 }
3491 while(this.offset < this.size) {
3492 ch = this.input();
3493 if (ch === '*' && this._input[this.offset] === '/') {
3494 this.input();
3495 break;
3496 }
3497 }
3498 return token;
3499 }
3500 };
3501
3502 },{}],94:[function(require,module,exports){
3503 /*!
3504 * Copyright (C) 2017 Glayzzle (BSD3 License)
3505 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
3506 * @url http://glayzzle.com
3507 */
3508 module.exports = {
3509 nextINITIAL: function() {
3510 if (
3511 this.conditionStack.length > 1
3512 && this.conditionStack[this.conditionStack.length - 1] === 'INITIAL'
3513 ) {
3514 // Return to HEREDOC/ST_DOUBLE_QUOTES mode
3515 this.popState();
3516 } else {
3517 this.begin("ST_IN_SCRIPTING");
3518 }
3519 return this;
3520 },
3521 matchINITIAL: function() {
3522 while(this.offset < this.size) {
3523 var ch = this.input();
3524 if (ch == '<') {
3525 ch = this.ahead(1);
3526 if (ch == '?') {
3527 if (this.tryMatch('?=')) {
3528 this.unput(1).appendToken(this.tok.T_OPEN_TAG_WITH_ECHO, 3).nextINITIAL();
3529 break;
3530 } else if (this.tryMatchCaseless('?php')) {
3531 ch = this._input[this.offset + 4];
3532 if (ch === ' ' || ch === '\t' || ch === '\n' || ch === '\r') {
3533 this.unput(1).appendToken(this.tok.T_OPEN_TAG, 6).nextINITIAL();
3534 break;
3535 }
3536 }
3537 if (this.short_tags) {
3538 this.unput(1).appendToken(this.tok.T_OPEN_TAG, 2).nextINITIAL();
3539 break;
3540 }
3541 } else if(this.asp_tags && ch == '%') {
3542 if (this.tryMatch('%=')) {
3543 this.aspTagMode = true;
3544 this.unput(1).appendToken(this.tok.T_OPEN_TAG_WITH_ECHO, 3).nextINITIAL();
3545 break;
3546 } else {
3547 this.aspTagMode = true;
3548 this.unput(1).appendToken(this.tok.T_OPEN_TAG, 2).nextINITIAL();
3549 break;
3550 }
3551 }
3552 }
3553 }
3554 if (this.yytext.length > 0) {
3555 return this.tok.T_INLINE_HTML;
3556 } else {
3557 return false;
3558 }
3559 }
3560 };
3561
3562 },{}],95:[function(require,module,exports){
3563 (function (process){
3564 /*!
3565 * Copyright (C) 2017 Glayzzle (BSD3 License)
3566 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
3567 * @url http://glayzzle.com
3568 */
3569
3570 "use strict";
3571
3572 /* istanbul ignore else */
3573 if (process.arch == 'x64') {
3574 var SIZEOF_LONG = 8;
3575 var MAX_LENGTH_OF_LONG = 19;
3576 var long_min_digits = "9223372036854775808";
3577 } else {
3578 var SIZEOF_LONG = 4;
3579 var MAX_LENGTH_OF_LONG = 10;
3580 var long_min_digits = "2147483648";
3581 }
3582
3583 module.exports = {
3584 consume_NUM: function() {
3585 var ch = this.yytext[0];
3586 var hasPoint = this.yytext[0] === '.';
3587 if (ch === '0') {
3588 ch = this.input();
3589 // check if hexa
3590 if (ch === 'x' || ch === 'X') {
3591 this.input();
3592 if (this.is_HEX()) {
3593 return this.consume_HNUM();
3594 } else {
3595 this.unput(2);
3596 }
3597 } else if (ch === 'b' || ch === 'B') {
3598 ch = this.input();
3599 if (ch === '0' || ch === '1') {
3600 return this.consume_BNUM();
3601 } else {
3602 this.unput(2);
3603 }
3604 } else if (!this.is_NUM()) {
3605 this.unput(1);
3606 }
3607 }
3608
3609 while(this.offset < this.size) {
3610 ch = this.input();
3611 if (!this.is_NUM()) {
3612 if (ch === '.' && !hasPoint) {
3613 hasPoint = true;
3614 } else if (ch === 'e' || ch === 'E') {
3615 ch = this.input();
3616 if (ch === '+' || ch === '-') {
3617 ch = this.input();
3618 if (this.is_NUM()) {
3619 this.consume_LNUM();
3620 return this.tok.T_DNUMBER;
3621 } else {
3622 if (ch) this.unput(3);
3623 break;
3624 }
3625 } else if (this.is_NUM()) {
3626 this.consume_LNUM();
3627 return this.tok.T_DNUMBER;
3628 } else {
3629 if (ch) this.unput(2);
3630 break;
3631 }
3632 } else {
3633 this.unput(1);
3634 break;
3635 }
3636 }
3637 }
3638 if (hasPoint) {
3639 return this.tok.T_DNUMBER;
3640 } else if (this.yytext.length < MAX_LENGTH_OF_LONG - 1) {
3641 return this.tok.T_LNUMBER;
3642 } else {
3643 if (
3644 this.yytext.length < MAX_LENGTH_OF_LONG || (
3645 this.yytext.length == MAX_LENGTH_OF_LONG
3646 && this.yytext < long_min_digits
3647 )
3648 ) {
3649 return this.tok.T_LNUMBER;
3650 }
3651 return this.tok.T_DNUMBER;
3652 }
3653 },
3654 // read hexa
3655 consume_HNUM: function() {
3656 while(this.offset < this.size) {
3657 this.input();
3658 if (!this.is_HEX()) {
3659 this.unput(1);
3660 break;
3661 }
3662 }
3663 return this.tok.T_LNUMBER;
3664 },
3665 // read a generic number
3666 consume_LNUM: function() {
3667 while(this.offset < this.size) {
3668 this.input();
3669 if (!this.is_NUM()) {
3670 this.unput(1);
3671 break;
3672 }
3673 }
3674 return this.tok.T_LNUMBER;
3675 },
3676 // read binary
3677 consume_BNUM: function() {
3678 var ch;
3679 while(this.offset < this.size) {
3680 ch = this.input();
3681 if (ch !== '0' && ch !== '1') {
3682 if (ch) this.unput(1);
3683 break;
3684 }
3685 }
3686 return this.tok.T_LNUMBER;
3687 }
3688 };
3689
3690 }).call(this,require('_process'))
3691 },{"_process":2}],96:[function(require,module,exports){
3692 /*!
3693 * Copyright (C) 2017 Glayzzle (BSD3 License)
3694 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
3695 * @url http://glayzzle.com
3696 */
3697 module.exports = {
3698 matchST_LOOKING_FOR_PROPERTY: function() {
3699 var ch = this.input();
3700 if (ch === '-') {
3701 ch = this.input();
3702 if (ch === '>') {
3703 // https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1296
3704 return this.tok.T_OBJECT_OPERATOR;
3705 }
3706 if (ch) this.unput(1);
3707 } else if (this.is_LABEL_START()) {
3708 // https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1300
3709 this.consume_LABEL();
3710 this.popState();
3711 return this.tok.T_STRING;
3712 }
3713 // https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1306
3714 this.popState();
3715 if (ch) this.unput(1);
3716 return false;
3717 },
3718 matchST_LOOKING_FOR_VARNAME: function() {
3719 var ch = this.input();
3720 if (this.is_LABEL_START()) {
3721 this.consume_LABEL();
3722 ch = this.input();
3723 this.popState();
3724 if (ch === '[' || ch === '}') {
3725 this.begin('ST_IN_SCRIPTING');
3726 this.unput(1);
3727 return this.tok.T_STRING_VARNAME;
3728 } else {
3729 this.unput(this.yytext.length);
3730 return false;
3731 }
3732 } else {
3733 if (ch) this.unput(1);
3734 this.popState();
3735 this.begin('ST_IN_SCRIPTING');
3736 // console.log(this.yylineno, 'ST_LOOKING_FOR_VARNAME', this._input[this.offset - 1], this.conditionStack);
3737 return false;
3738 }
3739 },
3740 matchST_VAR_OFFSET: function() {
3741 var ch = this.input();
3742 if (this.is_NUM()) {
3743 this.consume_NUM();
3744 return this.tok.T_NUM_STRING;
3745 } else if (ch === ']') {
3746 this.popState();
3747 return ']';
3748 } else if (ch === '$') {
3749 this.input();
3750 if (this.is_LABEL_START()) {
3751 this.consume_LABEL();
3752 return this.tok.T_VARIABLE;
3753 } else {
3754 throw new Error('Unexpected terminal');
3755 }
3756 } else if (this.is_LABEL_START()) {
3757 this.consume_LABEL();
3758 return this.tok.T_STRING;
3759 } else if (this.is_WHITESPACE() || ch === '\\' || ch === '\'' || ch === '#') {
3760 return this.tok.T_ENCAPSED_AND_WHITESPACE;
3761 } else if (ch === '[' || ch === '{' || ch === '}' || ch === '"' || ch === '`' || this.is_TOKEN()) {
3762 return ch;
3763 } else {
3764 throw new Error('Unexpected terminal');
3765 }
3766 }
3767 };
3768
3769 },{}],97:[function(require,module,exports){
3770 /*!
3771 * Copyright (C) 2017 Glayzzle (BSD3 License)
3772 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
3773 * @url http://glayzzle.com
3774 */
3775 module.exports = {
3776 matchST_IN_SCRIPTING: function() {
3777 var ch = this.input();
3778 switch(ch) {
3779 case ' ':
3780 case '\t':
3781 case '\n':
3782 case '\r':
3783 case '\r\n':
3784 return this.T_WHITESPACE();
3785 case '#':
3786 return this.T_COMMENT();
3787 case '/':
3788 if (this._input[this.offset] === '/') {
3789 return this.T_COMMENT();
3790 } else if (this._input[this.offset] === '*') {
3791 this.input();
3792 return this.T_DOC_COMMENT();
3793 }
3794 return this.consume_TOKEN();
3795 case '\'':
3796 return this.T_CONSTANT_ENCAPSED_STRING();
3797 case '"':
3798 return this.ST_DOUBLE_QUOTES();
3799 case '`':
3800 this.begin('ST_BACKQUOTE');
3801 return '`';
3802 case '?':
3803 if (!this.aspTagMode && this.tryMatch('>')) {
3804 this.input();
3805 var nextCH = this._input[this.offset];
3806 if (nextCH === '\n' || nextCH === '\r') this.input();
3807 if (this.conditionStack.length > 1) {
3808 this.begin('INITIAL');
3809 }
3810 return this.tok.T_CLOSE_TAG;
3811 }
3812 return this.consume_TOKEN();
3813 case '%':
3814 if (this.aspTagMode && this._input[this.offset] === '>') {
3815 this.input(); // consume the '>'
3816 ch = this._input[this.offset]; // read next
3817 if (ch === '\n' || ch === '\r') {
3818 this.input(); // consume the newline
3819 }
3820 this.aspTagMode = false;
3821 if (this.conditionStack.length > 1) {
3822 this.begin('INITIAL');
3823 }
3824 return this.tok.T_CLOSE_TAG;
3825 }
3826 return this.consume_TOKEN();
3827 case '{':
3828 this.begin('ST_IN_SCRIPTING');
3829 return '{';
3830 case '}':
3831 if (this.conditionStack.length > 2) {
3832 // Return to HEREDOC/ST_DOUBLE_QUOTES mode
3833 this.popState();
3834 }
3835 return '}';
3836 default:
3837 if (ch === '.') {
3838 ch = this.input();
3839 if (this.is_NUM()) {
3840 return this.consume_NUM();
3841 } else {
3842 if (ch) this.unput(1);
3843 }
3844 }
3845 if (this.is_NUM()) {
3846 return this.consume_NUM();
3847 } else if (this.is_LABEL_START()) {
3848 return this.consume_LABEL().T_STRING();
3849 } else if(this.is_TOKEN()) {
3850 return this.consume_TOKEN();
3851 }
3852 }
3853 throw new Error(
3854 'Bad terminal sequence "' + ch + '" at line ' + this.yylineno + ' (offset ' + this.offset + ')'
3855 );
3856 },
3857
3858 T_WHITESPACE: function() {
3859 while(this.offset < this.size) {
3860 var ch = this.input();
3861 if (ch === ' ' || ch === '\t' || ch === '\n' || ch === '\r') {
3862 continue;
3863 }
3864 this.unput(1);
3865 break;
3866 }
3867 return this.tok.T_WHITESPACE;
3868 }
3869 };
3870
3871 },{}],98:[function(require,module,exports){
3872 /*!
3873 * Copyright (C) 2017 Glayzzle (BSD3 License)
3874 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
3875 * @url http://glayzzle.com
3876 */
3877 module.exports = {
3878 T_CONSTANT_ENCAPSED_STRING: function() {
3879 var ch;
3880 while(this.offset < this.size) {
3881 ch = this.input();
3882 if (ch == '\\') {
3883 this.input();
3884 } else if (ch == '\'') {
3885 break;
3886 }
3887 }
3888 return this.tok.T_CONSTANT_ENCAPSED_STRING;
3889 },
3890 // check if matching a HEREDOC state
3891 is_HEREDOC: function() {
3892 var revert = this.offset;
3893 if (
3894 this._input[this.offset - 1] === '<'
3895 && this._input[this.offset] === '<'
3896 && this._input[this.offset + 1] === '<'
3897 ) {
3898 this.offset += 3;
3899
3900 // optional tabs / spaces
3901 if (this.is_TABSPACE()) {
3902 while(this.offset < this.size) {
3903 this.offset ++;
3904 if (!this.is_TABSPACE()) {
3905 break;
3906 }
3907 }
3908 }
3909
3910 // optional quotes
3911 var tChar = this._input[this.offset - 1];
3912 if (tChar === '\'' || tChar === '"') {
3913 this.offset ++;
3914 } else {
3915 tChar = null;
3916 }
3917
3918 // required label
3919 if (this.is_LABEL_START()) {
3920 var yyoffset = this.offset - 1;
3921 while(this.offset < this.size) {
3922 this.offset++;
3923 if (!this.is_LABEL()) {
3924 break;
3925 }
3926 }
3927 var yylabel = this._input.substring(yyoffset, this.offset - 1);
3928 if (!tChar || tChar === this._input[this.offset - 1]) { // required ending quote
3929 if (tChar) this.offset ++;
3930 // require newline
3931 if (this._input[this.offset - 1] === '\r' || this._input[this.offset - 1] === '\n') {
3932 // go go go
3933 this.heredoc_label = yylabel;
3934 yyoffset = this.offset - revert;
3935 this.offset = revert;
3936 this.consume(yyoffset);
3937 if (tChar === '\'') {
3938 this.begin('ST_NOWDOC');
3939 } else {
3940 this.begin('ST_HEREDOC');
3941 }
3942 return this.tok.T_START_HEREDOC;
3943 }
3944 }
3945 }
3946 }
3947 this.offset = revert;
3948 return false;
3949 },
3950 ST_DOUBLE_QUOTES: function() {
3951 var ch;
3952 while(this.offset < this.size) {
3953 ch = this.input();
3954 if (ch == '\\') {
3955 this.input();
3956 } else if (ch == '"') {
3957 break;
3958 } else if (ch == '$') {
3959 ch = this.input();
3960 if ( ch == '{' || this.is_LABEL_START()) {
3961 this.unput(2);
3962 break;
3963 }
3964 this.unput(1);
3965 } else if (ch == '{') {
3966 ch = this.input();
3967 if (ch == '$') {
3968 this.unput(2);
3969 break;
3970 }
3971 this.unput(1);
3972 }
3973 }
3974 if (ch == '"') {
3975 return this.tok.T_CONSTANT_ENCAPSED_STRING;
3976 } else {
3977 var prefix = 1;
3978 if (this.yytext[0] === 'b' || this.yytext[0] === 'B') {
3979 prefix = 2;
3980 }
3981 if (this.yytext.length > 2) {
3982 this.appendToken(
3983 this.tok.T_ENCAPSED_AND_WHITESPACE,
3984 this.yytext.length - prefix
3985 );
3986 }
3987 this.unput(this.yytext.length - prefix);
3988 this.begin("ST_DOUBLE_QUOTES");
3989 return this.yytext;
3990 }
3991 },
3992
3993 // check if its a DOC end sequence
3994 isDOC_MATCH: function() {
3995 // @fixme : check if out of text limits
3996 if (this._input.substring(this.offset - 1, this.offset - 1 + this.heredoc_label.length) === this.heredoc_label) {
3997 var ch = this._input[this.offset - 1 + this.heredoc_label.length];
3998 if (ch === '\n' || ch === '\r' || ch === ';') {
3999 return true;
4000 }
4001 }
4002 return false;
4003 },
4004
4005 matchST_NOWDOC: function() {
4006 /** edge case : empty now doc **/
4007 if (this.isDOC_MATCH()) {
4008 // @fixme : never reached (may be caused by quotes)
4009 this.consume(this.heredoc_label.length);
4010 this.popState();
4011 return this.tok.T_END_HEREDOC;
4012 }
4013 /** SCANNING CONTENTS **/
4014 var ch = this._input[this.offset - 1];
4015 while(this.offset < this.size) {
4016 if (ch === '\n' || ch === '\r') {
4017 ch = this.input();
4018 if (this.isDOC_MATCH()) {
4019 this.unput(1).popState();
4020 this.appendToken(
4021 this.tok.T_END_HEREDOC, this.heredoc_label.length
4022 );
4023 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4024 }
4025 } else {
4026 ch = this.input();
4027 }
4028 }
4029 // too bad ! reached end of document (will get a parse error)
4030 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4031 },
4032
4033 matchST_HEREDOC: function() {
4034 /** edge case : empty here doc **/
4035 var ch = this.input();
4036 if (this.isDOC_MATCH()) {
4037 this.consume(this.heredoc_label.length - 1);
4038 this.popState();
4039 return this.tok.T_END_HEREDOC;
4040 }
4041 /** SCANNING CONTENTS **/
4042 while(this.offset < this.size) {
4043
4044 if (ch === '\\') {
4045 ch = this.input(); // ignore next
4046 if (ch !== '\n' && ch !== '\r') {
4047 ch = this.input();
4048 }
4049 }
4050
4051 if (ch === '\n' || ch === '\r') {
4052 ch = this.input();
4053 if (this.isDOC_MATCH()) {
4054 this.unput(1).popState();
4055 this.appendToken(
4056 this.tok.T_END_HEREDOC, this.heredoc_label.length
4057 );
4058 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4059 }
4060 } else if (ch === '$') {
4061 ch = this.input();
4062 if (ch === '{') {
4063 // start of ${
4064 this.begin('ST_LOOKING_FOR_VARNAME');
4065 if (this.yytext.length > 2) {
4066 this.appendToken(this.tok.T_DOLLAR_OPEN_CURLY_BRACES, 2);
4067 this.unput(2);
4068 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4069 }else {
4070 return this.tok.T_DOLLAR_OPEN_CURLY_BRACES;
4071 }
4072 } else if (this.is_LABEL_START()) {
4073 // start of $var...
4074 var yyoffset = this.offset;
4075 var next = this.consume_VARIABLE();
4076 if (this.yytext.length > this.offset - yyoffset + 2) {
4077 this.appendToken(next, this.offset - yyoffset + 2);
4078 this.unput(this.offset - yyoffset + 2);
4079 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4080 } else {
4081 return next;
4082 }
4083 //console.log(this.yytext);
4084 }
4085 } else if (ch === '{') {
4086 ch = this.input();
4087 if (ch === '$') {
4088 // start of {$...
4089 this.begin('ST_IN_SCRIPTING');
4090 if (this.yytext.length > 2) {
4091 this.appendToken(this.tok.T_CURLY_OPEN, 1);
4092 this.unput(2);
4093 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4094 } else {
4095 this.unput(1);
4096 return this.tok.T_CURLY_OPEN;
4097 }
4098 }
4099 } else {
4100 ch = this.input();
4101 }
4102 }
4103
4104 // too bad ! reached end of document (will get a parse error)
4105 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4106 },
4107
4108 consume_VARIABLE: function() {
4109 this.consume_LABEL();
4110 ch = this.input();
4111 if (ch == '[') {
4112 this.unput(1);
4113 this.begin('ST_VAR_OFFSET');
4114 return this.tok.T_VARIABLE;
4115 } else if (ch === '-') {
4116 if (this.input() === '>') {
4117 this.input();
4118 if (this.is_LABEL_START()) {
4119 this.begin('ST_LOOKING_FOR_PROPERTY');
4120 }
4121 this.unput(3);
4122 return this.tok.T_VARIABLE;
4123 } else {
4124 this.unput(2);
4125 }
4126 } else {
4127 this.unput(1);
4128 }
4129 return this.tok.T_VARIABLE;
4130 },
4131 // HANDLES BACKQUOTES
4132 matchST_BACKQUOTE: function() {
4133
4134 var ch = this.input();
4135 if (ch === '$') {
4136 ch = this.input();
4137 if (ch === '{') {
4138 this.begin('ST_LOOKING_FOR_VARNAME');
4139 return this.tok.T_DOLLAR_OPEN_CURLY_BRACES;
4140 } else if (this.is_LABEL_START()) {
4141 var tok = this.consume_VARIABLE();
4142 return tok;
4143 }
4144 } else if (ch === '{') {
4145 if (this._input[this.offset] === '$') {
4146 this.begin('ST_IN_SCRIPTING');
4147 return this.tok.T_CURLY_OPEN;
4148 }
4149 } else if (ch === '`') {
4150 this.popState();
4151 return '`';
4152 }
4153
4154 // any char
4155 while(this.offset < this.size) {
4156 if (ch === '\\') {
4157 this.input();
4158 } else if (ch === '`') {
4159 this.unput(1);
4160 this.popState();
4161 this.appendToken('`', 1);
4162 break;
4163 } else if (ch === '$') {
4164 ch = this.input();
4165 if (ch === '{') {
4166 this.begin('ST_LOOKING_FOR_VARNAME');
4167 if (this.yytext.length > 2) {
4168 this.appendToken(this.tok.T_DOLLAR_OPEN_CURLY_BRACES, 2);
4169 this.unput(2);
4170 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4171 }else {
4172 return this.tok.T_DOLLAR_OPEN_CURLY_BRACES;
4173 }
4174 } else if (this.is_LABEL_START()) {
4175 // start of $var...
4176 var yyoffset = this.offset;
4177 var next = this.consume_VARIABLE();
4178 if (this.yytext.length > this.offset - yyoffset + 2) {
4179 this.appendToken(next, this.offset - yyoffset + 2);
4180 this.unput(this.offset - yyoffset + 2);
4181 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4182 } else {
4183 return next;
4184 }
4185 }
4186 this.unput(1);
4187 } else if (ch === '{') {
4188 ch = this.input();
4189 if (ch === '$') {
4190 // start of {$...
4191 this.begin('ST_IN_SCRIPTING');
4192 if (this.yytext.length > 2) {
4193 this.appendToken(this.tok.T_CURLY_OPEN, 1);
4194 this.unput(2);
4195 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4196 } else {
4197 this.unput(1);
4198 return this.tok.T_CURLY_OPEN;
4199 }
4200 }
4201 this.unput(1);
4202 }
4203 ch = this.input();
4204 }
4205 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4206
4207 },
4208
4209 matchST_DOUBLE_QUOTES: function() {
4210
4211 var ch = this.input();
4212 if (ch === '$') {
4213 ch = this.input();
4214 if (ch === '{') {
4215 this.begin('ST_LOOKING_FOR_VARNAME');
4216 return this.tok.T_DOLLAR_OPEN_CURLY_BRACES;
4217 } else if (this.is_LABEL_START()) {
4218 var tok = this.consume_VARIABLE();
4219 return tok;
4220 }
4221 } else if (ch === '{') {
4222 if (this._input[this.offset] === '$') {
4223 this.begin('ST_IN_SCRIPTING');
4224 return this.tok.T_CURLY_OPEN;
4225 }
4226 } else if (ch === '"') {
4227 this.popState();
4228 return '"';
4229 }
4230
4231 // any char
4232 while(this.offset < this.size) {
4233 if (ch === '\\') {
4234 this.input();
4235 } else if (ch === '"') {
4236 this.unput(1);
4237 this.popState();
4238 this.appendToken('"', 1);
4239 break;
4240 } else if (ch === '$') {
4241 ch = this.input();
4242 if (ch === '{') {
4243 this.begin('ST_LOOKING_FOR_VARNAME');
4244 if (this.yytext.length > 2) {
4245 this.appendToken(this.tok.T_DOLLAR_OPEN_CURLY_BRACES, 2);
4246 this.unput(2);
4247 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4248 }else {
4249 return this.tok.T_DOLLAR_OPEN_CURLY_BRACES;
4250 }
4251 } else if (this.is_LABEL_START()) {
4252 // start of $var...
4253 var yyoffset = this.offset;
4254 var next = this.consume_VARIABLE();
4255 if (this.yytext.length > this.offset - yyoffset + 2) {
4256 this.appendToken(next, this.offset - yyoffset + 2);
4257 this.unput(this.offset - yyoffset + 2);
4258 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4259 } else {
4260 return next;
4261 }
4262 }
4263 this.unput(1);
4264 } else if (ch === '{') {
4265 ch = this.input();
4266 if (ch === '$') {
4267 // start of {$...
4268 this.begin('ST_IN_SCRIPTING');
4269 if (this.yytext.length > 2) {
4270 this.appendToken(this.tok.T_CURLY_OPEN, 1);
4271 this.unput(2);
4272 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4273 } else {
4274 // @fixme : yytext = '"{$' (this.yytext.length > 3)
4275 this.unput(1);
4276 return this.tok.T_CURLY_OPEN;
4277 }
4278 }
4279 if (ch) this.unput(1);
4280 }
4281 ch = this.input();
4282 }
4283 return this.tok.T_ENCAPSED_AND_WHITESPACE;
4284 }
4285 };
4286
4287 },{}],99:[function(require,module,exports){
4288 /*!
4289 * Copyright (C) 2017 Glayzzle (BSD3 License)
4290 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
4291 * @url http://glayzzle.com
4292 */
4293 module.exports = {
4294 T_STRING: function() {
4295 var token = this.yytext.toLowerCase();
4296 var id = this.keywords[token];
4297 if (typeof id !== 'number') {
4298 if (token === 'yield') {
4299 if (this.tryMatch(' from')) {
4300 this.consume(5);
4301 id = this.tok.T_YIELD_FROM;
4302 } else {
4303 id = this.tok.T_YIELD;
4304 }
4305 } else {
4306 id = this.tok.T_STRING;
4307 if (token === 'b' || token === 'B') {
4308 var ch = this.input(1);
4309 if (ch === '"') {
4310 return this.ST_DOUBLE_QUOTES();
4311 } else if (ch === '\'') {
4312 return this.T_CONSTANT_ENCAPSED_STRING();
4313 } else if (ch) {
4314 this.unput(1);
4315 }
4316 }
4317 }
4318 }
4319 return id;
4320 },
4321 // reads a custom token
4322 consume_TOKEN: function() {
4323 var ch = this._input[this.offset - 1];
4324 var fn = this.tokenTerminals[ch];
4325 if (fn) {
4326 return fn.apply(this, []);
4327 } else {
4328 return this.yytext;
4329 }
4330 },
4331 // list of special char tokens
4332 tokenTerminals: {
4333 '$': function() {
4334 this.offset++;
4335 if (this.is_LABEL_START()) {
4336 this.offset--;
4337 this.consume_LABEL();
4338 return this.tok.T_VARIABLE;
4339 } else {
4340 this.offset--;
4341 return '$';
4342 }
4343 },
4344 '-': function() {
4345 var nchar = this._input[this.offset];
4346 if (nchar === '>') {
4347 this.begin('ST_LOOKING_FOR_PROPERTY').input();
4348 return this.tok.T_OBJECT_OPERATOR;
4349 } else if (nchar === '-') {
4350 this.input();
4351 return this.tok.T_DEC;
4352 } else if (nchar === '=') {
4353 this.input();
4354 return this.tok.T_MINUS_EQUAL;
4355 }
4356 return '-';
4357 },
4358 '\\': function() {
4359 return this.tok.T_NS_SEPARATOR;
4360 },
4361 '/': function() {
4362 if (this._input[this.offset] === '=') {
4363 this.input();
4364 return this.tok.T_DIV_EQUAL;
4365 }
4366 return '/';
4367 },
4368 ':': function() {
4369 if (this._input[this.offset] === ':') {
4370 this.input();
4371 return this.tok.T_DOUBLE_COLON;
4372 } else {
4373 return ':';
4374 }
4375 },
4376 '(': function() {
4377 var initial = this.offset;
4378 this.input();
4379 if (this.is_TABSPACE()) {
4380 this.consume_TABSPACE().input();
4381 }
4382 if (this.is_LABEL_START()) {
4383 var yylen = this.yytext.length;
4384 this.consume_LABEL();
4385 var castToken = this.yytext.substring(yylen - 1).toLowerCase();
4386 var castId = this.castKeywords[castToken];
4387 if (typeof castId === 'number') {
4388 this.input();
4389 if (this.is_TABSPACE()) {
4390 this.consume_TABSPACE().input();
4391 }
4392 if (this._input[this.offset - 1] === ')') {
4393 return castId;
4394 }
4395 }
4396 }
4397 // revert the check
4398 this.unput(this.offset - initial);
4399 return '(';
4400 },
4401 '=': function() {
4402 var nchar = this._input[this.offset];
4403 if (nchar === '>') {
4404 this.input();
4405 return this.tok.T_DOUBLE_ARROW;
4406 } else if (nchar === '=') {
4407 if (this._input[this.offset + 1] === '=') {
4408 this.consume(2);
4409 return this.tok.T_IS_IDENTICAL;
4410 } else {
4411 this.input();
4412 return this.tok.T_IS_EQUAL;
4413 }
4414 }
4415 return '=';
4416 },
4417 '+': function() {
4418 var nchar = this._input[this.offset];
4419 if (nchar === '+') {
4420 this.input();
4421 return this.tok.T_INC;
4422 } else if (nchar === '=') {
4423 this.input();
4424 return this.tok.T_PLUS_EQUAL;
4425 }
4426 return '+';
4427 },
4428 '!': function() {
4429 if (this._input[this.offset] === '=') {
4430 if (this._input[this.offset + 1] === '=') {
4431 this.consume(2);
4432 return this.tok.T_IS_NOT_IDENTICAL;
4433 } else {
4434 this.input();
4435 return this.tok.T_IS_NOT_EQUAL;
4436 }
4437 }
4438 return '!';
4439 },
4440 '?': function() {
4441 if (this._input[this.offset] === '?') {
4442 this.input();
4443 return this.tok.T_COALESCE;
4444 }
4445 return '?';
4446 },
4447 '<': function() {
4448 var nchar = this._input[this.offset];
4449 if (nchar === '<') {
4450 nchar = this._input[this.offset + 1];
4451 if (nchar === '=') {
4452 this.consume(2);
4453 return this.tok.T_SL_EQUAL;
4454 } else if (nchar === '<') {
4455 if (this.is_HEREDOC()) {
4456 return this.tok.T_START_HEREDOC;
4457 }
4458 }
4459 this.input();
4460 return this.tok.T_SL;
4461 } else if (nchar === '=') {
4462 this.input();
4463 if (this._input[this.offset] === '>') {
4464 this.input();
4465 return this.tok.T_SPACESHIP;
4466 } else {
4467 return this.tok.T_IS_SMALLER_OR_EQUAL;
4468 }
4469 } else if (nchar === '>') {
4470 this.input();
4471 return this.tok.T_IS_NOT_EQUAL;
4472 }
4473 return '<';
4474 },
4475 '>': function() {
4476 var nchar = this._input[this.offset];
4477 if (nchar === '=') {
4478 this.input();
4479 return this.tok.T_IS_GREATER_OR_EQUAL;
4480 } else if (nchar === '>') {
4481 nchar = this._input[this.offset + 1];
4482 if (nchar === '=') {
4483 this.consume(2);
4484 return this.tok.T_SR_EQUAL;
4485 } else {
4486 this.input();
4487 return this.tok.T_SR;
4488 }
4489 }
4490 return '>';
4491 },
4492 '*': function() {
4493 var nchar = this._input[this.offset];
4494 if (nchar === '=') {
4495 this.input();
4496 return this.tok.T_MUL_EQUAL;
4497 } else if(nchar === '*') {
4498 this.input();
4499 if (this._input[this.offset] === '=') {
4500 this.input();
4501 return this.tok.T_POW_EQUAL;
4502 } else {
4503 return this.tok.T_POW;
4504 }
4505 }
4506 return '*';
4507 },
4508 '.': function() {
4509 var nchar = this._input[this.offset];
4510 if (nchar === '=') {
4511 this.input();
4512 return this.tok.T_CONCAT_EQUAL;
4513 } else if (nchar === '.' && this._input[this.offset + 1] === '.') {
4514 this.consume(2);
4515 return this.tok.T_ELLIPSIS;
4516 }
4517 return '.';
4518 },
4519 '%': function() {
4520 if (this._input[this.offset] === '=') {
4521 this.input();
4522 return this.tok.T_MOD_EQUAL;
4523 }
4524 return '%';
4525 },
4526 '&': function() {
4527 var nchar = this._input[this.offset];
4528 if (nchar === '=') {
4529 this.input();
4530 return this.tok.T_AND_EQUAL;
4531 } else if (nchar === '&') {
4532 this.input();
4533 return this.tok.T_BOOLEAN_AND;
4534 }
4535 return '&';
4536 },
4537 '|': function() {
4538 var nchar = this._input[this.offset];
4539 if (nchar === '=') {
4540 this.input();
4541 return this.tok.T_OR_EQUAL;
4542 } else if (nchar === '|') {
4543 this.input();
4544 return this.tok.T_BOOLEAN_OR;
4545 }
4546 return '|';
4547 },
4548 '^': function() {
4549 if (this._input[this.offset] === '=') {
4550 this.input();
4551 return this.tok.T_XOR_EQUAL;
4552 }
4553 return '^';
4554 }
4555 }
4556 };
4557
4558 },{}],100:[function(require,module,exports){
4559 /*!
4560 * Copyright (C) 2017 Glayzzle (BSD3 License)
4561 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
4562 * @url http://glayzzle.com
4563 */
4564 var tokens = ';:,.\\[]()|^&+-/*=%!~$<>?@';
4565
4566 module.exports = {
4567
4568 // check if the char can be a numeric
4569 is_NUM: function() {
4570 var ch = this._input.charCodeAt(this.offset - 1);
4571 return ch > 47 && ch < 58;
4572 },
4573
4574 // check if current char can be a label
4575 is_LABEL: function() {
4576 var ch = this._input.charCodeAt(this.offset - 1);
4577 return (ch > 96 && ch < 123)
4578 || (ch > 64 && ch < 91)
4579 || ch === 95
4580 || (ch > 47 && ch < 58)
4581 || ch > 126
4582 ;
4583 },
4584
4585 // check if current char can be a label
4586 is_LABEL_START: function() {
4587 var ch = this._input.charCodeAt(this.offset - 1);
4588 return (ch > 96 && ch < 123)
4589 || (ch > 64 && ch < 91)
4590 || ch === 95
4591 || (ch > 126)
4592 ;
4593 },
4594
4595
4596 // reads each char of the label
4597 consume_LABEL: function() {
4598 while(this.offset < this.size) {
4599 this.input();
4600 if (!this.is_LABEL()) {
4601 this.unput(1);
4602 break;
4603 }
4604 }
4605 return this;
4606 },
4607
4608 // check if current char is a token char
4609 is_TOKEN: function() {
4610 var ch = this._input[this.offset - 1];
4611 return tokens.indexOf(ch) !== -1;
4612 },
4613 // check if current char is a whitespace
4614 is_WHITESPACE: function() {
4615 var ch = this._input[this.offset - 1];
4616 return ch === ' ' || ch === '\t' || ch === '\n' || ch === '\r';
4617 },
4618 // check if current char is a whitespace (without newlines)
4619 is_TABSPACE: function() {
4620 var ch = this._input[this.offset - 1];
4621 return ch === ' ' || ch === '\t';
4622 },
4623 // consume all whitespaces (excluding newlines)
4624 consume_TABSPACE: function() {
4625 while(this.offset < this.size) {
4626 this.input();
4627 if (!this.is_TABSPACE()) {
4628 this.unput(1);
4629 break;
4630 }
4631 }
4632 return this;
4633 },
4634 // check if current char can be a hexadecimal number
4635 is_HEX: function() {
4636 var ch = this._input.charCodeAt(this.offset - 1);
4637 return (ch > 47 && ch < 58) || (ch > 64 && ch < 71) || (ch > 96 && ch < 103);
4638 }
4639 };
4640
4641 },{}],101:[function(require,module,exports){
4642 /*!
4643 * Copyright (C) 2017 Glayzzle (BSD3 License)
4644 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
4645 * @url http://glayzzle.com
4646 */
4647
4648 /**
4649 * @private check if argument is a number
4650 */
4651 function isNumber(n) {
4652 return n != '.' && n != ',' && !isNaN(parseFloat(n)) && isFinite(n);
4653 }
4654
4655
4656 /**
4657 * The PHP Parser class that build the AST tree from the lexer
4658 * @constructor {Parser}
4659 * @property {Lexer} lexer - current lexer instance
4660 * @property {AST} ast - the AST factory instance
4661 * @property {Integer|String} token - current token
4662 * @property {Boolean} extractDoc - should extract documentation as AST node
4663 * @property {Boolean} suppressErrors - should ignore parsing errors and continue
4664 * @property {Boolean} debug - should output debug informations
4665 */
4666 var parser = function(lexer, ast) {
4667 this.lexer = lexer;
4668 this.ast = ast;
4669 this.tok = lexer.tok;
4670 this.EOF = lexer.EOF;
4671 this.token = null;
4672 this.prev = null;
4673 this.debug = false;
4674 this.extractDoc = false;
4675 this.suppressErrors = false;
4676 this.entries = {
4677 'IDENTIFIER': [
4678 this.tok.T_CLASS_C,
4679 this.tok.T_DIR,
4680 this.tok.T_FILE,
4681 this.tok.T_FUNC_C,
4682 this.tok.T_LINE,
4683 this.tok.T_METHOD_C,
4684 this.tok.T_NS_C,
4685 this.tok.T_TRAIT,
4686 this.tok.T_ABSTRACT,
4687 this.tok.T_LOGICAL_AND,
4688 this.tok.T_ARRAY,
4689 this.tok.T_AS,
4690 this.tok.T_BREAK,
4691 this.tok.T_CALLABLE,
4692 this.tok.T_CASE,
4693 this.tok.T_CATCH,
4694 this.tok.T_CLASS,
4695 this.tok.T_CLONE,
4696 this.tok.T_CONST,
4697 this.tok.T_CONTINUE,
4698 this.tok.T_DECLARE,
4699 this.tok.T_DEFAULT,
4700 this.tok.T_DO,
4701 this.tok.T_ECHO,
4702 this.tok.T_ELSE,
4703 this.tok.T_ELSEIF,
4704 this.tok.T_EMPTY,
4705 this.tok.T_ENDDECLARE,
4706 this.tok.T_ENDFOR,
4707 this.tok.T_ENDFOREACH,
4708 this.tok.T_ENDIF,
4709 this.tok.T_ENDSWITCH,
4710 this.tok.T_ENDWHILE,
4711 this.tok.T_EVAL,
4712 this.tok.T_EXIT,
4713 this.tok.T_EXTENDS,
4714 this.tok.T_FINAL,
4715 this.tok.T_FINALLY,
4716 this.tok.T_FOR,
4717 this.tok.T_FOREACH,
4718 this.tok.T_FUNCTION,
4719 this.tok.T_GLOBAL,
4720 this.tok.T_GOTO,
4721 this.tok.T_IF,
4722 this.tok.T_IMPLEMENTS,
4723 this.tok.T_INCLUDE,
4724 this.tok.T_INCLUDE_ONCE,
4725 this.tok.T_INSTANCEOF,
4726 this.tok.T_INSTEADOF,
4727 this.tok.T_INTERFACE,
4728 this.tok.T_ISSET,
4729 this.tok.T_LIST,
4730 this.tok.T_NAMESPACE,
4731 this.tok.T_NEW,
4732 this.tok.T_LOGICAL_OR,
4733 this.tok.T_PRINT,
4734 this.tok.T_PRIVATE,
4735 this.tok.T_PROTECTED,
4736 this.tok.T_PUBLIC,
4737 this.tok.T_REQUIRE,
4738 this.tok.T_REQUIRE_ONCE,
4739 this.tok.T_RETURN,
4740 this.tok.T_STATIC,
4741 this.tok.T_SWITCH,
4742 this.tok.T_THROW,
4743 this.tok.T_TRAIT,
4744 this.tok.T_TRY,
4745 this.tok.T_UNSET,
4746 this.tok.T_USE,
4747 this.tok.T_VAR,
4748 this.tok.T_WHILE,
4749 this.tok.T_LOGICAL_XOR,
4750 this.tok.T_YIELD
4751 ],
4752 'VARIABLE': [
4753 this.tok.T_VARIABLE,
4754 '$', '&',
4755 this.tok.T_NS_SEPARATOR,
4756 this.tok.T_STRING,
4757 this.tok.T_NAMESPACE,
4758 this.tok.T_STATIC
4759 ],
4760 'SCALAR': [
4761 this.tok.T_CONSTANT_ENCAPSED_STRING,
4762 this.tok.T_START_HEREDOC,
4763 this.tok.T_LNUMBER,
4764 this.tok.T_DNUMBER,
4765 this.tok.T_ARRAY,'[',
4766 this.tok.T_CLASS_C,
4767 this.tok.T_TRAIT_C,
4768 this.tok.T_FUNC_C,
4769 this.tok.T_METHOD_C,
4770 this.tok.T_LINE,
4771 this.tok.T_FILE,
4772 this.tok.T_DIR,
4773 this.tok.T_NS_C,
4774 '"',
4775 'b"',
4776 'B"',
4777 '-',
4778 this.tok.T_NS_SEPARATOR
4779 ],
4780 'T_MAGIC_CONST': [
4781 this.tok.T_CLASS_C,
4782 this.tok.T_TRAIT_C,
4783 this.tok.T_FUNC_C,
4784 this.tok.T_METHOD_C,
4785 this.tok.T_LINE,
4786 this.tok.T_FILE,
4787 this.tok.T_DIR,
4788 this.tok.T_NS_C
4789 ],
4790 'T_MEMBER_FLAGS': [
4791 this.tok.T_PUBLIC,
4792 this.tok.T_PRIVATE,
4793 this.tok.T_PROTECTED,
4794 this.tok.T_STATIC,
4795 this.tok.T_ABSTRACT,
4796 this.tok.T_FINAL
4797 ],
4798 'EOS': [
4799 ';',
4800 this.tok.T_CLOSE_TAG,
4801 this.EOF,
4802 this.tok.T_INLINE_HTML
4803 ],
4804 'EXPR': [
4805 '@','-','+','!','~','(','`',
4806 this.tok.T_LIST,
4807 this.tok.T_CLONE,
4808 this.tok.T_INC,
4809 this.tok.T_DEC,
4810 this.tok.T_NEW,
4811 this.tok.T_ISSET,
4812 this.tok.T_EMPTY,
4813 this.tok.T_INCLUDE,
4814 this.tok.T_INCLUDE_ONCE,
4815 this.tok.T_REQUIRE,
4816 this.tok.T_REQUIRE_ONCE,
4817 this.tok.T_EVAL,
4818 this.tok.T_INT_CAST,
4819 this.tok.T_DOUBLE_CAST,
4820 this.tok.T_STRING_CAST,
4821 this.tok.T_ARRAY_CAST,
4822 this.tok.T_OBJECT_CAST,
4823 this.tok.T_BOOL_CAST,
4824 this.tok.T_UNSET_CAST,
4825 this.tok.T_EXIT,
4826 this.tok.T_PRINT,
4827 this.tok.T_YIELD,
4828 this.tok.T_STATIC,
4829 this.tok.T_FUNCTION,
4830 // using VARIABLES :
4831 this.tok.T_VARIABLE,
4832 '$',
4833 this.tok.T_NS_SEPARATOR,
4834 this.tok.T_STRING,
4835 // using SCALAR :
4836 this.tok.T_STRING, // @see variable.js line 45 > conflict with variable = shift/reduce :)
4837 this.tok.T_CONSTANT_ENCAPSED_STRING,
4838 this.tok.T_START_HEREDOC,
4839 this.tok.T_LNUMBER,
4840 this.tok.T_DNUMBER,
4841 this.tok.T_ARRAY,'[',
4842 this.tok.T_CLASS_C,
4843 this.tok.T_TRAIT_C,
4844 this.tok.T_FUNC_C,
4845 this.tok.T_METHOD_C,
4846 this.tok.T_LINE,
4847 this.tok.T_FILE,
4848 this.tok.T_DIR,
4849 this.tok.T_NS_C
4850 ]
4851 };
4852 };
4853
4854 /**
4855 * helper : gets a token name
4856 */
4857 parser.prototype.getTokenName = function(token) {
4858 if (!isNumber(token)) {
4859 return "'" + token + "'";
4860 } else {
4861 if (token == this.EOF) return 'the end of file (EOF)';
4862 return this.lexer.engine.tokens.values[token];
4863 }
4864 };
4865
4866 /**
4867 * main entry point : converts a source code to AST
4868 */
4869 parser.prototype.parse = function(code, filename) {
4870 this._errors = [];
4871 this.filename = filename || 'eval';
4872 this.currentNamespace = [''];
4873 this.lexer.setInput(code);
4874 this.lexer.comment_tokens = this.extractDoc;
4875 this.length = this.lexer._input.length;
4876 this.innerList = false;
4877 var program = this.ast.prepare('program', this);
4878 var childs = [];
4879 this.nextWithComments();
4880 while(this.token != this.EOF) {
4881 var node = this.read_start();
4882 if (node !== null && node !== undefined) {
4883 if (Array.isArray(node)) {
4884 childs = childs.concat(node);
4885 } else {
4886 childs.push(node);
4887 }
4888 }
4889 }
4890 return program(childs, this._errors);
4891 };
4892
4893 /**
4894 * Raise an error
4895 */
4896 parser.prototype.raiseError = function(message, msgExpect, expect, token) {
4897 message += ' on line ' + this.lexer.yylloc.first_line;
4898 if (!this.suppressErrors) {
4899 var err = new SyntaxError(
4900 message, this.filename, this.lexer.yylloc.first_line
4901 );
4902 err.lineNumber = this.lexer.yylloc.first_line;
4903 err.fileName = this.filename;
4904 err.columnNumber = this.lexer.yylloc.first_column
4905 throw err;
4906 }
4907 // Error node :
4908 var node = this.ast.prepare('error', this)(
4909 message, token, this.lexer.yylloc.first_line, expect
4910 );
4911 this._errors.push(node);
4912 return node;
4913 };
4914
4915 /**
4916 * handling errors
4917 */
4918 parser.prototype.error = function(expect) {
4919 var msg = 'Parse Error : syntax error';
4920 token = this.getTokenName(this.token);
4921 if (this.token !== this.EOF) {
4922 if (isNumber(this.token)) {
4923 var symbol = this.text();
4924 if (symbol.length > 10) {
4925 symbol = symbol.substring(0, 7) + '...';
4926 }
4927 token = '\''+symbol+'\' ('+token+')';
4928 }
4929 msg += ', unexpected ' + token;
4930 }
4931 var msgExpect = '';
4932 if (expect && !Array.isArray(expect)) {
4933 if (isNumber(expect) || expect.length === 1) {
4934 msgExpect = ', expecting ' + this.getTokenName(expect);
4935 }
4936 msg += msgExpect;
4937 }
4938 this.token !== this.EOF
4939 return this.raiseError(
4940 msg,
4941 msgExpect,
4942 expect,
4943 token
4944 );
4945 };
4946
4947 /**
4948 * Creates a new AST node
4949 */
4950 parser.prototype.node = function(name) {
4951 return this.ast.prepare(name, this);
4952 };
4953
4954 /**
4955 * expects an end of statement or end of file
4956 * @return {boolean}
4957 */
4958 parser.prototype.expectEndOfStatement = function() {
4959 if (this.token === ';') {
4960 this.nextWithComments();
4961 if (this.token === this.tok.T_CLOSE_TAG) {
4962 // strip close tag (statement already closed with ';')
4963 this.nextWithComments();
4964 }
4965 } else if (this.token === this.tok.T_CLOSE_TAG) {
4966 this.nextWithComments();
4967 } else if (this.token !== this.tok.T_INLINE_HTML && this.token !== this.EOF) {
4968 this.error(';');
4969 return false;
4970 }
4971 return true;
4972 };
4973
4974 /** outputs some debug information on current token **/
4975 var ignoreStack = ['parser.next', 'parser.ignoreComments', 'parser.nextWithComments'];
4976 parser.prototype.showlog = function() {
4977 var stack = (new Error()).stack.split('\n');
4978 var line;
4979 for (var offset = 2; offset < stack.length; offset ++) {
4980 line = stack[offset].trim();
4981 var found = false;
4982 for(var i = 0; i < ignoreStack.length; i++) {
4983 if (line.substring(3, 3 + ignoreStack[i].length) === ignoreStack[i]) {
4984 found = true;
4985 break;
4986 }
4987 }
4988 if (!found) {
4989 break;
4990 }
4991 }
4992
4993 console.log(
4994 'Line '
4995 + this.lexer.yylloc.first_line
4996 + ' : '
4997 + this.getTokenName(this.token)
4998 + ">" + this.lexer.yytext + "<"
4999 + ' @-->' + line
5000 );
5001 return this;
5002 };
5003
5004 /**
5005 * Force the parser to check the current token.
5006 *
5007 * If the current token does not match to expected token,
5008 * the an error will be raised.
5009 *
5010 * If the suppressError mode is activated, then the error will
5011 * be added to the program error stack and this function will return `false`.
5012 *
5013 * @param {String|Number} token
5014 * @return {boolean}
5015 * @throws Error
5016 */
5017 parser.prototype.expect = function(token) {
5018 if (Array.isArray(token)) {
5019 if (token.indexOf(this.token) === -1) {
5020 this.error(token);
5021 return false;
5022 }
5023 } else if (this.token != token) {
5024 this.error(token);
5025 return false;
5026 }
5027 return true;
5028 };
5029
5030 /**
5031 * Returns the current token contents
5032 * @return {String}
5033 */
5034 parser.prototype.text = function() {
5035 return this.lexer.yytext;
5036 };
5037
5038 /** consume the next token **/
5039 parser.prototype.next = function() {
5040 if (this.debug) {
5041 this.showlog();
5042 this.debug = false;
5043 this.nextWithComments().ignoreComments();
5044 this.debug = true;
5045 } else {
5046 this.nextWithComments().ignoreComments();
5047 }
5048 return this;
5049 };
5050
5051 /** consume comments (if found) **/
5052 parser.prototype.ignoreComments = function() {
5053 if (this.debug) this.showlog();
5054 while(this.token === this.tok.T_COMMENT || this.token === this.tok.T_DOC_COMMENT) {
5055 // IGNORE COMMENTS
5056 this.nextWithComments();
5057 }
5058 return this;
5059 };
5060
5061 /** consume the next token (including doc) **/
5062 parser.prototype.nextWithComments = function() {
5063 this.prev = [
5064 this.lexer.yylloc.first_line,
5065 this.lexer.yylloc.first_column,
5066 this.lexer.offset
5067 ];
5068 this.token = this.lexer.lex() || this.EOF;
5069 if (this.debug) this.showlog();
5070 return this;
5071 };
5072
5073 /**
5074 * Check if token is of specified type
5075 */
5076 parser.prototype.is = function(type) {
5077 if (Array.isArray(type)) {
5078 return type.indexOf(this.token) !== -1;
5079 } else {
5080 return this.entries[type].indexOf(this.token) != -1;
5081 }
5082 };
5083
5084 // extends the parser with syntax files
5085 [
5086 require('./parser/array.js'),
5087 require('./parser/class.js'),
5088 require('./parser/comment.js'),
5089 require('./parser/expr.js'),
5090 require('./parser/function.js'),
5091 require('./parser/if.js'),
5092 require('./parser/loops.js'),
5093 require('./parser/main.js'),
5094 require('./parser/namespace.js'),
5095 require('./parser/scalar.js'),
5096 require('./parser/statement.js'),
5097 require('./parser/switch.js'),
5098 require('./parser/try.js'),
5099 require('./parser/utils.js'),
5100 require('./parser/variable.js')
5101 ].forEach(function (ext) {
5102 for(var k in ext) {
5103 parser.prototype[k] = ext[k];
5104 }
5105 });
5106
5107 module.exports = parser;
5108
5109 },{"./parser/array.js":102,"./parser/class.js":103,"./parser/comment.js":104,"./parser/expr.js":105,"./parser/function.js":106,"./parser/if.js":107,"./parser/loops.js":108,"./parser/main.js":109,"./parser/namespace.js":110,"./parser/scalar.js":111,"./parser/statement.js":112,"./parser/switch.js":113,"./parser/try.js":114,"./parser/utils.js":115,"./parser/variable.js":116}],102:[function(require,module,exports){
5110 /*!
5111 * Copyright (C) 2017 Glayzzle (BSD3 License)
5112 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
5113 * @url http://glayzzle.com
5114 */
5115 var ArrayExpr = 'array';
5116 var ArrayEntry = 'entry';
5117
5118 module.exports = {
5119 /**
5120 * Parse an array
5121 * ```ebnf
5122 * array ::= T_ARRAY '(' array_pair_list ')' |
5123 * '[' array_pair_list ']'
5124 * ```
5125 */
5126 read_array: function() {
5127 var expect = null;
5128 var shortForm = false;
5129 var items = [];
5130 var result = this.node(ArrayExpr);
5131
5132 if (this.token === this.tok.T_ARRAY) {
5133 this.next().expect('(');
5134 expect = ')';
5135 } else {
5136 shortForm = true;
5137 expect = ']';
5138 }
5139
5140 if (this.next().token != expect) {
5141 while(this.token != this.EOF) {
5142 items.push(this.read_array_pair_list());
5143 if (this.token == ',') {
5144 this.next();
5145 if (this.token === expect) {
5146 break;
5147 }
5148 } else break;
5149 }
5150 }
5151 this.expect(expect);
5152 this.next();
5153 return result(shortForm, items);
5154 },
5155 /**
5156 * Reads an array entry item
5157 * ```ebnf
5158 * array_pair_list ::= '&' w_variable |
5159 * (
5160 * expr (
5161 * T_DOUBLE_ARROW (
5162 * expr | '&' w_variable
5163 * )
5164 * )?
5165 * )
5166 * ```
5167 */
5168 read_array_pair_list: function() {
5169 var result = this.node(ArrayEntry);
5170 var key = null;
5171 var value = null;
5172 if (this.token === '&') {
5173 value = this.next().read_variable(true, false, true);
5174 } else {
5175 var expr = this.read_expr();
5176 if (this.token === this.tok.T_DOUBLE_ARROW) {
5177 key = expr;
5178 if (this.next().token === '&') {
5179 value = this.next().read_variable(true, false, true);
5180 } else {
5181 value = this.read_expr();
5182 }
5183 } else {
5184 value = expr;
5185 }
5186 }
5187 return result(key, value);
5188 },
5189 /**
5190 * ```ebnf
5191 * dim_offset ::= expr?
5192 * ```
5193 */
5194 read_dim_offset: function() {
5195 if (this.token == ']') return false;
5196 return this.read_expr();
5197 }
5198 };
5199
5200 },{}],103:[function(require,module,exports){
5201 /*!
5202 * Copyright (C) 2017 Glayzzle (BSD3 License)
5203 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
5204 * @url http://glayzzle.com
5205 */
5206
5207 module.exports = {
5208 /**
5209 * reading a class
5210 * ```ebnf
5211 * class ::= class_scope? T_CLASS T_STRING (T_EXTENDS NAMESPACE_NAME)? (T_IMPLEMENTS (NAMESPACE_NAME ',')* NAMESPACE_NAME)? '{' CLASS_BODY '}'
5212 * ```
5213 */
5214 read_class: function(flag) {
5215 var result = this.node('class');
5216 this.expect(this.tok.T_CLASS);
5217 this.next().expect(this.tok.T_STRING);
5218 var propName = this.text()
5219 , propExtends = null
5220 , propImplements = null
5221 , body
5222 ;
5223 if (this.next().token == this.tok.T_EXTENDS) {
5224 propExtends = this.next().read_namespace_name();
5225 }
5226 if (this.token == this.tok.T_IMPLEMENTS) {
5227 propImplements = this.next().read_name_list();
5228 }
5229 this.expect('{');
5230 body = this.nextWithComments().read_class_body();
5231 return result(
5232 propName
5233 ,propExtends
5234 ,propImplements
5235 ,body
5236 ,flag
5237 );
5238 }
5239 /**
5240 * Read the class visibility
5241 * ```ebnf
5242 * class_scope ::= (T_FINAL | T_ABSTRACT)?
5243 * ```
5244 */
5245 ,read_class_scope: function() {
5246 var result = this.token;
5247 if (result == this.tok.T_FINAL) {
5248 this.next();
5249 return [0, 0, 2];
5250 } else if (result == this.tok.T_ABSTRACT) {
5251 this.next();
5252 return [0, 0, 1];
5253 }
5254 return [0, 0, 0];
5255 }
5256 /**
5257 * Reads a class body
5258 * ```ebnf
5259 * class_body ::= (member_flags? (T_VAR | T_STRING | T_FUNCTION))*
5260 * ```
5261 */
5262 ,read_class_body: function() {
5263 var result = [];
5264
5265 while(this.token !== this.EOF && this.token !== '}') {
5266
5267 if (this.token === this.tok.T_COMMENT) {
5268 result.push(this.read_comment());
5269 continue;
5270 }
5271
5272 if (this.token === this.tok.T_DOC_COMMENT) {
5273 result.push(this.read_doc_comment());
5274 continue;
5275 }
5276
5277 // check T_USE trait
5278 if (this.token === this.tok.T_USE) {
5279 result = result.concat(
5280 this.next().read_trait_use_statement()
5281 );
5282 continue;
5283 }
5284
5285 // read member flags
5286 var flags = this.read_member_flags(false);
5287
5288 // check constant
5289 if (this.token === this.tok.T_CONST) {
5290 var constants = this.read_constant_list(flags);
5291 this.expect(';');
5292 this.nextWithComments();
5293 result = result.concat(constants);
5294 continue;
5295 }
5296
5297 // jump over T_VAR then land on T_VARIABLE
5298 if (this.token === this.tok.T_VAR) {
5299 this.next().expect(this.tok.T_VARIABLE);
5300 flags[0] = flags[1] = 0; // public & non static var
5301 }
5302
5303 if (this.token === this.tok.T_VARIABLE) {
5304
5305 // reads a variable
5306 var variables = this.read_variable_list(flags);
5307 this.expect(';');
5308 this.nextWithComments();
5309 result = result.concat(variables);
5310
5311 } else if (this.token === this.tok.T_FUNCTION) {
5312
5313 // reads a function
5314 result.push(this.read_function(false, flags));
5315
5316 } else {
5317
5318 // raise an error
5319 this.error([
5320 this.tok.T_CONST,
5321 this.tok.T_VARIABLE,
5322 this.tok.T_FUNCTION
5323 ]);
5324 // ignore token
5325 this.next();
5326
5327 }
5328 }
5329 this.expect('}');
5330 this.nextWithComments();
5331 return result;
5332 }
5333 /**
5334 * Reads variable list
5335 * ```ebnf
5336 * variable_list ::= (variable_declaration ',')* variable_declaration
5337 * ```
5338 */
5339 ,read_variable_list: function(flags) {
5340 return this.read_list(
5341 /**
5342 * Reads a variable declaration
5343 *
5344 * ```ebnf
5345 * variable_declaration ::= T_VARIABLE '=' scalar
5346 * ```
5347 */
5348 function read_variable_declaration() {
5349 var result = this.node('property');
5350 this.expect(this.tok.T_VARIABLE);
5351 var name = this.text().substring(1); // ignore $
5352 this.next();
5353 if (this.token === ';' || this.token === ',') {
5354 return result(name, null, flags);
5355 } else if(this.token === '=') {
5356 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L815
5357 return result(name, this.next().read_expr(), flags);
5358 } else {
5359 this.expect([',', ';', '=']);
5360 return result(name, null, flags);
5361 }
5362 }, ','
5363 );
5364 }
5365 /**
5366 * Reads constant list
5367 * ```ebnf
5368 * constant_list ::= T_CONST (constant_declaration ',')* constant_declaration
5369 * ```
5370 */
5371 ,read_constant_list: function(flags) {
5372 if (this.expect(this.tok.T_CONST)) {
5373 this.next();
5374 }
5375 return this.read_list(
5376 /**
5377 * Reads a constant declaration
5378 *
5379 * ```ebnf
5380 * constant_declaration ::= T_STRING '=' expr
5381 * ```
5382 * @return {Constant} [:link:](AST.md#constant)
5383 */
5384 function read_constant_declaration() {
5385 var result = this.node('classconstant'), name = null, value = null;
5386 if (this.is('IDENTIFIER') || this.expect(this.tok.T_STRING)) {
5387 name = this.text();
5388 this.next();
5389 }
5390 if (this.expect('=')) {
5391 value = this.next().read_expr();
5392 }
5393 return result(name, value, flags);
5394 }, ','
5395 )
5396 ;
5397 }
5398 /**
5399 * Read member flags
5400 * @return array
5401 * 1st index : 0 => public, 1 => protected, 2 => private
5402 * 2nd index : 0 => instance member, 1 => static member
5403 * 3rd index : 0 => normal, 1 => abstract member, 2 => final member
5404 */
5405 ,read_member_flags: function(asInterface) {
5406 var result = [-1, -1, -1];
5407 if (this.is('T_MEMBER_FLAGS')) {
5408 var idx = 0, val = 0;
5409 do {
5410 switch(this.token) {
5411 case this.tok.T_PUBLIC: idx = 0; val = 0; break;
5412 case this.tok.T_PROTECTED: idx = 0; val = 1; break;
5413 case this.tok.T_PRIVATE: idx = 0; val = 2; break;
5414 case this.tok.T_STATIC: idx = 1; val = 1; break;
5415 case this.tok.T_ABSTRACT: idx = 2; val = 1; break;
5416 case this.tok.T_FINAL: idx = 2; val = 2; break;
5417 }
5418 if (asInterface) {
5419 if (idx == 0 && val == 2) {
5420 // an interface can't be private
5421 this.expect([this.tok.T_PUBLIC, this.tok.T_PROTECTED]);
5422 val = -1;
5423 } else if (idx == 2 && val == 1) {
5424 // an interface cant be abstract
5425 this.error();
5426 val = -1;
5427 }
5428 }
5429 if (result[idx] !== -1) {
5430 // already defined flag
5431 this.error();
5432 } else if (val !== -1) {
5433 result[idx] = val;
5434 }
5435 } while(this.next().is('T_MEMBER_FLAGS'));
5436 }
5437
5438 if (result[0] == -1) result[0] = 0;
5439 if (result[1] == -1) result[1] = 0;
5440 if (result[2] == -1) result[2] = 0;
5441 return result;
5442 }
5443 /**
5444 * reading an interface
5445 * ```ebnf
5446 * interface ::= T_INTERFACE T_STRING (T_EXTENDS (NAMESPACE_NAME ',')* NAMESPACE_NAME)? '{' INTERFACE_BODY '}'
5447 * ```
5448 */
5449 ,read_interface: function() {
5450 var result = this.node('interface'), name = null, body = null, propExtends = null;
5451 if (this.expect(this.tok.T_INTERFACE)) {
5452 this.next();
5453 }
5454 if (this.expect(this.tok.T_STRING)) {
5455 name = this.text();
5456 this.next();
5457 }
5458 if (this.token === this.tok.T_EXTENDS) {
5459 propExtends = this.next().read_name_list();
5460 }
5461 if (this.expect('{')) {
5462 body = this.next().read_interface_body();
5463 }
5464 return result(name, propExtends, body);
5465 }
5466 /**
5467 * Reads an interface body
5468 * ```ebnf
5469 * interface_body ::= (member_flags? (T_CONST | T_FUNCTION))*
5470 * ```
5471 */
5472 ,read_interface_body: function() {
5473 var result = [];
5474
5475 while(this.token !== this.EOF && this.token !== '}') {
5476
5477 if (this.token === this.tok.T_COMMENT) {
5478 result.push(this.read_comment());
5479 continue;
5480 }
5481
5482 if (this.token === this.tok.T_DOC_COMMENT) {
5483 result.push(this.read_doc_comment());
5484 continue;
5485 }
5486
5487 // read member flags
5488 var flags = this.read_member_flags(true);
5489
5490 // check constant
5491 if (this.token == this.tok.T_CONST) {
5492 var constants = this.read_constant_list(flags);
5493 if (this.expect(';')) {
5494 this.nextWithComments();
5495 }
5496 result = result.concat(constants);
5497 }
5498
5499 // reads a function
5500 else if (this.token === this.tok.T_FUNCTION) {
5501 var method = this.read_function_declaration(2, flags);
5502 method.parseFlags(flags);
5503 result.push(method);
5504 if (this.expect(';')) {
5505 this.nextWithComments();
5506 }
5507 } else {
5508 // raise an error
5509 this.error([
5510 this.tok.T_CONST,
5511 this.tok.T_FUNCTION
5512 ]);
5513 this.next();
5514 }
5515 }
5516 if (this.expect('}')) {
5517 this.next();
5518 }
5519 return result;
5520 }
5521 /**
5522 * reading a trait
5523 * ```ebnf
5524 * trait ::= T_TRAIT T_STRING (T_EXTENDS (NAMESPACE_NAME ',')* NAMESPACE_NAME)? '{' FUNCTION* '}'
5525 * ```
5526 */
5527 ,read_trait: function(flag) {
5528 var result = this.node('trait'),
5529 propName = null,
5530 propExtends = null,
5531 propImplements = null,
5532 body = null;
5533 if (this.expect(this.tok.T_TRAIT)) {
5534 this.next();
5535 }
5536 if (this.expect(this.tok.T_STRING)) {
5537 propName = this.text();
5538 }
5539 if (this.next().token == this.tok.T_EXTENDS) {
5540 propExtends = this.next().read_namespace_name();
5541 }
5542 if (this.token == this.tok.T_IMPLEMENTS) {
5543 propImplements = this.next().read_name_list();
5544 }
5545 if (this.expect('{')) {
5546 body = this.next().read_class_body();
5547 }
5548 return result(
5549 propName,
5550 propExtends,
5551 propImplements,
5552 body
5553 );
5554 }
5555 /**
5556 * reading a use statement
5557 * ```ebnf
5558 * trait_use_statement ::= namespace_name (',' namespace_name)* ('{' trait_use_alias '}')?
5559 * ```
5560 */
5561 ,read_trait_use_statement: function() {
5562 // defines use statements
5563 var node = this.node('traituse');
5564 var traits = [this.read_namespace_name()];
5565 var adaptations = null;
5566 while(this.token === ',') {
5567 traits.push(
5568 this.next().read_namespace_name()
5569 );
5570 }
5571 if (this.token === '{') {
5572 adaptations = [];
5573 // defines alias statements
5574 while(this.next().token !== this.EOF) {
5575 if (this.token === '}') break;
5576 adaptations.push(this.read_trait_use_alias());
5577 this.expect(';');
5578 }
5579 if (this.expect('}')) {
5580 this.nextWithComments();
5581 }
5582 } else {
5583 if (this.expect(';')) {
5584 this.nextWithComments();
5585 }
5586 }
5587 return node(traits, adaptations);
5588 }
5589 /**
5590 * Reading trait alias
5591 * ```ebnf
5592 * trait_use_alias ::= namespace_name ( T_DOUBLE_COLON T_STRING )? (T_INSTEADOF namespace_name) | (T_AS member_flags? T_STRING)
5593 * ```
5594 */
5595 ,read_trait_use_alias: function() {
5596 var node = this.node();
5597 var trait = null;
5598 var method;
5599
5600 if(this.is('IDENTIFIER')) {
5601 method = this.text();
5602 this.next();
5603 } else {
5604 method = this.read_namespace_name();
5605
5606 if (this.token === this.tok.T_DOUBLE_COLON) {
5607 this.next();
5608
5609 if (this.is('IDENTIFIER') || this.expect(this.tok.T_STRING)) {
5610 trait = method;
5611 method = this.text();
5612 this.next();
5613 }
5614 } else {
5615 // convert identifier as string
5616 method = method.name;
5617 }
5618 }
5619
5620 // handle trait precedence
5621 if (this.token === this.tok.T_INSTEADOF) {
5622 return node(
5623 'traitprecedence',
5624 trait, method,
5625 this.next().read_name_list()
5626 );
5627 }
5628
5629 // handle trait alias
5630 else if (this.token === this.tok.T_AS) {
5631 var flags = false;
5632 var alias = null;
5633 if (this.next().is('T_MEMBER_FLAGS')) {
5634 flags = this.read_member_flags();
5635 }
5636
5637 if (this.is('IDENTIFIER') || this.token === this.tok.T_STRING) {
5638 alias = this.text();
5639 this.next();
5640 } else if (flags === false) {
5641 // no visibility flags and no name => too bad
5642 this.expect(this.tok.T_STRING);
5643 }
5644
5645 return node('traitalias', trait, method, alias, flags)
5646 }
5647
5648 // handle errors
5649 this.expect([this.tok.T_AS, this.tok.T_INSTEADOF]);
5650 return node('traitalias', trait, method, null, null);
5651 }
5652 };
5653
5654 },{}],104:[function(require,module,exports){
5655 /*!
5656 * Copyright (C) 2017 Glayzzle (BSD3 License)
5657 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
5658 * @url http://glayzzle.com
5659 */
5660
5661 var docSplit = /^(\s*\*[ \t]*|[ \t]*)(.*)$/gm;
5662
5663 module.exports = {
5664 /**
5665 * Comments with // or # or / * ... * /
5666 */
5667 read_comment: function() {
5668 var result = this.node('doc');
5669 var lines = [];
5670 do {
5671 var line = this.text();
5672 if (line[0] === '#') {
5673 line = line.substring(1);
5674 } else {
5675 line = line.substring(2);
5676 if (line.substring(line.length - 2) === '*/') {
5677 line = line.substring(0, line.length - 2);
5678 }
5679 }
5680 lines.push(line.trim());
5681 } while(this.nextWithComments().token === this.tok.T_COMMENT);
5682 return result(false, lines);
5683 },
5684 /**
5685 * Comments with / ** ... * /
5686 */
5687 read_doc_comment: function() {
5688 var result = this.node('doc');
5689 var text = this.text();
5690 text = text.substring(2, text.length - 2);
5691 var lines = [];
5692 text = text.split(docSplit);
5693 for(var i = 2; i < text.length; i += 3) {
5694 lines.push(text[i].trim());
5695 }
5696 this.nextWithComments();
5697 return result(true, lines);
5698 }
5699 };
5700
5701 },{}],105:[function(require,module,exports){
5702 /*!
5703 * Copyright (C) 2017 Glayzzle (BSD3 License)
5704 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
5705 * @url http://glayzzle.com
5706 */
5707 "use strict";
5708
5709 module.exports = {
5710
5711 read_expr: function() {
5712 var result = this.node();
5713 var expr = this.read_expr_item();
5714 // binary operations
5715 if (this.token === '|')
5716 return result('bin', '|', expr, this.next().read_expr());
5717 if (this.token === '&')
5718 return result('bin', '&', expr, this.next().read_expr());
5719 if (this.token === '^')
5720 return result('bin', '^', expr, this.next().read_expr());
5721 if (this.token === '.')
5722 return result('bin', '.', expr, this.next().read_expr());
5723 if (this.token === '+')
5724 return result('bin', '+', expr, this.next().read_expr());
5725 if (this.token === '-')
5726 return result('bin', '-', expr, this.next().read_expr());
5727 if (this.token === '*')
5728 return result('bin', '*', expr, this.next().read_expr());
5729 if (this.token === '/')
5730 return result('bin', '/', expr, this.next().read_expr());
5731 if (this.token === '%')
5732 return result('bin', '%', expr, this.next().read_expr());
5733 if (this.token === this.tok.T_POW)
5734 return result('bin', '**', expr, this.next().read_expr());
5735 if (this.token === this.tok.T_SL)
5736 return result('bin', '<<', expr, this.next().read_expr());
5737 if (this.token === this.tok.T_SR)
5738 return result('bin', '>>', expr, this.next().read_expr());
5739 // more binary operations (formerly bool)
5740 if (this.token === this.tok.T_BOOLEAN_OR)
5741 return result('bin', '||', expr, this.next().read_expr());
5742 if (this.token === this.tok.T_LOGICAL_OR)
5743 return result('bin', 'or', expr, this.next().read_expr());
5744 if (this.token === this.tok.T_BOOLEAN_AND)
5745 return result('bin', '&&', expr, this.next().read_expr());
5746 if (this.token === this.tok.T_LOGICAL_AND)
5747 return result('bin', 'and', expr, this.next().read_expr());
5748 if (this.token === this.tok.T_LOGICAL_XOR)
5749 return result('bin', 'xor', expr, this.next().read_expr());
5750 if (this.token === this.tok.T_IS_IDENTICAL)
5751 return result('bin', '===', expr, this.next().read_expr());
5752 if (this.token === this.tok.T_IS_NOT_IDENTICAL)
5753 return result('bin', '!==', expr, this.next().read_expr());
5754 if (this.token === this.tok.T_IS_EQUAL)
5755 return result('bin', '==', expr, this.next().read_expr());
5756 if (this.token === this.tok.T_IS_NOT_EQUAL)
5757 return result('bin', '!=', expr, this.next().read_expr());
5758 if (this.token === '<')
5759 return result('bin', '<', expr, this.next().read_expr());
5760 if (this.token === '>')
5761 return result('bin', '>', expr, this.next().read_expr());
5762 if (this.token === this.tok.T_IS_SMALLER_OR_EQUAL)
5763 return result('bin', '<=', expr, this.next().read_expr());
5764 if (this.token === this.tok.T_IS_GREATER_OR_EQUAL)
5765 return result('bin', '>=', expr, this.next().read_expr());
5766 if (this.token === this.tok.T_SPACESHIP)
5767 return result('bin', '<=>', expr, this.next().read_expr());
5768 if (this.token === this.tok.T_INSTANCEOF)
5769 return result('bin', 'instanceof', expr, this.next().read_expr());
5770
5771 // extra operations :
5772 // $username = $_GET['user'] ?? 'nobody';
5773 if (this.token === this.tok.T_COALESCE)
5774 return result('bin', '??', expr, this.next().read_expr());
5775
5776 // extra operations :
5777 // $username = $_GET['user'] ? true : false;
5778 if (this.token === '?') {
5779 var trueArg = null;
5780 if (this.next().token !== ':') {
5781 trueArg = this.read_expr();
5782 }
5783 this.expect(':') && this.next();
5784 return result('retif', expr, trueArg, this.read_expr());
5785 }
5786
5787 return expr;
5788 }
5789
5790 /**
5791 * ```ebnf
5792 * Reads an expression
5793 * expr ::= @todo
5794 * ```
5795 */
5796 ,read_expr_item: function() {
5797
5798 if (this.token === '@')
5799 return this.node('silent')(this.next().read_expr());
5800 if (this.token === '+')
5801 return this.node('unary')('+', this.next().read_expr());
5802 if (this.token === '!')
5803 return this.node('unary')('!', this.next().read_expr());
5804 if (this.token === '~')
5805 return this.node('unary')('~', this.next().read_expr());
5806
5807 if (this.token === '-') {
5808 var result = this.node();
5809 this.next();
5810 if (
5811 this.token === this.tok.T_LNUMBER ||
5812 this.token === this.tok.T_DNUMBER
5813 ) {
5814 // negative number
5815 result = result('number', '-' + this.text());
5816 this.next();
5817 return result;
5818 } else {
5819 return result('unary', '-', this.read_expr());
5820 }
5821 }
5822
5823 if (this.token === '(') {
5824 var node = this.node('parenthesis');
5825 var expr = this.next().read_expr();
5826 this.expect(')') && this.next();
5827 expr = node(expr);
5828 // handle dereferencable
5829 if (this.token === this.tok.T_OBJECT_OPERATOR) {
5830 return this.recursive_variable_chain_scan(expr, false);
5831 } else if (this.token === this.tok.T_CURLY_OPEN || this.token === '[') {
5832 return this.read_dereferencable(expr);
5833 } else if (this.token === '(') {
5834 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1118
5835 return this.node('call')(
5836 expr, this.read_function_argument_list()
5837 );
5838 } else {
5839 return expr;
5840 }
5841 }
5842
5843 if (this.token === '`') {
5844 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1048
5845 return this.next().read_encapsed_string('`');
5846 }
5847
5848 if (this.token === this.tok.T_LIST) {
5849 var result = this.node('list'), assign = null;
5850 var isInner = this.innerList;
5851 if (!isInner) {
5852 assign = this.node('assign');
5853 }
5854 if (this.next().expect('(')) {
5855 this.next();
5856 }
5857
5858 if (!this.innerList) this.innerList = true;
5859 var assignList = this.read_assignment_list();
5860
5861 // check if contains at least one assignment statement
5862 var hasItem = false;
5863 for(var i = 0; i < assignList.length; i++) {
5864 if (assignList[i] !== null) {
5865 hasItem = true;
5866 break;
5867 }
5868 }
5869 if (!hasItem) {
5870 this.raiseError(
5871 'Fatal Error : Cannot use empty list on line ' + this.lexer.yylloc.first_line
5872 );
5873 }
5874 if (this.expect(')')) {
5875 this.next();
5876 }
5877
5878 if (!isInner) {
5879 this.innerList = false;
5880 if (this.expect('=')) {
5881 return assign(
5882 result(assignList),
5883 this.next().read_expr(),
5884 '='
5885 );
5886 } else {
5887 // fallback : list($a, $b);
5888 return result(assignList);
5889 }
5890 } else {
5891 return result(assignList);
5892 }
5893 }
5894
5895 if (this.token === this.tok.T_CLONE)
5896 return this.node('clone')(
5897 this.next().read_expr()
5898 );
5899
5900 switch(this.token) {
5901
5902 case this.tok.T_INC:
5903 return this.node('pre')(
5904 '+', this.next().read_variable(false, false, false)
5905 );
5906
5907 case this.tok.T_DEC:
5908 return this.node('pre')(
5909 '-', this.next().read_variable(false, false, false)
5910 );
5911
5912 case this.tok.T_NEW:
5913 return this.next().read_new_expr();
5914
5915 case this.tok.T_ISSET:
5916 var result = this.node('isset');
5917 if (this.next().expect('(')) {
5918 this.next();
5919 }
5920 var args = this.read_list(this.read_expr, ',');
5921 if (this.expect(')')) {
5922 this.next();
5923 }
5924 return result(args);
5925
5926 case this.tok.T_EMPTY:
5927 var result = this.node('empty');
5928 if (this.next().expect('(')) {
5929 this.next();
5930 }
5931 var arg = this.read_expr();
5932 if (this.expect(')')) {
5933 this.next();
5934 }
5935 return result([arg]);
5936
5937 case this.tok.T_INCLUDE:
5938 return this.node('include')(
5939 false, false,
5940 this.next().read_expr()
5941 );
5942
5943 case this.tok.T_INCLUDE_ONCE:
5944 return this.node('include')(
5945 true, false,
5946 this.next().read_expr()
5947 );
5948
5949 case this.tok.T_REQUIRE:
5950 return this.node('include')(
5951 false, true,
5952 this.next().read_expr()
5953 );
5954
5955 case this.tok.T_REQUIRE_ONCE:
5956 return this.node('include')(
5957 true, true,
5958 this.next().read_expr()
5959 );
5960
5961 case this.tok.T_EVAL:
5962 var result = this.node('eval');
5963 if (this.next().expect('(')) {
5964 this.next();
5965 }
5966 var expr = this.read_expr();
5967 if (this.expect(')')) {
5968 this.next();
5969 }
5970 return result(expr);
5971
5972 case this.tok.T_INT_CAST:
5973 return this.node('cast')('int', this.next().read_expr());
5974
5975 case this.tok.T_DOUBLE_CAST:
5976 return this.node('cast')('double', this.next().read_expr());
5977
5978 case this.tok.T_STRING_CAST:
5979 return this.node('cast')('string', this.next().read_expr());
5980
5981 case this.tok.T_ARRAY_CAST:
5982 return this.node('cast')('array', this.next().read_expr());
5983
5984 case this.tok.T_OBJECT_CAST:
5985 return this.node('cast')('object', this.next().read_expr());
5986
5987 case this.tok.T_BOOL_CAST:
5988 return this.node('cast')('boolean', this.next().read_expr());
5989
5990 case this.tok.T_UNSET_CAST:
5991 return this.node('unset')(
5992 this.next().read_expr()
5993 );
5994
5995 case this.tok.T_EXIT:
5996 var result = this.node('exit');
5997 var status = null;
5998 if ( this.next().token === '(' ) {
5999 if (this.next().token !== ')') {
6000 status = this.read_expr();
6001 if (this.expect(')')) {
6002 this.next();
6003 }
6004 } else {
6005 this.next();
6006 }
6007 }
6008 return result(status);
6009
6010 case this.tok.T_PRINT:
6011 return this.node('print')(
6012 this.next().read_expr()
6013 );
6014
6015 // T_YIELD (expr (T_DOUBLE_ARROW expr)?)?
6016 case this.tok.T_YIELD:
6017 var result = this.node('yield'), value = null, key = null;
6018 if (this.next().is('EXPR')) {
6019 // reads the yield return value
6020 value = this.read_expr();
6021 if (this.token === this.tok.T_DOUBLE_ARROW) {
6022 // reads the yield returned key
6023 key = value;
6024 value = this.next().read_expr();
6025 }
6026 }
6027 return result(value, key);
6028
6029 // T_YIELD_FROM expr
6030 case this.tok.T_YIELD_FROM:
6031 var result = this.node('yieldfrom');
6032 var expr = this.next().read_expr();
6033 return result(expr);
6034
6035 case this.tok.T_FUNCTION:
6036 return this.read_function(true);
6037
6038 case this.tok.T_STATIC:
6039 var backup = [this.token, this.lexer.getState()];
6040 if (this.next().token === this.tok.T_FUNCTION) {
6041 // handles static function
6042 return this.read_function(true, [0, 1, 0]);
6043 } else {
6044 // rollback
6045 this.lexer.tokens.push(backup);
6046 this.next();
6047 }
6048
6049
6050 }
6051
6052 // SCALAR | VARIABLE
6053 var expr;
6054 if (this.is('VARIABLE')) {
6055 var result = this.node();
6056 expr = this.read_variable(false, false, false);
6057
6058 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L877
6059 // should accept only a variable
6060 var isConst = (
6061 expr.kind === 'constref' || (
6062 expr.kind === 'staticlookup' &&
6063 expr.offset.kind === 'constref'
6064 )
6065 );
6066
6067 // VARIABLES SPECIFIC OPERATIONS
6068 switch(this.token) {
6069 case '=':
6070 if (isConst) this.error('VARIABLE');
6071 var right;
6072 if (this.next().token == '&') {
6073 if (this.next().token === this.tok.T_NEW) {
6074 right = this.next().read_new_expr();
6075 } else {
6076 right = this.read_variable(false, false, true);
6077 }
6078 } else {
6079 right = this.read_expr();
6080 }
6081 return result('assign', expr, right, '=');
6082
6083 // operations :
6084 case this.tok.T_PLUS_EQUAL:
6085 if (isConst) this.error('VARIABLE');
6086 return result('assign', expr, this.next().read_expr(), '+=');
6087
6088 case this.tok.T_MINUS_EQUAL:
6089 if (isConst) this.error('VARIABLE');
6090 return result('assign', expr, this.next().read_expr(), '-=');
6091
6092 case this.tok.T_MUL_EQUAL:
6093 if (isConst) this.error('VARIABLE');
6094 return result('assign', expr, this.next().read_expr(), '*=');
6095
6096 case this.tok.T_POW_EQUAL:
6097 if (isConst) this.error('VARIABLE');
6098 return result('assign', expr, this.next().read_expr(), '**=');
6099
6100 case this.tok.T_DIV_EQUAL:
6101 if (isConst) this.error('VARIABLE');
6102 return result('assign', expr, this.next().read_expr(), '/=');
6103
6104 case this.tok.T_CONCAT_EQUAL:
6105 if (isConst) this.error('VARIABLE');
6106 return result('assign', expr, this.next().read_expr(), '.=');
6107
6108 case this.tok.T_MOD_EQUAL:
6109 if (isConst) this.error('VARIABLE');
6110 return result('assign', expr, this.next().read_expr(), '%=');
6111
6112 case this.tok.T_AND_EQUAL:
6113 if (isConst) this.error('VARIABLE');
6114 return result('assign', expr, this.next().read_expr(), '&=');
6115
6116 case this.tok.T_OR_EQUAL:
6117 if (isConst) this.error('VARIABLE');
6118 return result('assign', expr, this.next().read_expr(), '|=');
6119
6120 case this.tok.T_XOR_EQUAL:
6121 if (isConst) this.error('VARIABLE');
6122 return result('assign', expr, this.next().read_expr(), '^=');
6123
6124 case this.tok.T_SL_EQUAL:
6125 if (isConst) this.error('VARIABLE');
6126 return result('assign', expr, this.next().read_expr(), '<<=');
6127
6128 case this.tok.T_SR_EQUAL:
6129 if (isConst) this.error('VARIABLE');
6130 return result('assign',expr, this.next().read_expr(), '>>=');
6131
6132 case this.tok.T_INC:
6133 if (isConst) this.error('VARIABLE');
6134 this.next();
6135 return result('post', '+', expr);
6136 case this.tok.T_DEC:
6137 if (isConst) this.error('VARIABLE');
6138 this.next();
6139 return result('post', '-', expr);
6140 }
6141 } else if (this.is('SCALAR')) {
6142 expr = this.read_scalar();
6143 // handle dereferencable
6144 while(this.token !== this.EOF) {
6145 if (this.token === this.tok.T_OBJECT_OPERATOR) {
6146 expr = this.recursive_variable_chain_scan(expr, false);
6147 } else if (this.token === this.tok.T_CURLY_OPEN || this.token === '[') {
6148 expr = this.read_dereferencable(expr);
6149 } else if (this.token === '(') {
6150 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1118
6151 expr = this.node('call')(expr, this.read_function_argument_list());
6152 } else {
6153 return expr;
6154 }
6155 }
6156 } else {
6157 this.error('EXPR');
6158 this.next();
6159 }
6160
6161 // returns variable | scalar
6162 return expr;
6163
6164 }
6165 /**
6166 * ```ebnf
6167 * new_expr ::= T_NEW (namespace_name function_argument_list) | (T_CLASS ... class declaration)
6168 * ```
6169 * https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L850
6170 */
6171 ,read_new_expr: function() {
6172 var result = this.node('new');
6173 if (this.token === this.tok.T_CLASS) {
6174 var what = this.node('class');
6175 // Annonymous class declaration
6176 var propExtends = null, propImplements = null, body = null, args = [];
6177 if (this.next().token === '(') {
6178 args = this.read_function_argument_list();
6179 }
6180 if (this.token == this.tok.T_EXTENDS) {
6181 propExtends = this.next().read_namespace_name();
6182 }
6183 if (this.token == this.tok.T_IMPLEMENTS) {
6184 propImplements = this.next().read_name_list();
6185 }
6186 if (this.expect('{')) {
6187 body = this.next().read_class_body();
6188 }
6189 return result(
6190 what(
6191 null
6192 ,propExtends
6193 ,propImplements
6194 ,body
6195 ,[0, 0, 0]
6196 ), args
6197 );
6198 } else {
6199 // Already existing class
6200 var name = this.read_class_name_reference();
6201 var args = [];
6202 if (this.token === '(') {
6203 args = this.read_function_argument_list();
6204 }
6205 return result(name, args);
6206 }
6207 }
6208 /**
6209 * Reads a class name
6210 * ```ebnf
6211 * class_name_reference ::= namespace_name | variable
6212 * ```
6213 */
6214 ,read_class_name_reference: function() {
6215 if (
6216 this.token === this.tok.T_NS_SEPARATOR ||
6217 this.token === this.tok.T_STRING ||
6218 this.token === this.tok.T_NAMESPACE
6219 ) {
6220 var result = this.read_namespace_name();
6221 if (this.token === this.tok.T_DOUBLE_COLON) {
6222 result = this.read_static_getter(result);
6223 }
6224 return result;
6225 } else if (this.is('VARIABLE')) {
6226 return this.read_variable(true, false, false);
6227 } else {
6228 this.expect([this.tok.T_STRING, 'VARIABLE']);
6229 }
6230 }
6231 /**
6232 * ```ebnf
6233 * assignment_list ::= assignment_list_element (',' assignment_list_element?)*
6234 * ```
6235 */
6236 ,read_assignment_list: function() {
6237 return this.read_list(
6238 this.read_assignment_list_element, ','
6239 );
6240 }
6241
6242 /**
6243 * ```ebnf
6244 * assignment_list_element ::= expr | expr T_DOUBLE_ARROW expr
6245 * ```
6246 */
6247 ,read_assignment_list_element: function() {
6248 if (this.token === ',' || this.token === ')') return null;
6249 var result = this.read_expr_item();
6250 if (this.token === this.tok.T_DOUBLE_ARROW) {
6251 result = [
6252 'key',
6253 result,
6254 this.next().read_expr_item()
6255 ];
6256 }
6257 return result;
6258 }
6259 };
6260
6261 },{}],106:[function(require,module,exports){
6262 /*!
6263 * Copyright (C) 2017 Glayzzle (BSD3 License)
6264 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
6265 * @url http://glayzzle.com
6266 */
6267
6268 module.exports = {
6269 /**
6270 * checks if current token is a reference keyword
6271 */
6272 is_reference: function() {
6273 if (this.token == '&') {
6274 this.next();
6275 return true;
6276 }
6277 return false;
6278 }
6279 /**
6280 * checks if current token is a variadic keyword
6281 */
6282 ,is_variadic: function() {
6283 if (this.token === this.tok.T_ELLIPSIS) {
6284 this.next();
6285 return true;
6286 }
6287 return false;
6288 }
6289 /**
6290 * reading a function
6291 * ```ebnf
6292 * function ::= function_declaration code_block
6293 * ```
6294 */
6295 ,read_function: function(closure, flag) {
6296 var result = this.read_function_declaration(
6297 closure ? 1 : (flag ? 2 : 0),
6298 flag && flag[1] === 1
6299 );
6300 if (flag && flag[2] == 1) {
6301 // abstract function :
6302 result.parseFlags(flag);
6303 if (this.expect(';')) {
6304 this.nextWithComments();
6305 }
6306 } else {
6307 if (this.expect('{')) {
6308 result.body = this.read_code_block(false);
6309 if (result.loc && result.body.loc) {
6310 result.loc.end = result.body.loc.end;
6311 }
6312 }
6313 if (!closure && flag) {
6314 result.parseFlags(flag);
6315 }
6316 }
6317 return result;
6318 }
6319 /**
6320 * reads a function declaration (without his body)
6321 * ```ebnf
6322 * function_declaration ::= T_FUNCTION '&'? T_STRING '(' parameter_list ')'
6323 * ```
6324 */
6325 ,read_function_declaration: function(type, isStatic) {
6326 var nodeName = 'function';
6327 if (type === 1) {
6328 nodeName = 'closure';
6329 } else if (type === 2) {
6330 nodeName = 'method';
6331 }
6332 var result = this.node(nodeName);
6333
6334 if (this.expect(this.tok.T_FUNCTION)) {
6335 this.next();
6336 }
6337 var isRef = this.is_reference();
6338 var name = false, use = [], returnType = null, nullable = false;
6339 if (type !== 1) {
6340 if ((type === 2 && this.is('IDENTIFIER')) || this.expect(this.tok.T_STRING)) {
6341 name = this.text();
6342 this.next();
6343 } else {
6344 this.next();
6345 }
6346 }
6347 if (this.expect('(')) this.next();
6348 var params = this.read_parameter_list();
6349 if (this.expect(')')) this.next();
6350 if (type === 1 && this.token === this.tok.T_USE) {
6351 if (this.next().expect('(')) this.next();
6352 use = this.read_list(this.read_lexical_var, ',');
6353 if (this.expect(')')) this.next();
6354 }
6355 if (this.token === ':') {
6356 if (this.next().token === '?') {
6357 nullable = true;
6358 this.next();
6359 }
6360 returnType = this.read_type();
6361 }
6362 if (type === 1) {
6363 // closure
6364 return result(params, isRef, use, returnType, nullable, isStatic);
6365 }
6366 return result(name, params, isRef, returnType, nullable);
6367 }
6368 /**
6369 * ```ebnf
6370 * lexical_var ::= '&'? T_VARIABLE
6371 * ```
6372 */
6373 ,read_lexical_var: function() {
6374 var result = this.node('variable');
6375 var isRef = false;
6376 if (this.token === '&') {
6377 isRef = true;
6378 this.next();
6379 }
6380 this.expect(this.tok.T_VARIABLE);
6381 var name = this.text().substring(1);
6382 this.next();
6383 return result(name, isRef, false);
6384 }
6385 /**
6386 * reads a list of parameters
6387 * ```ebnf
6388 * parameter_list ::= (parameter ',')* parameter?
6389 * ```
6390 */
6391 ,read_parameter_list: function() {
6392 var result = [];
6393 if (this.token != ')') {
6394 while(this.token != this.EOF) {
6395 result.push(this.read_parameter());
6396 if (this.token == ',') {
6397 this.next();
6398 } else if (this.token == ')') {
6399 break;
6400 } else {
6401 this.error([',', ')']);
6402 break;
6403 }
6404 }
6405 }
6406 return result;
6407 }
6408 /**
6409 * ```ebnf
6410 * parameter ::= type? '&'? T_ELLIPSIS? T_VARIABLE ('=' expr)?
6411 * ```
6412 * @see https://github.com/php/php-src/blob/493524454d66adde84e00d249d607ecd540de99f/Zend/zend_language_parser.y#L640
6413 */
6414 ,read_parameter: function() {
6415 var node = this.node('parameter'),
6416 name = null,
6417 value = null,
6418 type = null,
6419 nullable = false;
6420 if (this.token === '?') {
6421 this.next();
6422 nullable = true;
6423 }
6424 type = this.read_type();
6425 if (nullable && !type) {
6426 this.raiseError('Expecting a type definition combined with nullable operator');
6427 }
6428 var isRef = this.is_reference();
6429 var isVariadic = this.is_variadic();
6430 if (this.expect(this.tok.T_VARIABLE)) {
6431 name = this.text().substring(1);
6432 this.next();
6433 }
6434 if (this.token == '=') {
6435 value = this.next().read_expr();
6436 }
6437 return node(name, type, value, isRef, isVariadic, nullable);
6438 }
6439 /**
6440 * Reads a list of arguments
6441 * ```ebnf
6442 * function_argument_list ::= '(' (argument_list (',' argument_list)*)? ')'
6443 * ```
6444 */
6445 ,read_function_argument_list: function() {
6446 var result = [];
6447 var wasVariadic = false;
6448 this.expect('(') && this.next();
6449 if (this.token !== ')') {
6450 while(this.token != this.EOF) {
6451 var argument = this.read_argument_list();
6452 if (argument) {
6453 result.push(argument);
6454 if (argument.kind === 'variadic') {
6455 wasVariadic = true;
6456 } else if (wasVariadic) {
6457 this.raiseError('Unexpected argument after a variadic argument');
6458 }
6459 }
6460 if (this.token === ',') {
6461 this.next();
6462 } else break;
6463 }
6464 }
6465 this.expect(')') && this.next();
6466 return result;
6467 }
6468 /**
6469 * ```ebnf
6470 * argument_list ::= T_ELLIPSIS? expr
6471 * ```
6472 */
6473 ,read_argument_list: function() {
6474 if (this.token === this.tok.T_ELLIPSIS ) {
6475 return this.node('variadic')(this.next().read_expr());
6476 }
6477 return this.read_expr();
6478 }
6479 /**
6480 * read type hinting
6481 * ```ebnf
6482 * type ::= T_ARRAY | T_CALLABLE | namespace_name
6483 * ```
6484 */
6485 ,read_type: function() {
6486 var result = this.node('identifier');
6487 switch(this.token) {
6488 case this.tok.T_ARRAY:
6489 this.next();
6490 return result(['', 'array'], false);
6491 case this.tok.T_NAMESPACE:
6492 case this.tok.T_NS_SEPARATOR:
6493 case this.tok.T_STRING:
6494 return this.read_namespace_name();
6495 case this.tok.T_CALLABLE:
6496 this.next();
6497 return result(['', 'callable'], false);
6498 default:
6499 return null;
6500 }
6501 }
6502 };
6503
6504 },{}],107:[function(require,module,exports){
6505 /*!
6506 * Copyright (C) 2017 Glayzzle (BSD3 License)
6507 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
6508 * @url http://glayzzle.com
6509 */
6510
6511 module.exports = {
6512 /**
6513 * Reads an IF statement
6514 *
6515 * ```ebnf
6516 * if ::= T_IF '(' expr ')' ':' ...
6517 * ```
6518 */
6519 read_if: function() {
6520 var result = this.node('if'),
6521 body = null,
6522 alternate = null,
6523 shortForm = false,
6524 test = null;
6525 test = this.read_if_expr();
6526
6527 if (this.token === ':') {
6528 shortForm = true;
6529 this.next();
6530 body = this.node('block');
6531 var items = [];
6532 while(this.token !== this.EOF && this.token !== this.tok.T_ENDIF) {
6533 if (this.token === this.tok.T_ELSEIF) {
6534 alternate = this.next().read_elseif_short();
6535 break;
6536 } else if (this.token === this.tok.T_ELSE) {
6537 alternate = this.next().read_else_short();
6538 break;
6539 }
6540 items.push(this.read_inner_statement());
6541 }
6542 body = body(null, items);
6543 this.expect(this.tok.T_ENDIF) && this.next();
6544 this.expectEndOfStatement();
6545 } else {
6546 body = this.read_statement();
6547 /**
6548 * ignore : if (..) { } /* *./ else { }
6549 */
6550 this.ignoreComments();
6551 if (this.token === this.tok.T_ELSEIF) {
6552 alternate = this.next().read_if();
6553 } else if (this.token === this.tok.T_ELSE) {
6554 alternate = this.next().read_statement();
6555 }
6556 }
6557 return result(test, body, alternate, shortForm);
6558 },
6559 /**
6560 * reads an if expression : '(' expr ')'
6561 */
6562 read_if_expr: function() {
6563 this.expect('(') && this.next();
6564 var result = this.read_expr();
6565 this.expect(')') && this.next();
6566 return result;
6567 },
6568 /**
6569 * reads an elseif (expr): statements
6570 */
6571 read_elseif_short: function() {
6572 var result = this.node('if'),
6573 alternate = null,
6574 test = null,
6575 body = null,
6576 items = [];
6577 test = this.read_if_expr();
6578 if (this.expect(':')) this.next();
6579 body = this.node('block');
6580 while(this.token != this.EOF && this.token !== this.tok.T_ENDIF) {
6581 if (this.token === this.tok.T_ELSEIF) {
6582 alternate = this.next().read_elseif_short();
6583 break;
6584 } else if (this.token === this.tok.T_ELSE) {
6585 alternate = this.next().read_else_short();
6586 break;
6587 }
6588 items.push(this.read_inner_statement());
6589 }
6590 body = body(null, items);
6591 return result(test, body, alternate, true);
6592 },
6593 /**
6594 *
6595 */
6596 read_else_short: function() {
6597 if (this.expect(':')) this.next();
6598 var body = this.node('block'), items = [];
6599 while(this.token != this.EOF && this.token !== this.tok.T_ENDIF) {
6600 items.push(this.read_inner_statement());
6601 }
6602 return body(null, items);
6603 }
6604 };
6605
6606 },{}],108:[function(require,module,exports){
6607 /*!
6608 * Copyright (C) 2017 Glayzzle (BSD3 License)
6609 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
6610 * @url http://glayzzle.com
6611 */
6612 "use strict";
6613 module.exports = {
6614 /**
6615 * Reads a while statement
6616 * ```ebnf
6617 * while ::= T_WHILE (statement | ':' inner_statement_list T_ENDWHILE ';')
6618 * ```
6619 * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L587
6620 * @return {While}
6621 */
6622 read_while: function() {
6623 var result = this.node('while'),
6624 test = null,
6625 body = null,
6626 shortForm = false
6627 ;
6628 if (this.expect('(')) this.next();
6629 test = this.read_expr();
6630 if (this.expect(')')) this.next();
6631 if (this.token === ':') {
6632 shortForm = true;
6633 body = this.read_short_form(this.tok.T_ENDWHILE);
6634 } else {
6635 body = this.read_statement();
6636 }
6637 return result(test, body, shortForm);
6638 }
6639 /**
6640 * Reads a do / while loop
6641 * ```ebnf
6642 * do ::= T_DO statement T_WHILE '(' expr ')' ';'
6643 * ```
6644 * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L423
6645 * @return {Do}
6646 */
6647 ,read_do: function() {
6648 var result = this.node('do'),
6649 test = null,
6650 body = null
6651 ;
6652 body = this.read_statement();
6653 if (this.ignoreComments().expect(this.tok.T_WHILE)) {
6654 if (this.next().expect('(')) this.next();
6655 test = this.read_expr();
6656 if (this.expect(')')) this.next();
6657 if (this.expect(';')) this.next();
6658 }
6659 return result(test, body);
6660 }
6661 /**
6662 * Read a for incremental loop
6663 * ```ebnf
6664 * for ::= T_FOR '(' for_exprs ';' for_exprs ';' for_exprs ')' for_statement
6665 * for_statement ::= statement | ':' inner_statement_list T_ENDFOR ';'
6666 * for_exprs ::= expr? (',' expr)*
6667 * ```
6668 * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L425
6669 * @return {For}
6670 */
6671 ,read_for: function() {
6672 var result = this.node('for'),
6673 init = [],
6674 test = [],
6675 increment = [],
6676 body = null,
6677 shortForm = false;
6678 if (this.expect('(')) this.next();
6679 if (this.token !== ';') {
6680 init = this.read_list(this.read_expr, ',');
6681 if (this.expect(';')) this.next();
6682 } else {
6683 this.next();
6684 }
6685 if (this.token !== ';') {
6686 test = this.read_list(this.read_expr, ',');
6687 if (this.expect(';')) this.next();
6688 } else {
6689 this.next();
6690 }
6691 if (this.token !== ')') {
6692 increment = this.read_list(this.read_expr, ',');
6693 if (this.expect(')')) this.next();
6694 } else {
6695 this.next();
6696 }
6697 if (this.token === ':') {
6698 shortForm = true;
6699 body = this.read_short_form(this.tok.T_ENDFOR);
6700 } else {
6701 body = this.read_statement();
6702 }
6703 return result(init, test, increment, body, shortForm);
6704 }
6705 /**
6706 * Reads a foreach loop
6707 * ```ebnf
6708 * foreach ::= '(' expr T_AS foreach_variable (T_DOUBLE_ARROW foreach_variable)? ')' statement
6709 * ```
6710 * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L438
6711 * @return {Foreach}
6712 */
6713 ,read_foreach: function() {
6714 var result = this.node('foreach'),
6715 source = null,
6716 key = null,
6717 value = null,
6718 body = null,
6719 shortForm = false;
6720 if (this.expect('(')) this.next();
6721 source = this.read_expr();
6722 if (this.ignoreComments().expect(this.tok.T_AS)) {
6723 this.next();
6724 value = this.read_foreach_variable();
6725 if (this.token === this.tok.T_DOUBLE_ARROW) {
6726 key = value;
6727 value = this.next().read_foreach_variable();
6728 }
6729 }
6730
6731 if (this.expect(')')) this.next();
6732
6733 if (this.token === ':') {
6734 shortForm = true;
6735 body = this.read_short_form(this.tok.T_ENDFOREACH);
6736 } else {
6737 body = this.read_statement();
6738 }
6739 return result(source, key, value, body, shortForm);
6740 }
6741 /**
6742 * Reads a foreach variable statement
6743 * ```ebnf
6744 * foreach_variable = variable |
6745 * T_LIST '(' assignment_list ')' |
6746 * '[' array_pair_list ']'
6747 * ```
6748 * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L544
6749 * @return {Expression}
6750 */
6751 ,read_foreach_variable: function() {
6752 if (this.token === this.tok.T_LIST) {
6753 var result = this.node('list');
6754 if (this.next().expect('(')) this.next();
6755 var assignList = this.read_assignment_list();
6756 if (this.expect(')')) this.next();
6757 return result(assignList);
6758 } else if (this.token === '[' || this.token === this.tok.T_ARRAY) {
6759 return this.read_array();
6760 } else {
6761 return this.read_variable(false, false, false);
6762 }
6763 }
6764 };
6765
6766 },{}],109:[function(require,module,exports){
6767 /*!
6768 * Copyright (C) 2017 Glayzzle (BSD3 License)
6769 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
6770 * @url http://glayzzle.com
6771 */
6772
6773 module.exports = {
6774 /**
6775 * ```ebnf
6776 * start ::= (namespace | top_statement)*
6777 * ```
6778 */
6779 read_start: function() {
6780 if (this.token == this.tok.T_NAMESPACE) {
6781 return this.read_namespace();
6782 } else {
6783 return this.read_top_statement();
6784 }
6785 }
6786 };
6787
6788 },{}],110:[function(require,module,exports){
6789 /*!
6790 * Copyright (C) 2017 Glayzzle (BSD3 License)
6791 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
6792 * @url http://glayzzle.com
6793 */
6794 "use strict";
6795
6796 module.exports = {
6797 /**
6798 * Reads a namespace declaration block
6799 * ```ebnf
6800 * namespace ::= T_NAMESPACE namespace_name? '{'
6801 * top_statements
6802 * '}'
6803 * | T_NAMESPACE namespace_name ';' top_statements
6804 * ```
6805 * @see http://php.net/manual/en/language.namespaces.php
6806 * @return {Namespace}
6807 */
6808 read_namespace: function() {
6809 var result = this.node('namespace');
6810 this.expect(this.tok.T_NAMESPACE) && this.next();
6811 if (this.token == '{') {
6812 this.currentNamespace = [''];
6813 var body = this.nextWithComments().read_top_statements();
6814 this.expect('}') && this.nextWithComments();
6815 return result([''], body, true);
6816 } else {
6817 var name = this.read_namespace_name();
6818 if (this.token == ';') {
6819 this.currentNamespace = name;
6820 var body = this.nextWithComments().read_top_statements();
6821 this.expect(this.EOF);
6822 return result(name.name, body, false);
6823 } else if (this.token == '{') {
6824 this.currentNamespace = name;
6825 var body = this.nextWithComments().read_top_statements();
6826 this.expect('}') && this.nextWithComments();
6827 return result(name.name, body, true);
6828 } else if (this.token === '(') {
6829 // resolve ambuiguity between namespace & function call
6830 name.resolution = this.ast.identifier.RELATIVE_NAME;
6831 name.name = name.name.substring(1);
6832 return this.node('call')(
6833 name, this.read_function_argument_list()
6834 );
6835 } else {
6836 this.error(['{', ';']);
6837 // graceful mode :
6838 this.currentNamespace = name;
6839 var body = this.read_top_statements();
6840 this.expect(this.EOF);
6841 return result(name, body, false);
6842 }
6843 }
6844 }
6845 /**
6846 * Reads a namespace name
6847 * ```ebnf
6848 * namespace_name ::= T_NS_SEPARATOR? (T_STRING T_NS_SEPARATOR)* T_STRING
6849 * ```
6850 * @see http://php.net/manual/en/language.namespaces.rules.php
6851 * @return {Identifier}
6852 */
6853 ,read_namespace_name: function() {
6854 var result = this.node('identifier'), relative = false;
6855 if (this.token === this.tok.T_NAMESPACE) {
6856 this.next().expect(this.tok.T_NS_SEPARATOR) && this.next();
6857 relative = true
6858 }
6859 return result(
6860 this.read_list(this.tok.T_STRING, this.tok.T_NS_SEPARATOR, true),
6861 relative
6862 );
6863 }
6864 /**
6865 * Reads a use statement
6866 * ```ebnf
6867 * use_statement ::= T_USE
6868 * use_type? use_declarations |
6869 * use_type use_statement '{' use_declarations '}' |
6870 * use_statement '{' use_declarations(=>typed) '}'
6871 * ';'
6872 * ```
6873 * @see http://php.net/manual/en/language.namespaces.importing.php
6874 * @return {UseGroup}
6875 */
6876 ,read_use_statement: function() {
6877 var result = this.node('usegroup'),
6878 type = null,
6879 items = [],
6880 name = null
6881 ;
6882 this.expect(this.tok.T_USE) && this.next();
6883 type = this.read_use_type();
6884 items.push(this.read_use_declaration(false));
6885 if (this.token === ',') {
6886 items = items.concat(this.next().read_use_declarations(false));
6887 } else if (this.token === '{') {
6888 name = items[0].name;
6889 items = this.next().read_use_declarations(type === null);
6890 this.expect('}') && this.next();
6891 }
6892 this.expect(';') && this.nextWithComments();
6893 return result(name, type, items);
6894 }
6895 /**
6896 * Reads a use declaration
6897 * ```ebnf
6898 * use_declaration ::= use_type? namespace_name use_alias
6899 * ```
6900 * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L380
6901 * @return {UseItem}
6902 */
6903 ,read_use_declaration: function(typed) {
6904 var result = this.node('useitem'), type = null;
6905 if (typed) type = this.read_use_type();
6906 var name = this.read_namespace_name();
6907 var alias = this.read_use_alias();
6908 return result(name.name, alias, type);
6909 }
6910 /**
6911 * Reads a list of use declarations
6912 * ```ebnf
6913 * use_declarations ::= use_declaration (',' use_declaration)*
6914 * ```
6915 * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L380
6916 * @return {UseItem[]}
6917 */
6918 ,read_use_declarations: function(typed) {
6919 var result = [this.read_use_declaration(typed)];
6920 while(this.token === ',') {
6921 result.push(this.next().read_use_declaration(typed));
6922 }
6923 return result;
6924 }
6925 /**
6926 * Reads a use statement
6927 * ```ebnf
6928 * use_alias ::= (T_AS T_STRING)?
6929 * ```
6930 * @return {String|null}
6931 */
6932 ,read_use_alias: function() {
6933 var result = null;
6934 if (this.token === this.tok.T_AS) {
6935 if (this.next().expect(this.tok.T_STRING)) {
6936 result = this.text();
6937 this.next();
6938 }
6939 }
6940 return result;
6941 }
6942 /**
6943 * Reads the namespace type declaration
6944 * ```ebnf
6945 * use_type ::= (T_FUNCTION | T_CONST)?
6946 * ```
6947 * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L335
6948 * @return {String|null} Possible values : function, const
6949 */
6950 ,read_use_type: function() {
6951 if (this.token === this.tok.T_FUNCTION) {
6952 this.next();
6953 return this.ast.useitem.TYPE_FUNCTION;
6954 } else if (this.token === this.tok.T_CONST) {
6955 this.next();
6956 return this.ast.useitem.TYPE_CONST;
6957 }
6958 return null;
6959 }
6960 };
6961
6962 },{}],111:[function(require,module,exports){
6963 /*!
6964 * Copyright (C) 2017 Glayzzle (BSD3 License)
6965 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
6966 * @url http://glayzzle.com
6967 */
6968
6969 var specialChar = {
6970 '\\r': "\r",
6971 '\\n': "\n",
6972 '\\t': "\t",
6973 '\\v': String.fromCharCode(11),
6974 '\\e': String.fromCharCode(27),
6975 '\\f': String.fromCharCode(12),
6976 "\\\\": "\\",
6977 '\\$': "$",
6978 '\\"': '"',
6979 '\\\'': "'"
6980 };
6981
6982 module.exports = {
6983 /**
6984 * Unescape special chars
6985 */
6986 resolve_special_chars: function(text) {
6987 return text.replace(
6988 /\\[rntvef"'\\\$]/g,
6989 function(seq) {
6990 return specialChar[seq];
6991 }
6992 );
6993 },
6994 /**
6995 * ```ebnf
6996 * scalar ::= T_MAGIC_CONST
6997 * | T_LNUMBER | T_DNUMBER
6998 * | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE? T_END_HEREDOC
6999 * | '"' encaps_list '"'
7000 * | T_START_HEREDOC encaps_list T_END_HEREDOC
7001 * | namespace_name (T_DOUBLE_COLON T_STRING)?
7002 * ```
7003 */
7004 read_scalar: function() {
7005 if (this.is('T_MAGIC_CONST')) {
7006 return this.get_magic_constant();
7007 } else {
7008 switch(this.token) {
7009
7010 // TEXTS
7011 case this.tok.T_CONSTANT_ENCAPSED_STRING:
7012 var value = this.node('string');
7013 var text = this.text();
7014 var isDoubleQuote = text[0] === '"';
7015 text = text.substring(1, text.length - 1);
7016 this.next();
7017 value = value(isDoubleQuote, this.resolve_special_chars(text));
7018 if (this.token === this.tok.T_DOUBLE_COLON) {
7019 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1151
7020 return this.read_static_getter(value);
7021 } else {
7022 // dirrect string
7023 return value;
7024 }
7025 case this.tok.T_START_HEREDOC:
7026 if (this.lexer.curCondition === 'ST_NOWDOC') {
7027 var node = this.node('nowdoc');
7028 var value = this.next().text();
7029 // strip the last line return char
7030 var lastCh = value[value.length-1];
7031 if (lastCh === '\n') {
7032 if (value[value.length-2] === '\r') {
7033 // windows style
7034 value = value.substring(0, value.length - 2);
7035 } else {
7036 // linux style
7037 value = value.substring(0, value.length - 1);
7038 }
7039 } else if (lastCh === '\r') {
7040 // mac style
7041 value = value.substring(0, value.length - 1);
7042 }
7043 this.expect(this.tok.T_ENCAPSED_AND_WHITESPACE) && this.next();
7044 node = node(value, this.lexer.heredoc_label);
7045 this.expect(this.tok.T_END_HEREDOC) && this.next();
7046 return node;
7047 } else {
7048 return this.next().read_encapsed_string(
7049 this.tok.T_END_HEREDOC
7050 );
7051 }
7052
7053 case '"':
7054 return this.next().read_encapsed_string('"');
7055
7056 case 'b"':
7057 case 'B"':
7058 var node = this.node('cast');
7059 var what = this.next().read_encapsed_string('"');
7060 return node('binary', what);
7061
7062 // NUMERIC
7063 case this.tok.T_LNUMBER: // long
7064 case this.tok.T_DNUMBER: // double
7065 var result = this.node('number');
7066 var value = this.text();
7067 this.next();
7068 result = result(value);
7069 return result;
7070
7071 // ARRAYS
7072 case this.tok.T_ARRAY: // array parser
7073 case '[': // short array format
7074 return this.read_array();
7075 default:
7076 var err = this.error('SCALAR');
7077 // graceful mode : ignore token & return error node
7078 this.next();
7079 return err;
7080 }
7081 }
7082 }
7083 /**
7084 * Handles the dereferencing
7085 */
7086 ,read_dereferencable: function(expr) {
7087 var result;
7088 var node = this.node('offsetlookup');
7089 if (this.token === '[') {
7090 var offset = this.next().read_expr();
7091 if (this.expect(']')) this.next();
7092 result = node(expr, offset);
7093 } else if (this.token === this.tok.T_DOLLAR_OPEN_CURLY_BRACES) {
7094 var offset = this.read_encapsed_string_item();
7095 result = node(expr, offset);
7096 }
7097 return result;
7098 }
7099 /**
7100 * Reads and extracts an encapsed item
7101 * ```ebnf
7102 * encapsed_string_item ::= T_ENCAPSED_AND_WHITESPACE
7103 * | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
7104 * | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}'
7105 * | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
7106 * | T_CURLY_OPEN variable '}'
7107 * | variable
7108 * | variable '[' expr ']'
7109 * | variable T_OBJECT_OPERATOR T_STRING
7110 * ```
7111 * @return {String|Variable|Expr|Lookup}
7112 * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1219
7113 */
7114 ,read_encapsed_string_item: function() {
7115 var result = this.node();
7116
7117 // plain text
7118 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1222
7119 if (this.token === this.tok.T_ENCAPSED_AND_WHITESPACE) {
7120 var text = this.text();
7121 this.next();
7122 result = result(
7123 'string', false, this.resolve_special_chars(text)
7124 );
7125 }
7126
7127 // dynamic variable name
7128 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1239
7129 else if (this.token === this.tok.T_DOLLAR_OPEN_CURLY_BRACES) {
7130 var name = null;
7131 if (this.next().token === this.tok.T_STRING_VARNAME) {
7132 var varName = this.text();
7133 name = this.node('variable');
7134 this.next();
7135 // check if lookup an offset
7136 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1243
7137 if (this.token === '[') {
7138 name = name(varName, false);
7139 var node = this.node('offsetlookup');
7140 var offset = this.next().read_expr();
7141 this.expect(']') && this.next();
7142 name = node(name, offset);
7143 } else {
7144 name = varName;
7145 }
7146 } else {
7147 name = this.read_expr();
7148 }
7149 this.expect('}') && this.next();
7150 result = result('variable', name, false, true);
7151 }
7152
7153 // expression
7154 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1246
7155 else if (this.token === this.tok.T_CURLY_OPEN) {
7156 result = this.next().read_variable(false, false, false);
7157 this.expect('}') && this.next();
7158 }
7159
7160 // plain variable
7161 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1231
7162 else if (this.token === this.tok.T_VARIABLE) {
7163 result = this.read_simple_variable(false);
7164
7165 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1233
7166 if (this.token === '[') {
7167 var node = this.node('offsetlookup');
7168 var offset = this.next().read_encaps_var_offset();
7169 this.expect(']') && this.next();
7170 result = node(result, offset);
7171 }
7172
7173 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1236
7174 if (this.token === this.tok.T_OBJECT_OPERATOR) {
7175 var node = this.node('propertylookup');
7176 var what = this.node('constref');
7177 this.next().expect(this.tok.T_STRING);
7178 var name = this.text();
7179 this.next();
7180 result = node(result, what(name));
7181 }
7182
7183 // error / fallback
7184 } else {
7185 this.expect(this.tok.T_ENCAPSED_AND_WHITESPACE);
7186 var value = this.text();
7187 this.next();
7188 // consider it as string
7189 result = result('string', false, value);
7190 }
7191
7192 return result;
7193 }
7194 /**
7195 * Reads an encapsed string
7196 */
7197 ,read_encapsed_string: function(expect) {
7198 var node = this.node('encapsed'), value = [], type = null;
7199
7200 if (expect === '`') {
7201 type = this.ast.encapsed.TYPE_SHELL;
7202 } else if (expect === '"') {
7203 type = this.ast.encapsed.TYPE_STRING;
7204 } else {
7205 type = this.ast.encapsed.TYPE_HEREDOC;
7206 }
7207
7208 // reading encapsed parts
7209 while(this.token !== expect && this.token !== this.EOF) {
7210 value.push(this.read_encapsed_string_item());
7211 }
7212
7213 this.expect(expect) && this.next();
7214 node = node(value, type);
7215
7216 if (expect === this.tok.T_END_HEREDOC) {
7217 node.label = this.lexer.heredoc_label;
7218 }
7219 return node;
7220 }
7221 /**
7222 * Constant token
7223 */
7224 ,get_magic_constant: function() {
7225 var result = this.node('magic');
7226 var name = this.text();
7227 this.next();
7228 return result(name);
7229 }
7230 };
7231
7232 },{}],112:[function(require,module,exports){
7233 /*!
7234 * Copyright (C) 2017 Glayzzle (BSD3 License)
7235 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
7236 * @url http://glayzzle.com
7237 */
7238 module.exports = {
7239 /**
7240 * reading a list of top statements (helper for top_statement*)
7241 * ```ebnf
7242 * top_statements ::= top_statement*
7243 * ```
7244 */
7245 read_top_statements: function() {
7246 var result = [];
7247 while(this.token !== this.EOF && this.token !== '}') {
7248 var statement = this.read_top_statement();
7249 if (statement) {
7250 if (Array.isArray(statement)) {
7251 result = result.concat(statement);
7252 } else {
7253 result.push(statement);
7254 }
7255 }
7256 }
7257 return result;
7258 }
7259 /**
7260 * reading a top statement
7261 * ```ebnf
7262 * top_statement ::=
7263 * namespace | function | class
7264 * | interface | trait
7265 * | use_statements | const_list
7266 * | statement
7267 * ```
7268 */
7269 ,read_top_statement: function() {
7270 switch(this.token) {
7271 case this.tok.T_FUNCTION:
7272 return this.read_function(false, false);
7273 // optional flags
7274 case this.tok.T_ABSTRACT:
7275 case this.tok.T_FINAL:
7276 var flag = this.read_class_scope();
7277 if (this.token === this.tok.T_CLASS) {
7278 return this.read_class(flag);
7279 } else {
7280 this.error(this.tok.T_CLASS);
7281 this.next();
7282 return null;
7283 }
7284 case this.tok.T_CLASS:
7285 return this.read_class([0, 0, 0]);
7286 case this.tok.T_INTERFACE:
7287 return this.read_interface();
7288 case this.tok.T_TRAIT:
7289 return this.read_trait();
7290 case this.tok.T_USE:
7291 return this.read_use_statement();
7292 case this.tok.T_CONST:
7293 return this.next().read_const_list();
7294 case this.tok.T_NAMESPACE:
7295 return this.read_namespace();
7296 case this.tok.T_HALT_COMPILER:
7297 var result = this.node('halt');
7298 if (this.next().expect('(')) this.next();
7299 if (this.expect(')')) this.next();
7300 this.expect(';');
7301 this.lexer.done = true;
7302 return result(this.lexer._input.substring(
7303 this.lexer.offset
7304 ));
7305 default:
7306 return this.read_statement();
7307 }
7308 }
7309 /**
7310 * reads a list of simple inner statements (helper for inner_statement*)
7311 * ```ebnf
7312 * inner_statements ::= inner_statement*
7313 * ```
7314 */
7315 ,read_inner_statements: function() {
7316 var result = [];
7317 while(this.token != this.EOF && this.token !== '}') {
7318 var statement = this.read_inner_statement();
7319 if (statement) {
7320 if (Array.isArray(statement)) {
7321 result = result.concat(statement);
7322 } else {
7323 result.push(statement);
7324 }
7325 }
7326 }
7327 return result;
7328 }
7329 /**
7330 * Reads a list of constants declaration
7331 * ```ebnf
7332 * const_list ::= T_CONST T_STRING '=' expr (',' T_STRING '=' expr)* ';'
7333 * ```
7334 */
7335 ,read_const_list: function() {
7336 var result = this.read_list(function() {
7337 this.expect(this.tok.T_STRING);
7338 var result = this.node('constant');
7339 var name = this.text();
7340 if (this.next().expect('=')) {
7341 return result(name, this.next().read_expr());
7342 } else {
7343 // fallback
7344 return result(name, null);
7345 }
7346 }, ',', false);
7347 this.expectEndOfStatement();
7348 return result;
7349 }
7350 /**
7351 * Reads a list of constants declaration
7352 * ```ebnf
7353 * declare_list ::= T_STRING '=' expr (',' T_STRING '=' expr)*
7354 * ```
7355 * @retrurn {Object}
7356 */
7357 ,read_declare_list: function() {
7358 var result = {};
7359 while(this.token != this.EOF && this.token !== ')') {
7360 this.expect(this.tok.T_STRING);
7361 var name = this.text().toLowerCase();
7362 if (this.next().expect('=')) {
7363 result[name] = this.next().read_expr();
7364 } else {
7365 result[name] = null;
7366 }
7367 if (this.token !== ',') break;
7368 this.next();
7369 }
7370 return result;
7371 }
7372 /**
7373 * reads a simple inner statement
7374 * ```ebnf
7375 * inner_statement ::= '{' inner_statements '}' | token
7376 * ```
7377 */
7378 ,read_inner_statement: function() {
7379 switch(this.token) {
7380 case this.tok.T_FUNCTION:
7381 return this.read_function(false, false);
7382 // optional flags
7383 case this.tok.T_ABSTRACT:
7384 case this.tok.T_FINAL:
7385 var flag = this.read_class_scope();
7386 if (this.token === this.tok.T_CLASS) {
7387 return this.read_class(flag);
7388 } else {
7389 this.error(this.tok.T_CLASS);
7390 // graceful mode : ignore token & go next
7391 this.next();
7392 return null;
7393 }
7394 case this.tok.T_CLASS:
7395 return this.read_class([0, 0, 0]);
7396 case this.tok.T_INTERFACE:
7397 return this.read_interface();
7398 case this.tok.T_TRAIT:
7399 return this.read_trait();
7400 case this.tok.T_HALT_COMPILER:
7401 this.raiseError(
7402 '__HALT_COMPILER() can only be used from the outermost scope'
7403 );
7404 // fallback : returns a node but does not stop the parsing
7405 var node = this.node('halt');
7406 this.next().expect('(') && this.next();
7407 this.expect(')') && this.next();
7408 node = node(this.lexer._input.substring(
7409 this.lexer.offset
7410 ));
7411 this.expect(';') && this.next();
7412 return node;
7413 default:
7414 return this.read_statement();
7415 }
7416 }
7417 /**
7418 * Reads statements
7419 */
7420 ,read_statement: function() {
7421
7422 switch(this.token) {
7423
7424 case '{': return this.read_code_block(false);
7425
7426 case this.tok.T_IF: return this.next().read_if();
7427
7428 case this.tok.T_SWITCH: return this.read_switch();
7429
7430 case this.tok.T_FOR: return this.next().read_for();
7431
7432 case this.tok.T_FOREACH: return this.next().read_foreach();
7433
7434 case this.tok.T_WHILE: return this.next().read_while();
7435
7436 case this.tok.T_DO: return this.next().read_do();
7437
7438 case this.tok.T_COMMENT: return this.read_comment();
7439
7440 case this.tok.T_DOC_COMMENT: return this.read_doc_comment();
7441
7442 case this.tok.T_RETURN:
7443 var result = this.node('return'), expr = null;
7444 if (!this.next().is('EOS')) {
7445 expr = this.read_expr();
7446 }
7447 this.expectEndOfStatement();
7448 return result(expr);
7449
7450 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L429
7451 case this.tok.T_BREAK:
7452 case this.tok.T_CONTINUE:
7453 var result = this.node(
7454 this.token === this.tok.T_CONTINUE ? 'continue' : 'break'
7455 ), level = null;
7456 this.next(); // look ahead
7457 if (this.token !== ';' && this.token !== this.tok.T_CLOSE_TAG) {
7458 level = this.read_expr();
7459 }
7460 this.expectEndOfStatement();
7461 return result(level);
7462
7463 case this.tok.T_GLOBAL:
7464 var result = this.node('global');
7465 var items = this.next().read_list(this.read_simple_variable, ',');
7466 this.expectEndOfStatement();
7467 return result(items);
7468
7469 case this.tok.T_STATIC:
7470 var current = [this.token, this.lexer.getState()];
7471 var result = this.node('static');
7472 if (this.next().token === this.tok.T_DOUBLE_COLON) {
7473 // static keyword for a class
7474 this.lexer.tokens.push(current);
7475 var expr = this.next().read_expr();
7476 this.expect(';') && this.nextWithComments();
7477 return expr;
7478 }
7479 if (this.token === this.tok.T_FUNCTION) {
7480 return this.read_function(true, [0, 1, 0]);
7481 }
7482 var items = this.read_variable_declarations();
7483 this.expectEndOfStatement();
7484 return result(items);
7485
7486 case this.tok.T_ECHO:
7487 var result = this.node('echo');
7488 var args = this.next().read_list(this.read_expr, ',');
7489 this.expectEndOfStatement();
7490 return result(args);
7491
7492 case this.tok.T_INLINE_HTML:
7493 var result = this.node('inline'), value = this.text();
7494 this.next();
7495 return result(value);
7496
7497 case this.tok.T_UNSET:
7498 var result = this.node('unset');
7499 this.next().expect('(') && this.next();
7500 var items = this.read_list(this.read_variable, ',');
7501 this.expect(')') && this.next();
7502 this.expect(';') && this.nextWithComments();
7503 return result(items);
7504
7505 case this.tok.T_DECLARE:
7506 var result = this.node('declare'),
7507 what,
7508 body = [],
7509 mode;
7510 this.next().expect('(') && this.next();
7511 what = this.read_declare_list();
7512 this.expect(')') && this.next();
7513 if (this.token === ':') {
7514 this.nextWithComments();
7515 while(this.token != this.EOF && this.token !== this.tok.T_ENDDECLARE) {
7516 // @todo : check declare_statement from php / not valid
7517 body.push(this.read_top_statement());
7518 }
7519 this.expect(this.tok.T_ENDDECLARE) && this.next();
7520 this.expectEndOfStatement();
7521 mode = this.ast.declare.MODE_SHORT;
7522 } else if (this.token === '{') {
7523 this.nextWithComments();
7524 while(this.token != this.EOF && this.token !== '}') {
7525 // @todo : check declare_statement from php / not valid
7526 body.push(this.read_top_statement());
7527 }
7528 this.expect('}') && this.next();
7529 mode = this.ast.declare.MODE_BLOCK;
7530 } else {
7531 this.expect(';') && this.nextWithComments();
7532 while(this.token != this.EOF && this.token !== this.tok.T_DECLARE) {
7533 // @todo : check declare_statement from php / not valid
7534 body.push(this.read_top_statement());
7535 }
7536 mode = this.ast.declare.MODE_NONE;
7537 }
7538 return result(what, body, mode);
7539
7540 case this.tok.T_TRY:
7541 return this.read_try();
7542
7543 case this.tok.T_THROW:
7544 var result = this.node('throw');
7545 var expr = this.next().read_expr();
7546 this.expectEndOfStatement();
7547 return result(expr);
7548
7549 case ';': // ignore this (extra ponctuation)
7550 case this.tok.T_CLOSE_TAG: // empty tag
7551 this.next();
7552 return null;
7553
7554 case this.tok.T_STRING:
7555 var current = [this.token, this.lexer.getState()];
7556 var label = this.text();
7557 // AST : https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L457
7558 if (this.next().token === ':') {
7559 var result = this.node('label');
7560 this.next();
7561 return result(label);
7562 }
7563
7564 // default fallback expr / T_STRING '::' (etc...)
7565 this.lexer.tokens.push(current);
7566 var expr = this.next().read_expr();
7567 this.expectEndOfStatement();
7568 return expr;
7569
7570 case this.tok.T_GOTO:
7571 var result = this.node('goto'), label = null;
7572 if (this.next().expect(this.tok.T_STRING)) {
7573 label = this.text();
7574 this.next().expectEndOfStatement();
7575 }
7576 return result(label);
7577
7578 default: // default fallback expr
7579 var expr = this.read_expr();
7580 this.expectEndOfStatement();
7581 return expr;
7582 }
7583 }
7584 /**
7585 * ```ebnf
7586 * code_block ::= '{' (inner_statements | top_statements) '}'
7587 * ```
7588 */
7589 ,read_code_block: function(top) {
7590 var result = this.node('block');
7591 this.expect('{') && this.nextWithComments();
7592 var body = top ?
7593 this.read_top_statements()
7594 : this.read_inner_statements()
7595 ;
7596 this.expect('}') && this.nextWithComments();
7597 return result(null, body);
7598 }
7599 };
7600
7601 },{}],113:[function(require,module,exports){
7602 /*!
7603 * Copyright (C) 2017 Glayzzle (BSD3 License)
7604 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
7605 * @url http://glayzzle.com
7606 */
7607 "use strict";
7608
7609 module.exports = {
7610 /**
7611 * Reads a switch statement
7612 * ```ebnf
7613 * switch ::= T_SWITCH '(' expr ')' switch_case_list
7614 * ```
7615 * @return {Switch}
7616 * @see http://php.net/manual/en/control-structures.switch.php
7617 */
7618 read_switch: function() {
7619 this.expect(this.tok.T_SWITCH) && this.next();
7620 var result = this.node('switch'), test, body, shortForm;
7621 this.expect('(') && this.next();
7622 test = this.read_expr();
7623 this.expect(')') && this.next();
7624 shortForm = (this.token === ':');
7625 body = this.read_switch_case_list();
7626 return result(test, body, shortForm);
7627 }
7628 /**
7629 * ```ebnf
7630 * switch_case_list ::= '{' ';'? case_list* '}' | ':' ';'? case_list* T_ENDSWITCH ';'
7631 * ```
7632 * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L566
7633 */
7634 ,read_switch_case_list: function() {
7635 // DETECT SWITCH MODE
7636 var expect = null,
7637 result = this.node('block'),
7638 items = [];
7639 if (this.token === '{') {
7640 expect = '}';
7641 } else if (this.token === ':') {
7642 expect = this.tok.T_ENDSWITCH;
7643 } else {
7644 this.expect(['{', ':']);
7645 }
7646 // OPTIONNAL ';'
7647 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L570
7648 if (this.next().token === ';') {
7649 this.next();
7650 }
7651 // IGNORE THE CLOSE TAG TOKEN WITH SHORT MODE
7652 if (this.token === this.tok.T_CLOSE_TAG) {
7653 this.next();
7654 }
7655 // EXTRACTING CASES
7656 while(this.token !== this.EOF && this.token !== expect) {
7657 items.push( this.read_case_list(expect) );
7658 }
7659 // CHECK END TOKEN
7660 this.expect(expect) && this.next();
7661 if (expect === this.tok.T_ENDSWITCH) {
7662 this.expectEndOfStatement();
7663 }
7664 return result(null, items);
7665 }
7666 /**
7667 * ```ebnf
7668 * case_list ::= ((T_CASE expr) | T_DEFAULT) (':' | ';') inner_statement*
7669 * ```
7670 */
7671 ,read_case_list: function(stopToken) {
7672 var result = this.node('case'), test = null, body = null, items = [];
7673 if (this.token === this.tok.T_CASE) {
7674 test = this.next().read_expr();
7675 } else if (this.token === this.tok.T_DEFAULT) {
7676 // the defaut entry - no condition
7677 this.next();
7678 } else {
7679 this.expect([this.tok.T_CASE, this.tok.T_DEFAULT]);
7680 }
7681 this.expect([':', ';']) && this.next();
7682 body = this.node('block');
7683 while(
7684 this.token != this.EOF
7685 && this.token !== stopToken
7686 && this.token !== this.tok.T_CASE
7687 && this.token !== this.tok.T_DEFAULT
7688 ) {
7689 items.push(this.read_inner_statement());
7690 }
7691 return result(
7692 test, items.length > 0 ? body(null, items) : null
7693 );
7694 }
7695 };
7696
7697 },{}],114:[function(require,module,exports){
7698 /*!
7699 * Copyright (C) 2017 Glayzzle (BSD3 License)
7700 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
7701 * @url http://glayzzle.com
7702 */
7703 module.exports = {
7704 /**
7705 * ```ebnf
7706 * try ::= T_TRY '{' inner_statement* '}'
7707 * (
7708 * T_CATCH '(' namespace_name variable ')' '{' inner_statement* '}'
7709 * )*
7710 * (T_FINALLY '{' inner_statement* '}')?
7711 * ```
7712 * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L448
7713 * @return {Try}
7714 */
7715 read_try: function() {
7716 this.expect(this.tok.T_TRY);
7717 var result = this.node('try'),
7718 always = null,
7719 body,
7720 catches = []
7721 ;
7722 body = this.next().read_statement();
7723 // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L455
7724 while(this.ignoreComments().token === this.tok.T_CATCH) {
7725 var item = this.node('catch'), what = [], variable = null;
7726 this.next().expect('(') && this.next();
7727 what = this.read_list(
7728 this.read_namespace_name, '|', false
7729 );
7730 variable = this.read_variable(true, false, false);
7731 this.expect(')');
7732 catches.push(
7733 item(this.next().read_statement(), what, variable)
7734 );
7735 }
7736 if (this.token === this.tok.T_FINALLY) {
7737 always = this.next().read_statement();
7738 }
7739 return result(body, catches, always);
7740 }
7741 };
7742
7743 },{}],115:[function(require,module,exports){
7744 /*!
7745 * Defines a list of helper functions for parsing
7746 * Copyright (C) 2017 Glayzzle (BSD3 License)
7747 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
7748 * @url http://glayzzle.com
7749 */
7750 "use strict";
7751
7752 module.exports = {
7753 /**
7754 * Reads a short form of tokens
7755 * @param {Number} token - The ending token
7756 * @return {Block}
7757 */
7758 read_short_form: function(token) {
7759 var body = this.node('block'), items = [];
7760 if (this.expect(':')) this.next();
7761 while(this.token != this.EOF && this.token !== token) {
7762 items.push(this.read_inner_statement());
7763 }
7764 if (this.expect(token)) this.next();
7765 this.expectEndOfStatement();
7766 return body(null, items);
7767 }
7768
7769 /**
7770 * Helper : reads a list of tokens / sample : T_STRING ',' T_STRING ...
7771 * ```ebnf
7772 * list ::= separator? ( item separator )* item
7773 * ```
7774 */
7775 ,read_list: function(item, separator, preserveFirstSeparator) {
7776 var result = [];
7777
7778 if (this.token == separator) {
7779 if (preserveFirstSeparator) result.push('');
7780 this.next();
7781 }
7782
7783 if (typeof (item) === "function") {
7784 do {
7785 result.push(item.apply(this, []));
7786 if (this.token != separator) {
7787 break;
7788 }
7789 } while(this.next().token != this.EOF);
7790 } else {
7791 if (this.expect(item)) {
7792 result.push(this.text());
7793 } else {
7794 return [];
7795 }
7796 while (this.next().token != this.EOF) {
7797 if (this.token != separator) break;
7798 // trim current separator & check item
7799 if (this.next().token != item) break;
7800 result.push(this.text());
7801 }
7802 }
7803 return result;
7804 }
7805
7806 /**
7807 * Reads a list of names separated by a comma
7808 *
7809 * ```ebnf
7810 * name_list ::= namespace (',' namespace)*
7811 * ```
7812 *
7813 * Sample code :
7814 * ```php
7815 * <?php class foo extends bar, baz { }
7816 * ```
7817 *
7818 * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L726
7819 * @return {Identifier[]}
7820 */
7821 ,read_name_list: function() {
7822 return this.read_list(
7823 this.read_namespace_name, ',', false
7824 );
7825 }
7826
7827 /**
7828 * Reads a list of variables declarations
7829 *
7830 * ```ebnf
7831 * variable_declaration ::= T_VARIABLE ('=' expr)?*
7832 * variable_declarations ::= variable_declaration (',' variable_declaration)*
7833 * ```
7834 *
7835 * Sample code :
7836 * ```php
7837 * <?php class foo extends bar, baz { }
7838 * ```
7839 * @return {Variable[]|Assign[]} Returns an array composed by a list of variables, or
7840 * assign values
7841 */
7842 ,read_variable_declarations: function() {
7843 return this.read_list(function() {
7844 var node = this.node('assign'),
7845 value = null,
7846 variable = this.node('variable');
7847 // plain variable name
7848 if (this.expect(this.tok.T_VARIABLE)) {
7849 var name = this.text().substring(1);
7850 this.next();
7851 variable = variable(name, false, false);
7852 } else {
7853 variable = variable('#ERR', false, false);
7854 }
7855 if (this.token === '=') {
7856 return node(variable, this.next().read_expr());
7857 } else {
7858 return variable;
7859 }
7860 }, ',');
7861 }
7862
7863 };
7864
7865 },{}],116:[function(require,module,exports){
7866 /*!
7867 * Copyright (C) 2017 Glayzzle (BSD3 License)
7868 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
7869 * @url http://glayzzle.com
7870 */
7871 "use strict";
7872 module.exports = {
7873 /**
7874 * Reads a variable
7875 *
7876 * ```ebnf
7877 * variable ::= &? ...complex @todo
7878 * ```
7879 *
7880 * Some samples of parsed code :
7881 * ```php
7882 * &$var // simple var
7883 * $var // simple var
7884 * classname::CONST_NAME // dynamic class name with const retrieval
7885 * foo() // function call
7886 * $var->func()->property // chained calls
7887 * ```
7888 */
7889 read_variable: function(read_only, encapsed, byref) {
7890 var result;
7891
7892 // check the byref flag
7893 if (!byref && this.token === '&') {
7894 byref = true;
7895 this.next();
7896 }
7897
7898 // reads the entry point
7899 if (this.is([this.tok.T_VARIABLE, '$'])) {
7900 result = this.read_reference_variable(encapsed, byref);
7901 } else if (this.is([this.tok.T_NS_SEPARATOR, this.tok.T_STRING, this.tok.T_NAMESPACE])) {
7902 result = this.node();
7903 var name = this.read_namespace_name();
7904 if (
7905 this.token != this.tok.T_DOUBLE_COLON
7906 && this.token != '('
7907 ) {
7908 // @see parser.js line 130 : resolves a conflict with scalar
7909 var literal = name.name.toLowerCase();
7910 if (literal === 'true') {
7911 result = result('boolean', true);
7912 } else if (literal === 'false') {
7913 result = result('boolean', false);
7914 } else {
7915 // @todo null keyword ?
7916 result = result('constref', name);
7917 }
7918 } else {
7919 result = name;
7920 }
7921 } else if (this.token === this.tok.T_STATIC) {
7922 result = this.node('constref');
7923 this.next();
7924 result = result('static');
7925 } else {
7926 this.expect('VARIABLE');
7927 }
7928
7929 // static mode
7930 if (this.token === this.tok.T_DOUBLE_COLON) {
7931 result = this.read_static_getter(result, encapsed);
7932 }
7933
7934 return this.recursive_variable_chain_scan(result, read_only, encapsed);
7935 }
7936
7937 // resolves a static call
7938 ,read_static_getter: function(what, encapsed) {
7939 var result = this.node('staticlookup');
7940 var offset = null;
7941 if (this.next().is([this.tok.T_VARIABLE, '$'])) {
7942 offset = this.read_reference_variable(encapsed, false);
7943 } else if (
7944 this.is('IDENTIFIER') || this.token === this.tok.T_STRING
7945 || this.token === this.tok.T_CLASS
7946 ) {
7947 offset = this.node('constref');
7948 var name = this.text();
7949 this.next();
7950 offset = offset(name);
7951 } else {
7952 this.error([this.tok.T_VARIABLE, this.tok.T_STRING]);
7953 // graceful mode : set getter as error node and continue
7954 offset = this.node('constref');
7955 var name = this.text();
7956 this.next();
7957 offset = offset(name);
7958 }
7959 return result(what, offset);
7960 }
7961
7962 ,recursive_variable_chain_scan: function(result, read_only, encapsed) {
7963 recursive_scan_loop:
7964 while(this.token != this.EOF) {
7965 switch(this.token) {
7966 case '(':
7967 if (read_only) {
7968 // @fixme : add more informations & test
7969 return result;
7970 } else {
7971 result = this.node('call')(
7972 result, this.read_function_argument_list()
7973 );
7974 }
7975 break;
7976 case '[':
7977 var node = this.node('offsetlookup');
7978 this.next();
7979 var offset = false;
7980 if (encapsed) {
7981 offset = this.read_encaps_var_offset();
7982 this.expect(']') && this.next();
7983 } else {
7984 // callable_variable : https://github.com/php/php-src/blob/493524454d66adde84e00d249d607ecd540de99f/Zend/zend_language_parser.y#L1122
7985 if (this.token !== ']') {
7986 offset = this.read_expr();
7987 this.expect(']') && this.next();
7988 } else {
7989 this.next();
7990 }
7991 }
7992 result = node(result, offset);
7993 break;
7994 case this.tok.T_DOUBLE_COLON:
7995 var node = this.node('staticlookup'), offset;
7996 this.next();
7997
7998 if(this.is('IDENTIFIER') || this.token === this.tok.T_STRING
7999 || this.token === this.tok.T_CLASS
8000 ) {
8001 offset = this.node('constref');
8002 var name = this.text();
8003 this.next();
8004 offset = offset(name);
8005
8006 if(this.token === this.tok.T_OBJECT_OPERATOR || this.token === this.tok.T_DOUBLE_COLON) {
8007 this.error();
8008 }
8009 }
8010
8011 result = node(result, offset);
8012 break;
8013 case this.tok.T_OBJECT_OPERATOR:
8014 var node = this.node('propertylookup');
8015 var what = null;
8016 switch(this.next().token) {
8017 case this.tok.T_STRING:
8018 what = this.node('constref');
8019 var name = this.text();
8020 this.next();
8021 what = what(name);
8022 if (this.token === this.tok.T_VARIABLE) {
8023 var inner = this.node('variable');
8024 name = this.text().substring(1);
8025 this.next();
8026 what = this.node('encapsed')(
8027 [what, inner(name, false, false)],
8028 'offset'
8029 );
8030 if (what.loc && what.value[0].loc) {
8031 what.loc.start = what.value[0].loc.start;
8032 }
8033 } else if (this.token === '{') {
8034 var expr = this.next().read_expr();
8035 this.expect('}') && this.next();
8036 what = this.node('encapsed')(
8037 [what, expr],
8038 'offset'
8039 );
8040 if (what.loc && what.value[0].loc) {
8041 what.loc.start = what.value[0].loc.start;
8042 }
8043 }
8044 break;
8045 case this.tok.T_VARIABLE:
8046 what = this.node('variable');
8047 var name = this.text().substring(1);
8048 this.next();
8049 what = what(name, false, false);
8050 break;
8051 case '$':
8052 this.next().expect(['{', this.tok.T_VARIABLE]);
8053 if (this.token === '{') {
8054 // $obj->${$varname}
8055 what = this.next().read_expr();
8056 this.expect('}') && this.next();
8057 } else {
8058 // $obj->$$varname
8059 what = this.read_expr();
8060 }
8061 break;
8062 case '{':
8063 what = this.next().read_expr();
8064 this.expect('}') && this.next();
8065 break;
8066 default:
8067 this.error([this.tok.T_STRING, this.tok.T_VARIABLE]);
8068 // graceful mode : set what as error mode & continue
8069 what = this.node('constref');
8070 var name = this.text();
8071 this.next();
8072 what = what(name);
8073 break;
8074 }
8075 result = node(result, what);
8076 break;
8077 default:
8078 break recursive_scan_loop;
8079 }
8080 }
8081 return result;
8082 }
8083 /**
8084 * https://github.com/php/php-src/blob/493524454d66adde84e00d249d607ecd540de99f/Zend/zend_language_parser.y#L1231
8085 */
8086 ,read_encaps_var_offset: function() {
8087 var offset = this.node();
8088 if (this.token === this.tok.T_STRING) {
8089 var text = this.text();
8090 var isDblQuote = text[0] === '"';
8091 text = text.substring(1, text.length - 1);
8092 this.next();
8093 offset = offset(
8094 'string', isDblQuote, this.resolve_special_chars(text)
8095 );
8096 } else if (this.token === this.tok.T_NUM_STRING) {
8097 var num = this.text();
8098 this.next();
8099 offset = offset('number', num);
8100 } else if (this.token === this.tok.T_VARIABLE) {
8101 var name = this.text().substring(1);
8102 this.next();
8103 offset = offset('variable', name, false, false);
8104 } else {
8105 this.expect([
8106 this.tok.T_STRING,
8107 this.tok.T_NUM_STRING,
8108 this.tok.T_VARIABLE
8109 ]);
8110 // fallback : consider as text
8111 var text = this.text();
8112 this.next();
8113 offset = offset('string', false, text);
8114 }
8115 return offset;
8116 }
8117 /**
8118 * ```ebnf
8119 * reference_variable ::= simple_variable ('[' OFFSET ']')* | '{' EXPR '}'
8120 * ```
8121 * <code>
8122 * $foo[123]; // foo is an array ==> gets its entry
8123 * $foo{1}; // foo is a string ==> get the 2nd char offset
8124 * ${'foo'}[123]; // get the dynamic var $foo
8125 * $foo[123]{1}; // gets the 2nd char from the 123 array entry
8126 * </code>
8127 */
8128 ,read_reference_variable: function(encapsed, byref) {
8129 var result = this.read_simple_variable(byref);
8130 while(this.token != this.EOF) {
8131 var node = this.node();
8132 if (this.token == '[') {
8133 var offset = null;
8134 if (encapsed) {
8135 offset = this.next().read_encaps_var_offset();
8136 } else {
8137 offset = this.next().token === ']' ? null : this.read_dim_offset();
8138 }
8139 this.expect(']') && this.next();
8140 result = node('offsetlookup', result, offset);
8141 } else if (this.token == '{' && !encapsed) {
8142 var offset = this.next().read_expr();
8143 this.expect('}') && this.next();
8144 result = node('offsetlookup', result, offset);
8145 } else break;
8146 }
8147 return result;
8148 }
8149 /**
8150 * ```ebnf
8151 * simple_variable ::= T_VARIABLE | '$' '{' expr '}' | '$' simple_variable
8152 * ```
8153 */
8154 ,read_simple_variable: function(byref) {
8155 var result = this.node('variable');
8156 if (this.expect([this.tok.T_VARIABLE, '$']) && this.token === this.tok.T_VARIABLE) {
8157 // plain variable name
8158 var name = this.text().substring(1);
8159 this.next();
8160 result = result(name, byref, false);
8161 } else {
8162 if (this.token === '$') this.next();
8163 // dynamic variable name
8164 switch(this.token) {
8165 case '{':
8166 var expr = this.next().read_expr();
8167 this.expect('}') && this.next();
8168 result = result(expr, byref, true);
8169 break;
8170 case '$': // $$$var
8171 result = result(this.read_simple_variable(false), byref);
8172 break;
8173 case this.tok.T_VARIABLE: // $$var
8174 var name = this.text().substring(1);
8175 var node = this.node('variable');
8176 this.next();
8177 result = result(node(name, false, false), byref, false);
8178 break;
8179 default:
8180 this.error(['{', '$', this.tok.T_VARIABLE]);
8181 // graceful mode
8182 var name = this.text();
8183 this.next();
8184 result = result(name, byref, false);
8185 }
8186 }
8187 return result;
8188 }
8189 };
8190
8191 },{}],117:[function(require,module,exports){
8192 /*!
8193 * Copyright (C) 2017 Glayzzle (BSD3 License)
8194 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
8195 * @url http://glayzzle.com
8196 */
8197
8198 // exports token index
8199 module.exports = {
8200 values: {
8201 101: 'T_HALT_COMPILER',
8202 102: 'T_USE',
8203 103: 'T_ENCAPSED_AND_WHITESPACE',
8204 104: 'T_OBJECT_OPERATOR',
8205 105: 'T_STRING',
8206 106: 'T_DOLLAR_OPEN_CURLY_BRACES',
8207 107: 'T_STRING_VARNAME',
8208 108: 'T_CURLY_OPEN',
8209 109: 'T_NUM_STRING',
8210 110: 'T_ISSET',
8211 111: 'T_EMPTY',
8212 112: 'T_INCLUDE',
8213 113: 'T_INCLUDE_ONCE',
8214 114: 'T_EVAL',
8215 115: 'T_REQUIRE',
8216 116: 'T_REQUIRE_ONCE',
8217 117: 'T_NAMESPACE',
8218 118: 'T_NS_SEPARATOR',
8219 119: 'T_AS',
8220 120: 'T_IF',
8221 121: 'T_ENDIF',
8222 122: 'T_WHILE',
8223 123: 'T_DO',
8224 124: 'T_FOR',
8225 125: 'T_SWITCH',
8226 126: 'T_BREAK',
8227 127: 'T_CONTINUE',
8228 128: 'T_RETURN',
8229 129: 'T_GLOBAL',
8230 130: 'T_STATIC',
8231 131: 'T_ECHO',
8232 132: 'T_INLINE_HTML',
8233 133: 'T_UNSET',
8234 134: 'T_FOREACH',
8235 135: 'T_DECLARE',
8236 136: 'T_TRY',
8237 137: 'T_THROW',
8238 138: 'T_GOTO',
8239 139: 'T_FINALLY',
8240 140: 'T_CATCH',
8241 141: 'T_ENDDECLARE',
8242 142: 'T_LIST',
8243 143: 'T_CLONE',
8244 144: 'T_PLUS_EQUAL',
8245 145: 'T_MINUS_EQUAL',
8246 146: 'T_MUL_EQUAL',
8247 147: 'T_DIV_EQUAL',
8248 148: 'T_CONCAT_EQUAL',
8249 149: 'T_MOD_EQUAL',
8250 150: 'T_AND_EQUAL',
8251 151: 'T_OR_EQUAL',
8252 152: 'T_XOR_EQUAL',
8253 153: 'T_SL_EQUAL',
8254 154: 'T_SR_EQUAL',
8255 155: 'T_INC',
8256 156: 'T_DEC',
8257 157: 'T_BOOLEAN_OR',
8258 158: 'T_BOOLEAN_AND',
8259 159: 'T_LOGICAL_OR',
8260 160: 'T_LOGICAL_AND',
8261 161: 'T_LOGICAL_XOR',
8262 162: 'T_SL',
8263 163: 'T_SR',
8264 164: 'T_IS_IDENTICAL',
8265 165: 'T_IS_NOT_IDENTICAL',
8266 166: 'T_IS_EQUAL',
8267 167: 'T_IS_NOT_EQUAL',
8268 168: 'T_IS_SMALLER_OR_EQUAL',
8269 169: 'T_IS_GREATER_OR_EQUAL',
8270 170: 'T_INSTANCEOF',
8271 171: 'T_INT_CAST',
8272 172: 'T_DOUBLE_CAST',
8273 173: 'T_STRING_CAST',
8274 174: 'T_ARRAY_CAST',
8275 175: 'T_OBJECT_CAST',
8276 176: 'T_BOOL_CAST',
8277 177: 'T_UNSET_CAST',
8278 178: 'T_EXIT',
8279 179: 'T_PRINT',
8280 180: 'T_YIELD',
8281 181: 'T_YIELD_FROM',
8282 182: 'T_FUNCTION',
8283 183: 'T_DOUBLE_ARROW',
8284 184: 'T_DOUBLE_COLON',
8285 185: 'T_ARRAY',
8286 186: 'T_CALLABLE',
8287 187: 'T_CLASS',
8288 188: 'T_ABSTRACT',
8289 189: 'T_TRAIT',
8290 190: 'T_FINAL',
8291 191: 'T_EXTENDS',
8292 192: 'T_INTERFACE',
8293 193: 'T_IMPLEMENTS',
8294 194: 'T_VAR',
8295 195: 'T_PUBLIC',
8296 196: 'T_PROTECTED',
8297 197: 'T_PRIVATE',
8298 198: 'T_CONST',
8299 199: 'T_NEW',
8300 200: 'T_INSTEADOF',
8301 201: 'T_ELSEIF',
8302 202: 'T_ELSE',
8303 203: 'T_ENDSWITCH',
8304 204: 'T_CASE',
8305 205: 'T_DEFAULT',
8306 206: 'T_ENDFOR',
8307 207: 'T_ENDFOREACH',
8308 208: 'T_ENDWHILE',
8309 209: 'T_CONSTANT_ENCAPSED_STRING',
8310 210: 'T_LNUMBER',
8311 211: 'T_DNUMBER',
8312 212: 'T_LINE',
8313 213: 'T_FILE',
8314 214: 'T_DIR',
8315 215: 'T_TRAIT_C',
8316 216: 'T_METHOD_C',
8317 217: 'T_FUNC_C',
8318 218: 'T_NS_C',
8319 219: 'T_START_HEREDOC',
8320 220: 'T_END_HEREDOC',
8321 221: 'T_CLASS_C',
8322 222: 'T_VARIABLE',
8323 223: 'T_OPEN_TAG',
8324 224: 'T_OPEN_TAG_WITH_ECHO',
8325 225: 'T_CLOSE_TAG',
8326 226: 'T_WHITESPACE',
8327 227: 'T_COMMENT',
8328 228: 'T_DOC_COMMENT',
8329 229: 'T_ELLIPSIS',
8330 230: 'T_COALESCE',
8331 231: 'T_POW',
8332 232: 'T_POW_EQUAL',
8333 233: 'T_SPACESHIP'
8334 },
8335 names: {
8336 T_HALT_COMPILER: 101,
8337 T_USE: 102,
8338 T_ENCAPSED_AND_WHITESPACE: 103,
8339 T_OBJECT_OPERATOR: 104,
8340 T_STRING: 105,
8341 T_DOLLAR_OPEN_CURLY_BRACES: 106,
8342 T_STRING_VARNAME: 107,
8343 T_CURLY_OPEN: 108,
8344 T_NUM_STRING: 109,
8345 T_ISSET: 110,
8346 T_EMPTY: 111,
8347 T_INCLUDE: 112,
8348 T_INCLUDE_ONCE: 113,
8349 T_EVAL: 114,
8350 T_REQUIRE: 115,
8351 T_REQUIRE_ONCE: 116,
8352 T_NAMESPACE: 117,
8353 T_NS_SEPARATOR: 118,
8354 T_AS: 119,
8355 T_IF: 120,
8356 T_ENDIF: 121,
8357 T_WHILE: 122,
8358 T_DO: 123,
8359 T_FOR: 124,
8360 T_SWITCH: 125,
8361 T_BREAK: 126,
8362 T_CONTINUE: 127,
8363 T_RETURN: 128,
8364 T_GLOBAL: 129,
8365 T_STATIC: 130,
8366 T_ECHO: 131,
8367 T_INLINE_HTML: 132,
8368 T_UNSET: 133,
8369 T_FOREACH: 134,
8370 T_DECLARE: 135,
8371 T_TRY: 136,
8372 T_THROW: 137,
8373 T_GOTO: 138,
8374 T_FINALLY: 139,
8375 T_CATCH: 140,
8376 T_ENDDECLARE: 141,
8377 T_LIST: 142,
8378 T_CLONE: 143,
8379 T_PLUS_EQUAL: 144,
8380 T_MINUS_EQUAL: 145,
8381 T_MUL_EQUAL: 146,
8382 T_DIV_EQUAL: 147,
8383 T_CONCAT_EQUAL: 148,
8384 T_MOD_EQUAL: 149,
8385 T_AND_EQUAL: 150,
8386 T_OR_EQUAL: 151,
8387 T_XOR_EQUAL: 152,
8388 T_SL_EQUAL: 153,
8389 T_SR_EQUAL: 154,
8390 T_INC: 155,
8391 T_DEC: 156,
8392 T_BOOLEAN_OR: 157,
8393 T_BOOLEAN_AND: 158,
8394 T_LOGICAL_OR: 159,
8395 T_LOGICAL_AND: 160,
8396 T_LOGICAL_XOR: 161,
8397 T_SL: 162,
8398 T_SR: 163,
8399 T_IS_IDENTICAL: 164,
8400 T_IS_NOT_IDENTICAL: 165,
8401 T_IS_EQUAL: 166,
8402 T_IS_NOT_EQUAL: 167,
8403 T_IS_SMALLER_OR_EQUAL: 168,
8404 T_IS_GREATER_OR_EQUAL: 169,
8405 T_INSTANCEOF: 170,
8406 T_INT_CAST: 171,
8407 T_DOUBLE_CAST: 172,
8408 T_STRING_CAST: 173,
8409 T_ARRAY_CAST: 174,
8410 T_OBJECT_CAST: 175,
8411 T_BOOL_CAST: 176,
8412 T_UNSET_CAST: 177,
8413 T_EXIT: 178,
8414 T_PRINT: 179,
8415 T_YIELD: 180,
8416 T_YIELD_FROM: 181,
8417 T_FUNCTION: 182,
8418 T_DOUBLE_ARROW: 183,
8419 T_DOUBLE_COLON: 184,
8420 T_ARRAY: 185,
8421 T_CALLABLE: 186,
8422 T_CLASS: 187,
8423 T_ABSTRACT: 188,
8424 T_TRAIT: 189,
8425 T_FINAL: 190,
8426 T_EXTENDS: 191,
8427 T_INTERFACE: 192,
8428 T_IMPLEMENTS: 193,
8429 T_VAR: 194,
8430 T_PUBLIC: 195,
8431 T_PROTECTED: 196,
8432 T_PRIVATE: 197,
8433 T_CONST: 198,
8434 T_NEW: 199,
8435 T_INSTEADOF: 200,
8436 T_ELSEIF: 201,
8437 T_ELSE: 202,
8438 T_ENDSWITCH: 203,
8439 T_CASE: 204,
8440 T_DEFAULT: 205,
8441 T_ENDFOR: 206,
8442 T_ENDFOREACH: 207,
8443 T_ENDWHILE: 208,
8444 T_CONSTANT_ENCAPSED_STRING: 209,
8445 T_LNUMBER: 210,
8446 T_DNUMBER: 211,
8447 T_LINE: 212,
8448 T_FILE: 213,
8449 T_DIR: 214,
8450 T_TRAIT_C: 215,
8451 T_METHOD_C: 216,
8452 T_FUNC_C: 217,
8453 T_NS_C: 218,
8454 T_START_HEREDOC: 219,
8455 T_END_HEREDOC: 220,
8456 T_CLASS_C: 221,
8457 T_VARIABLE: 222,
8458 T_OPEN_TAG: 223,
8459 T_OPEN_TAG_WITH_ECHO: 224,
8460 T_CLOSE_TAG: 225,
8461 T_WHITESPACE: 226,
8462 T_COMMENT: 227,
8463 T_DOC_COMMENT: 228,
8464 T_ELLIPSIS: 229,
8465 T_COALESCE: 230,
8466 T_POW: 231,
8467 T_POW_EQUAL: 232,
8468 T_SPACESHIP: 233
8469 }
8470 };
8471
8472 },{}],"php-parser":[function(require,module,exports){
8473 (function (Buffer){
8474 /*!
8475 * Copyright (C) 2017 Glayzzle (BSD3 License)
8476 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
8477 * @url http://glayzzle.com
8478 */
8479
8480 var lexer = require('./lexer');
8481 var parser = require('./parser');
8482 var tokens = require('./tokens');
8483 var AST = require('./ast');
8484
8485 /**
8486 * @private combine structures
8487 */
8488 function combine(src, to) {
8489 var keys = Object.keys(src);
8490 var i = keys.length;
8491 while (i--) {
8492 var k = keys[i];
8493 var val = src[k];
8494 if (val === null) {
8495 delete to[k];
8496 } else if (typeof val === 'function') {
8497 to[k] = val.bind(to);
8498 } else if (Array.isArray(val)) {
8499 to[k] = Array.isArray(to[k]) ? to[k].concat(val) : val;
8500 } else if (typeof val === 'object') {
8501 to[k] = typeof to[k] === 'object' ? combine(val, to[k]) : val;
8502 } else {
8503 to[k] = val;
8504 }
8505 }
8506 return to;
8507 }
8508
8509 /**
8510 * Initialise a new parser instance with the specified options
8511 *
8512 * Usage :
8513 * ```js
8514 * var parser = require('php-parser');
8515 * var instance = new parser({
8516 * parser: {
8517 * extractDoc: true,
8518 * suppressErrors: true
8519 * },
8520 * ast: {
8521 * withPositions: true
8522 * },
8523 * lexer: {
8524 * short_tags: true,
8525 * asp_tags: true
8526 * }
8527 * });
8528 *
8529 * var evalAST = instance.parseEval('some php code');
8530 * var codeAST = instance.parseCode('<?php some php code', 'foo.php');
8531 * var tokens = instance.tokenGetAll('<?php some php code');
8532 * ```
8533 *
8534 * @constructor {Engine}
8535 * @param {Object} options - List of options
8536 *
8537 * @property {Lexer} lexer
8538 * @property {Parser} parser
8539 * @property {AST} ast
8540 * @property {Object} tokens
8541 */
8542 var engine = function(options) {
8543 if (typeof this === 'function') {
8544 return new this(options);
8545 }
8546 this.tokens = tokens;
8547 this.lexer = new lexer(this);
8548 this.ast = new AST();
8549 this.parser = new parser(this.lexer, this.ast);
8550 if (options && typeof options === 'object') {
8551 combine(options, this);
8552 }
8553 };
8554
8555 /**
8556 * Check if the inpyt is a buffer or a string
8557 * @param {Buffer|String} buffer Input value that can be either a buffer or a string
8558 * @return {String} Returns the string from input
8559 */
8560 var getStringBuffer = function(buffer) {
8561 return Buffer.isBuffer(buffer) ? buffer.toString() : buffer;
8562 };
8563
8564 /**
8565 * Creates a new instance (Helper)
8566 * @param {Object} options
8567 * @return {Engine}
8568 * @private
8569 */
8570 engine.create = function(options) {
8571 return new engine(options);
8572 };
8573
8574 /**
8575 * Evaluate the buffer
8576 * @private
8577 */
8578 engine.parseEval = function(buffer, options) {
8579 var self = new engine(options);
8580 return self.parseEval(buffer);
8581 };
8582
8583 /**
8584 * Parse an evaluating mode string (no need to open php tags)
8585 * @param {String} buffer
8586 * @return {Program}
8587 */
8588 engine.prototype.parseEval = function(buffer) {
8589 this.lexer.mode_eval = true;
8590 this.lexer.all_tokens = false;
8591 buffer = getStringBuffer(buffer);
8592 return this.parser.parse(buffer, 'eval');
8593 };
8594
8595 /**
8596 * Static function that parse a php code with open/close tags
8597 * @private
8598 */
8599 engine.parseCode = function(buffer, filename, options) {
8600 if (typeof filename === 'object') {
8601 // retro-compatibility
8602 options = filename;
8603 filename = 'unknown';
8604 }
8605 var self = new engine(options);
8606 return self.parseCode(buffer, filename);
8607 };
8608
8609 /**
8610 * Function that parse a php code with open/close tags
8611 *
8612 * Sample code :
8613 * ```php
8614 * <?php $x = 1;
8615 * ```
8616 *
8617 * Usage :
8618 * ```js
8619 * var parser = require('php-parser');
8620 * var phpParser = new parser({
8621 * // some options
8622 * });
8623 * var ast = phpParser.parseCode('...php code...', 'foo.php');
8624 * ```
8625 * @param {String} buffer - The code to be parsed
8626 * @param {String} filename - Filename
8627 * @return {Program}
8628 */
8629 engine.prototype.parseCode = function(buffer, filename) {
8630 this.lexer.mode_eval = false;
8631 this.lexer.all_tokens = false;
8632 buffer = getStringBuffer(buffer);
8633 return this.parser.parse(buffer, filename);
8634 };
8635
8636 /**
8637 * Split the buffer into tokens
8638 * @private
8639 */
8640 engine.tokenGetAll = function(buffer, options) {
8641 var self = new engine(options);
8642 return self.tokenGetAll(buffer);
8643 };
8644
8645 /**
8646 * Extract tokens from the specified buffer.
8647 * > Note that the output tokens are *STRICLY* similar to PHP function `token_get_all`
8648 * @param {String} buffer
8649 * @return {String[]} - Each item can be a string or an array with following informations [token_name, text, line_number]
8650 */
8651 engine.prototype.tokenGetAll = function(buffer) {
8652 this.lexer.mode_eval = false;
8653 this.lexer.all_tokens = true;
8654 buffer = getStringBuffer(buffer);
8655 var EOF = this.lexer.EOF;
8656 var names = this.tokens.values;
8657 this.lexer.setInput(buffer);
8658 var token = this.lexer.lex() || EOF;
8659 var result = [];
8660 while(token != EOF) {
8661 var entry = this.lexer.yytext;
8662 if (names.hasOwnProperty(token)) {
8663 entry = [names[token], entry, this.lexer.yylloc.first_line];
8664 }
8665 result.push(entry);
8666 token = this.lexer.lex() || EOF;
8667 }
8668 return result;
8669 };
8670
8671 // exports the function
8672 module.exports = engine;
8673
8674 }).call(this,{"isBuffer":require("../node_modules/is-buffer/index.js")})
8675 },{"../node_modules/is-buffer/index.js":1,"./ast":3,"./lexer":92,"./parser":101,"./tokens":117}]},{},[]);
8676